[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