From 4094706828b92a98e9a52e9c65c81ae093492d46 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 6 Aug 2025 14:13:29 +0200 Subject: [PATCH] radv: invalidate compute/rt descriptors at dispatch time Invalidating descriptors at bind time is wrong in a scenario like trace rays -> dispatch -> trace rays because RT uses compute shaders and the user SGPRs need to be re-emitted. Noticed by Konstantin. Fixes: 40ceece75f0 ("radv: invalidate compute/rt descriptors at pipeline bind time") Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_cmd_buffer.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index bb721754b14..37c48bdb379 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -7860,7 +7860,6 @@ radv_CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipeline if (cmd_buffer->state.compute_pipeline == compute_pipeline) return; radv_mark_descriptor_sets_dirty(cmd_buffer, pipelineBindPoint); - radv_mark_descriptor_sets_dirty(cmd_buffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR); radv_bind_shader(cmd_buffer, compute_pipeline->base.shaders[MESA_SHADER_COMPUTE], MESA_SHADER_COMPUTE); @@ -7876,15 +7875,6 @@ radv_CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipeline return; radv_mark_descriptor_sets_dirty(cmd_buffer, pipelineBindPoint); - /* Raytracing uses compute shaders but has separate bind points and pipelines. - * So if we set compute userdata & shader registers we should dirty the raytracing - * ones and the other way around. - * - * We only need to do this when the pipeline is dirty because when we switch between - * the two we always need to switch pipelines. - */ - radv_mark_descriptor_sets_dirty(cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE); - radv_bind_shader(cmd_buffer, rt_pipeline->base.base.shaders[MESA_SHADER_INTERSECTION], MESA_SHADER_INTERSECTION); radv_bind_rt_prolog(cmd_buffer, rt_pipeline->prolog); @@ -12590,6 +12580,7 @@ radv_before_dispatch(struct radv_cmd_buffer *cmd_buffer, struct radv_compute_pip { struct radv_device *device = radv_cmd_buffer_device(cmd_buffer); const struct radv_physical_device *pdev = radv_device_physical(device); + const bool pipeline_is_dirty = pipeline != cmd_buffer->state.emitted_compute_pipeline; struct radv_shader *compute_shader = bind_point == VK_PIPELINE_BIND_POINT_COMPUTE ? cmd_buffer->state.shaders[MESA_SHADER_COMPUTE] : cmd_buffer->state.rt_prolog; @@ -12636,6 +12627,19 @@ radv_before_dispatch(struct radv_cmd_buffer *cmd_buffer, struct radv_compute_pip if (bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR) radv_emit_rt_stack_size(cmd_buffer); } + + if (pipeline_is_dirty) { + /* Raytracing uses compute shaders but has separate bind points and pipelines. + * So if we set compute userdata & shader registers we should dirty the raytracing + * ones and the other way around. + * + * We only need to do this when the pipeline is dirty because when we switch between + * the two we always need to switch pipelines. + */ + radv_mark_descriptor_sets_dirty(cmd_buffer, bind_point == VK_PIPELINE_BIND_POINT_COMPUTE + ? VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR + : VK_PIPELINE_BIND_POINT_COMPUTE); + } } static void