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,
* 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;
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));
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);
}