Module: Mesa Branch: main Commit: 5fd55ab16d770b9f59a63d125834a6e82e69bf51 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=5fd55ab16d770b9f59a63d125834a6e82e69bf51
Author: Iago Toral Quiroga <[email protected]> Date: Fri Jul 23 09:41:14 2021 +0200 v3dv: broadcast multiview draw commands We implement multiview by replicating draw commands for all enabled views and setting a command buffer state for the currently active view we are broadcasting to. Reviewed-by: Alejandro PiƱeiro <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12034> --- src/broadcom/vulkan/v3dv_cmd_buffer.c | 90 +++++++++++++++++++++++++++++----- src/broadcom/vulkan/v3dv_private.h | 4 ++ src/broadcom/vulkan/v3dv_uniforms.c | 4 ++ src/broadcom/vulkan/v3dvx_cmd_buffer.c | 6 --- 4 files changed, 87 insertions(+), 17 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index 557b703ae04..68bc7161f4f 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -2096,6 +2096,7 @@ update_gfx_uniform_state(struct v3dv_cmd_buffer *cmd_buffer, const bool has_new_viewport = dirty_uniform_state & V3DV_CMD_DIRTY_VIEWPORT; const bool has_new_push_constants = dirty_uniform_state & V3DV_CMD_DIRTY_PUSH_CONSTANTS; const bool has_new_descriptors = dirty_uniform_state & V3DV_CMD_DIRTY_DESCRIPTOR_SETS; + const bool has_new_view_index = dirty_uniform_state & V3DV_CMD_DIRTY_VIEW_INDEX; /* VK_SHADER_STAGE_FRAGMENT_BIT */ const bool has_new_descriptors_fs = @@ -2107,8 +2108,10 @@ update_gfx_uniform_state(struct v3dv_cmd_buffer *cmd_buffer, (cmd_buffer->state.dirty_push_constants_stages & VK_SHADER_STAGE_FRAGMENT_BIT); const bool needs_fs_update = has_new_pipeline || + has_new_view_index || has_new_push_constants_fs || - has_new_descriptors_fs; + has_new_descriptors_fs || + has_new_view_index; if (needs_fs_update) { struct v3dv_shader_variant *fs_variant = @@ -2131,6 +2134,7 @@ update_gfx_uniform_state(struct v3dv_cmd_buffer *cmd_buffer, VK_SHADER_STAGE_GEOMETRY_BIT); const bool needs_gs_update = has_new_viewport || + has_new_view_index || has_new_pipeline || has_new_push_constants_gs || has_new_descriptors_gs; @@ -2160,6 +2164,7 @@ update_gfx_uniform_state(struct v3dv_cmd_buffer *cmd_buffer, (cmd_buffer->state.dirty_push_constants_stages & VK_SHADER_STAGE_VERTEX_BIT); const bool needs_vs_update = has_new_viewport || + has_new_view_index || has_new_pipeline || has_new_push_constants_vs || has_new_descriptors_vs; @@ -2177,6 +2182,8 @@ update_gfx_uniform_state(struct v3dv_cmd_buffer *cmd_buffer, cmd_buffer->state.uniforms.vs_bin = v3dv_write_uniforms(cmd_buffer, pipeline, vs_bin_variant); } + + cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_VIEW_INDEX; } /* This stores command buffer state that we might be about to stomp for @@ -2462,7 +2469,8 @@ v3dv_cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer) *dirty & (V3DV_CMD_DIRTY_PIPELINE | V3DV_CMD_DIRTY_PUSH_CONSTANTS | V3DV_CMD_DIRTY_DESCRIPTOR_SETS | - V3DV_CMD_DIRTY_VIEWPORT); + V3DV_CMD_DIRTY_VIEWPORT | + V3DV_CMD_DIRTY_VIEW_INDEX); if (dirty_uniform_state) update_gfx_uniform_state(cmd_buffer, dirty_uniform_state); @@ -2513,12 +2521,32 @@ v3dv_cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer) cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_PIPELINE; } +static inline void +cmd_buffer_set_view_index(struct v3dv_cmd_buffer *cmd_buffer, + uint32_t view_index) +{ + cmd_buffer->state.view_index = view_index; + cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_VIEW_INDEX; +} + static void cmd_buffer_draw(struct v3dv_cmd_buffer *cmd_buffer, struct v3dv_draw_info *info) { - v3dv_cmd_buffer_emit_pre_draw(cmd_buffer); - v3dv_X(cmd_buffer->device, cmd_buffer_emit_draw)(cmd_buffer, info); + + struct v3dv_render_pass *pass = cmd_buffer->state.pass; + if (likely(!pass->multiview_enabled)) { + v3dv_cmd_buffer_emit_pre_draw(cmd_buffer); + v3dv_X(cmd_buffer->device, cmd_buffer_emit_draw)(cmd_buffer, info); + return; + } + + uint32_t view_mask = pass->subpasses[cmd_buffer->state.subpass_idx].view_mask; + while (view_mask) { + cmd_buffer_set_view_index(cmd_buffer, u_bit_scan(&view_mask)); + v3dv_cmd_buffer_emit_pre_draw(cmd_buffer); + v3dv_X(cmd_buffer->device, cmd_buffer_emit_draw)(cmd_buffer, info); + } } VKAPI_ATTR void VKAPI_CALL @@ -2554,9 +2582,23 @@ v3dv_CmdDrawIndexed(VkCommandBuffer commandBuffer, V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer); - v3dv_X(cmd_buffer->device, cmd_buffer_emit_draw_indexed) - (cmd_buffer, indexCount, instanceCount, - firstIndex, vertexOffset, firstInstance); + struct v3dv_render_pass *pass = cmd_buffer->state.pass; + if (likely(!pass->multiview_enabled)) { + v3dv_cmd_buffer_emit_pre_draw(cmd_buffer); + v3dv_X(cmd_buffer->device, cmd_buffer_emit_draw_indexed) + (cmd_buffer, indexCount, instanceCount, + firstIndex, vertexOffset, firstInstance); + return; + } + + uint32_t view_mask = pass->subpasses[cmd_buffer->state.subpass_idx].view_mask; + while (view_mask) { + cmd_buffer_set_view_index(cmd_buffer, u_bit_scan(&view_mask)); + v3dv_cmd_buffer_emit_pre_draw(cmd_buffer); + v3dv_X(cmd_buffer->device, cmd_buffer_emit_draw_indexed) + (cmd_buffer, indexCount, instanceCount, + firstIndex, vertexOffset, firstInstance); + } } VKAPI_ATTR void VKAPI_CALL @@ -2573,8 +2615,21 @@ v3dv_CmdDrawIndirect(VkCommandBuffer commandBuffer, V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer); V3DV_FROM_HANDLE(v3dv_buffer, buffer, _buffer); - v3dv_X(cmd_buffer->device, cmd_buffer_emit_draw_indirect) - (cmd_buffer, buffer, offset, drawCount, stride); + struct v3dv_render_pass *pass = cmd_buffer->state.pass; + if (likely(!pass->multiview_enabled)) { + v3dv_cmd_buffer_emit_pre_draw(cmd_buffer); + v3dv_X(cmd_buffer->device, cmd_buffer_emit_draw_indirect) + (cmd_buffer, buffer, offset, drawCount, stride); + return; + } + + uint32_t view_mask = pass->subpasses[cmd_buffer->state.subpass_idx].view_mask; + while (view_mask) { + cmd_buffer_set_view_index(cmd_buffer, u_bit_scan(&view_mask)); + v3dv_cmd_buffer_emit_pre_draw(cmd_buffer); + v3dv_X(cmd_buffer->device, cmd_buffer_emit_draw_indirect) + (cmd_buffer, buffer, offset, drawCount, stride); + } } VKAPI_ATTR void VKAPI_CALL @@ -2591,8 +2646,21 @@ v3dv_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer); V3DV_FROM_HANDLE(v3dv_buffer, buffer, _buffer); - v3dv_X(cmd_buffer->device, cmd_buffer_emit_indexed_indirect) - (cmd_buffer, buffer, offset, drawCount, stride); + struct v3dv_render_pass *pass = cmd_buffer->state.pass; + if (likely(!pass->multiview_enabled)) { + v3dv_cmd_buffer_emit_pre_draw(cmd_buffer); + v3dv_X(cmd_buffer->device, cmd_buffer_emit_indexed_indirect) + (cmd_buffer, buffer, offset, drawCount, stride); + return; + } + + uint32_t view_mask = pass->subpasses[cmd_buffer->state.subpass_idx].view_mask; + while (view_mask) { + cmd_buffer_set_view_index(cmd_buffer, u_bit_scan(&view_mask)); + v3dv_cmd_buffer_emit_pre_draw(cmd_buffer); + v3dv_X(cmd_buffer->device, cmd_buffer_emit_indexed_indirect) + (cmd_buffer, buffer, offset, drawCount, stride); + } } VKAPI_ATTR void VKAPI_CALL diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 5d2549a6319..14f140b5b3c 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -807,6 +807,7 @@ enum v3dv_cmd_dirty_bits { V3DV_CMD_DIRTY_OCCLUSION_QUERY = 1 << 13, V3DV_CMD_DIRTY_DEPTH_BIAS = 1 << 14, V3DV_CMD_DIRTY_LINE_WIDTH = 1 << 15, + V3DV_CMD_DIRTY_VIEW_INDEX = 1 << 16, }; struct v3dv_dynamic_state { @@ -1148,6 +1149,9 @@ struct v3dv_cmd_buffer_state { struct v3dv_cl_reloc fs; } uniforms; + /* Current view index for multiview rendering */ + uint32_t view_index; + /* Used to flag OOM conditions during command buffer recording */ bool oom; diff --git a/src/broadcom/vulkan/v3dv_uniforms.c b/src/broadcom/vulkan/v3dv_uniforms.c index d97d3b263c1..dd915100c74 100644 --- a/src/broadcom/vulkan/v3dv_uniforms.c +++ b/src/broadcom/vulkan/v3dv_uniforms.c @@ -525,6 +525,10 @@ v3dv_write_uniforms_wg_offsets(struct v3dv_cmd_buffer *cmd_buffer, break; } + case QUNIFORM_VIEW_INDEX: + cl_aligned_u32(&uniforms, job->cmd_buffer->state.view_index); + break; + case QUNIFORM_NUM_WORK_GROUPS: assert(job->type == V3DV_JOB_TYPE_GPU_CSD); assert(job->csd.wg_count[data] > 0); diff --git a/src/broadcom/vulkan/v3dvx_cmd_buffer.c b/src/broadcom/vulkan/v3dvx_cmd_buffer.c index 2fd307a4507..0f17700fe07 100644 --- a/src/broadcom/vulkan/v3dvx_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dvx_cmd_buffer.c @@ -2096,8 +2096,6 @@ v3dX(cmd_buffer_emit_draw_indexed)(struct v3dv_cmd_buffer *cmd_buffer, int32_t vertexOffset, uint32_t firstInstance) { - v3dv_cmd_buffer_emit_pre_draw(cmd_buffer); - struct v3dv_job *job = cmd_buffer->state.job; assert(job); @@ -2152,8 +2150,6 @@ v3dX(cmd_buffer_emit_draw_indirect)(struct v3dv_cmd_buffer *cmd_buffer, uint32_t drawCount, uint32_t stride) { - v3dv_cmd_buffer_emit_pre_draw(cmd_buffer); - struct v3dv_job *job = cmd_buffer->state.job; assert(job); @@ -2180,8 +2176,6 @@ v3dX(cmd_buffer_emit_indexed_indirect)(struct v3dv_cmd_buffer *cmd_buffer, uint32_t drawCount, uint32_t stride) { - v3dv_cmd_buffer_emit_pre_draw(cmd_buffer); - struct v3dv_job *job = cmd_buffer->state.job; assert(job); _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
