Mesa (main): v3dv: use correct number of layers for multiview

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jul 27 07:45:58 UTC 2021


Module: Mesa
Branch: main
Commit: 32cb8809aa32f34245100f9661e19e5933adfb19
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=32cb8809aa32f34245100f9661e19e5933adfb19

Author: Iago Toral Quiroga <itoral at igalia.com>
Date:   Thu Jul 22 13:50:16 2021 +0200

v3dv: use correct number of layers for multiview

The Vulkan spec states that when multiview is enabled the number of
layers in the framebuffer is set to one and that each attachment
must then have at least as many layers as referenced by view masks
in the subpasses in which is used.

Reviewed-by: Alejandro Piñeiro <apinheiro at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12034>

---

 src/broadcom/vulkan/v3dv_cmd_buffer.c  | 18 +++++++++++++++++-
 src/broadcom/vulkan/v3dv_uniforms.c    | 15 ++++++++++++++-
 src/broadcom/vulkan/v3dvx_cmd_buffer.c |  9 ++++++---
 3 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c
index 36cf6eb54bd..194ddc07b99 100644
--- a/src/broadcom/vulkan/v3dv_cmd_buffer.c
+++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c
@@ -1504,10 +1504,26 @@ cmd_buffer_subpass_create_job(struct v3dv_cmd_buffer *cmd_buffer,
       v3dv_X(job->device, framebuffer_compute_internal_bpp_msaa)
          (framebuffer, subpass, &internal_bpp, &msaa);
 
+      /* From the Vulkan 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 when multiview is enabled, we take the number of layers from the
+       * last bit set in the view mask.
+       */
+      uint32_t layers = framebuffer->layers;
+      if (subpass->view_mask != 0) {
+         assert(framebuffer->layers == 1);
+         layers = util_last_bit(subpass->view_mask);
+      }
+
       v3dv_job_start_frame(job,
                            framebuffer->width,
                            framebuffer->height,
-                           framebuffer->layers,
+                           layers,
                            true,
                            subpass->color_count,
                            internal_bpp,
diff --git a/src/broadcom/vulkan/v3dv_uniforms.c b/src/broadcom/vulkan/v3dv_uniforms.c
index dd915100c74..bf25e64d4b3 100644
--- a/src/broadcom/vulkan/v3dv_uniforms.c
+++ b/src/broadcom/vulkan/v3dv_uniforms.c
@@ -506,10 +506,23 @@ v3dv_write_uniforms_wg_offsets(struct v3dv_cmd_buffer *cmd_buffer,
        * is only for sanityzing the shader and it only affects the specific case
        * of secondary command buffers without framebuffer info available it
        * might not be worth the trouble.
+       *
+       * With multiview the number of layers is dictated by the view mask
+       * and not by the framebuffer layers. We do set the job's frame tiling
+       * information correctly from the view mask in that case, however,
+       * secondary command buffers may not have valid frame tiling data,
+       * so when multiview is enabled, we always set the number of layers
+       * from the subpass view mask.
        */
       case QUNIFORM_FB_LAYERS: {
+         const struct v3dv_cmd_buffer_state *state = &job->cmd_buffer->state;
+         const uint32_t view_mask =
+            state->pass->subpasses[state->subpass_idx].view_mask;
+
          uint32_t num_layers;
-         if (job->frame_tiling.layers != 0) {
+         if (view_mask != 0) {
+            num_layers = util_last_bit(view_mask);
+         } else if (job->frame_tiling.layers != 0) {
             num_layers = job->frame_tiling.layers;
          } else if (cmd_buffer->state.framebuffer) {
             num_layers = cmd_buffer->state.framebuffer->layers;
diff --git a/src/broadcom/vulkan/v3dvx_cmd_buffer.c b/src/broadcom/vulkan/v3dvx_cmd_buffer.c
index 0f17700fe07..8f8cf73a1ff 100644
--- a/src/broadcom/vulkan/v3dvx_cmd_buffer.c
+++ b/src/broadcom/vulkan/v3dvx_cmd_buffer.c
@@ -764,7 +764,8 @@ v3dX(cmd_buffer_emit_render_pass_rcl)(struct v3dv_cmd_buffer *cmd_buffer)
 
    const struct v3dv_frame_tiling *tiling = &job->frame_tiling;
 
-   const uint32_t fb_layers = framebuffer->layers;
+   const uint32_t fb_layers = job->frame_tiling.layers;
+
    v3dv_cl_ensure_space_with_branch(&job->rcl, 200 +
                                     MAX2(fb_layers, 1) * 256 *
                                     cl_packet_length(SUPERTILE_COORDINATES));
@@ -948,8 +949,10 @@ v3dX(cmd_buffer_emit_render_pass_rcl)(struct v3dv_cmd_buffer *cmd_buffer)
          TILE_ALLOCATION_BLOCK_SIZE_64B;
    }
 
-   for (int layer = 0; layer < MAX2(1, fb_layers); layer++)
-      cmd_buffer_emit_render_pass_layer_rcl(cmd_buffer, layer);
+   /* FIXME: skip layers not in the view mask */
+   for (int layer = 0; layer < MAX2(1, fb_layers); layer++) {
+         cmd_buffer_emit_render_pass_layer_rcl(cmd_buffer, layer);
+   }
 
    cl_emit(rcl, END_OF_RENDERING, end);
 }



More information about the mesa-commit mailing list