From 07eb970d67f30e1a2ed53ad5124447f61f385f76 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Tue, 11 Jun 2024 16:13:18 +0200 Subject: [PATCH] radv: always save/restore all shader objects for internal operations If the application binds graphics shaders and that RADV performs an internal operation with a compute pipeline, no shader objects would be restored because binding the internal compute pipeline resets the ESO state. Cc: mesa-stable Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/meta/radv_meta.c | 57 +++++++++++++-------------------- 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/src/amd/vulkan/meta/radv_meta.c b/src/amd/vulkan/meta/radv_meta.c index fe1e9a96a4e..7d60fa1400c 100644 --- a/src/amd/vulkan/meta/radv_meta.c +++ b/src/amd/vulkan/meta/radv_meta.c @@ -125,13 +125,6 @@ radv_meta_save(struct radv_meta_saved_state *state, struct radv_cmd_buffer *cmd_ state->old_graphics_pipeline = cmd_buffer->state.graphics_pipeline; - for (unsigned i = 0; i <= MESA_SHADER_MESH; i++) { - if (i == MESA_SHADER_COMPUTE) - continue; - - state->old_shader_objs[i] = cmd_buffer->state.shader_objs[i]; - } - /* Save all dynamic states. */ state->dynamic = cmd_buffer->state.dynamic; } @@ -140,8 +133,10 @@ radv_meta_save(struct radv_meta_saved_state *state, struct radv_cmd_buffer *cmd_ assert(!(state->flags & RADV_META_SAVE_GRAPHICS_PIPELINE)); state->old_compute_pipeline = cmd_buffer->state.compute_pipeline; + } - state->old_shader_objs[MESA_SHADER_COMPUTE] = cmd_buffer->state.shader_objs[MESA_SHADER_COMPUTE]; + for (unsigned i = 0; i <= MESA_SHADER_MESH; i++) { + state->old_shader_objs[i] = cmd_buffer->state.shader_objs[i]; } if (state->flags & RADV_META_SAVE_DESCRIPTORS) { @@ -177,21 +172,6 @@ radv_meta_restore(const struct radv_meta_saved_state *state, struct radv_cmd_buf if (state->old_graphics_pipeline) { radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS, radv_pipeline_to_handle(&state->old_graphics_pipeline->base)); - } else { - cmd_buffer->state.graphics_pipeline = NULL; - - for (unsigned i = 0; i <= MESA_SHADER_MESH; i++) { - if (i == MESA_SHADER_COMPUTE) - continue; - - if (!state->old_shader_objs[i]) - continue; - - VkShaderEXT old_shader_obj = radv_shader_object_to_handle(state->old_shader_objs[i]); - VkShaderStageFlagBits s = mesa_to_vk_shader_stage(i); - - radv_CmdBindShadersEXT(radv_cmd_buffer_to_handle(cmd_buffer), 1, &s, &old_shader_obj); - } } /* Restore all dynamic states. */ @@ -206,29 +186,36 @@ radv_meta_restore(const struct radv_meta_saved_state *state, struct radv_cmd_buf if (state->old_compute_pipeline) { radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE, radv_pipeline_to_handle(&state->old_compute_pipeline->base)); - } else { - cmd_buffer->state.compute_pipeline = NULL; - - if (state->old_shader_objs[MESA_SHADER_COMPUTE]) { - VkShaderEXT old_shader_obj = radv_shader_object_to_handle(state->old_shader_objs[MESA_SHADER_COMPUTE]); - VkShaderStageFlagBits s = VK_SHADER_STAGE_COMPUTE_BIT; - - radv_CmdBindShadersEXT(radv_cmd_buffer_to_handle(cmd_buffer), 1, &s, &old_shader_obj); - } } } + VkShaderEXT shaders[MESA_SHADER_MESH + 1]; + VkShaderStageFlagBits stages[MESA_SHADER_MESH + 1]; + uint32_t stage_count = 0; + + for (unsigned i = 0; i <= MESA_SHADER_MESH; i++) { + if (state->old_shader_objs[i]) { + stages[stage_count] = mesa_to_vk_shader_stage(i); + shaders[stage_count] = radv_shader_object_to_handle(state->old_shader_objs[i]); + stage_count++; + } + } + + if (stage_count > 0) { + radv_CmdBindShadersEXT(radv_cmd_buffer_to_handle(cmd_buffer), stage_count, stages, shaders); + } + if (state->flags & RADV_META_SAVE_DESCRIPTORS) { radv_set_descriptor_set(cmd_buffer, bind_point, state->old_descriptor_set0, 0); } if (state->flags & RADV_META_SAVE_CONSTANTS) { - VkShaderStageFlags stages = VK_SHADER_STAGE_COMPUTE_BIT; + VkShaderStageFlags stage_flags = VK_SHADER_STAGE_COMPUTE_BIT; if (state->flags & RADV_META_SAVE_GRAPHICS_PIPELINE) - stages |= VK_SHADER_STAGE_ALL_GRAPHICS; + stage_flags |= VK_SHADER_STAGE_ALL_GRAPHICS; - vk_common_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), VK_NULL_HANDLE, stages, 0, + vk_common_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), VK_NULL_HANDLE, stage_flags, 0, MAX_PUSH_CONSTANTS_SIZE, state->push_constants); }