<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Nov 28, 2017 at 10:07 AM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail_extra">This patch causes a perf drop in sascha gears.  I'm investigating.<br></div></blockquote><div><br></div><div>Found it!  Read below.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail_extra"><div class="gmail_quote">On Mon, Nov 27, 2017 at 7:06 PM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">---<br>
 src/intel/vulkan/genX_cmd_buf<wbr>fer.c | 187 +++++++++++++-----------------<wbr>-------<br>
 1 file changed, 65 insertions(+), 122 deletions(-)<br>
<br>
diff --git a/src/intel/vulkan/genX_cmd_bu<wbr>ffer.c b/src/intel/vulkan/genX_cmd_bu<wbr>ffer.c<br>
index 7901b0c..2c4ab38 100644<br>
--- a/src/intel/vulkan/genX_cmd_bu<wbr>ffer.c<br>
+++ b/src/intel/vulkan/genX_cmd_bu<wbr>ffer.c<br>
@@ -2982,120 +2982,6 @@ cmd_buffer_emit_depth_stencil(<wbr>struct anv_cmd_buffer *cmd_buffer)<br>
    cmd_buffer->state.hiz_enabled = info.hiz_usage == ISL_AUX_USAGE_HIZ;<br>
 }<br>
<br>
-<br>
-/**<br>
- * @brief Perform any layout transitions required at the beginning and/or end<br>
- *        of the current subpass for depth buffers.<br>
- *<br>
- * TODO: Consider preprocessing the attachment reference array at render pass<br>
- *       create time to determine if no layout transition is needed at the<br>
- *       beginning and/or end of each subpass.<br>
- *<br>
- * @param cmd_buffer The command buffer the transition is happening within.<br>
- * @param subpass_end If true, marks that the transition is happening at the<br>
- *                    end of the subpass.<br>
- */<br>
-static void<br>
-cmd_buffer_subpass_transition<wbr>_layouts(struct anv_cmd_buffer * const cmd_buffer,<br>
-                                      const bool subpass_end)<br>
-{<br>
-   /* We need a non-NULL command buffer. */<br>
-   assert(cmd_buffer);<br>
-<br>
-   const struct anv_cmd_state * const cmd_state = &cmd_buffer->state;<br>
-   const struct anv_subpass * const subpass = cmd_state->subpass;<br>
-<br>
-   /* This function must be called within a subpass. */<br>
-   assert(subpass);<br>
-<br>
-   /* If there are attachment references, the array shouldn't be NULL.<br>
-    */<br>
-   if (subpass->attachment_count > 0)<br>
-      assert(subpass->attachments);<br>
-<br>
-   /* Iterate over the array of attachment references. */<br>
-   for (const VkAttachmentReference *att_ref = subpass->attachments;<br>
-        att_ref < subpass->attachments + subpass->attachment_count; att_ref++) {<br>
-<br>
-      /* If the attachment is unused, we can't perform a layout transition. */<br>
-      if (att_ref->attachment == VK_ATTACHMENT_UNUSED)<br>
-         continue;<br>
-<br>
-      /* This attachment index shouldn't go out of bounds. */<br>
-      assert(att_ref->attachment < cmd_state->pass->attachment_co<wbr>unt);<br>
-<br>
-      const struct anv_render_pass_attachment * const att_desc =<br>
-         &cmd_state->pass-><wbr>attachments[att_ref-><wbr>attachment];<br>
-      struct anv_attachment_state * const att_state =<br>
-         &cmd_buffer->state.attachment<wbr>s[att_ref->attachment];<br>
-<br>
-      /* The attachment should not be used in a subpass after its last. */<br>
-      assert(att_desc->last_subpass_<wbr>idx >= anv_get_subpass_id(cmd_state))<wbr>;<br>
-<br>
-      if (subpass_end && anv_get_subpass_id(cmd_state) <<br>
-          att_desc->last_subpass_idx) {<br>
-         /* We're calling this function on a buffer twice in one subpass and<br>
-          * this is not the last use of the buffer. The layout should not have<br>
-          * changed from the first call and no transition is necessary.<br>
-          */<br>
-         assert(att_state->current_lay<wbr>out == att_ref->layout ||<br>
-                att_state->current_layout ==<br>
-                VK_IMAGE_LAYOUT_COLOR_ATTACHME<wbr>NT_OPTIMAL);<br>
-         continue;<br>
-      }<br>
-<br>
-      /* The attachment index must be less than the number of attachments<br>
-       * within the framebuffer.<br>
-       */<br>
-      assert(att_ref->attachment < cmd_state->framebuffer->attach<wbr>ment_count);<br>
-<br>
-      const struct anv_image_view * const iview =<br>
-         cmd_state->framebuffer->attac<wbr>hments[att_ref->attachment];<br>
-      const struct anv_image * const image = iview->image;<br>
-<br>
-      /* Get the appropriate target layout for this attachment. */<br>
-      VkImageLayout target_layout;<br>
-<br>
-      /* A resolve is necessary before use as an input attachment if the clear<br>
-       * color or auxiliary buffer usage isn't supported by the sampler.<br>
-       */<br>
-      const bool input_needs_resolve =<br>
-            (att_state->fast_clear && !att_state->clear_color_is_zer<wbr>o_one) ||<br>
-            att_state->input_aux_usage != att_state->aux_usage;<br>
-      if (subpass_end) {<br>
-         target_layout = att_desc->final_layout;<br>
-      } else if (iview->aspect_mask & VK_IMAGE_ASPECT_ANY_COLOR_BIT_<wbr>ANV &&<br>
-                 !input_needs_resolve) {<br>
-         /* Layout transitions before the final only help to enable sampling as<br>
-          * an input attachment. If the input attachment supports sampling<br>
-          * using the auxiliary surface, we can skip such transitions by making<br>
-          * the target layout one that is CCS-aware.<br>
-          */<br>
-         target_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHME<wbr>NT_OPTIMAL;<br>
-      } else {<br>
-         target_layout = att_ref->layout;<br>
-      }<br>
-<br>
-      /* Perform the layout transition. */<br>
-      if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {<br>
-         transition_depth_buffer(cmd_b<wbr>uffer, image,<br>
-                                 att_state->current_layout, target_layout);<br>
-         att_state->aux_usage =<br>
-            anv_layout_to_aux_usage(&cmd_b<wbr>uffer->device->info, image,<br>
-                                    VK_IMAGE_ASPECT_DEPTH_BIT, target_layout);<br>
-      } else if (image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_<wbr>ANV) {<br>
-         assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);<br>
-         transition_color_buffer(cmd_b<wbr>uffer, image, VK_IMAGE_ASPECT_COLOR_BIT,<br>
-                                 iview->planes[0].isl.base_lev<wbr>el, 1,<br>
-                                 iview->planes[0].isl.base_arr<wbr>ay_layer,<br>
-                                 iview->planes[0].isl.array_le<wbr>n,<br>
-                                 att_state->current_layout, target_layout);<br>
-      }<br>
-<br>
-      att_state->current_layout = target_layout;<br>
-   }<br>
-}<br>
-<br>
 static void<br>
 cmd_buffer_begin_subpass(stru<wbr>ct anv_cmd_buffer *cmd_buffer,<br>
                          uint32_t subpass_id)<br>
@@ -3120,11 +3006,6 @@ cmd_buffer_begin_subpass(struc<wbr>t anv_cmd_buffer *cmd_buffer,<br>
    cmd_buffer->state.pending_pipe<wbr>_bits |=<br>
       cmd_buffer->state.pass->subpa<wbr>ss_flushes[subpass_id];<br>
<br>
-   /* Perform transitions to the subpass layout before any writes have<br>
-    * occurred.<br>
-    */<br>
-   cmd_buffer_subpass_<wbr>transition_layouts(cmd_buffer, false);<br>
-<br>
    VkRect2D render_area = cmd_buffer->state.render_area;<br>
    struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;<br>
<br>
@@ -3139,6 +3020,39 @@ cmd_buffer_begin_subpass(struc<wbr>t anv_cmd_buffer *cmd_buffer,<br>
       struct anv_image_view *iview = fb->attachments[a];<br>
       const struct anv_image *image = iview->image;<br>
<br>
+      /* A resolve is necessary before use as an input attachment if the clear<br>
+       * color or auxiliary buffer usage isn't supported by the sampler.<br>
+       */<br>
+      const bool input_needs_resolve =<br>
+            (att_state->fast_clear && !att_state->clear_color_is_zer<wbr>o_one) ||<br>
+            att_state->input_aux_usage != att_state->aux_usage;<br>
+<br>
+      VkImageLayout target_layout;<br>
+      if (iview->aspect_mask & VK_IMAGE_ASPECT_ANY_COLOR_BIT_<wbr>ANV &&<br>
+          !input_needs_resolve) {<br>
+         /* Layout transitions before the final only help to enable sampling<br>
+          * as an input attachment. If the input attachment supports sampling<br>
+          * using the auxiliary surface, we can skip such transitions by<br>
+          * making the target layout one that is CCS-aware.<br>
+          */<br>
+         target_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHME<wbr>NT_OPTIMAL;<br>
+      } else {<br>
+         target_layout = subpass->attachments[i].layout<wbr>;<br>
+      }<br>
+<br>
+      if (image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_<wbr>ANV) {<br>
+         assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);<br>
+         transition_color_buffer(cmd_b<wbr>uffer, image, VK_IMAGE_ASPECT_COLOR_BIT,<br>
+                                 iview->planes[0].isl.base_lev<wbr>el, 1,<br>
+                                 iview->planes[0].isl.base_arr<wbr>ay_layer,<br>
+                                 iview->planes[0].isl.array_le<wbr>n,<br>
+                                 att_state->current_layout, target_layout);<br>
+      } else if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {<br>
+         transition_depth_buffer(cmd_b<wbr>uffer, image,<br>
+                                 att_state->current_layout, target_layout);<br></blockquote></div></div></blockquote><div><br></div><div>I accidentally dropped a bit here:</div><div><br></div><div>+         att_state->aux_usage =<br>+            anv_layout_to_aux_usage(&cmd_buffer->device->info, image,<br>+                                    VK_IMAGE_ASPECT_DEPTH_BIT, target_layout);<br></div><div><br></div><div>I've added it locally.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+      }<br>
+      att_state->current_layout = target_layout;<br>
+<br>
       if (att_state->pending_clear_aspe<wbr>cts & VK_IMAGE_ASPECT_COLOR_BIT) {<br>
          assert(att_state->pending_clea<wbr>r_aspects == VK_IMAGE_ASPECT_COLOR_BIT);<br>
<br>
@@ -3251,13 +3165,42 @@ cmd_buffer_begin_subpass(struc<wbr>t anv_cmd_buffer *cmd_buffer,<br>
 static void<br>
 cmd_buffer_end_subpass(struct anv_cmd_buffer *cmd_buffer)<br>
 {<br>
+   struct anv_cmd_state *cmd_state = &cmd_buffer->state;<br>
+   struct anv_subpass *subpass = cmd_state->subpass;<br>
    uint32_t subpass_id = anv_get_subpass_id(&cmd_buffer<wbr>->state);<br>
<br>
    anv_cmd_buffer_resolve_subpass<wbr>(cmd_buffer);<br>
<br>
-   /* Perform transitions to the final layout after all writes have occurred.<br>
-    */<br>
-   cmd_buffer_subpass_<wbr>transition_layouts(cmd_buffer, true);<br>
+   struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;<br>
+   for (uint32_t i = 0; i < subpass->attachment_count; ++i) {<br>
+      const uint32_t a = subpass->attachments[i].attach<wbr>ment;<br>
+      if (a == VK_ATTACHMENT_UNUSED)<br>
+         continue;<br>
+<br>
+      if (cmd_state->pass->attachments[<wbr>a].last_subpass_idx != subpass_id)<br>
+         continue;<br>
+<br>
+      assert(a < cmd_state->pass->attachment_co<wbr>unt);<br>
+      struct anv_attachment_state *att_state = &cmd_state->attachments[a];<br>
+      struct anv_image_view *iview = fb->attachments[a];<br>
+      const struct anv_image *image = iview->image;<br>
+<br>
+      /* Transition the image into the final layout for this render pass */<br>
+      VkImageLayout target_layout =<br>
+         cmd_state->pass->attachments[<wbr>a].final_layout;<br>
+<br>
+      if (image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_<wbr>ANV) {<br>
+         assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);<br>
+         transition_color_buffer(cmd_b<wbr>uffer, image, VK_IMAGE_ASPECT_COLOR_BIT,<br>
+                                 iview->planes[0].isl.base_lev<wbr>el, 1,<br>
+                                 iview->planes[0].isl.base_arr<wbr>ay_layer,<br>
+                                 iview->planes[0].isl.array_le<wbr>n,<br>
+                                 att_state->current_layout, target_layout);<br>
+      } else if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {<br>
+         transition_depth_buffer(cmd_b<wbr>uffer, image,<br>
+                                 att_state->current_layout, target_layout);<br>
+      }<br>
+   }<br>
<br>
    /* Accumulate any subpass flushes that need to happen after the subpass.<br>
     * Yes, they do get accumulated twice in the NextSubpass case but since<br>
<span class="gmail-m_-3472840471167407836HOEnZb"><font color="#888888">--<br>
2.5.0.400.gff86faf<br>
<br>
</font></span></blockquote></div><br></div><div class="gmail-HOEnZb"><div class="gmail-h5">
</div></div></blockquote></div><br></div></div>