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 <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32115>
This commit is contained in:
Samuel Pitoiset 2024-11-13 17:34:06 +01:00 committed by Marge Bot
parent 0ad835a929
commit c08d2c40ed

View file

@ -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;