From defcae86e6fc7969e4e4d1dd3f4f9a5781a935fa Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Thu, 7 May 2026 17:24:42 +0200 Subject: [PATCH 1/4] radv: fix another case of VRS with mipmaps on GFX10.3 When a VRS view is used with a depth/stencil view, the driver is expected to copy the VRS rates to the HTILE buffer of the depth/stencil view. Though if the image uses mipmaps and the base level can't support HTILE there is no way to copy the rates. The workaround is to force VRS to be 1x1 which is valid in Vulkan. This fixes old VKCTS failures on RAPHAEL just because it supports fragmentShadingRateWithShaderDepthStencilWrites compared to other GPUs in CI (NAVI21/VANGOGH). Cc: mesa-stable Signed-off-by: Samuel Pitoiset --- src/amd/ci/radv-raphael-fails.txt | 26 -------------------------- src/amd/vulkan/radv_cmd_buffer.c | 17 ++++++++++++++++- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/amd/ci/radv-raphael-fails.txt b/src/amd/ci/radv-raphael-fails.txt index 516acccbb94..7197240c446 100644 --- a/src/amd/ci/radv-raphael-fails.txt +++ b/src/amd/ci/radv-raphael-fails.txt @@ -1,29 +1,3 @@ -# Issues specific to the Raphael. The list can be reduced when disabling VRS flat shading -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragdepth_baselevel.dynamic.attachment.noshaderrate.keep.replace.1x1.samples1.ms,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragdepth_baselevel.dynamic.attachment.noshaderrate.keep.replace.1x1.samples1.vs,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragdepth_baselevel.dynamic.attachment.noshaderrate.keep.replace.4x4.samples1.ms,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragdepth_baselevel.dynamic.attachment.noshaderrate.keep.replace.4x4.samples1.vs,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragdepth_baselevel.dynamic.attachment.shaderrate.keep.replace.1x1.samples1.ms,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragdepth_baselevel.dynamic.attachment.shaderrate.keep.replace.1x1.samples1.vs,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragdepth_baselevel.dynamic.attachment.shaderrate.keep.replace.4x4.samples1.ms,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragdepth_baselevel.dynamic.attachment.shaderrate.keep.replace.4x4.samples1.vs,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragdepth_baselevel.dynamic.attachment.shaderrate.replace.replace.1x1.samples1.ms,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragdepth_baselevel.dynamic.attachment.shaderrate.replace.replace.1x1.samples1.vs,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragdepth_baselevel.dynamic.attachment.shaderrate.replace.replace.4x4.samples1.ms,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragdepth_baselevel.dynamic.attachment.shaderrate.replace.replace.4x4.samples1.vs,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragstencil_baselevel.dynamic.attachment.noshaderrate.keep.replace.1x1.samples1.ms,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragstencil_baselevel.dynamic.attachment.noshaderrate.keep.replace.1x1.samples1.vs,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragstencil_baselevel.dynamic.attachment.noshaderrate.keep.replace.4x4.samples1.ms,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragstencil_baselevel.dynamic.attachment.noshaderrate.keep.replace.4x4.samples1.vs,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragstencil_baselevel.dynamic.attachment.shaderrate.keep.replace.1x1.samples1.ms,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragstencil_baselevel.dynamic.attachment.shaderrate.keep.replace.1x1.samples1.vs,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragstencil_baselevel.dynamic.attachment.shaderrate.keep.replace.4x4.samples1.ms,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragstencil_baselevel.dynamic.attachment.shaderrate.keep.replace.4x4.samples1.vs,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragstencil_baselevel.dynamic.attachment.shaderrate.replace.replace.1x1.samples1.ms,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragstencil_baselevel.dynamic.attachment.shaderrate.replace.replace.1x1.samples1.vs,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragstencil_baselevel.dynamic.attachment.shaderrate.replace.replace.4x4.samples1.ms,Fail -dEQP-VK.fragment_shading_rate.renderpass2.monolithic.fragstencil_baselevel.dynamic.attachment.shaderrate.replace.replace.4x4.samples1.vs,Fail - # RADV bug dEQP-VK.api.copy_and_blit.core.use_after_copy.d16_unorm.general.32x32x1_cq_regions,Fail dEQP-VK.api.copy_and_blit.core.use_after_copy.d16_unorm.general.32x32x2_cq_img2img_msaa,Fail diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 22b43179c17..06718f95cc8 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -4319,6 +4319,7 @@ radv_emit_fsr_state(struct radv_cmd_buffer *cmd_buffer) struct radv_device *device = radv_cmd_buffer_device(cmd_buffer); const struct radv_physical_device *pdev = radv_device_physical(device); const struct radv_dynamic_state *d = &cmd_buffer->state.dynamic; + const struct radv_rendering_state *render = &cmd_buffer->state.render; struct radv_cmd_stream *cs = cmd_buffer->cs; /* When per-vertex VRS is forced and the dynamic fragment shading rate is a no-op, ignore @@ -4338,7 +4339,7 @@ radv_emit_fsr_state(struct radv_cmd_buffer *cmd_buffer) assert(pdev->info.gfx_level >= GFX10_3); - if (!cmd_buffer->state.render.vrs_att.iview) { + if (!render->vrs_att.iview) { /* When the current subpass has no VRS attachment, the VRS rates are expected to be 1x1, so we * can cheat by tweaking the different combiner modes. */ @@ -4364,6 +4365,20 @@ radv_emit_fsr_state(struct radv_cmd_buffer *cmd_buffer) default: break; } + } else if (render->ds_att.iview && radv_image_has_vrs_htile(device, render->ds_att.iview->image) && + !radv_htile_enabled(render->ds_att.iview->image, render->ds_att.iview->vk.base_mip_level)) { + /* Otherwise, adjust the combiners to force VRS rate to 1x1 when the depth/stencil view is + * incompatible with VRS which can happen with mipmaps. + */ + switch (htile_comb_mode) { + case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR: + case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR: + rate_x = rate_y = 0; + pipeline_comb_mode = V_028848_SC_VRS_COMB_MODE_PASSTHRU; + break; + default: + break; + } } /* Disable VRS and use the rates from PS_ITER_SAMPLES if: From 8a5b9fdbe847fca90336f30f4fe3e0a188d316b2 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Thu, 7 May 2026 17:46:15 +0200 Subject: [PATCH 2/4] radv: avoid an useless copy of VRS rates to the internal ds image It's only needed when there is a VRS view without a depth/stencil view because if the driver can't copy the VRS rates to the depth/stencil view it forces VRS to be 1x1. Signed-off-by: Samuel Pitoiset --- src/amd/vulkan/radv_cmd_buffer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 06718f95cc8..d5a86fee919 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -10414,9 +10414,9 @@ radv_CmdBeginRendering(VkCommandBuffer commandBuffer, const VkRenderingInfo *pRe /* Copy the VRS rates to the HTILE buffer. */ radv_copy_vrs_htile(cmd_buffer, vrs_att.iview, &render_area, ds_image, htile_va, true); - } else { - /* When a subpass uses a VRS attachment without binding a depth/stencil attachment, or when - * HTILE isn't enabled, we use a fallback that copies the VRS rates to our internal HTILE buffer. + } else if (!ds_att.iview) { + /* When a subpass uses a VRS attachment without binding a depth/stencil attachment, we + * use a fallback that copies the VRS rates to our internal HTILE buffer. */ struct radv_image *ds_image = radv_cmd_buffer_get_vrs_image(cmd_buffer); From 881f56f77a3e5859c0a4945852899b7751b06667 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Thu, 7 May 2026 17:50:12 +0200 Subject: [PATCH 3/4] radv: prevent using VRS HTILE encoding if the iview isn't compatible Signed-off-by: Samuel Pitoiset --- src/amd/vulkan/radv_image_view.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/amd/vulkan/radv_image_view.c b/src/amd/vulkan/radv_image_view.c index c404e1adfb3..e52de49e087 100644 --- a/src/amd/vulkan/radv_image_view.c +++ b/src/amd/vulkan/radv_image_view.c @@ -595,7 +595,8 @@ radv_initialise_ds_surface(const struct radv_device *device, struct radv_ds_buff .stencil_read_only = !(ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT), .htile_enabled = radv_htile_enabled(iview->image, level), .htile_stencil_disabled = radv_image_tile_stencil_disabled(device, iview->image), - .vrs_enabled = radv_image_has_vrs_htile(device, iview->image), + .vrs_enabled = radv_image_has_vrs_htile(device, iview->image) && + radv_htile_enabled(iview->image, iview->vk.base_mip_level), }; ac_init_ds_surface(&pdev->info, &ds_state, &ds->ac); From 1e11a6d186c836def59fd84737a97f7b459c6064 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Thu, 7 May 2026 17:59:47 +0200 Subject: [PATCH 4/4] radv: remove a TODO about layeredShadingRateAttachments This will never be supported. Signed-off-by: Samuel Pitoiset --- src/amd/vulkan/radv_physical_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/amd/vulkan/radv_physical_device.c b/src/amd/vulkan/radv_physical_device.c index 6e2952b0e00..51b61c97fbf 100644 --- a/src/amd/vulkan/radv_physical_device.c +++ b/src/amd/vulkan/radv_physical_device.c @@ -2103,7 +2103,7 @@ radv_get_physical_device_properties(struct radv_physical_device *pdev) .maxFragmentShadingRateAttachmentTexelSize = vrs_texel_extent, .maxFragmentShadingRateAttachmentTexelSizeAspectRatio = 1, .primitiveFragmentShadingRateWithMultipleViewports = true, - .layeredShadingRateAttachments = false, /* TODO */ + .layeredShadingRateAttachments = false, .fragmentShadingRateNonTrivialCombinerOps = true, .maxFragmentSize = (VkExtent2D){2, 2}, .maxFragmentSizeAspectRatio = 2,