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 > > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev