turnip: improve GMEM load/store logic
authorJonathan Marek <jonathan@marek.ca>
Thu, 9 Apr 2020 23:32:19 +0000 (19:32 -0400)
committerMarge Bot <eric+marge@anholt.net>
Wed, 22 Apr 2020 17:45:33 +0000 (17:45 +0000)
Determine load/store at renderpass creation time.

This also fixes behavior with S8_UINT.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4588>

src/freedreno/vulkan/tu_clear_blit.c
src/freedreno/vulkan/tu_cmd_buffer.c
src/freedreno/vulkan/tu_pass.c
src/freedreno/vulkan/tu_private.h

index c07e7e0bd0e485a3c3f9646fd5191a94f695d888..621449285d65af0350a73b2b8e501ddbbefd22cb 100644 (file)
@@ -2123,17 +2123,14 @@ tu_clear_sysmem_attachment(struct tu_cmd_buffer *cmd,
       &cmd->state.pass->attachments[a];
    uint8_t mask = 0;
 
-   if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
+   if (attachment->clear_mask == VK_IMAGE_ASPECT_COLOR_BIT)
       mask = 0xf;
+   if (attachment->clear_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
+      mask |= 0x7;
+   if (attachment->clear_mask & VK_IMAGE_ASPECT_STENCIL_BIT)
+      mask |= 0x8;
 
-   if (attachment->format == VK_FORMAT_D24_UNORM_S8_UINT) {
-      mask &= 0x7;
-      if (attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
-         mask |= 0x8;
-   }
-
-   /* gmem_offset<0 means it isn't used by any subpass and shouldn't be cleared */
-   if (attachment->gmem_offset < 0 || !mask)
+   if (!mask)
       return;
 
    const struct blit_ops *ops = &r2d_ops;
@@ -2160,18 +2157,13 @@ tu_clear_gmem_attachment(struct tu_cmd_buffer *cmd,
       &cmd->state.pass->attachments[a];
    unsigned clear_mask = 0;
 
-   /* note: this means it isn't used by any subpass and shouldn't be cleared anyway */
-   if (attachment->gmem_offset < 0)
-      return;
-
-   if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
+   if (attachment->clear_mask == VK_IMAGE_ASPECT_COLOR_BIT)
       clear_mask = 0xf;
+   if (attachment->clear_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
+      clear_mask |= 0x7;
+   if (attachment->clear_mask & VK_IMAGE_ASPECT_STENCIL_BIT)
+      clear_mask |= 0x8;
 
-   if (vk_format_has_stencil(attachment->format)) {
-      clear_mask &= 0x7;
-      if (attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
-         clear_mask |= 0x8;
-   }
    if (!clear_mask)
       return;
 
@@ -2185,7 +2177,7 @@ static void
 tu_emit_blit(struct tu_cmd_buffer *cmd,
              struct tu_cs *cs,
              const struct tu_image_view *iview,
-             struct tu_render_pass_attachment *attachment,
+             const struct tu_render_pass_attachment *attachment,
              bool resolve)
 {
    tu_cs_emit_regs(cs,
@@ -2246,28 +2238,18 @@ blit_can_resolve(VkFormat format)
 }
 
 void
-tu_emit_load_gmem_attachment(struct tu_cmd_buffer *cmd, struct tu_cs *cs, uint32_t a)
-{
-   tu_emit_blit(cmd, cs,
-                cmd->state.framebuffer->attachments[a].attachment,
-                &cmd->state.pass->attachments[a],
-                false);
-}
-
-void
-tu_load_gmem_attachment(struct tu_cmd_buffer *cmd, struct tu_cs *cs, uint32_t a)
+tu_load_gmem_attachment(struct tu_cmd_buffer *cmd,
+                        struct tu_cs *cs,
+                        uint32_t a,
+                        bool force_load)
 {
+   const struct tu_image_view *iview =
+      cmd->state.framebuffer->attachments[a].attachment;
    const struct tu_render_pass_attachment *attachment =
       &cmd->state.pass->attachments[a];
 
-   if (attachment->gmem_offset < 0)
-      return;
-
-   if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_LOAD ||
-       (vk_format_has_stencil(attachment->format) &&
-        attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_LOAD)) {
-      tu_emit_load_gmem_attachment(cmd, cs, a);
-   }
+   if (attachment->load || force_load)
+      tu_emit_blit(cmd, cs, iview, attachment, false);
 }
 
 void
@@ -2282,7 +2264,7 @@ tu_store_gmem_attachment(struct tu_cmd_buffer *cmd,
    struct tu_image_view *iview = cmd->state.framebuffer->attachments[a].attachment;
    struct tu_render_pass_attachment *src = &cmd->state.pass->attachments[gmem_a];
 
-   if (dst->store_op == VK_ATTACHMENT_STORE_OP_DONT_CARE)
+   if (!dst->store)
       return;
 
    uint32_t x1 = render_area->offset.x;
index 11269c2a98cd1c5b0b0a2549521cffd9b1c5973b..b6ca849c80c3fe8fc985fc70f3029836094abee5 100644 (file)
@@ -1123,7 +1123,7 @@ tu_emit_load_clear(struct tu_cmd_buffer *cmd,
    tu6_emit_blit_scissor(cmd, cs, true);
 
    for (uint32_t i = 0; i < cmd->state.pass->attachment_count; ++i)
-      tu_load_gmem_attachment(cmd, cs, i);
+      tu_load_gmem_attachment(cmd, cs, i, false);
 
    tu6_emit_blit_scissor(cmd, cs, false);
 
@@ -2362,7 +2362,7 @@ tu_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
           * if it is, should be doing a GMEM->GMEM resolve instead of GMEM->MEM->GMEM..
           */
          tu_finishme("missing GMEM->GMEM resolve path\n");
-         tu_emit_load_gmem_attachment(cmd, cs, a);
+         tu_load_gmem_attachment(cmd, cs, a, true);
       }
    }
 
index b14eab022fa6704e33d4a69a72103c0006d63ff6..7d537973e5e20ee13549a3fa6c17a54bda333944 100644 (file)
@@ -102,6 +102,53 @@ create_render_pass_common(struct tu_render_pass *pass,
             subpass->srgb_cntl |= 1 << i;
       }
    }
+
+   /* disable unused attachments */
+   for (uint32_t i = 0; i < pass->attachment_count; i++) {
+      struct tu_render_pass_attachment *att = &pass->attachments[i];
+      if (att->gmem_offset < 0) {
+         att->clear_mask = 0;
+         att->load = false;
+      }
+   }
+}
+
+static void
+attachment_set_ops(struct tu_render_pass_attachment *att,
+                   VkAttachmentLoadOp load_op,
+                   VkAttachmentLoadOp stencil_load_op,
+                   VkAttachmentStoreOp store_op,
+                   VkAttachmentStoreOp stencil_store_op)
+{
+   /* load/store ops */
+   att->clear_mask =
+      (load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ? VK_IMAGE_ASPECT_COLOR_BIT : 0;
+   att->load = (load_op == VK_ATTACHMENT_LOAD_OP_LOAD);
+   att->store = (store_op == VK_ATTACHMENT_STORE_OP_STORE);
+
+   bool stencil_clear = (stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR);
+   bool stencil_load = (stencil_load_op == VK_ATTACHMENT_LOAD_OP_LOAD);
+   bool stencil_store = (stencil_store_op == VK_ATTACHMENT_STORE_OP_STORE);
+
+   switch (att->format) {
+   case VK_FORMAT_D24_UNORM_S8_UINT: /* || stencil load/store */
+      if (att->clear_mask)
+         att->clear_mask = VK_IMAGE_ASPECT_DEPTH_BIT;
+      if (stencil_clear)
+         att->clear_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
+      if (stencil_load)
+         att->load = true;
+      if (stencil_store)
+         att->store = true;
+      break;
+   case VK_FORMAT_S8_UINT: /* replace load/store with stencil load/store */
+      att->clear_mask = stencil_clear ? VK_IMAGE_ASPECT_COLOR_BIT : 0;
+      att->load = stencil_load;
+      att->store = stencil_store;
+      break;
+   default:
+      break;
+   }
 }
 
 VkResult
@@ -138,13 +185,13 @@ tu_CreateRenderPass(VkDevice _device,
       att->format = pCreateInfo->pAttachments[i].format;
       att->samples = pCreateInfo->pAttachments[i].samples;
       att->cpp = vk_format_get_blocksize(att->format) * att->samples;
-      att->load_op = pCreateInfo->pAttachments[i].loadOp;
-      att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
-      att->store_op = pCreateInfo->pAttachments[i].storeOp;
-      if (pCreateInfo->pAttachments[i].stencilStoreOp == VK_ATTACHMENT_STORE_OP_STORE &&
-          vk_format_has_stencil(att->format))
-         att->store_op = VK_ATTACHMENT_STORE_OP_STORE;
       att->gmem_offset = -1;
+
+      attachment_set_ops(att,
+                         pCreateInfo->pAttachments[i].loadOp,
+                         pCreateInfo->pAttachments[i].stencilLoadOp,
+                         pCreateInfo->pAttachments[i].storeOp,
+                         pCreateInfo->pAttachments[i].stencilStoreOp);
    }
 
    uint32_t subpass_attachment_count = 0;
@@ -266,14 +313,13 @@ tu_CreateRenderPass2(VkDevice _device,
       att->format = pCreateInfo->pAttachments[i].format;
       att->samples = pCreateInfo->pAttachments[i].samples;
       att->cpp = vk_format_get_blocksize(att->format) * att->samples;
-      att->load_op = pCreateInfo->pAttachments[i].loadOp;
-      att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
-      att->store_op = pCreateInfo->pAttachments[i].storeOp;
-      att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
-      if (pCreateInfo->pAttachments[i].stencilStoreOp == VK_ATTACHMENT_STORE_OP_STORE &&
-          vk_format_has_stencil(att->format))
-         att->store_op = VK_ATTACHMENT_STORE_OP_STORE;
       att->gmem_offset = -1;
+
+      attachment_set_ops(att,
+                         pCreateInfo->pAttachments[i].loadOp,
+                         pCreateInfo->pAttachments[i].stencilLoadOp,
+                         pCreateInfo->pAttachments[i].storeOp,
+                         pCreateInfo->pAttachments[i].stencilStoreOp);
    }
    uint32_t subpass_attachment_count = 0;
    struct tu_subpass_attachment *p;
index 4953075375fada85998e5754797fde28cc0a4f15..eb026998293d99ac4e932e131dd2af166f399abd 100644 (file)
@@ -1319,7 +1319,10 @@ tu_clear_gmem_attachment(struct tu_cmd_buffer *cmd,
                          const VkRenderPassBeginInfo *info);
 
 void
-tu_load_gmem_attachment(struct tu_cmd_buffer *cmd, struct tu_cs *cs, uint32_t a);
+tu_load_gmem_attachment(struct tu_cmd_buffer *cmd,
+                        struct tu_cs *cs,
+                        uint32_t a,
+                        bool force_load);
 
 /* expose this function to be able to emit load without checking LOAD_OP */
 void
@@ -1590,10 +1593,9 @@ struct tu_render_pass_attachment
    VkFormat format;
    uint32_t samples;
    uint32_t cpp;
-   VkAttachmentLoadOp load_op;
-   VkAttachmentLoadOp stencil_load_op;
-   VkAttachmentStoreOp store_op;
-   VkAttachmentStoreOp stencil_store_op;
+   VkImageAspectFlags clear_mask;
+   bool load;
+   bool store;
    int32_t gmem_offset;
 };