From cf96edff1cf01346a694970986065ac2b7ce4c08 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Thu, 9 Feb 2023 22:10:10 -0500 Subject: [PATCH] agx: Implement gathers (nir_texop_tg4) Passes dEQP-GLES31.functional.texture.gather.* Signed-off-by: Alyssa Rosenzweig Part-of: --- docs/features.txt | 6 ++--- src/asahi/compiler/agx_compile.c | 28 +++++++++++++++++++++- src/asahi/compiler/agx_nir_lower_texture.c | 1 + src/gallium/drivers/asahi/agx_pipe.c | 6 ++--- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/docs/features.txt b/docs/features.txt index 08c8a5ec546..fb3ae9e2bf9 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -122,7 +122,7 @@ GL 4.0, GLSL 4.00 --- all DONE: freedreno/a6xx, i965/gen7+, nvc0, r600, radeonsi - Implicit signed -> unsigned conversions DONE (softpipe, ) - Fused multiply-add DONE (softpipe, ) - Packing/bitfield/conversion functions DONE (freedreno, softpipe, panfrost, asahi) - - Enhanced textureGather DONE (freedreno, softpipe, panfrost) + - Enhanced textureGather DONE (freedreno, softpipe, panfrost, asahi) - Geometry shader instancing DONE (softpipe, ) - Geometry shader multiple streams DONE (softpipe, ) - Enhanced per-sample shading DONE () @@ -134,7 +134,7 @@ GL 4.0, GLSL 4.00 --- all DONE: freedreno/a6xx, i965/gen7+, nvc0, r600, radeonsi GL_ARB_tessellation_shader DONE (freedreno/a6xx, i965/gen7+, ) GL_ARB_texture_buffer_object_rgb32 DONE (freedreno, i965/gen6+, softpipe, panfrost) GL_ARB_texture_cube_map_array DONE (freedreno/a4xx+, i965/gen6+, nv50, softpipe) - GL_ARB_texture_gather DONE (freedreno, i965/gen6+, nv50, softpipe, v3d, panfrost) + GL_ARB_texture_gather DONE (freedreno, i965/gen6+, nv50, softpipe, v3d, panfrost, asahi) GL_ARB_texture_query_lod DONE (freedreno, i965, nv50, softpipe, v3d, panfrost) GL_ARB_transform_feedback2 DONE (freedreno/a3xx+, i965/gen6+, nv50, softpipe, v3d, panfrost) GL_ARB_transform_feedback3 DONE (freedreno/a3xx+, i965/gen7+, softpipe, ) @@ -258,7 +258,7 @@ GLES3.1, GLSL ES 3.1 -- all DONE: freedreno/a5xx+, i965/hsw+, nvc0, r600, radeon GL_ARB_texture_multisample (Multisample textures) DONE (freedreno/a5xx+, i965/gen7+, nv50) GL_ARB_texture_storage_multisample DONE (all drivers that support GL_ARB_texture_multisample) GL_ARB_vertex_attrib_binding DONE (all drivers) - GS5 Enhanced textureGather DONE (freedreno, i965/gen7+) + GS5 Enhanced textureGather DONE (freedreno, i965/gen7+, asahi) GS5 Packing/bitfield/conversion functions DONE (freedreno/a5xx+, i965/gen6+, asahi) GL_EXT_shader_integer_mix DONE (all drivers that support GLSL) diff --git a/src/asahi/compiler/agx_compile.c b/src/asahi/compiler/agx_compile.c index b904c4f4991..5c8cf1c4597 100644 --- a/src/asahi/compiler/agx_compile.c +++ b/src/asahi/compiler/agx_compile.c @@ -1132,6 +1132,7 @@ agx_lod_mode_for_nir(nir_texop op) { switch (op) { case nir_texop_tex: + case nir_texop_tg4: return AGX_LOD_MODE_AUTO_LOD; case nir_texop_txb: return AGX_LOD_MODE_AUTO_LOD_BIAS; @@ -1148,6 +1149,24 @@ agx_lod_mode_for_nir(nir_texop op) } } +static enum agx_gather +agx_gather_for_nir(nir_tex_instr *tex) +{ + if (tex->op == nir_texop_tg4) { + enum agx_gather components[] = { + AGX_GATHER_R, + AGX_GATHER_G, + AGX_GATHER_B, + AGX_GATHER_A, + }; + + assert(tex->component < ARRAY_SIZE(components)); + return components[tex->component]; + } else { + return AGX_GATHER_NONE; + } +} + static void agx_emit_tex(agx_builder *b, nir_tex_instr *instr) { @@ -1227,13 +1246,20 @@ agx_emit_tex(agx_builder *b, nir_tex_instr *instr) unsigned nr_channels = nir_dest_num_components(instr->dest); nir_component_mask_t mask = nir_ssa_def_components_read(&instr->dest.ssa); + /* Destination masking doesn't seem to work properly for gathers (because + * it's mostly pointless), but it does show up in the lowering of + * textureGatherOffsets. Don't try to mask the destination for gathers. + */ + if (instr->op == nir_texop_tg4) + mask = BITFIELD_MASK(nr_channels); + agx_index tmp = agx_temp(b->shader, dst.size); agx_instr *I = agx_texture_sample_to( b, tmp, coords, lod, texture, sampler, compare_offset, agx_tex_dim(instr->sampler_dim, instr->is_array), agx_lod_mode_for_nir(instr->op), mask, 0, !agx_is_null(packed_offset), - !agx_is_null(compare), AGX_GATHER_NONE); + !agx_is_null(compare), agx_gather_for_nir(instr)); if (txf) I->op = AGX_OPCODE_TEXTURE_LOAD; diff --git a/src/asahi/compiler/agx_nir_lower_texture.c b/src/asahi/compiler/agx_nir_lower_texture.c index 259facd9349..affdf55a6be 100644 --- a/src/asahi/compiler/agx_nir_lower_texture.c +++ b/src/asahi/compiler/agx_nir_lower_texture.c @@ -241,6 +241,7 @@ agx_nir_lower_texture(nir_shader *s) nir_lower_tex_options lower_tex_options = { .lower_txp = ~0, .lower_invalid_implicit_lod = true, + .lower_tg4_offsets = true, /* XXX: Metal seems to handle just like 3D txd, so why doesn't it work? * TODO: Stop using this lowering diff --git a/src/gallium/drivers/asahi/agx_pipe.c b/src/gallium/drivers/asahi/agx_pipe.c index 81087066f74..2363bb58153 100644 --- a/src/gallium/drivers/asahi/agx_pipe.c +++ b/src/gallium/drivers/asahi/agx_pipe.c @@ -1362,11 +1362,11 @@ agx_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return PIPE_ENDIAN_LITTLE; case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: - return is_deqp ? 4 : 0; + return 4; case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET: - return is_deqp ? -8 : 0; + return -8; case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET: - return is_deqp ? 7 : 0; + return 7; case PIPE_CAP_DRAW_INDIRECT: return true;