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