Mesa (main): tu/lrz: Do not use framebuffer when inheriting LRZ

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jul 27 20:15:21 UTC 2022


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

Author: Connor Abbott <cwabbott0 at gmail.com>
Date:   Wed Jun 29 11:33:56 2022 +0200

tu/lrz: Do not use framebuffer when inheriting LRZ

The only thing it's used for is to get the image view, and we can't rely
on it existing anyway. With dynamic rendering, we only have the format
of the attachments and sample count, so moving forward we can't rely on
anything other than that.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17378>

---

 src/freedreno/vulkan/tu_cmd_buffer.c |  4 +--
 src/freedreno/vulkan/tu_lrz.c        | 70 ++++++++++++++++++++++++++++++------
 src/freedreno/vulkan/tu_private.h    |  3 +-
 3 files changed, 61 insertions(+), 16 deletions(-)

diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c
index a56c0296e19..5196191fd41 100644
--- a/src/freedreno/vulkan/tu_cmd_buffer.c
+++ b/src/freedreno/vulkan/tu_cmd_buffer.c
@@ -1772,13 +1772,11 @@ tu_BeginCommandBuffer(VkCommandBuffer commandBuffer,
       }
 
       if (pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) {
-         TU_FROM_HANDLE(tu_framebuffer, fb, pBeginInfo->pInheritanceInfo->framebuffer);
-
          cmd_buffer->state.pass = tu_render_pass_from_handle(pBeginInfo->pInheritanceInfo->renderPass);
          cmd_buffer->state.subpass =
             &cmd_buffer->state.pass->subpasses[pBeginInfo->pInheritanceInfo->subpass];
 
-         tu_lrz_begin_secondary_cmdbuf(cmd_buffer, fb);
+         tu_lrz_begin_secondary_cmdbuf(cmd_buffer);
       } else {
          /* When executing in the middle of another command buffer, the CCU
           * state is unknown.
diff --git a/src/freedreno/vulkan/tu_lrz.c b/src/freedreno/vulkan/tu_lrz.c
index 9f372064bac..d820823f0d8 100644
--- a/src/freedreno/vulkan/tu_lrz.c
+++ b/src/freedreno/vulkan/tu_lrz.c
@@ -202,8 +202,11 @@ tu_lrz_init_state(struct tu_cmd_buffer *cmd,
                   const struct tu_render_pass_attachment *att,
                   const struct tu_image_view *view)
 {
-   if (!view->image->lrz_height)
+   if (!view->image->lrz_height) {
+      assert((cmd->device->instance->debug_flags & TU_DEBUG_NOLRZ) ||
+             !vk_format_has_depth(att->format));
       return;
+   }
 
    bool clears_depth = att->clear_mask &
       (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT);
@@ -213,10 +216,17 @@ tu_lrz_init_state(struct tu_cmd_buffer *cmd,
    if (!has_gpu_tracking && !clears_depth)
       return;
 
+   /* We need to always have an LRZ view just to disable it if there is a
+    * depth attachment, there are any secondaries, and GPU tracking is
+    * enabled, in order not to rely on loadOp state which doesn't exist with
+    * dynamic rendering in secondaries. Otherwise the secondary will have LRZ
+    * enabled and there will be a NULL/garbage LRZ buffer.
+    */
+   cmd->state.lrz.image_view = view;
+
    if (!clears_depth && !att->load)
       return;
 
-   cmd->state.lrz.image_view = view;
    cmd->state.lrz.valid = true;
    cmd->state.lrz.prev_direction = TU_LRZ_UNKNOWN;
    /* Be optimistic and unconditionally enable fast-clear in
@@ -228,6 +238,43 @@ tu_lrz_init_state(struct tu_cmd_buffer *cmd,
    cmd->state.lrz.reuse_previous_state = !clears_depth;
 }
 
+/* Note: if we enable LRZ here, then tu_lrz_init_state() must at least set
+ * lrz.image_view, so that an LRZ buffer is present (even if LRZ is
+ * dynamically disabled).
+ */
+
+static void
+tu_lrz_init_secondary(struct tu_cmd_buffer *cmd,
+                      const struct tu_render_pass_attachment *att)
+{
+   bool has_gpu_tracking =
+      cmd->device->physical_device->info->a6xx.has_lrz_dir_tracking;
+
+   if (!has_gpu_tracking)
+      return;
+
+   if (cmd->device->instance->debug_flags & TU_DEBUG_NOLRZ)
+      return;
+
+   if (!vk_format_has_depth(att->format))
+      return;
+
+   cmd->state.lrz.valid = true;
+   cmd->state.lrz.prev_direction = TU_LRZ_UNKNOWN;
+   cmd->state.lrz.gpu_dir_tracking = has_gpu_tracking;
+
+   /* We may not have the depth attachment when executing in a secondary
+    * inside a render pass. This means we have to be even more optimistic than
+    * the normal case and enable fast clear even if the depth image doesn't
+    * support it.
+    */
+   cmd->state.lrz.fast_clear = true;
+
+   /* These are not used inside secondaries */
+   cmd->state.lrz.image_view = NULL;
+   cmd->state.lrz.reuse_previous_state = false;
+}
+
 void
 tu_lrz_begin_renderpass(struct tu_cmd_buffer *cmd,
                         const VkRenderPassBeginInfo *pRenderPassBegin)
@@ -257,7 +304,7 @@ tu_lrz_begin_renderpass(struct tu_cmd_buffer *cmd,
    }
 
     /* Track LRZ valid state */
-   cmd->state.lrz.valid = false;
+   memset(&cmd->state.lrz, 0, sizeof(cmd->state.lrz));
    uint32_t a = cmd->state.subpass->depth_stencil_attachment.attachment;
    if (a != VK_ATTACHMENT_UNUSED) {
       const struct tu_render_pass_attachment *att = &cmd->state.pass->attachments[a];
@@ -273,28 +320,29 @@ tu_lrz_begin_renderpass(struct tu_cmd_buffer *cmd,
    }
 
    if (!cmd->state.lrz.valid) {
-      memset(&cmd->state.lrz, 0, sizeof(cmd->state.lrz));
       tu6_emit_lrz_buffer(&cmd->cs, NULL);
    }
 }
 
 void
-tu_lrz_begin_secondary_cmdbuf(struct tu_cmd_buffer *cmd,
-                              struct tu_framebuffer *fb)
+tu_lrz_begin_secondary_cmdbuf(struct tu_cmd_buffer *cmd)
 {
+   memset(&cmd->state.lrz, 0, sizeof(cmd->state.lrz));
    uint32_t a = cmd->state.subpass->depth_stencil_attachment.attachment;
-   if (a != VK_ATTACHMENT_UNUSED &&
-       cmd->device->physical_device->info->a6xx.has_lrz_dir_tracking) {
+   if (a != VK_ATTACHMENT_UNUSED) {
       const struct tu_render_pass_attachment *att = &cmd->state.pass->attachments[a];
-      struct tu_image_view *view = fb->attachments[a].attachment;
-
-      tu_lrz_init_state(cmd, att, view);
+      tu_lrz_init_secondary(cmd, att);
    }
 }
 
 void
 tu_lrz_tiling_begin(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
 {
+   /* TODO: If lrz was never valid for the entire renderpass, we could exit
+    * early here. Sometimes we know this ahead of time and null out
+    * image_view, but with LOAD_OP_DONT_CARE this only happens if there were
+    * no secondaries.
+    */
    if (!cmd->state.lrz.image_view)
       return;
 
diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h
index 439c12dc8d2..d605268095b 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -1591,8 +1591,7 @@ tu_lrz_begin_renderpass(struct tu_cmd_buffer *cmd,
                         const VkRenderPassBeginInfo *pRenderPassBegin);
 
 void
-tu_lrz_begin_secondary_cmdbuf(struct tu_cmd_buffer *cmd,
-                              struct tu_framebuffer *fb);
+tu_lrz_begin_secondary_cmdbuf(struct tu_cmd_buffer *cmd);
 
 void
 tu_lrz_tiling_begin(struct tu_cmd_buffer *cmd, struct tu_cs *cs);



More information about the mesa-commit mailing list