agx: wire up texture_samples/image_samplers

CL makes this too easy, lmao

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26614>
This commit is contained in:
Alyssa Rosenzweig 2023-11-21 19:26:53 -04:00 committed by Alyssa Rosenzweig
parent 6979a1aa07
commit bc6b2d087b
2 changed files with 44 additions and 17 deletions

View file

@ -27,7 +27,7 @@ texture_descriptor_ptr(nir_builder *b, nir_tex_instr *tex)
}
static bool
lower_txs(nir_builder *b, nir_instr *instr, UNUSED void *data)
lower_tex_crawl(nir_builder *b, nir_instr *instr, UNUSED void *data)
{
if (instr->type != nir_instr_type_tex)
return false;
@ -35,7 +35,7 @@ lower_txs(nir_builder *b, nir_instr *instr, UNUSED void *data)
nir_tex_instr *tex = nir_instr_as_tex(instr);
b->cursor = nir_before_instr(instr);
if (tex->op != nir_texop_txs)
if (tex->op != nir_texop_txs && tex->op != nir_texop_texture_samples)
return false;
nir_def *ptr = texture_descriptor_ptr(b, tex);
@ -46,13 +46,18 @@ lower_txs(nir_builder *b, nir_instr *instr, UNUSED void *data)
nir_def *lod = lod_idx >= 0 ? nir_u2u16(b, tex->src[lod_idx].src.ssa)
: nir_imm_intN_t(b, 0, 16);
nir_def *res =
libagx_txs(b, ptr, lod, nir_imm_int(b, nr_comps),
nir_imm_bool(b, tex->sampler_dim == GLSL_SAMPLER_DIM_BUF),
nir_imm_bool(b, tex->sampler_dim == GLSL_SAMPLER_DIM_1D),
nir_imm_bool(b, tex->sampler_dim == GLSL_SAMPLER_DIM_2D),
nir_imm_bool(b, tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE),
nir_imm_bool(b, tex->is_array));
nir_def *res;
if (tex->op == nir_texop_txs) {
res =
libagx_txs(b, ptr, lod, nir_imm_int(b, nr_comps),
nir_imm_bool(b, tex->sampler_dim == GLSL_SAMPLER_DIM_BUF),
nir_imm_bool(b, tex->sampler_dim == GLSL_SAMPLER_DIM_1D),
nir_imm_bool(b, tex->sampler_dim == GLSL_SAMPLER_DIM_2D),
nir_imm_bool(b, tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE),
nir_imm_bool(b, tex->is_array));
} else {
res = libagx_texture_samples(b, ptr);
}
nir_def_rewrite_uses(&tex->def, nir_trim_vector(b, res, nr_comps));
nir_instr_remove(instr);
@ -346,24 +351,27 @@ legalize_image_lod(nir_builder *b, nir_intrinsic_instr *intr, UNUSED void *data)
static nir_def *
txs_for_image(nir_builder *b, nir_intrinsic_instr *intr,
unsigned num_components, unsigned bit_size)
unsigned num_components, unsigned bit_size, bool query_samples)
{
nir_tex_instr *tex = nir_tex_instr_create(b->shader, 2);
tex->op = nir_texop_txs;
nir_tex_instr *tex = nir_tex_instr_create(b->shader, query_samples ? 1 : 2);
tex->op = query_samples ? nir_texop_texture_samples : nir_texop_txs;
tex->is_array = nir_intrinsic_image_array(intr);
tex->dest_type = nir_type_uint32;
tex->sampler_dim = nir_intrinsic_image_dim(intr);
tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_lod, intr->src[1].ssa);
tex->src[1] =
tex->src[0] =
nir_tex_src_for_ssa(nir_tex_src_texture_handle, intr->src[0].ssa);
if (!query_samples)
tex->src[1] = nir_tex_src_for_ssa(nir_tex_src_lod, intr->src[1].ssa);
nir_def_init(&tex->instr, &tex->def, num_components, bit_size);
nir_builder_instr_insert(b, &tex->instr);
nir_def *res = &tex->def;
/* Cube images are implemented as 2D arrays, so we need to divide here. */
if (tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE && res->num_components > 2) {
if (tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE && res->num_components > 2 &&
!query_samples) {
nir_def *divided = nir_udiv_imm(b, nir_channel(b, res, 2), 6);
res = nir_vector_insert_imm(b, res, divided, 2);
}
@ -468,9 +476,12 @@ lower_images(nir_builder *b, nir_intrinsic_instr *intr, UNUSED void *data)
}
case nir_intrinsic_bindless_image_size:
case nir_intrinsic_bindless_image_samples:
nir_def_rewrite_uses(
&intr->def,
txs_for_image(b, intr, intr->def.num_components, intr->def.bit_size));
txs_for_image(
b, intr, intr->def.num_components, intr->def.bit_size,
intr->intrinsic == nir_intrinsic_bindless_image_samples));
return true;
case nir_intrinsic_bindless_image_texel_address:
@ -558,7 +569,7 @@ agx_nir_lower_texture(nir_shader *s)
*/
NIR_PASS(progress, s, nir_shader_instructions_pass, lower_regular_texture,
nir_metadata_none, NULL);
NIR_PASS(progress, s, nir_shader_instructions_pass, lower_txs,
NIR_PASS(progress, s, nir_shader_instructions_pass, lower_tex_crawl,
nir_metadata_block_index | nir_metadata_dominance, NULL);
return progress;
@ -610,6 +621,8 @@ agx_nir_needs_texture_crawl(nir_instr *instr)
/* Queries, atomics always become a crawl */
case nir_intrinsic_image_size:
case nir_intrinsic_image_deref_size:
case nir_intrinsic_image_samples:
case nir_intrinsic_image_deref_samples:
case nir_intrinsic_image_atomic:
case nir_intrinsic_image_deref_atomic:
case nir_intrinsic_image_atomic_swap:
@ -635,6 +648,7 @@ agx_nir_needs_texture_crawl(nir_instr *instr)
switch (tex->op) {
/* Queries always become a crawl */
case nir_texop_txs:
case nir_texop_texture_samples:
return true;
/* Buffer textures need their format read */

View file

@ -55,6 +55,19 @@ libagx_txs(constant struct agx_texture_packed *ptr, uint16_t lod,
return size;
}
uint
libagx_texture_samples(constant struct agx_texture_packed *ptr)
{
agx_unpack(NULL, ptr, TEXTURE, d);
/* As above */
if (d.null)
return 0;
/* We may assume the input is multisampled, so just check the samples */
return (d.samples == AGX_SAMPLE_COUNT_2) ? 2 : 4;
}
static uint32_t
calculate_twiddled_coordinates(ushort2 coord, uint16_t tile_w_px,
uint16_t tile_h_px, uint32_t width_tl)