From e47d584fede2448776c57f10f4163918015a78cb Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Fri, 24 Apr 2026 12:30:08 +0200 Subject: [PATCH] radv: re-introduce DGC+multiview support and enable it for vkd3d-proton only The Vulkan spec says: "VUID-vkCmdExecuteGeneratedCommandsEXT-None-11062 If a rendering pass is currently active, the view mask must be 0." So, it's invalid with VK_EXT_device_generated_commands but it's allowed in DX12, it seems we missed this during the spec review. Crimson Desert uses this and emulating in vkd3d-proton would be complex, so let's re-introduce this support only for vkd3d-proton. Cc: mesa-stable Signed-off-by: Samuel Pitoiset (cherry picked from commit 782254b820f4e4c73eb680b6e702a3688ae844d8) Part-of: --- .pick_status.json | 2 +- src/amd/vulkan/radv_cmd_buffer.c | 19 ++++++++++++++++++- src/amd/vulkan/radv_instance.c | 2 ++ src/amd/vulkan/radv_instance.h | 1 + src/util/00-radv-defaults.conf | 1 + src/util/driconf.h | 4 ++++ 6 files changed, 27 insertions(+), 2 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 58ceb6463ee..b31a2d4a88a 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -1434,7 +1434,7 @@ "description": "radv: re-introduce DGC+multiview support and enable it for vkd3d-proton only", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 2c419282d96..20592c20f33 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -13315,6 +13315,8 @@ radv_CmdExecuteGeneratedCommandsEXT(VkCommandBuffer commandBuffer, VkBool32 isPr VK_FROM_HANDLE(radv_indirect_execution_set, ies, pGeneratedCommandsInfo->indirectExecutionSet); VK_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); const struct radv_device *device = radv_cmd_buffer_device(cmd_buffer); + const struct radv_physical_device *pdev = radv_device_physical(device); + const struct radv_instance *instance = radv_physical_device_instance(pdev); const bool use_predication = radv_use_dgc_predication(cmd_buffer, pGeneratedCommandsInfo); const bool compute = !!(layout->vk.dgc_info & BITFIELD_BIT(MESA_VK_DGC_DISPATCH)); const bool rt = !!(layout->vk.dgc_info & BITFIELD_BIT(MESA_VK_DGC_RT)); @@ -13413,7 +13415,22 @@ radv_CmdExecuteGeneratedCommandsEXT(VkCommandBuffer commandBuffer, VkBool32 isPr ac_emit_cp_pfp_sync_me(cs->b, cmd_buffer->state.predicating); } - radv_dgc_execute_ib(cmd_buffer, pGeneratedCommandsInfo); + /* The Vulkan spec 1.4.349 says: + * + * "VUID-vkCmdExecuteGeneratedCommandsEXT-None-11062 + * If a rendering pass is currently active, the view mask must be 0." + * + * But it's a valid behavior with DX12, so it can be enabled via drirc. + */ + const uint32_t view_mask = instance->drirc.features.allow_dgc_multiview ? cmd_buffer->state.render.view_mask : 0; + if (rt || compute || !view_mask) { + radv_dgc_execute_ib(cmd_buffer, pGeneratedCommandsInfo); + } else { + u_foreach_bit (view, view_mask) { + radv_emit_view_index(&cmd_buffer->state, cmd_buffer->cs, view); + radv_dgc_execute_ib(cmd_buffer, pGeneratedCommandsInfo); + } + } if (rt) { cmd_buffer->push_constant_stages |= RADV_RT_STAGE_BITS; diff --git a/src/amd/vulkan/radv_instance.c b/src/amd/vulkan/radv_instance.c index 60a2838096d..971b153fe03 100644 --- a/src/amd/vulkan/radv_instance.c +++ b/src/amd/vulkan/radv_instance.c @@ -206,6 +206,7 @@ static const driOptionDescription radv_dri_options[] = { DRI_CONF_RADV_EMULATE_RT(false) DRI_CONF_RADV_ENABLE_FLOAT16_GFX8(false) DRI_CONF_RADV_COOPERATIVE_MATRIX2_NV(false) + DRI_CONF_RADV_ALLOW_DGC_MULTIVIEW(false) DRI_CONF_RADV_WAIT_FOR_VM_MAP_UPDATES(false) DRI_CONF_RADV_NO_IMPLICIT_VARYING_SUBGROUP_SIZE(false) DRI_CONF_RADV_HIDE_REBAR_ON_DGPU(false) @@ -278,6 +279,7 @@ radv_init_dri_features_options(struct radv_instance *instance) struct radv_drirc *drirc = &instance->drirc; drirc->features.cooperative_matrix2_nv = driQueryOptionb(&drirc->options, "radv_cooperative_matrix2_nv"); + drirc->features.allow_dgc_multiview = driQueryOptionb(&drirc->options, "radv_allow_dgc_multiview"); drirc->features.emulate_rt = driQueryOptionb(&drirc->options, "radv_emulate_rt"); drirc->features.expose_float16_gfx8 = driQueryOptionb(&drirc->options, "radv_enable_float16_gfx8"); drirc->features.vk_require_etc2 = driQueryOptionb(&drirc->options, "vk_require_etc2"); diff --git a/src/amd/vulkan/radv_instance.h b/src/amd/vulkan/radv_instance.h index ba1f9f40ea3..99f4ea1c2a4 100644 --- a/src/amd/vulkan/radv_instance.h +++ b/src/amd/vulkan/radv_instance.h @@ -76,6 +76,7 @@ struct radv_drirc { struct { bool cooperative_matrix2_nv; + bool allow_dgc_multiview; bool emulate_rt; bool expose_float16_gfx8; bool vk_require_astc; diff --git a/src/util/00-radv-defaults.conf b/src/util/00-radv-defaults.conf index b7dc8812ee1..b2892e72f0f 100644 --- a/src/util/00-radv-defaults.conf +++ b/src/util/00-radv-defaults.conf @@ -43,6 +43,7 @@ Application bugs worked around in this file: