[Mesa-dev] [PATCH v3 10/18] anv/cmd_buffer: Move the rest of clear_subpass into begin_subpass
Nanley Chery
nanleychery at gmail.com
Wed Feb 14 22:51:17 UTC 2018
On Wed, Feb 14, 2018 at 12:16:25PM -0800, Jason Ekstrand wrote:
> ---
> src/intel/vulkan/anv_blorp.c | 242 ++++++++++++++++---------------------
> src/intel/vulkan/anv_private.h | 17 ++-
> src/intel/vulkan/genX_cmd_buffer.c | 68 ++++++++++-
> 3 files changed, 186 insertions(+), 141 deletions(-)
>
> diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c
> index fd32227..6c0c858 100644
> --- a/src/intel/vulkan/anv_blorp.c
> +++ b/src/intel/vulkan/anv_blorp.c
> @@ -1136,143 +1136,6 @@ enum subpass_stage {
> SUBPASS_STAGE_RESOLVE,
> };
>
> -static bool
> -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;
> -
> - if (ds != VK_ATTACHMENT_UNUSED) {
> - assert(ds < cmd_state->pass->attachment_count);
> - if (cmd_state->attachments[ds].pending_clear_aspects)
> - return true;
> - }
> -
> - return false;
> -}
> -
> -void
> -anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
> -{
> - const struct anv_cmd_state *cmd_state = &cmd_buffer->state;
> - const VkRect2D render_area = cmd_buffer->state.render_area;
> -
> -
> - if (!subpass_needs_clear(cmd_buffer))
> - return;
> -
> - /* Because this gets called within a render pass, we tell blorp not to
> - * trash our depth and stencil buffers.
> - */
> - struct blorp_batch batch;
> - blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer,
> - BLORP_BATCH_NO_EMIT_DEPTH_STENCIL);
> -
> - VkClearRect clear_rect = {
> - .rect = cmd_buffer->state.render_area,
> - .baseArrayLayer = 0,
> - .layerCount = cmd_buffer->state.framebuffer->layers,
> - };
> -
> - struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
> -
> - const uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment;
> - assert(ds == VK_ATTACHMENT_UNUSED || ds < cmd_state->pass->attachment_count);
> -
> - if (ds != VK_ATTACHMENT_UNUSED &&
> - cmd_state->attachments[ds].pending_clear_aspects) {
> -
> - VkClearAttachment clear_att = {
> - .aspectMask = cmd_state->attachments[ds].pending_clear_aspects,
> - .clearValue = cmd_state->attachments[ds].clear_value,
> - };
> -
> -
> - const uint8_t gen = cmd_buffer->device->info.gen;
> - bool clear_with_hiz = gen >= 8 && cmd_state->attachments[ds].aux_usage ==
> - ISL_AUX_USAGE_HIZ;
> - const struct anv_image_view *iview = fb->attachments[ds];
> -
> - if (clear_with_hiz) {
> - const bool clear_depth = clear_att.aspectMask &
> - VK_IMAGE_ASPECT_DEPTH_BIT;
> - const bool clear_stencil = clear_att.aspectMask &
> - VK_IMAGE_ASPECT_STENCIL_BIT;
> -
> - /* Check against restrictions for depth buffer clearing. A great GPU
> - * performance benefit isn't expected when using the HZ sequence for
> - * stencil-only clears. Therefore, we don't emit a HZ op sequence for
> - * a stencil clear in addition to using the BLORP-fallback for depth.
> - */
> - if (clear_depth) {
> - if (!blorp_can_hiz_clear_depth(gen, iview->planes[0].isl.format,
> - iview->image->samples,
> - render_area.offset.x,
> - render_area.offset.y,
> - render_area.offset.x +
> - render_area.extent.width,
> - render_area.offset.y +
> - render_area.extent.height)) {
> - clear_with_hiz = false;
> - } else if (clear_att.clearValue.depthStencil.depth !=
> - ANV_HZ_FC_VAL) {
> - /* Don't enable fast depth clears for any color not equal to
> - * ANV_HZ_FC_VAL.
> - */
> - clear_with_hiz = false;
> - } else if (gen == 8 &&
> - anv_can_sample_with_hiz(&cmd_buffer->device->info,
> - iview->image)) {
> - /* Only gen9+ supports returning ANV_HZ_FC_VAL when sampling a
> - * fast-cleared portion of a HiZ buffer. Testing has revealed
> - * that Gen8 only supports returning 0.0f. Gens prior to gen8 do
> - * not support this feature at all.
> - */
> - clear_with_hiz = false;
> - }
> - }
> -
> - if (clear_with_hiz) {
> - blorp_gen8_hiz_clear_attachments(&batch, iview->image->samples,
> - render_area.offset.x,
> - render_area.offset.y,
> - render_area.offset.x +
> - render_area.extent.width,
> - render_area.offset.y +
> - render_area.extent.height,
> - clear_depth, clear_stencil,
> - clear_att.clearValue.
> - depthStencil.stencil);
> -
> - /* From the SKL PRM, Depth Buffer Clear:
> - *
> - * Depth Buffer Clear Workaround
> - * Depth buffer clear pass using any of the methods (WM_STATE,
> - * 3DSTATE_WM or 3DSTATE_WM_HZ_OP) must be followed by a
> - * PIPE_CONTROL command with DEPTH_STALL bit and Depth FLUSH bits
> - * “set” before starting to render. DepthStall and DepthFlush are
> - * not needed between consecutive depth clear passes nor is it
> - * required if the depth-clear pass was done with “full_surf_clear”
> - * bit set in the 3DSTATE_WM_HZ_OP.
> - */
> - if (clear_depth) {
> - cmd_buffer->state.pending_pipe_bits |=
> - ANV_PIPE_DEPTH_CACHE_FLUSH_BIT | ANV_PIPE_DEPTH_STALL_BIT;
> - }
> - }
> - }
> -
> - if (!clear_with_hiz) {
> - clear_depth_stencil_attachment(cmd_buffer, &batch,
> - &clear_att, 1, &clear_rect);
> - }
> -
> - cmd_state->attachments[ds].pending_clear_aspects = 0;
> - }
> -
> - blorp_batch_finish(&batch);
> -}
> -
> static void
> resolve_surface(struct blorp_batch *batch,
> struct blorp_surf *src_surf,
> @@ -1561,13 +1424,57 @@ anv_image_clear_color(struct anv_cmd_buffer *cmd_buffer,
> }
>
> void
> +anv_image_clear_depth_stencil(struct anv_cmd_buffer *cmd_buffer,
> + const struct anv_image *image,
> + VkImageAspectFlags aspects,
> + enum isl_aux_usage depth_aux_usage,
> + uint32_t level,
> + uint32_t base_layer, uint32_t layer_count,
> + VkRect2D area,
> + float depth_value, uint8_t stencil_value)
> +{
> + assert(image->aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
> + VK_IMAGE_ASPECT_STENCIL_BIT));
> +
> + struct blorp_batch batch;
> + blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
> +
> + struct blorp_surf depth = {};
> + if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
> + get_blorp_surf_for_anv_image(cmd_buffer->device,
> + image, VK_IMAGE_ASPECT_DEPTH_BIT,
> + depth_aux_usage, &depth);
> + depth.clear_color.f32[0] = ANV_HZ_FC_VAL;
> + }
> +
> + struct blorp_surf stencil = {};
> + if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
> + get_blorp_surf_for_anv_image(cmd_buffer->device,
> + image, VK_IMAGE_ASPECT_STENCIL_BIT,
> + ISL_AUX_USAGE_NONE, &stencil);
> + }
> +
> + blorp_clear_depth_stencil(&batch, &depth, &stencil,
> + level, base_layer, layer_count,
> + area.offset.x, area.offset.y,
> + area.offset.x + area.extent.width,
> + area.offset.y + area.extent.height,
> + aspects & VK_IMAGE_ASPECT_DEPTH_BIT,
> + depth_value,
> + (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) ? 0xff : 0,
> + stencil_value);
> +
> + 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,
> uint32_t base_layer, uint32_t layer_count,
> enum isl_aux_op hiz_op)
> {
> - assert(aspect == VK_IMAGE_ASPECT_DEPTH_BIT);
> + assert(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT);
> assert(base_layer + layer_count <= anv_image_aux_layers(image, aspect, level));
> assert(anv_image_aspect_to_plane(image->aspects,
> VK_IMAGE_ASPECT_DEPTH_BIT) == 0);
> @@ -1587,6 +1494,65 @@ anv_image_hiz_op(struct anv_cmd_buffer *cmd_buffer,
> }
>
> void
> +anv_image_hiz_clear(struct anv_cmd_buffer *cmd_buffer,
> + const struct anv_image *image,
> + VkImageAspectFlags aspects,
> + uint32_t level,
> + uint32_t base_layer, uint32_t layer_count,
> + VkRect2D area, uint8_t stencil_value)
> +{
> + assert(image->aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
> + VK_IMAGE_ASPECT_STENCIL_BIT));
> +
> + struct blorp_batch batch;
> + blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
> +
> + struct blorp_surf depth = {};
> + if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
> + assert(base_layer + layer_count <=
> + anv_image_aux_layers(image, VK_IMAGE_ASPECT_DEPTH_BIT, 0));
The last parameter of anv_image_aux_layers should be level.
With that fixed, this patch is
Reviewed-by: Nanley Chery <nanley.g.chery at intel.com>
> + get_blorp_surf_for_anv_image(cmd_buffer->device,
> + image, VK_IMAGE_ASPECT_DEPTH_BIT,
> + ISL_AUX_USAGE_HIZ, &depth);
> + depth.clear_color.f32[0] = ANV_HZ_FC_VAL;
> + }
> +
> + struct blorp_surf stencil = {};
> + if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
> + get_blorp_surf_for_anv_image(cmd_buffer->device,
> + image, VK_IMAGE_ASPECT_STENCIL_BIT,
> + ISL_AUX_USAGE_NONE, &stencil);
> + }
> +
> + blorp_hiz_clear_depth_stencil(&batch, &depth, &stencil,
> + level, base_layer, layer_count,
> + area.offset.x, area.offset.y,
> + area.offset.x + area.extent.width,
> + area.offset.y + area.extent.height,
> + aspects & VK_IMAGE_ASPECT_DEPTH_BIT,
> + ANV_HZ_FC_VAL,
> + aspects & VK_IMAGE_ASPECT_STENCIL_BIT,
> + stencil_value);
> +
> + blorp_batch_finish(&batch);
> +
> + /* From the SKL PRM, Depth Buffer Clear:
> + *
> + * Depth Buffer Clear Workaround
> + * Depth buffer clear pass using any of the methods (WM_STATE, 3DSTATE_WM
> + * or 3DSTATE_WM_HZ_OP) must be followed by a PIPE_CONTROL command with
> + * DEPTH_STALL bit and Depth FLUSH bits “set” before starting to render.
> + * DepthStall and DepthFlush are not needed between consecutive depth clear
> + * passes nor is it required if the depth-clear pass was done with
> + * “full_surf_clear” bit set in the 3DSTATE_WM_HZ_OP.
> + */
> + if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
> + cmd_buffer->state.pending_pipe_bits |=
> + ANV_PIPE_DEPTH_CACHE_FLUSH_BIT | ANV_PIPE_DEPTH_STALL_BIT;
> + }
> +}
> +
> +void
> anv_image_mcs_op(struct anv_cmd_buffer *cmd_buffer,
> const struct anv_image *image,
> VkImageAspectFlagBits aspect,
> diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
> index 73004a3..906c6f3 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -1923,7 +1923,6 @@ anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
> struct anv_state
> anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer);
>
> -void anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer);
> void anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer *cmd_buffer);
>
> const struct anv_image_view *
> @@ -2617,12 +2616,28 @@ anv_image_clear_color(struct anv_cmd_buffer *cmd_buffer,
> uint32_t level, uint32_t base_layer, uint32_t layer_count,
> VkRect2D area, union isl_color_value clear_color);
> void
> +anv_image_clear_depth_stencil(struct anv_cmd_buffer *cmd_buffer,
> + const struct anv_image *image,
> + VkImageAspectFlags aspects,
> + enum isl_aux_usage depth_aux_usage,
> + uint32_t level,
> + uint32_t base_layer, uint32_t layer_count,
> + VkRect2D area,
> + float depth_value, uint8_t stencil_value);
> +void
> anv_image_hiz_op(struct anv_cmd_buffer *cmd_buffer,
> const struct anv_image *image,
> VkImageAspectFlagBits aspect, uint32_t level,
> uint32_t base_layer, uint32_t layer_count,
> enum isl_aux_op hiz_op);
> void
> +anv_image_hiz_clear(struct anv_cmd_buffer *cmd_buffer,
> + const struct anv_image *image,
> + VkImageAspectFlags aspects,
> + uint32_t level,
> + uint32_t base_layer, uint32_t layer_count,
> + VkRect2D area, uint8_t stencil_value);
> +void
> anv_image_mcs_op(struct anv_cmd_buffer *cmd_buffer,
> const struct anv_image *image,
> VkImageAspectFlagBits aspect,
> diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c
> index badb423..93894c1 100644
> --- a/src/intel/vulkan/genX_cmd_buffer.c
> +++ b/src/intel/vulkan/genX_cmd_buffer.c
> @@ -3527,9 +3527,73 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
> att_state->pending_clear_aspects = 0;
> }
>
> - cmd_buffer_emit_depth_stencil(cmd_buffer);
> + if (subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) {
> + const uint32_t a = subpass->depth_stencil_attachment.attachment;
> +
> + assert(a < cmd_state->pass->attachment_count);
> + struct anv_attachment_state *att_state = &cmd_state->attachments[a];
> + struct anv_image_view *iview = fb->attachments[a];
> + const struct anv_image *image = iview->image;
> +
> + assert(image->aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
> + VK_IMAGE_ASPECT_STENCIL_BIT));
> +
> + if (att_state->pending_clear_aspects) {
> + bool clear_with_hiz = att_state->aux_usage == ISL_AUX_USAGE_HIZ;
> + if (clear_with_hiz &&
> + (att_state->pending_clear_aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) {
> + if (!blorp_can_hiz_clear_depth(GEN_GEN,
> + iview->planes[0].isl.format,
> + iview->image->samples,
> + render_area.offset.x,
> + render_area.offset.y,
> + render_area.offset.x +
> + render_area.extent.width,
> + render_area.offset.y +
> + render_area.extent.height)) {
> + clear_with_hiz = false;
> + } else if (att_state->clear_value.depthStencil.depth != ANV_HZ_FC_VAL) {
> + clear_with_hiz = false;
> + } else if (GEN_GEN == 8 &&
> + anv_can_sample_with_hiz(&cmd_buffer->device->info,
> + iview->image)) {
> + /* Only gen9+ supports returning ANV_HZ_FC_VAL when sampling a
> + * fast-cleared portion of a HiZ buffer. Testing has revealed
> + * that Gen8 only supports returning 0.0f. Gens prior to gen8
> + * do not support this feature at all.
> + */
> + clear_with_hiz = false;
> + }
> + }
> +
> + if (clear_with_hiz) {
> + /* We currently only support HiZ for single-slice images */
> + assert(iview->planes[0].isl.base_level == 0);
> + assert(iview->planes[0].isl.base_array_layer == 0);
> + assert(fb->layers == 1);
> +
> + anv_image_hiz_clear(cmd_buffer, image,
> + att_state->pending_clear_aspects,
> + iview->planes[0].isl.base_level,
> + iview->planes[0].isl.base_array_layer,
> + fb->layers, render_area,
> + att_state->clear_value.depthStencil.stencil);
> + } else {
> + anv_image_clear_depth_stencil(cmd_buffer, image,
> + att_state->pending_clear_aspects,
> + att_state->aux_usage,
> + iview->planes[0].isl.base_level,
> + iview->planes[0].isl.base_array_layer,
> + fb->layers, render_area,
> + att_state->clear_value.depthStencil.depth,
> + att_state->clear_value.depthStencil.stencil);
> + }
> + }
>
> - anv_cmd_buffer_clear_subpass(cmd_buffer);
> + att_state->pending_clear_aspects = 0;
> + }
> +
> + cmd_buffer_emit_depth_stencil(cmd_buffer);
> }
>
> static void
> --
> 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