[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