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

Pohjolainen, Topi topi.pohjolainen at gmail.com
Fri Dec 8 14:16:04 UTC 2017


On Mon, Nov 27, 2017 at 07:06:07PM -0800, Jason Ekstrand wrote:
> 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);

I didn't spot anything amiss elsewhere. Here I'm a little puzzled though. It
looks there is functional change as now the fast clear targets the entire
level. Before in anv_cmd_buffer_clear_subpass() the render area was passed to
blorp_fast_clear():

 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);

Clearing the entire level makes sense to me and I'm more wondering that did we
really do partial fast clears before? Or was the render_area in practise
covering the entire level.

> +      } 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
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list