From 1dc7d0ade9b547f511bf970d975c02bc1bace4f9 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 14 Jan 2026 15:05:05 -0800 Subject: [PATCH] ir3: Skip shading_rate lowering when unneeded Some newer gen8 devices (like a840/kaanapali, but not x2-85 which is otherwise similar) flip the hw shading rate value around to match vulkan/gl instead of DX. Signed-off-by: Rob Clark Part-of: --- src/freedreno/common/freedreno_dev_info.h | 7 +++++++ src/freedreno/common/freedreno_devices.py | 3 ++- src/freedreno/ir3/ir3_compiler.c | 1 + src/freedreno/ir3/ir3_compiler.h | 2 ++ src/freedreno/ir3/ir3_nir.c | 6 ++++-- 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/freedreno/common/freedreno_dev_info.h b/src/freedreno/common/freedreno_dev_info.h index e2edf97a847..89c060567e1 100644 --- a/src/freedreno/common/freedreno_dev_info.h +++ b/src/freedreno/common/freedreno_dev_info.h @@ -373,6 +373,13 @@ struct fd_dev_info { bool has_primitive_shading_rate; + /* If true, the hw shading rate value matches vk/gl rather than dx. + * + * dx: (width_log2 << 2) | height_log2 + * vk: (height_log2 << 2) | width_log2 + */ + bool shading_rate_matches_vk; + /* A7XX gen1 and gen2 seem to require declaring SAMPLEMASK input * for fragment shading rate to be read correctly. * This workaround was seen in the prop driver v512.762.12. diff --git a/src/freedreno/common/freedreno_devices.py b/src/freedreno/common/freedreno_devices.py index 54640ccff74..6bd2e50964e 100644 --- a/src/freedreno/common/freedreno_devices.py +++ b/src/freedreno/common/freedreno_devices.py @@ -1522,7 +1522,8 @@ add_gpus([ GPUId(chip_id=0xffff44050A31, name="Adreno (TM) 840"), ], A6xxGPUInfo( CHIP.A8XX, - [a7xx_base, a7xx_gen3, a8xx_base, a8xx_gen2], + [a7xx_base, a7xx_gen3, a8xx_base, a8xx_gen2, + GPUProps(shading_rate_matches_vk = True)], num_ccu = 6, num_slices = 3, tile_align_w = 96, diff --git a/src/freedreno/ir3/ir3_compiler.c b/src/freedreno/ir3/ir3_compiler.c index 1acf7649f36..4598c429be1 100644 --- a/src/freedreno/ir3/ir3_compiler.c +++ b/src/freedreno/ir3/ir3_compiler.c @@ -266,6 +266,7 @@ ir3_compiler_create(struct fd_device *dev, const struct fd_dev_id *dev_id, compiler->has_shfl = true; compiler->reading_shading_rate_requires_smask_quirk = dev_info->props.reading_shading_rate_requires_smask_quirk; + compiler->shading_rate_matches_vk = dev_info->props.shading_rate_matches_vk; compiler->has_alias_rt = dev_info->props.has_alias_rt; compiler->mergedregs = true; compiler->has_sel_b_fneg = dev_info->props.has_sel_b_fneg; diff --git a/src/freedreno/ir3/ir3_compiler.h b/src/freedreno/ir3/ir3_compiler.h index 7540c5bec7b..c86845186c5 100644 --- a/src/freedreno/ir3/ir3_compiler.h +++ b/src/freedreno/ir3/ir3_compiler.h @@ -314,6 +314,8 @@ struct ir3_compiler { bool reading_shading_rate_requires_smask_quirk; + bool shading_rate_matches_vk; + bool cat3_rel_offset_0_quirk; bool has_sel_b_fneg; diff --git a/src/freedreno/ir3/ir3_nir.c b/src/freedreno/ir3/ir3_nir.c index a3f89236f64..c1b85dd7cb5 100644 --- a/src/freedreno/ir3/ir3_nir.c +++ b/src/freedreno/ir3/ir3_nir.c @@ -870,11 +870,13 @@ ir3_nir_post_finalize(struct ir3_shader *shader) NIR_PASS(_, s, ir3_nir_move_varying_inputs); NIR_PASS(_, s, nir_lower_fb_read); NIR_PASS(_, s, ir3_nir_lower_layer_id); - NIR_PASS(_, s, ir3_nir_lower_frag_shading_rate); + if (!compiler->shading_rate_matches_vk) + NIR_PASS(_, s, ir3_nir_lower_frag_shading_rate); } if (s->info.stage == MESA_SHADER_VERTEX || s->info.stage == MESA_SHADER_GEOMETRY) { - NIR_PASS(_, s, ir3_nir_lower_primitive_shading_rate); + if (!compiler->shading_rate_matches_vk) + NIR_PASS(_, s, ir3_nir_lower_primitive_shading_rate); } if (compiler->gen >= 6 && s->info.stage == MESA_SHADER_FRAGMENT &&