Mesa (main): v3dv: support resolving depth/stencil attachments

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jan 28 12:59:09 UTC 2022


Module: Mesa
Branch: main
Commit: 7f87a1256e093c5846622930361991fb10eada0f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7f87a1256e093c5846622930361991fb10eada0f

Author: Iago Toral Quiroga <itoral at igalia.com>
Date:   Thu Jan 27 11:57:08 2022 +0100

v3dv: support resolving depth/stencil attachments

This implements the bulk of VK_KHR_depth_stencil_resolve

Reviewed-by: Alejandro Piñeiro <apinheiro at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14752>

---

 src/broadcom/vulkan/v3dv_cmd_buffer.c  |  7 +++++--
 src/broadcom/vulkan/v3dv_pass.c        | 32 ++++++++++++++++++++++++++++++++
 src/broadcom/vulkan/v3dv_private.h     |  2 ++
 src/broadcom/vulkan/v3dvx_cmd_buffer.c | 22 ++++++++++++++++++++--
 4 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c
index 2c18fe2ac9c..667fa7402b5 100644
--- a/src/broadcom/vulkan/v3dv_cmd_buffer.c
+++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c
@@ -410,10 +410,13 @@ cmd_buffer_can_merge_subpass(struct v3dv_cmd_buffer *cmd_buffer,
    /* FIXME: Since some attachment formats can't be resolved using the TLB we
     * need to emit separate resolve jobs for them and that would not be
     * compatible with subpass merges. We could fix that by testing if any of
-    * the attachments to resolve doesn't suppotr TLB resolves.
+    * the attachments to resolve doesn't support TLB resolves.
     */
-   if (prev_subpass->resolve_attachments || subpass->resolve_attachments)
+   if (prev_subpass->resolve_attachments || subpass->resolve_attachments ||
+       prev_subpass->resolve_depth || prev_subpass->resolve_stencil ||
+       subpass->resolve_depth || subpass->resolve_stencil) {
       return false;
+   }
 
    return true;
 }
diff --git a/src/broadcom/vulkan/v3dv_pass.c b/src/broadcom/vulkan/v3dv_pass.c
index 0dcb6c91c95..7ba144f5aa4 100644
--- a/src/broadcom/vulkan/v3dv_pass.c
+++ b/src/broadcom/vulkan/v3dv_pass.c
@@ -92,6 +92,9 @@ pass_find_subpass_range_for_attachments(struct v3dv_device *device,
             pass->attachments[ds_attachment_idx].first_subpass = i;
          if (i > pass->attachments[ds_attachment_idx].last_subpass)
             pass->attachments[ds_attachment_idx].last_subpass = i;
+
+         if (subpass->ds_resolve_attachment.attachment != VK_ATTACHMENT_UNUSED)
+            set_use_tlb_resolve(device, &pass->attachments[ds_attachment_idx]);
       }
 
       for (uint32_t j = 0; j < subpass->input_count; j++) {
@@ -250,8 +253,37 @@ v3dv_CreateRenderPass2(VkDevice _device,
                }
             }
          }
+
+         /* VK_KHR_depth_stencil_resolve */
+         const VkSubpassDescriptionDepthStencilResolveKHR *resolve_desc =
+            vk_find_struct_const(desc->pNext, SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE);
+         const VkAttachmentReference2 *resolve_att =
+            resolve_desc && resolve_desc->pDepthStencilResolveAttachment &&
+            resolve_desc->pDepthStencilResolveAttachment->attachment != VK_ATTACHMENT_UNUSED ?
+               resolve_desc->pDepthStencilResolveAttachment : NULL;
+         if (resolve_att) {
+            subpass->ds_resolve_attachment = (struct v3dv_subpass_attachment) {
+               .attachment = resolve_att->attachment,
+               .layout = resolve_att->layout,
+            };
+            assert(resolve_desc->depthResolveMode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT ||
+                   resolve_desc->stencilResolveMode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT);
+            subpass->resolve_depth =
+               resolve_desc->depthResolveMode != VK_RESOLVE_MODE_NONE &&
+               resolve_att->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT;
+            subpass->resolve_stencil =
+               resolve_desc->stencilResolveMode != VK_RESOLVE_MODE_NONE &&
+               resolve_att->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT;
+         } else {
+            subpass->ds_resolve_attachment.attachment = VK_ATTACHMENT_UNUSED;
+            subpass->resolve_depth = false;
+            subpass->resolve_stencil = false;
+         }
       } else {
          subpass->ds_attachment.attachment = VK_ATTACHMENT_UNUSED;
+         subpass->ds_resolve_attachment.attachment = VK_ATTACHMENT_UNUSED;
+         subpass->resolve_depth = false;
+         subpass->resolve_stencil = false;
       }
    }
 
diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h
index ad3d466b7b6..94d59234dab 100644
--- a/src/broadcom/vulkan/v3dv_private.h
+++ b/src/broadcom/vulkan/v3dv_private.h
@@ -697,6 +697,8 @@ struct v3dv_subpass {
    struct v3dv_subpass_attachment *resolve_attachments;
 
    struct v3dv_subpass_attachment ds_attachment;
+   struct v3dv_subpass_attachment ds_resolve_attachment;
+   bool resolve_depth, resolve_stencil;
 
    /* If we need to emit the clear of the depth/stencil attachment using a
     * a draw call instead of using the TLB (GFXH-1461).
diff --git a/src/broadcom/vulkan/v3dvx_cmd_buffer.c b/src/broadcom/vulkan/v3dvx_cmd_buffer.c
index a1a36cf9349..ce6afcf5ee4 100644
--- a/src/broadcom/vulkan/v3dvx_cmd_buffer.c
+++ b/src/broadcom/vulkan/v3dvx_cmd_buffer.c
@@ -501,6 +501,22 @@ cmd_buffer_render_pass_emit_stores(struct v3dv_cmd_buffer *cmd_buffer,
                            ds_last_subpass,
                            ds_attachment->desc.stencilStoreOp);
 
+      /* If we have a resolve, handle it before storing the tile */
+      if (subpass->resolve_depth || subpass->resolve_stencil) {
+         assert(ds_attachment->use_tlb_resolve);
+         const uint32_t resolve_attachment_idx =
+            subpass->ds_resolve_attachment.attachment;
+         assert(resolve_attachment_idx != VK_ATTACHMENT_UNUSED);
+
+         const uint32_t zs_buffer =
+            v3dv_zs_buffer(subpass->resolve_depth, subpass->resolve_stencil);
+         cmd_buffer_render_pass_emit_store(cmd_buffer, cl,
+                                           resolve_attachment_idx, layer,
+                                           zs_buffer,
+                                           false, false);
+         has_stores = true;
+      }
+
       /* GFXH-1689: The per-buffer store command's clear buffer bit is broken
        * for depth/stencil.
        *
@@ -837,7 +853,8 @@ v3dX(cmd_buffer_emit_render_pass_rcl)(struct v3dv_cmd_buffer *cmd_buffer)
             check_needs_store(state,
                               ds_aspects & VK_IMAGE_ASPECT_DEPTH_BIT,
                               ds_attachment->last_subpass,
-                              ds_attachment->desc.storeOp);
+                              ds_attachment->desc.storeOp) ||
+                              subpass->resolve_depth;
 
          do_early_zs_clear = needs_depth_clear && !needs_depth_store;
          if (do_early_zs_clear &&
@@ -852,7 +869,8 @@ v3dX(cmd_buffer_emit_render_pass_rcl)(struct v3dv_cmd_buffer *cmd_buffer)
                check_needs_store(state,
                                  ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT,
                                  ds_attachment->last_subpass,
-                                 ds_attachment->desc.stencilStoreOp);
+                                 ds_attachment->desc.stencilStoreOp) ||
+                                 subpass->resolve_stencil;
 
             do_early_zs_clear = !needs_stencil_load && !needs_stencil_store;
          }



More information about the mesa-commit mailing list