From f866bed0db13434d404b27ef9cb4ae2b61097952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Fri, 19 Dec 2025 13:22:41 -0600 Subject: [PATCH] radv: Mitigate GFX6-7 SMEM bug for NULL and mutable descriptors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Samuel Pitoiset Part-of: --- docs/envvars.rst | 2 ++ src/amd/vulkan/radv_debug.h | 1 + src/amd/vulkan/radv_device.c | 2 +- src/amd/vulkan/radv_instance.c | 1 + src/amd/vulkan/radv_physical_device.c | 1 + src/amd/vulkan/radv_physical_device.h | 3 ++- src/amd/vulkan/radv_pipeline.c | 3 +++ src/amd/vulkan/radv_queue.c | 8 ++++++++ 8 files changed, 19 insertions(+), 2 deletions(-) diff --git a/docs/envvars.rst b/docs/envvars.rst index 6415bbe99d6..c1f2dadebc9 100644 --- a/docs/envvars.rst +++ b/docs/envvars.rst @@ -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`` diff --git a/src/amd/vulkan/radv_debug.h b/src/amd/vulkan/radv_debug.h index 787c5c0e2c9..42a9eb7f54b 100644 --- a/src/amd/vulkan/radv_debug.h +++ b/src/amd/vulkan/radv_debug.h @@ -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, diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 340c2b5ac7a..4f7ff197363 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -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, diff --git a/src/amd/vulkan/radv_instance.c b/src/amd/vulkan/radv_instance.c index da1ce3fd9d0..31cc63b2417 100644 --- a/src/amd/vulkan/radv_instance.c +++ b/src/amd/vulkan/radv_instance.c @@ -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}, }; diff --git a/src/amd/vulkan/radv_physical_device.c b/src/amd/vulkan/radv_physical_device.c index 79741c7eda3..fb6e0d355ec 100644 --- a/src/amd/vulkan/radv_physical_device.c +++ b/src/amd/vulkan/radv_physical_device.c @@ -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 diff --git a/src/amd/vulkan/radv_physical_device.h b/src/amd/vulkan/radv_physical_device.h index 8e4913be3f4..efd28d93f51 100644 --- a/src/amd/vulkan/radv_physical_device.h +++ b/src/amd/vulkan/radv_physical_device.h @@ -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 { diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 3f39e28e01e..deac4d7d881 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -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); diff --git a/src/amd/vulkan/radv_queue.c b/src/amd/vulkan/radv_queue.c index b3964396fdb..564a8d890e2 100644 --- a/src/amd/vulkan/radv_queue.c +++ b/src/amd/vulkan/radv_queue.c @@ -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;