radv: Mitigate GFX6-7 SMEM bug for NULL and mutable descriptors

Implement a mitigation for VM faults caused by SMEM reading
from NULL descriptors.

In order to satisfy VKD3D-Proton's expectations on mutable
descriptors, we must do this in shader code, it is not
sufficient to use the address of a mapped BO when writing
null descriptors. It is not feasible to mitigate this
in VKD3D-Proton.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38769>
This commit is contained in:
Timur Kristóf 2025-12-19 13:22:41 -06:00 committed by Marge Bot
parent 10a5e5e4f3
commit f866bed0db
8 changed files with 19 additions and 2 deletions

View file

@ -1446,6 +1446,8 @@ RADV driver environment variables
``nort``
skip executing vkCmdTraceRays and ray queries (RT extensions will still be
advertised)
``nosmemmitigation``
don't mitigate SMEM memory access issues on GFX6-7
``notccompatcmask``
disable TC-compat CMASK for MSAA surfaces
``noumr``

View file

@ -74,6 +74,7 @@ enum {
RADV_DEBUG_NO_BO_LIST = 1ull << 59,
RADV_DEBUG_DUMP_IBS = 1ull << 60,
RADV_DEBUG_VM = 1ull << 61,
RADV_DEBUG_NO_SMEM_MITIGATION = 1ull << 62,
RADV_DEBUG_DUMP_SHADERS = RADV_DEBUG_DUMP_VS | RADV_DEBUG_DUMP_TCS | RADV_DEBUG_DUMP_TES | RADV_DEBUG_DUMP_GS |
RADV_DEBUG_DUMP_PS | RADV_DEBUG_DUMP_TASK | RADV_DEBUG_DUMP_MESH | RADV_DEBUG_DUMP_CS |
RADV_DEBUG_DUMP_NIR | RADV_DEBUG_DUMP_ASM | RADV_DEBUG_DUMP_BACKEND_IR,

View file

@ -1402,7 +1402,7 @@ radv_CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCr
device->vk.enabled_features.extendedDynamicState3ColorBlendEquation)
radv_shader_part_cache_init(&device->ps_epilogs, &ps_epilog_ops);
if (pdev->info.has_zero_index_buffer_bug) {
if (pdev->info.has_zero_index_buffer_bug || pdev->cache_key.mitigate_smem_oob) {
result = radv_bo_create(device, NULL, 4096, 4096, RADEON_DOMAIN_VRAM,
RADEON_FLAG_NO_CPU_ACCESS | RADEON_FLAG_NO_INTERPROCESS_SHARING | RADEON_FLAG_READ_ONLY |
RADEON_FLAG_ZERO_VRAM | RADEON_FLAG_32BIT,

View file

@ -90,6 +90,7 @@ static const struct debug_control radv_debug_options[] = {
{"nobolist", RADV_DEBUG_NO_BO_LIST},
{"dumpibs", RADV_DEBUG_DUMP_IBS},
{"vm", RADV_DEBUG_VM},
{"nosmemmitigation", RADV_DEBUG_NO_SMEM_MITIGATION},
{NULL, 0},
};

View file

@ -301,6 +301,7 @@ radv_physical_device_init_cache_key(struct radv_physical_device *pdev)
key->use_ngg = pdev->use_ngg;
key->use_ngg_culling = pdev->use_ngg_culling;
key->no_implicit_varying_subgroup_size = instance->drirc.debug.no_implicit_varying_subgroup_size;
key->mitigate_smem_oob = pdev->info.cu_info.has_smem_oob_access_bug && !(instance->debug_flags & RADV_DEBUG_NO_SMEM_MITIGATION);
}
static int

View file

@ -65,8 +65,9 @@ struct radv_physical_device_cache_key {
uint32_t use_ngg : 1;
uint32_t use_ngg_culling : 1;
uint32_t no_implicit_varying_subgroup_size : 1;
uint32_t mitigate_smem_oob : 1;
uint32_t reserved : 9;
uint32_t reserved : 8;
};
enum radv_video_enc_hw_ver {

View file

@ -520,6 +520,9 @@ radv_postprocess_nir(struct radv_device *device, const struct radv_graphics_stat
NIR_PASS(_, stage->nir, ac_nir_lower_global_access);
NIR_PASS(_, stage->nir, nir_lower_int64);
if (pdev->cache_key.mitigate_smem_oob)
NIR_PASS(_, stage->nir, ac_nir_fixup_mem_access_gfx6, &stage->args.ac, 4096, true, false);
radv_optimize_nir_algebraic(
stage->nir, io_to_mem || lowered_ngg || stage->stage == MESA_SHADER_COMPUTE || stage->stage == MESA_SHADER_TASK,
gfx_level >= GFX8, gfx_level);

View file

@ -479,6 +479,10 @@ radv_emit_compute_scratch(struct radv_device *device, struct radv_cmd_stream *cs
uint64_t scratch_va;
uint32_t rsrc1;
/* Ensure there is always a mapped BO in s[0:1] for the SMEM OOB mitigation */
if (!compute_scratch_bo && pdev->cache_key.mitigate_smem_oob)
compute_scratch_bo = device->zero_bo;
if (!compute_scratch_bo)
return;
@ -538,6 +542,10 @@ radv_emit_graphics_shader_pointers(struct radv_device *device, struct radv_cmd_s
const struct radv_physical_device *pdev = radv_device_physical(device);
uint64_t va;
/* Ensure there is always a mapped BO in s[0:1] for the SMEM OOB mitigation */
if (!descriptor_bo && pdev->cache_key.mitigate_smem_oob)
descriptor_bo = device->zero_bo;
if (!descriptor_bo)
return;