radv: add a workaround for a synchronization bug in Strange Brigade Vulkan

This game has broken synchronization reported by VVL and it indeed
doesn't wait for idle right before present. Workaround this by
injecting a full barrier (easier than rewriting the dep struct).

This only applies to the Vulkan backend.

Cc: mesa-stable
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/14705
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39480>
(cherry picked from commit 14d3fb5f1b)
This commit is contained in:
Samuel Pitoiset 2026-01-23 09:19:21 +01:00 committed by Eric Engestrom
parent 33fbf9bf61
commit 362faeb15e
5 changed files with 39 additions and 1 deletions

View file

@ -1064,7 +1064,7 @@
"description": "radv: add a workaround for a synchronization bug in Strange Brigade Vulkan",
"nominated": true,
"nomination_type": 1,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null,
"notes": null

View file

@ -0,0 +1,31 @@
/*
* Copyright © 2026 Valve Corporation
*
* SPDX-License-Identifier: MIT
*/
#include "radv_cmd_buffer.h"
#include "radv_device.h"
#include "radv_entrypoints.h"
VKAPI_ATTR void VKAPI_CALL
strange_brigade_CmdPipelineBarrier2(VkCommandBuffer commandBuffer, const VkDependencyInfo *pDependencyInfo)
{
VK_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
struct radv_device *device = radv_cmd_buffer_device(cmd_buffer);
for (uint32_t i = 0; i < pDependencyInfo->imageMemoryBarrierCount; i++) {
VkImageMemoryBarrier2 *barrier = (VkImageMemoryBarrier2 *)&pDependencyInfo->pImageMemoryBarriers[i];
if (barrier->newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR &&
barrier->srcAccessMask == VK_ACCESS_COLOR_ATTACHMENT_READ_BIT) {
/* This game has a broken barrier right before present that causes rendering issues. Fix it
* by modifying the src access mask.
*/
barrier->srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
break;
}
}
device->layer_dispatch.app.CmdPipelineBarrier2(commandBuffer, pDependencyInfo);
}

View file

@ -22,6 +22,7 @@ radv_entrypoints_gen_command += [
'--device-prefix', 'rage2',
'--device-prefix', 'quantic_dream',
'--device-prefix', 'no_mans_sky',
'--device-prefix', 'strange_brigade',
# Command buffer annotation layer entrypoints
'--device-prefix', 'annotate',
@ -42,6 +43,7 @@ libradv_files = files(
'layers/radv_rage2.c',
'layers/radv_quantic_dream.c',
'layers/radv_no_mans_sky.c',
'layers/radv_strange_brigade.c',
'layers/radv_rmv_layer.c',
'layers/radv_rra_layer.c',
'layers/radv_sqtt_layer.c',

View file

@ -786,6 +786,8 @@ init_dispatch_tables(struct radv_device *device, struct radv_physical_device *pd
add_entrypoints(&b, &quantic_dream_device_entrypoints, RADV_APP_DISPATCH_TABLE);
} else if (!strcmp(instance->drirc.debug.app_layer, "no_mans_sky")) {
add_entrypoints(&b, &no_mans_sky_device_entrypoints, RADV_APP_DISPATCH_TABLE);
} else if (!strcmp(instance->drirc.debug.app_layer, "strange_brigade")) {
add_entrypoints(&b, &strange_brigade_device_entrypoints, RADV_APP_DISPATCH_TABLE);
}
if (instance->vk.trace_mode & RADV_TRACE_MODE_RGP)

View file

@ -227,6 +227,9 @@ Application bugs worked around in this file:
<!-- The full WA hurts performance too much, use the partial one
that seems fine overall. -->
<option name="radv_gfx12_hiz_wa" value="partial" />
<!-- To fix a hazard with present after write. -->
<option name="radv_app_layer" value="strange_brigade" />
</application>
<application name="Sniper Elite 5 (DX12)" application_name_match="sniper5_dx12.exe">