From c08d2c40ed3ae4008da31669f3d3b24c9b5aff0d Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 13 Nov 2024 17:34:06 +0100 Subject: [PATCH] radv: fix ignoring src stage mask when dst stage mask is BOTTOM_OF_PIPE Otherwise the driver doesn't synchronize if there are image layout transitions. This fixes rendering issues with displayable DCC (usually black squares in the bottom of screen). This mostly happens when an application uses a lower resolution than the screen supports and fshack (wine/proton) which upscales images uses COMPUTE_SHADER->BOTTOM_OF_PIPE for the barrier after a dispatch. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11547 Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11600 Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11789 Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/8705 Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/9890 Cc: mesa-stable Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_cmd_buffer.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index b18c65aaa4d..d98303324fc 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -12830,6 +12830,7 @@ radv_barrier(struct radv_cmd_buffer *cmd_buffer, uint32_t dep_count, const VkDep enum radv_cmd_flush_bits dst_flush_bits = 0; VkPipelineStageFlags2 src_stage_mask = 0; VkPipelineStageFlags2 dst_stage_mask = 0; + bool has_image_transitions = false; if (cmd_buffer->state.render.active) radv_mark_noncoherent_rb(cmd_buffer); @@ -12866,20 +12867,14 @@ radv_barrier(struct radv_cmd_buffer *cmd_buffer, uint32_t dep_count, const VkDep dst_flush_bits |= radv_dst_access_flush(cmd_buffer, barrier->dstStageMask, barrier->dstAccessMask, image, &barrier->subresourceRange); } + + has_image_transitions |= dep_info->imageMemoryBarrierCount > 0; } - /* The Vulkan spec 1.1.98 says: - * - * "An execution dependency with only - * VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT in the destination stage mask - * will only prevent that stage from executing in subsequently - * submitted commands. As this stage does not perform any actual - * execution, this is not observable - in effect, it does not delay - * processing of subsequent commands. Similarly an execution dependency - * with only VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT in the source stage mask - * will effectively not wait for any prior commands to complete." + /* Only optimize BOTTOM_OF_PIPE as dst when there is no image layout transitions because it might + * need to synchronize. */ - if (dst_stage_mask != VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT) + if (has_image_transitions || dst_stage_mask != VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT) radv_stage_flush(cmd_buffer, src_stage_mask); cmd_buffer->state.flush_bits |= src_flush_bits;