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: 95820584d0 ("pvr: Add deferred RTA clears for cores without gs_rta_support.")
Signed-off-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
Reviewed-by: Luigi Santivetti <luigi.santivetti@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40838>
This commit is contained in:
Icenowy Zheng 2026-04-21 15:37:47 +08:00 committed by Marge Bot
parent 43b22a477c
commit 40e0f0f933
2 changed files with 29 additions and 5 deletions

View file

@ -66,7 +66,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

View file

@ -1895,6 +1895,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.
*
@ -1914,7 +1938,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,
@ -1969,12 +1992,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))
@ -2003,15 +2027,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);
}