From f253c6079198f4e1bce05b452637bbeeae3f80ba Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Tue, 21 Apr 2026 15:37:47 +0800 Subject: [PATCH] pvr: properly handle deferred RTA clears for 2D array view of 3D image For 2D array views of 3D images, the layer of the view corresponds to the depth (instead of the layer, which should be always 0) of the image. Fix the code emitting deferred RTA clears to set the depth instead of the layer of the image to clear. Fixes the flakiness of `dEQP-VK.renderpasses.renderpass*. remaining_array_layers.multi_layer_fb.*`. Fixes: 95820584d06e ("pvr: Add deferred RTA clears for cores without gs_rta_support.") Signed-off-by: Icenowy Zheng Reviewed-by: Luigi Santivetti (cherry picked from commit 40e0f0f9338198441518f9769cbdc08488eca37f) Part-of: --- .pick_status.json | 2 +- src/imagination/ci/bxs-4-64-flakes.txt | 1 - src/imagination/vulkan/rogue/pvr_blit.c | 33 ++++++++++++++++++++++--- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index b2fc4c44d59..3f775cc4865 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -6184,7 +6184,7 @@ "description": "pvr: properly handle deferred RTA clears for 2D array view of 3D image", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "95820584d06e067766283ccb76c33a75c383a203", "notes": null diff --git a/src/imagination/ci/bxs-4-64-flakes.txt b/src/imagination/ci/bxs-4-64-flakes.txt index bcfd4a967e4..2ad5d4a746f 100644 --- a/src/imagination/ci/bxs-4-64-flakes.txt +++ b/src/imagination/ci/bxs-4-64-flakes.txt @@ -52,7 +52,6 @@ dEQP-VK.pipeline.monolithic.stencil.nocolor.format.d32_sfloat_s8_uint.states.fai dEQP-VK.pipeline.monolithic.vertex_input.multiple_attributes.layout_skip.binding_one_to_one.attributes.uvec2.uvec3.mat2 dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.random.seed16_multiview dEQP-VK.renderpasses.dynamic_rendering.primary_cmd_buff.suballocation.unused_clear_attachments.colorunused_colorused_colorunused_colorunused_stencilonly_d32s8_unused -dEQP-VK.renderpasses.renderpass1.remaining_array_layers.multi_layer_fb.2_2 dEQP-VK.renderpasses.renderpass2.dedicated_allocation.formats.a2b10g10r10_uint_pack32.input.load.dont_care.clear_draw dEQP-VK.renderpasses.renderpass2.suballocation.attachment_allocation.roll.87 dEQP-VK.renderpasses.renderpass2.suballocation.formats.r16_unorm.input.clear.store.self_dep_clear diff --git a/src/imagination/vulkan/rogue/pvr_blit.c b/src/imagination/vulkan/rogue/pvr_blit.c index 6f08b397223..02121440e7f 100644 --- a/src/imagination/vulkan/rogue/pvr_blit.c +++ b/src/imagination/vulkan/rogue/pvr_blit.c @@ -1824,6 +1824,30 @@ static VkResult pvr_clear_color_attachment_static( return VK_SUCCESS; } +static void +pvr_set_rta_clear_layer_depth(const struct pvr_image_view *image_view, + uint32_t view_layer, + uint32_t *image_layer, + float *image_depth) +{ + const struct pvr_image *image = vk_to_pvr_image(image_view->vk.image); + uint32_t view_image_layer = image_view->vk.base_array_layer + view_layer; + + /* Convert layer to depth for 2D array views of 3D images */ + if (image->memlayout == PVR_MEMLAYOUT_3DTWIDDLED) { + /* Vulkan does not have a 3D array image view type, so for RTAs the + * view must be a 2D array view of a 3D image. + */ + assert(image_view->vk.view_type == VK_IMAGE_VIEW_TYPE_2D_ARRAY); + + *image_layer = 0; + *image_depth = (float) view_image_layer; + } else { + *image_layer = view_image_layer; + *image_depth = 0.0f; + } +} + /** * \brief Record a deferred clear operation into the command buffer. * @@ -1843,7 +1867,6 @@ static VkResult pvr_add_deferred_rta_clear(struct pvr_cmd_buffer *cmd_buffer, pvr_arch_pass_info_get_hw_render(pass_info, sub_cmd->hw_render_idx); const struct pvr_image_view *image_view; const struct pvr_image *image; - uint32_t base_layer; const VkOffset3D offset = { .x = rect->rect.offset.x, @@ -1898,12 +1921,13 @@ static VkResult pvr_add_deferred_rta_clear(struct pvr_cmd_buffer *cmd_buffer, image_view = pass_info->attachments[attachment_idx]; } - base_layer = image_view->vk.base_array_layer + rect->baseArrayLayer; image = vk_to_pvr_image(image_view->vk.image); for (uint32_t i = 0; i < rect->layerCount; i++) { struct pvr_transfer_cmd *transfer_cmd; uint32_t rt_id = rect->baseArrayLayer + i; + float depth = 0.0f; + uint32_t layer = 0; /* Do not defer the clear of active render target */ if (hw_render->view_mask & (1 << rt_id)) @@ -1932,15 +1956,16 @@ static VkResult pvr_add_deferred_rta_clear(struct pvr_cmd_buffer *cmd_buffer, attachment->clearValue.depthStencil.stencil; } + pvr_set_rta_clear_layer_depth(image_view, rt_id, &layer, &depth); pvr_setup_transfer_surface(cmd_buffer->device, &transfer_cmd->dst, &transfer_cmd->scissor, image, - base_layer + i, + layer, 0, &offset, &extent, - 0.0f, + depth, image->vk.format, attachment->aspectMask); }