From a1be9ee375a089f2b0933ff8a22862f81adf9306 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 22 May 2024 16:22:11 +0200 Subject: [PATCH] panvk: Fix dynamic rendering with images containing both depth and stencil When the depth or stencil attachment points to an image that contains both components and only one of those is updated, we need to preload the other. We also need to patch the ZS view to use the format with both components when that happens. Signed-off-by: Boris Brezillon Acked-by: Erik Faye-Lund Part-of: --- src/panfrost/vulkan/panvk_cmd_buffer.h | 2 ++ src/panfrost/vulkan/panvk_vX_cmd_buffer.c | 34 +++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/panfrost/vulkan/panvk_cmd_buffer.h b/src/panfrost/vulkan/panvk_cmd_buffer.h index 58cac39f595..144dddd92da 100644 --- a/src/panfrost/vulkan/panvk_cmd_buffer.h +++ b/src/panfrost/vulkan/panvk_cmd_buffer.h @@ -141,6 +141,8 @@ struct panvk_cmd_graphics_state { uint8_t samples[MAX_RTS]; } color_attachments; + struct pan_image_view zs_pview; + struct { struct pan_fb_info info; bool crc_valid[MAX_RTS]; diff --git a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c index cc3519be7ad..da707afe198 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c @@ -2111,6 +2111,9 @@ panvk_cmd_begin_rendering_init_state(struct panvk_cmd_buffer *cmdbuf, .bos[cmdbuf->state.gfx.render.fb.bo_count++] = img->bo; fbinfo->zs.view.zs = &iview->pview; + if (vk_format_has_stencil(img->vk.format)) + fbinfo->zs.preload.s = true; + if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { fbinfo->zs.clear.z = true; fbinfo->zs.clear_value.depth = att->clearValue.depthStencil.depth; @@ -2142,6 +2145,17 @@ panvk_cmd_begin_rendering_init_state(struct panvk_cmd_buffer *cmdbuf, fbinfo->zs.view.s = &iview->pview != fbinfo->zs.view.zs ? &iview->pview : NULL; + if (vk_format_has_depth(img->vk.format)) { + assert(fbinfo->zs.view.zs == NULL || + &iview->pview == fbinfo->zs.view.zs); + fbinfo->zs.view.zs = &iview->pview; + + fbinfo->zs.preload.s = false; + fbinfo->zs.clear.s = false; + if (!fbinfo->zs.clear.z) + fbinfo->zs.preload.z = true; + } + if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { fbinfo->zs.clear.s = true; fbinfo->zs.clear_value.stencil = @@ -2152,6 +2166,26 @@ panvk_cmd_begin_rendering_init_state(struct panvk_cmd_buffer *cmdbuf, } } + if (fbinfo->zs.view.zs) { + const struct util_format_description *fdesc = + util_format_description(fbinfo->zs.view.zs->format); + bool needs_depth = fbinfo->zs.clear.z | fbinfo->zs.preload.z | + util_format_has_depth(fdesc); + bool needs_stencil = fbinfo->zs.clear.s | fbinfo->zs.preload.s | + util_format_has_stencil(fdesc); + enum pipe_format new_fmt = + util_format_get_blocksize(fbinfo->zs.view.zs->format) == 4 + ? PIPE_FORMAT_Z24_UNORM_S8_UINT + : PIPE_FORMAT_Z32_FLOAT_S8X24_UINT; + + if (needs_depth && needs_stencil && + fbinfo->zs.view.zs->format != new_fmt) { + cmdbuf->state.gfx.render.zs_pview = *fbinfo->zs.view.zs; + cmdbuf->state.gfx.render.zs_pview.format = new_fmt; + fbinfo->zs.view.zs = &cmdbuf->state.gfx.render.zs_pview; + } + } + fbinfo->extent.minx = pRenderingInfo->renderArea.offset.x; fbinfo->extent.maxx = pRenderingInfo->renderArea.offset.x + pRenderingInfo->renderArea.extent.width - 1;