[Mesa-dev] [PATCH v4 1/2] anv/cmd_buffer: consider multiview masks for tracking pending clear aspects
Iago Toral
itoral at igalia.com
Tue Mar 13 12:49:24 UTC 2018
Hi Jason, can you have a look at these two? We have some tests failing
because of this.
Iago
On Wed, 2018-03-07 at 10:33 +0100, Iago Toral wrote:
> 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_zer
> > o_
> > one;
> > bool clear_color_is_zer
> > o;
> > +
> > + /* 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_view
> > s;
> > };
> >
> > /** 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