[Mesa-dev] [PATCH v4 1/2] anv/cmd_buffer: consider multiview masks for tracking pending clear aspects
Iago Toral
itoral at igalia.com
Wed Mar 7 09:33:33 UTC 2018
This patches are still waiting for review.
On Wed, 2018-02-28 at 09:57 +0100, Iago Toral Quiroga wrote:
> When multiview is active a subpass clear may only clear a subset of
> the
> attachment layers. Other subpasses in the same render pass may also
> clear too and we want to honor those clears as well, however, we need
> to
> ensure that we only clear a layer once, on the first subpass that
> uses
> a particular layer (view) of a given attachment.
>
> This means that when we check if a subpass attachment needs to be
> cleared
> we need to check if all the layers used by that subpass (as indicated
> by
> its view_mask) have already been cleared in previous subpasses or
> not, in
> which case, we must clear any pending layers used by the subpass, and
> only
> those pending.
>
> v2:
> - track pending clear views in the attachment state (Jason)
> - rebased on top of fast-clear rework.
>
> v3:
> - rebased on top of subpass rework.
>
> v4: rebased.
>
> Fixes:
> dEQP-VK.multiview.readback_implicit_clear.*
> ---
> src/intel/vulkan/anv_private.h | 8 ++++
> src/intel/vulkan/genX_cmd_buffer.c | 87
> ++++++++++++++++++++++++++++++++++++--
> 2 files changed, 92 insertions(+), 3 deletions(-)
>
> diff --git a/src/intel/vulkan/anv_private.h
> b/src/intel/vulkan/anv_private.h
> index fb4fd19178..352f0483f0 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -1696,6 +1696,14 @@ struct anv_attachment_state {
> VkClearValue clear_value;
> bool clear_color_is_zero_
> one;
> bool clear_color_is_zero;
> +
> + /* When multiview is active, attachments with a renderpass clear
> + * operation have their respective layers cleared on the first
> + * subpass that uses them, and only in that subpass. We keep
> track
> + * of this using a bitfield to indicate which layers of an
> attachment
> + * have not been cleared yet when multiview is active.
> + */
> + uint32_t pending_clear_views;
> };
>
> /** State tracking for particular pipeline bind point
> diff --git a/src/intel/vulkan/genX_cmd_buffer.c
> b/src/intel/vulkan/genX_cmd_buffer.c
> index ce546249b3..c422ec8e1a 100644
> --- a/src/intel/vulkan/genX_cmd_buffer.c
> +++ b/src/intel/vulkan/genX_cmd_buffer.c
> @@ -1167,6 +1167,8 @@ genX(cmd_buffer_setup_attachments)(struct
> anv_cmd_buffer *cmd_buffer,
> if (clear_aspects)
> state->attachments[i].clear_value = begin-
> >pClearValues[i];
>
> + state->attachments[i].pending_clear_views = ~0;
> +
> struct anv_image_view *iview = framebuffer->attachments[i];
> anv_assert(iview->vk_format == att->format);
> anv_assert(iview->n_planes == 1);
> @@ -3288,6 +3290,31 @@ cmd_buffer_emit_depth_stencil(struct
> anv_cmd_buffer *cmd_buffer)
> cmd_buffer->state.hiz_enabled = info.hiz_usage ==
> ISL_AUX_USAGE_HIZ;
> }
>
> +/**
> + * This ANDs the view mask of the current subpass with the pending
> clear
> + * views in the attachment to get the mask of views active in the
> subpass
> + * that still need to be cleared.
> + */
> +static inline uint32_t
> +get_multiview_subpass_clear_mask(const struct anv_cmd_state
> *cmd_state,
> + const struct anv_attachment_state
> *att_state)
> +{
> + return cmd_state->subpass->view_mask & att_state-
> >pending_clear_views;
> +}
> +
> +static inline bool
> +do_first_layer_clear(const struct anv_cmd_state *cmd_state,
> + const struct anv_attachment_state *att_state)
> +{
> + if (!cmd_state->subpass->view_mask)
> + return true;
> +
> + uint32_t pending_clear_mask =
> + get_multiview_subpass_clear_mask(cmd_state, att_state);
> +
> + return pending_clear_mask & 1;
> +}
> +
> static void
> cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
> uint32_t subpass_id)
> @@ -3326,6 +3353,8 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer
> *cmd_buffer,
> VkRect2D render_area = cmd_buffer->state.render_area;
> struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
>
> + bool is_multiview = subpass->view_mask != 0;
> +
> for (uint32_t i = 0; i < subpass->attachment_count; ++i) {
> const uint32_t a = subpass->attachments[i].attachment;
> if (a == VK_ATTACHMENT_UNUSED)
> @@ -3393,7 +3422,8 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer
> *cmd_buffer,
> uint32_t base_clear_layer = iview-
> >planes[0].isl.base_array_layer;
> uint32_t clear_layer_count = fb->layers;
>
> - if (att_state->fast_clear) {
> + if (att_state->fast_clear &&
> + do_first_layer_clear(cmd_state, att_state)) {
> /* We only support fast-clears on the first layer */
> assert(iview->planes[0].isl.base_level == 0);
> assert(iview->planes[0].isl.base_array_layer == 0);
> @@ -3402,6 +3432,8 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer
> *cmd_buffer,
> 0, 0, 1, ISL_AUX_OP_FAST_CLEAR, false);
> base_clear_layer++;
> clear_layer_count--;
> + if (is_multiview)
> + att_state->pending_clear_views &= ~1;
>
> genX(copy_fast_clear_dwords)(cmd_buffer, att_state-
> >color.state,
> image,
> VK_IMAGE_ASPECT_COLOR_BIT,
> @@ -3423,7 +3455,39 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer
> *cmd_buffer,
> }
> }
>
> - if (clear_layer_count > 0) {
> + /* From the VkFramebufferCreateInfo spec:
> + *
> + * "If the render pass uses multiview, then layers must be
> one and each
> + * attachment requires a number of layers that is greater
> than the
> + * maximum bit index set in the view mask in the subpasses
> in which it
> + * is used."
> + *
> + * So if multiview is active we ignore the number of layers
> in the
> + * framebuffer and instead we honor the view mask from the
> subpass.
> + */
> + if (is_multiview) {
> + assert(image->n_planes == 1);
> + uint32_t pending_clear_mask =
> + get_multiview_subpass_clear_mask(cmd_state,
> att_state);
> +
> + uint32_t layer_idx;
> + for_each_bit(layer_idx, pending_clear_mask) {
> + uint32_t layer =
> + iview->planes[0].isl.base_array_layer + layer_idx;
> +
> + 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,
> + layer, 1,
> + render_area,
> + vk_to_isl_color(att_state-
> >clear_value.color));
> +
> + att_state->pending_clear_views &= ~(1 << layer_idx);
> + }
> + } else if (clear_layer_count > 0) {
> assert(image->n_planes == 1);
> anv_image_clear_color(cmd_buffer, image,
> VK_IMAGE_ASPECT_COLOR_BIT,
> att_state->aux_usage,
> @@ -3525,7 +3589,24 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer
> *cmd_buffer,
> }
> }
>
> - att_state->pending_clear_aspects = 0;
> + /* If multiview is enabled, then we are only done clearing
> when we no
> + * longer have pending layers to clear, or when we have
> processed the
> + * last subpass that uses this attachment.
> + */
> + if (!is_multiview) {
> + att_state->pending_clear_aspects = 0;
> + } else if (att_state->pending_clear_views == 0) {
> + att_state->pending_clear_aspects = 0;
> + } else {
> + uint32_t last_subpass_idx =
> + cmd_state->pass->attachments[a].last_subpass_idx;
> + const struct anv_subpass *last_subpass =
> + &cmd_state->pass->subpasses[last_subpass_idx];
> + if (last_subpass == cmd_state->subpass) {
> + att_state->pending_clear_aspects = 0;
> + }
> + }
> +
> att_state->pending_load_aspects = 0;
> }
>
> --
> 2.14.1
>
>
More information about the mesa-dev
mailing list