anv/pass: Move implicit dependency setup to anv_render_pass_compile
authorJason Ekstrand <jason.ekstrand@intel.com>
Tue, 24 Apr 2018 20:01:01 +0000 (13:01 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Mon, 9 Jul 2018 17:11:53 +0000 (10:11 -0700)
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
src/intel/vulkan/anv_pass.c

index b70de87a82b1a1ece6c44d516b919c0860aefa17..cb5e4bb7b79c3e1b89871dfd0521c67d39af1b2b 100644 (file)
@@ -62,6 +62,7 @@ anv_render_pass_compile(struct anv_render_pass *pass)
     * }
     */
 
+   VkImageUsageFlags all_usage = 0;
    for (uint32_t i = 0; i < pass->subpass_count; i++) {
       struct anv_subpass *subpass = &pass->subpasses[i];
 
@@ -77,6 +78,8 @@ anv_render_pass_compile(struct anv_render_pass *pass)
          pass_att->usage |= subpass_att->usage;
          pass_att->last_subpass_idx = i;
 
+         all_usage |= subpass_att->usage;
+
          if (pass_att->first_subpass_layout == VK_IMAGE_LAYOUT_UNDEFINED) {
             pass_att->first_subpass_layout = subpass_att->layout;
             assert(pass_att->first_subpass_layout != VK_IMAGE_LAYOUT_UNDEFINED);
@@ -105,6 +108,66 @@ anv_render_pass_compile(struct anv_render_pass *pass)
          }
       }
    }
+
+   /* From the Vulkan 1.0.39 spec:
+    *
+    *    If there is no subpass dependency from VK_SUBPASS_EXTERNAL to the
+    *    first subpass that uses an attachment, then an implicit subpass
+    *    dependency exists from VK_SUBPASS_EXTERNAL to the first subpass it is
+    *    used in. The subpass dependency operates as if defined with the
+    *    following parameters:
+    *
+    *    VkSubpassDependency implicitDependency = {
+    *        .srcSubpass = VK_SUBPASS_EXTERNAL;
+    *        .dstSubpass = firstSubpass; // First subpass attachment is used in
+    *        .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+    *        .dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
+    *        .srcAccessMask = 0;
+    *        .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
+    *                         VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
+    *                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
+    *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
+    *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+    *        .dependencyFlags = 0;
+    *    };
+    *
+    *    Similarly, if there is no subpass dependency from the last subpass
+    *    that uses an attachment to VK_SUBPASS_EXTERNAL, then an implicit
+    *    subpass dependency exists from the last subpass it is used in to
+    *    VK_SUBPASS_EXTERNAL. The subpass dependency operates as if defined
+    *    with the following parameters:
+    *
+    *    VkSubpassDependency implicitDependency = {
+    *        .srcSubpass = lastSubpass; // Last subpass attachment is used in
+    *        .dstSubpass = VK_SUBPASS_EXTERNAL;
+    *        .srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
+    *        .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+    *        .srcAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
+    *                         VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
+    *                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
+    *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
+    *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+    *        .dstAccessMask = 0;
+    *        .dependencyFlags = 0;
+    *    };
+    *
+    * We could implement this by walking over all of the attachments and
+    * subpasses and checking to see if any of them don't have an external
+    * dependency.  Or, we could just be lazy and add a couple extra flushes.
+    * We choose to be lazy.
+    */
+   if (all_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
+      pass->subpass_flushes[0] |=
+         ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT;
+   }
+   if (all_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
+      pass->subpass_flushes[pass->subpass_count] |=
+         ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT;
+   }
+   if (all_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+      pass->subpass_flushes[pass->subpass_count] |=
+         ANV_PIPE_DEPTH_CACHE_FLUSH_BIT;
+   }
 }
 
 static unsigned
@@ -170,7 +233,6 @@ VkResult anv_CreateRenderPass(
       };
    }
 
-   bool has_color = false, has_depth = false, has_input = false;
    for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
       const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
       struct anv_subpass *subpass = &pass->subpasses[i];
@@ -186,14 +248,11 @@ VkResult anv_CreateRenderPass(
          subpass_attachments += desc->inputAttachmentCount;
 
          for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
-            uint32_t a = desc->pInputAttachments[j].attachment;
             subpass->input_attachments[j] = (struct anv_subpass_attachment) {
                .usage =       VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
                .attachment =  desc->pInputAttachments[j].attachment,
                .layout =      desc->pInputAttachments[j].layout,
             };
-            if (a != VK_ATTACHMENT_UNUSED)
-               has_input = true;
          }
       }
 
@@ -202,14 +261,11 @@ VkResult anv_CreateRenderPass(
          subpass_attachments += desc->colorAttachmentCount;
 
          for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
-            uint32_t a = desc->pColorAttachments[j].attachment;
             subpass->color_attachments[j] = (struct anv_subpass_attachment) {
                .usage =       VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
                .attachment =  desc->pColorAttachments[j].attachment,
                .layout =      desc->pColorAttachments[j].layout,
             };
-            if (a != VK_ATTACHMENT_UNUSED)
-               has_color = true;
          }
       }
 
@@ -227,15 +283,12 @@ VkResult anv_CreateRenderPass(
       }
 
       if (desc->pDepthStencilAttachment) {
-         uint32_t a = desc->pDepthStencilAttachment->attachment;
          subpass->depth_stencil_attachment = (struct anv_subpass_attachment) {
             .usage =       VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
             .attachment =  desc->pDepthStencilAttachment->attachment,
             .layout =      desc->pDepthStencilAttachment->layout,
          };
          *subpass_attachments++ = subpass->depth_stencil_attachment;
-         if (a != VK_ATTACHMENT_UNUSED)
-            has_depth = true;
       } else {
          subpass->depth_stencil_attachment = (struct anv_subpass_attachment) {
             .usage =       VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
@@ -259,66 +312,6 @@ VkResult anv_CreateRenderPass(
       anv_render_pass_add_subpass_dep(pass, &dep2);
    }
 
-   /* From the Vulkan 1.0.39 spec:
-    *
-    *    If there is no subpass dependency from VK_SUBPASS_EXTERNAL to the
-    *    first subpass that uses an attachment, then an implicit subpass
-    *    dependency exists from VK_SUBPASS_EXTERNAL to the first subpass it is
-    *    used in. The subpass dependency operates as if defined with the
-    *    following parameters:
-    *
-    *    VkSubpassDependency implicitDependency = {
-    *        .srcSubpass = VK_SUBPASS_EXTERNAL;
-    *        .dstSubpass = firstSubpass; // First subpass attachment is used in
-    *        .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
-    *        .dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
-    *        .srcAccessMask = 0;
-    *        .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
-    *                         VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
-    *                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
-    *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
-    *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
-    *        .dependencyFlags = 0;
-    *    };
-    *
-    *    Similarly, if there is no subpass dependency from the last subpass
-    *    that uses an attachment to VK_SUBPASS_EXTERNAL, then an implicit
-    *    subpass dependency exists from the last subpass it is used in to
-    *    VK_SUBPASS_EXTERNAL. The subpass dependency operates as if defined
-    *    with the following parameters:
-    *
-    *    VkSubpassDependency implicitDependency = {
-    *        .srcSubpass = lastSubpass; // Last subpass attachment is used in
-    *        .dstSubpass = VK_SUBPASS_EXTERNAL;
-    *        .srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
-    *        .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
-    *        .srcAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
-    *                         VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
-    *                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
-    *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
-    *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
-    *        .dstAccessMask = 0;
-    *        .dependencyFlags = 0;
-    *    };
-    *
-    * We could implement this by walking over all of the attachments and
-    * subpasses and checking to see if any of them don't have an external
-    * dependency.  Or, we could just be lazy and add a couple extra flushes.
-    * We choose to be lazy.
-    */
-   if (has_input) {
-      pass->subpass_flushes[0] |=
-         ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT;
-   }
-   if (has_color) {
-      pass->subpass_flushes[pass->subpass_count] |=
-         ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT;
-   }
-   if (has_depth) {
-      pass->subpass_flushes[pass->subpass_count] |=
-         ANV_PIPE_DEPTH_CACHE_FLUSH_BIT;
-   }
-
    vk_foreach_struct(ext, pCreateInfo->pNext) {
       switch (ext->sType) {
       case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR: {