From 42aae5c3fad672f13be0a7ff99414ea6a7e321cb Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Sun, 20 Apr 2025 23:08:02 +0200 Subject: [PATCH] etnaviv: nir: Legalize txd derivatives src's The hardware expects textureGrad (txd) derivatives to be specified as offset coordinates from the base texture coordinate, rather than raw gradients. This change fixes the majority of the dEQP-GLES3.functional.shaders.texture_functions.texturegrad.* tests on GC7000. Remaining failures are due to shadow sampler handling, which will be addressed separately. Signed-off-by: Christian Gmeiner Part-of: --- .../etnaviv/etnaviv_nir_lower_texture.c | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/gallium/drivers/etnaviv/etnaviv_nir_lower_texture.c b/src/gallium/drivers/etnaviv/etnaviv_nir_lower_texture.c index 199ccc8f514..45ac922fcb2 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_nir_lower_texture.c +++ b/src/gallium/drivers/etnaviv/etnaviv_nir_lower_texture.c @@ -38,6 +38,34 @@ legalize_txf_lod(nir_builder *b, nir_tex_instr *tex, UNUSED void *data) return true; } +static bool +legalize_txd_derivatives(nir_builder *b, nir_tex_instr *tex, UNUSED void *data) +{ + if (tex->op != nir_texop_txd) + return false; + + b->cursor = nir_before_instr(&tex->instr); + + int coord_index = nir_tex_instr_src_index(tex, nir_tex_src_coord); + int ddx_index = nir_tex_instr_src_index(tex, nir_tex_src_ddx); + int ddy_index = nir_tex_instr_src_index(tex, nir_tex_src_ddy); + + assert(coord_index >= 0); + assert(ddx_index >= 0); + assert(ddy_index >= 0); + + nir_def *coord = tex->src[coord_index].src.ssa; + nir_def *ddx = tex->src[ddx_index].src.ssa; + nir_def *ddy = tex->src[ddy_index].src.ssa; + + coord = nir_trim_vector(b, coord, ddx->num_components); + + nir_src_rewrite(&tex->src[ddx_index].src, nir_fadd(b, coord, ddx)); + nir_src_rewrite(&tex->src[ddy_index].src, nir_fadd(b, coord, ddy)); + + return true; +} + bool etna_nir_lower_texture(nir_shader *s, struct etna_shader_key *key) { @@ -63,5 +91,8 @@ etna_nir_lower_texture(nir_shader *s, struct etna_shader_key *key) NIR_PASS(progress, s, nir_shader_tex_pass, legalize_txf_lod, nir_metadata_control_flow, NULL); + NIR_PASS(progress, s, nir_shader_tex_pass, legalize_txd_derivatives, + nir_metadata_control_flow, NULL); + return progress; }