From 76fdc606c8d6d486e5dda89398e04921cfbed76a Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 27 May 2026 17:30:30 +0200 Subject: [PATCH] ac/nir,radv: lower task payload to zeroes when the mesh shader has no task The Vulkan spec allows this to be used in a mesh shader as long as it's not accessed, so it can be eliminated. This fixes dEQP-VK.mesh_shader.ext.misc.payload_not_accessed. Cc: mesa-stable Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/common/nir/ac_nir.h | 2 +- .../common/nir/ac_nir_lower_taskmesh_io_to_mem.c | 13 ++++++++++++- src/amd/vulkan/nir/radv_nir_lower_io.c | 2 +- src/gallium/drivers/radeonsi/gfx/si_shader.c | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/amd/common/nir/ac_nir.h b/src/amd/common/nir/ac_nir.h index aa1c903def1..58a5c45054c 100644 --- a/src/amd/common/nir/ac_nir.h +++ b/src/amd/common/nir/ac_nir.h @@ -258,7 +258,7 @@ ac_nir_lower_task_outputs_to_mem(nir_shader *shader, bool has_query); bool -ac_nir_lower_mesh_inputs_to_mem(nir_shader *shader); +ac_nir_lower_mesh_inputs_to_mem(nir_shader *shader, bool has_task_shader); bool ac_nir_lower_global_access(nir_shader *shader); diff --git a/src/amd/common/nir/ac_nir_lower_taskmesh_io_to_mem.c b/src/amd/common/nir/ac_nir_lower_taskmesh_io_to_mem.c index 0cc85818e9f..d13d90e19c6 100644 --- a/src/amd/common/nir/ac_nir_lower_taskmesh_io_to_mem.c +++ b/src/amd/common/nir/ac_nir_lower_taskmesh_io_to_mem.c @@ -18,6 +18,8 @@ typedef struct { /* True if the lowering needs to insert shader query. */ bool has_query; + /* True if the mesh shader is linked with a task shader. */ + bool has_task_shader; } lower_tsms_io_state; static nir_def * @@ -264,6 +266,13 @@ lower_taskmesh_payload_load(nir_builder *b, unsigned num_components = intrin->def.num_components; unsigned bit_size = intrin->def.bit_size; + /* Lower payload to zeroes when the mesh shader isn't linked with a task + * shader because isn't going to be accessed. + */ + if (b->shader->info.stage == MESA_SHADER_MESH && !s->has_task_shader) { + return nir_imm_zero(b, num_components, bit_size); + } + nir_def *ptr = b->shader->info.stage == MESA_SHADER_TASK ? task_ring_entry_index(b, s) : @@ -361,10 +370,12 @@ lower_mesh_intrinsics(nir_builder *b, } bool -ac_nir_lower_mesh_inputs_to_mem(nir_shader *shader) +ac_nir_lower_mesh_inputs_to_mem(nir_shader *shader, bool has_task_shader) { lower_tsms_io_state state = {0}; + state.has_task_shader = has_task_shader; + return nir_shader_lower_instructions(shader, filter_mesh_input_load, lower_mesh_intrinsics, diff --git a/src/amd/vulkan/nir/radv_nir_lower_io.c b/src/amd/vulkan/nir/radv_nir_lower_io.c index b96d9134660..f993961ef2f 100644 --- a/src/amd/vulkan/nir/radv_nir_lower_io.c +++ b/src/amd/vulkan/nir/radv_nir_lower_io.c @@ -130,7 +130,7 @@ radv_nir_lower_io_to_mem(const struct radv_compiler_info *compiler_info, struct ac_nir_lower_task_outputs_to_mem(nir, info->cs.has_query); return true; } else if (nir->info.stage == MESA_SHADER_MESH) { - ac_nir_lower_mesh_inputs_to_mem(nir); + ac_nir_lower_mesh_inputs_to_mem(nir, stage->info.ms.has_task); return true; } diff --git a/src/gallium/drivers/radeonsi/gfx/si_shader.c b/src/gallium/drivers/radeonsi/gfx/si_shader.c index f354079c704..8490a4c675b 100644 --- a/src/gallium/drivers/radeonsi/gfx/si_shader.c +++ b/src/gallium/drivers/radeonsi/gfx/si_shader.c @@ -690,7 +690,7 @@ static void si_preprocess_nir(struct si_nir_shader_ctx *ctx) if (nir->info.stage == MESA_SHADER_TASK) { NIR_PASS(progress, nir, ac_nir_lower_task_outputs_to_mem, false); } else if (nir->info.stage == MESA_SHADER_MESH) { - NIR_PASS(progress, nir, ac_nir_lower_mesh_inputs_to_mem); + NIR_PASS(progress, nir, ac_nir_lower_mesh_inputs_to_mem, true); } if (mesa_shader_stage_is_compute(nir->info.stage)) {