[Mesa-dev] [PATCH 19/24] anv/cmd_buffer: Add transition_color_buffer()

Nanley Chery nanleychery at gmail.com
Thu May 11 19:05:26 UTC 2017


v2 (Jason Ekstrand):
- Provide a more detailed comment for the CCS pipe controls

Signed-off-by: Nanley Chery <nanley.g.chery at intel.com>
---
 src/intel/vulkan/genX_cmd_buffer.c | 103 +++++++++++++++++++++++++++++++++++++
 1 file changed, 103 insertions(+)

diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c
index 91a6be868c..5adf08b798 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -465,6 +465,109 @@ genX(transfer_clear_value)(struct anv_cmd_buffer * const cmd_buffer,
    }
 }
 
+/* Transitions a color buffer from one layout to another. */
+static void
+transition_color_buffer(struct anv_cmd_buffer * const cmd_buffer,
+                        const struct anv_image * const image,
+                        const uint32_t base_level, uint32_t level_count,
+                        const uint32_t base_layer, uint32_t layer_count,
+                        const VkImageLayout initial_layout,
+                        const VkImageLayout final_layout)
+{
+   assert(cmd_buffer && image);
+
+   /* This must be a color image. */
+   assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
+
+   /* Only color buffers with CCS need resolving.  */
+   if (image->aux_surface.isl.size == 0 || image->samples > 1)
+      return;
+
+   /* Don't transition this subresource range if it lacks auxiliary data. */
+   if (base_level >= anv_color_aux_levels(image) ||
+       base_layer >= anv_color_aux_layers(image, base_level))
+      return;
+
+   /* The undefined layout indicates that the user doesn't care about the
+    * data that's currently in the buffer. The pre-initialized layout is
+    * equivalent to the undefined layout for optimally-tiled images.
+    *
+    * We can only skip the resolve for CCS_E images in this layout because it
+    * is enabled outside of render passes. This allows previously fast-cleared
+    * and undefined buffers to be defined with transfer operations.
+    */
+   const bool is_ccs_e = image->aux_usage == ISL_AUX_USAGE_CCS_E;
+   const bool undef_layout = initial_layout == VK_IMAGE_LAYOUT_UNDEFINED ||
+                             initial_layout == VK_IMAGE_LAYOUT_PREINITIALIZED;
+   if (is_ccs_e && undef_layout)
+      return;
+
+   /* A resolve isn't necessary when transitioning from a layout that doesn't
+    * have fast-clear data or to a layout that will be aware of the fast-clear
+    * value.
+    */
+   const bool maybe_fast_cleared = undef_layout || initial_layout ==
+                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+   if (!maybe_fast_cleared || final_layout ==
+       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
+      return;
+
+   /* Determine the optimal resolve operation. For now we only need to resolve
+    * the clear color.
+    */
+   const enum blorp_fast_clear_op op = is_ccs_e ?
+                                       BLORP_FAST_CLEAR_OP_RESOLVE_PARTIAL :
+                                       BLORP_FAST_CLEAR_OP_RESOLVE_FULL;
+
+   /* The actual range that will be transitioned is limited by the number of
+    * subresources that have auxiliary data.
+    */
+   level_count = MIN2(level_count, anv_color_aux_levels(image));
+
+   /* From the Sky Lake PRM Vol. 7, "MCS Buffer for Render Target(s)":
+    *
+    *    Any transition from any value in {Clear, Render, Resolve} to a
+    *    different value in {Clear, Render, Resolve} requires end of pipe
+    *    synchronization.
+    *
+    * We perform a flush of the write cache before and after the clear and
+    * resolve operations to meet this requirement.
+    *
+    * Unlike other drawing, it seems that fast clear operations are not
+    * properly synchronized. The first PIPE_CONTROL here likely ensures that
+    * the contents of the previous render or clear hit the render target before
+    * we resolve and the second likely ensures that the resolve is complete
+    * before we do any more rendering or clearing.
+    */
+   cmd_buffer->state.pending_pipe_bits |=
+      ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
+
+   for (uint32_t level = base_level; level < base_level + level_count; level++) {
+
+      layer_count = MIN2(layer_count, anv_color_aux_layers(image, level));
+      for (uint32_t layer = base_layer; layer < base_layer + layer_count; layer++) {
+
+         /* Create a surface state with the right clear color and perform the
+          * resolve.
+          */
+         struct anv_state surface_state =
+            anv_cmd_buffer_alloc_surface_state(cmd_buffer);
+         anv_fill_ccs_resolve_ss(cmd_buffer->device, surface_state.map, image,
+                                 level, layer);
+         add_image_relocs(cmd_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT,
+                          is_ccs_e ?  ISL_AUX_USAGE_CCS_E : ISL_AUX_USAGE_CCS_D,
+                          surface_state);
+         anv_state_flush(cmd_buffer->device, surface_state);
+         genX(transfer_clear_value)(cmd_buffer, surface_state, image, level,
+                                    false);
+         anv_ccs_resolve(cmd_buffer, surface_state, image, level, layer, op);
+      }
+   }
+
+   cmd_buffer->state.pending_pipe_bits |=
+      ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
+}
+
 /**
  * Setup anv_cmd_state::attachments for vkCmdBeginRenderPass.
  */
-- 
2.12.2



More information about the mesa-dev mailing list