[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