That's a good question, I was asking this myself when I did this. The
spec says:
"loadOp is a VkAttachmentLoadOp value specifying how the
  contents of color and depth components of the attachment are treated
at
  the beginning of the subpass where it is first used."
So I figured the correct thing to do that follows the spirit of this
was to wait until the first subpass that uses a particular view to
clear it. Now, I have checked the spec (with KHX_multiview included)
and it seems to have some more text in place to address this
question:bit more:
"The load and store operations apply to attachments on a per-view
basis.
For example, an attachment using VK_ATTACHMENT_LOAD_OP_CLEAR will have
each view cleared on first use, but the first use of one view may be
temporally distant from the first use of another view.(...)This
interpretation motivates the answers to questions like “when does
theload op apply” - it is on the first use of each view of an
attachment, as
if each view were a separate attachment."
I understand this is consistent with the implementation in this patch
(although I wonder if there are any scenarios where this has actual
implications...)
Iago
On Tue, 2018-01-23 at 23:57 -0800, Jason Ekstrand wrote:
> Do we really want to wait until a subpass that uses the given view or
> do we just want to clear all of the relevant slices in the first
> subpass that touches it?  I haven't really thought about this much.
> 
> On Fri, Jan 5, 2018 at 8:38 AM, Iago Toral Quiroga <[email protected]
> > 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.
> > 
> > 
> > 
> > Fixes work-in-progress CTS tests:
> > 
> > dEQP-VK.multiview.readback_implicit_clear.*
> > 
> > ---
> > 
> >  src/intel/vulkan/anv_blorp.c | 56
> > ++++++++++++++++++++++++++++++++++++++++----
> > 
> >  1 file changed, 52 insertions(+), 4 deletions(-)
> > 
> > 
> > 
> > diff --git a/src/intel/vulkan/anv_blorp.c
> > b/src/intel/vulkan/anv_blorp.c
> > 
> > index 18fa4a4ae5..0dac20ea80 100644
> > 
> > --- a/src/intel/vulkan/anv_blorp.c
> > 
> > +++ b/src/intel/vulkan/anv_blorp.c
> > 
> > @@ -1110,6 +1110,39 @@ enum subpass_stage {
> > 
> >     SUBPASS_STAGE_RESOLVE,
> > 
> >  };
> > 
> > 
> > 
> > +/**
> > 
> > + * Goes through all the previous subpasses to the current subpass
> > and collects
> > 
> > + * information about the layers (views) of the given attachment
> > that have
> > 
> > + * already been cleared by previous subpasses. The function return
> > the layers
> > 
> > + * (views), if any, that still need to be cleared when current
> > subpass starts.
> > 
> > + */
> > 
> > +static uint32_t
> > 
> > +subpass_views_with_pending_clear(const struct anv_cmd_buffer
> > *cmd_buffer,
> > 
> > +                                 const uint32_t att_idx)
> > 
> > +{
> > 
> > +   const struct anv_cmd_state *cmd_state = &cmd_buffer->state;
> > 
> > +   const struct anv_render_pass *pass = cmd_state->pass;
> > 
> > +   const struct anv_subpass *subpass = cmd_state->subpass;
> > 
> > +
> > 
> > +   if (!subpass->view_mask)
> > 
> > +      return 0;
> > 
> > +
> > 
> > +   uint32_t cleared_views = 0;
> > 
> > +   uint32_t subpass_idx = 0;
> > 
> > +   const struct anv_subpass *s = &pass->subpasses[subpass_idx];
> > 
> > +   while (s != subpass) {
> > 
> > +      for (uint32_t i = 0; i < s->color_count; i++) {
> > 
> > +         uint32_t idx = s->color_attachments[i].attachment;
> > 
> > +         if (idx != att_idx)
> > 
> > +            continue;
> > 
> > +         cleared_views |= s->view_mask;
> > 
> > +      }
> > 
> > +      s = &pass->subpasses[++subpass_idx];
> > 
> > +   }
> > 
> > +
> > 
> > +   return subpass->view_mask & (~cleared_views);
> > 
> > +}
> > 
> > +
> > 
> >  static bool
> > 
> >  subpass_needs_clear(const struct anv_cmd_buffer *cmd_buffer)
> > 
> >  {
> > 
> > @@ -1142,7 +1175,6 @@ 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;
> > 
> > 
> > 
> > @@ -1205,7 +1237,9 @@ anv_cmd_buffer_clear_subpass(struct
> > anv_cmd_buffer *cmd_buffer)
> > 
> >           assert(image->n_planes == 1);
> > 
> >           if (cmd_state->subpass->view_mask) {
> > 
> >              uint32_t view_idx;
> > 
> > -            for_each_bit(view_idx, cmd_state->subpass->view_mask)
> > {
> > 
> > +            uint32_t pending_clear_mask =
> > 
> > +               subpass_views_with_pending_clear(cmd_buffer, a);
> > 
> > +            for_each_bit(view_idx, pending_clear_mask) {
> > 
> >                 blorp_fast_clear(&batch, &surf, iview-
> > >planes[0].isl.format,
> > 
> >                                  iview->planes[0].isl.base_level,
> > 
> >                                  view_idx, 1,
> > 
> > @@ -1227,7 +1261,9 @@ anv_cmd_buffer_clear_subpass(struct
> > anv_cmd_buffer *cmd_buffer)
> > 
> >           assert(image->n_planes == 1);
> > 
> >           if (cmd_state->subpass->view_mask) {
> > 
> >              uint32_t view_idx;
> > 
> > -            for_each_bit(view_idx, cmd_state->subpass->view_mask)
> > {
> > 
> > +            uint32_t pending_clear_mask =
> > 
> > +               subpass_views_with_pending_clear(cmd_buffer, a);
> > 
> > +            for_each_bit(view_idx, pending_clear_mask) {
> > 
> >                 blorp_clear(&batch, &surf, iview-
> > >planes[0].isl.format,
> > 
> >                             anv_swizzle_for_render(iview-
> > >planes[0].isl.swizzle),
> > 
> >                             iview->planes[0].isl.base_level,
> > 
> > @@ -1249,7 +1285,19 @@ anv_cmd_buffer_clear_subpass(struct
> > anv_cmd_buffer *cmd_buffer)
> > 
> >           }
> > 
> >        }
> > 
> > 
> > 
> > -      att_state->pending_clear_aspects = 0;
> > 
> > +      if (!cmd_state->subpass->view_mask) {
> > 
> > +         att_state->pending_clear_aspects = 0;
> > 
> > +      } else {
> > 
> > +         /* If multiview is enabled, then we are only done
> > clearing when the
> > 
> > +          * last subpass that uses this attachment has been
> > processed,
> > 
> > +          */
> > 
> > +         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;
> > 
> > +      }
> > 
> >     }
> > 
> > 
> > 
> >     const uint32_t ds = cmd_state->subpass-
> > >depth_stencil_attachment.attachment;
> > 
> > 
> > --
> > 
> > 2.11.0
> > 
> > 
> > 
_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to