[Mesa-dev] [PATCH 17/29] anv/cmd_buffer: Move the color portion of clear_subpass into begin_subpass

Jason Ekstrand jason at jlekstrand.net
Tue Nov 28 03:06:07 UTC 2017


This doesn't really change much now but it will give us more/better
control over clears in the future.  The one interesting functional
change here is that we are now re-emitting 3DSTATE_DEPTH_BUFFERS and
friends for each clear.  However, this only happens at begin_subpass
time so it shouldn't be substantially more expensive.
---
 src/intel/vulkan/anv_blorp.c       | 115 +++++++++++--------------------------
 src/intel/vulkan/anv_private.h     |   8 +++
 src/intel/vulkan/genX_cmd_buffer.c |  46 ++++++++++++++-
 3 files changed, 86 insertions(+), 83 deletions(-)

diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c
index 46e2eb0..7401234 100644
--- a/src/intel/vulkan/anv_blorp.c
+++ b/src/intel/vulkan/anv_blorp.c
@@ -1138,17 +1138,6 @@ subpass_needs_clear(const struct anv_cmd_buffer *cmd_buffer)
    const struct anv_cmd_state *cmd_state = &cmd_buffer->state;
    uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment;
 
-   for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
-      uint32_t a = cmd_state->subpass->color_attachments[i].attachment;
-      if (a == VK_ATTACHMENT_UNUSED)
-         continue;
-
-      assert(a < cmd_state->pass->attachment_count);
-      if (cmd_state->attachments[a].pending_clear_aspects) {
-         return true;
-      }
-   }
-
    if (ds != VK_ATTACHMENT_UNUSED) {
       assert(ds < cmd_state->pass->attachment_count);
       if (cmd_state->attachments[ds].pending_clear_aspects)
@@ -1182,77 +1171,6 @@ anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
    };
 
    struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
-   for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
-      const uint32_t a = cmd_state->subpass->color_attachments[i].attachment;
-      if (a == VK_ATTACHMENT_UNUSED)
-         continue;
-
-      assert(a < cmd_state->pass->attachment_count);
-      struct anv_attachment_state *att_state = &cmd_state->attachments[a];
-
-      if (!att_state->pending_clear_aspects)
-         continue;
-
-      assert(att_state->pending_clear_aspects == VK_IMAGE_ASPECT_COLOR_BIT);
-
-      struct anv_image_view *iview = fb->attachments[a];
-      const struct anv_image *image = iview->image;
-      struct blorp_surf surf;
-      get_blorp_surf_for_anv_image(cmd_buffer->device,
-                                   image, VK_IMAGE_ASPECT_COLOR_BIT,
-                                   att_state->aux_usage, &surf);
-
-      if (att_state->fast_clear) {
-         surf.clear_color = vk_to_isl_color(att_state->clear_value.color);
-
-         /* From the Sky Lake PRM Vol. 7, "Render Target Fast Clear":
-          *
-          *    "After Render target fast clear, pipe-control with color cache
-          *    write-flush must be issued before sending any DRAW commands on
-          *    that render target."
-          *
-          * This comment is a bit cryptic and doesn't really tell you what's
-          * going or what's really needed.  It appears that fast clear ops are
-          * not properly synchronized with other drawing.  This means that we
-          * cannot have a fast clear operation in the pipe at the same time as
-          * other regular drawing operations.  We need to use a PIPE_CONTROL
-          * to ensure that the contents of the previous draw hit the render
-          * target before we resolve and then use a second PIPE_CONTROL after
-          * the resolve to ensure that it is completed before any additional
-          * drawing occurs.
-          */
-         cmd_buffer->state.pending_pipe_bits |=
-            ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
-
-         assert(image->n_planes == 1);
-         blorp_fast_clear(&batch, &surf, iview->planes[0].isl.format,
-                          iview->planes[0].isl.base_level,
-                          iview->planes[0].isl.base_array_layer, fb->layers,
-                          render_area.offset.x, render_area.offset.y,
-                          render_area.offset.x + render_area.extent.width,
-                          render_area.offset.y + render_area.extent.height);
-
-         cmd_buffer->state.pending_pipe_bits |=
-            ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
-      } else {
-         assert(image->n_planes == 1);
-         anv_cmd_buffer_mark_image_written(cmd_buffer, image,
-                                           VK_IMAGE_ASPECT_COLOR_BIT,
-                                           att_state->aux_usage,
-                                           iview->planes[0].isl.base_level);
-
-         blorp_clear(&batch, &surf, iview->planes[0].isl.format,
-                     anv_swizzle_for_render(iview->planes[0].isl.swizzle),
-                     iview->planes[0].isl.base_level,
-                     iview->planes[0].isl.base_array_layer, fb->layers,
-                     render_area.offset.x, render_area.offset.y,
-                     render_area.offset.x + render_area.extent.width,
-                     render_area.offset.y + render_area.extent.height,
-                     vk_to_isl_color(att_state->clear_value.color), NULL);
-      }
-
-      att_state->pending_clear_aspects = 0;
-   }
 
    const uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment;
    assert(ds == VK_ATTACHMENT_UNUSED || ds < cmd_state->pass->attachment_count);
@@ -1617,6 +1535,39 @@ isl_to_blorp_hiz_op(enum isl_aux_op isl_op)
 }
 
 void
+anv_image_clear_color(struct anv_cmd_buffer *cmd_buffer,
+                      const struct anv_image *image,
+                      VkImageAspectFlagBits aspect,
+                      enum isl_aux_usage aux_usage,
+                      enum isl_format format, struct isl_swizzle swizzle,
+                      uint32_t level, uint32_t base_layer, uint32_t layer_count,
+                      VkRect2D area, union isl_color_value clear_color)
+{
+   assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
+
+   /* We don't support planar images with multisampling yet */
+   assert(image->n_planes == 1);
+
+   struct blorp_batch batch;
+   blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
+
+   struct blorp_surf surf;
+   get_blorp_surf_for_anv_image(cmd_buffer->device, image, aspect,
+                                aux_usage, &surf);
+   anv_cmd_buffer_mark_image_written(cmd_buffer, image, aspect,
+                                     aux_usage, level);
+
+   blorp_clear(&batch, &surf, format, anv_swizzle_for_render(swizzle),
+               level, base_layer, layer_count,
+               area.offset.x, area.offset.y,
+               area.offset.x + area.extent.width,
+               area.offset.y + area.extent.height,
+               clear_color, NULL);
+
+   blorp_batch_finish(&batch);
+}
+
+void
 anv_image_hiz_op(struct anv_cmd_buffer *cmd_buffer,
                  const struct anv_image *image,
                  VkImageAspectFlagBits aspect, uint32_t level,
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index e875705..bc355bb 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -2537,6 +2537,14 @@ anv_cmd_buffer_mark_image_written(struct anv_cmd_buffer *cmd_buffer,
                                   unsigned level);
 
 void
+anv_image_clear_color(struct anv_cmd_buffer *cmd_buffer,
+                      const struct anv_image *image,
+                      VkImageAspectFlagBits aspect,
+                      enum isl_aux_usage aux_usage,
+                      enum isl_format format, struct isl_swizzle swizzle,
+                      uint32_t level, uint32_t base_layer, uint32_t layer_count,
+                      VkRect2D area, union isl_color_value clear_color);
+void
 anv_image_hiz_op(struct anv_cmd_buffer *cmd_buffer,
                  const struct anv_image *image,
                  VkImageAspectFlagBits aspect, uint32_t level,
diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c
index 56036f7..265ae44 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -3140,7 +3140,9 @@ static void
 cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
                          uint32_t subpass_id)
 {
-   cmd_buffer->state.subpass = &cmd_buffer->state.pass->subpasses[subpass_id];
+   struct anv_cmd_state *cmd_state = &cmd_buffer->state;
+   struct anv_subpass *subpass = &cmd_state->pass->subpasses[subpass_id];
+   cmd_state->subpass = subpass;
 
    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_RENDER_TARGETS;
 
@@ -3172,6 +3174,48 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
     */
    cmd_buffer_subpass_sync_fast_clear_values(cmd_buffer);
 
+   VkRect2D render_area = cmd_buffer->state.render_area;
+   struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
+   for (uint32_t i = 0; i < subpass->color_count; ++i) {
+      const uint32_t a = subpass->color_attachments[i].attachment;
+      if (a == VK_ATTACHMENT_UNUSED)
+         continue;
+
+      assert(a < cmd_state->pass->attachment_count);
+      struct anv_attachment_state *att_state = &cmd_state->attachments[a];
+
+      if (!att_state->pending_clear_aspects)
+         continue;
+
+      assert(att_state->pending_clear_aspects == VK_IMAGE_ASPECT_COLOR_BIT);
+
+      struct anv_image_view *iview = fb->attachments[a];
+      const struct anv_image *image = iview->image;
+
+      /* Multi-planar images are not supported as attachments */
+      assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
+      assert(image->n_planes == 1);
+
+      if (att_state->fast_clear) {
+         anv_image_ccs_op(cmd_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT,
+                          iview->planes[0].isl.base_level,
+                          iview->planes[0].isl.base_array_layer,
+                          fb->layers,
+                          ISL_AUX_OP_FAST_CLEAR, false);
+      } else {
+         anv_image_clear_color(cmd_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT,
+                               att_state->aux_usage,
+                               iview->planes[0].isl.format,
+                               iview->planes[0].isl.swizzle,
+                               iview->planes[0].isl.base_level,
+                               iview->planes[0].isl.base_array_layer,
+                               fb->layers, render_area,
+                               vk_to_isl_color(att_state->clear_value.color));
+      }
+
+      att_state->pending_clear_aspects = 0;
+   }
+
    cmd_buffer_emit_depth_stencil(cmd_buffer);
 
    anv_cmd_buffer_clear_subpass(cmd_buffer);
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list