From 03afa95d9fb6045ef9e85b4584a89a00e13391fb Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Fri, 13 Oct 2017 17:34:35 +0200 Subject: [PATCH] radv: refactor simple and indexed draws with radv_draw_info Similar to the dispatch compute logic but for draw calls. For convenience, indirect draws will be converted in a separate patch. Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen --- src/amd/vulkan/radv_cmd_buffer.c | 186 ++++++++++++++++++++----------- 1 file changed, 118 insertions(+), 68 deletions(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 1b6cea95dc7..35e7af0c15b 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -2937,58 +2937,131 @@ radv_cs_emit_draw_packet(struct radv_cmd_buffer *cmd_buffer, S_0287F0_USE_OPAQUE(0)); } -void radv_CmdDraw( - VkCommandBuffer commandBuffer, - uint32_t vertexCount, - uint32_t instanceCount, - uint32_t firstVertex, - uint32_t firstInstance) +static void +radv_cs_emit_draw_indexed_packet(struct radv_cmd_buffer *cmd_buffer, + uint64_t index_va, + uint32_t index_count) { - RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); + radeon_emit(cmd_buffer->cs, PKT3(PKT3_DRAW_INDEX_2, 4, false)); + radeon_emit(cmd_buffer->cs, cmd_buffer->state.max_index_count); + radeon_emit(cmd_buffer->cs, index_va); + radeon_emit(cmd_buffer->cs, index_va >> 32); + radeon_emit(cmd_buffer->cs, index_count); + radeon_emit(cmd_buffer->cs, V_0287F0_DI_SRC_SEL_DMA); +} + +struct radv_draw_info { + /** + * Number of vertices. + */ + uint32_t count; + + /** + * Index of the first vertex. + */ + int32_t vertex_offset; - radv_cmd_buffer_flush_state(cmd_buffer, false, (instanceCount > 1), false, vertexCount); + /** + * First instance id. + */ + uint32_t first_instance; - MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws, cmd_buffer->cs, 20 * MAX_VIEWS); + /** + * Number of instances. + */ + uint32_t instance_count; - assert(cmd_buffer->state.pipeline->graphics.vtx_base_sgpr); - radeon_set_sh_reg_seq(cmd_buffer->cs, cmd_buffer->state.pipeline->graphics.vtx_base_sgpr, - cmd_buffer->state.pipeline->graphics.vtx_emit_num); - radeon_emit(cmd_buffer->cs, firstVertex); - radeon_emit(cmd_buffer->cs, firstInstance); - if (cmd_buffer->state.pipeline->graphics.vtx_emit_num == 3) - radeon_emit(cmd_buffer->cs, 0); + /** + * First index (indexed draws only). + */ + uint32_t first_index; - radeon_emit(cmd_buffer->cs, PKT3(PKT3_NUM_INSTANCES, 0, cmd_buffer->state.predicating)); - radeon_emit(cmd_buffer->cs, instanceCount); + /** + * Whether it's an indexed draw. + */ + bool indexed; +}; - if (!cmd_buffer->state.subpass->view_mask) { - radv_cs_emit_draw_packet(cmd_buffer, vertexCount); +static void +radv_emit_draw_packets(struct radv_cmd_buffer *cmd_buffer, + const struct radv_draw_info *info) +{ + struct radv_cmd_state *state = &cmd_buffer->state; + struct radv_device *device = cmd_buffer->device; + struct radeon_winsys_cs *cs = cmd_buffer->cs; + + radv_cmd_buffer_flush_state(cmd_buffer, info->indexed, + info->instance_count > 1, false, + info->count); + + MAYBE_UNUSED unsigned cdw_max = radeon_check_space(device->ws, cs, + 26 * MAX_VIEWS); + + assert(state->pipeline->graphics.vtx_base_sgpr); + radeon_set_sh_reg_seq(cs, state->pipeline->graphics.vtx_base_sgpr, + state->pipeline->graphics.vtx_emit_num); + radeon_emit(cs, info->vertex_offset); + radeon_emit(cs, info->first_instance); + if (state->pipeline->graphics.vtx_emit_num == 3) + radeon_emit(cs, 0); + + radeon_emit(cs, PKT3(PKT3_NUM_INSTANCES, 0, state->predicating)); + radeon_emit(cs, info->instance_count); + + if (info->indexed) { + int index_size = state->index_type ? 4 : 2; + uint64_t index_va; + + index_va = state->index_va; + index_va += info->first_index * index_size; + + if (!state->subpass->view_mask) { + radv_cs_emit_draw_indexed_packet(cmd_buffer, index_va, + info->count); + } else { + unsigned i; + for_each_bit(i, state->subpass->view_mask) { + radv_emit_view_index(cmd_buffer, i); + + radv_cs_emit_draw_indexed_packet(cmd_buffer, + index_va, + info->count); + } + } } else { - unsigned i; - for_each_bit(i, cmd_buffer->state.subpass->view_mask) { - radv_emit_view_index(cmd_buffer, i); + if (!state->subpass->view_mask) { + radv_cs_emit_draw_packet(cmd_buffer, info->count); + } else { + unsigned i; + for_each_bit(i, state->subpass->view_mask) { + radv_emit_view_index(cmd_buffer, i); - radv_cs_emit_draw_packet(cmd_buffer, vertexCount); + radv_cs_emit_draw_packet(cmd_buffer, + info->count); + } } } - assert(cmd_buffer->cs->cdw <= cdw_max); - + assert(cs->cdw <= cdw_max); radv_cmd_buffer_after_draw(cmd_buffer); } - -static void -radv_cs_emit_draw_indexed_packet(struct radv_cmd_buffer *cmd_buffer, - uint64_t index_va, - uint32_t index_count) +void radv_CmdDraw( + VkCommandBuffer commandBuffer, + uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) { - radeon_emit(cmd_buffer->cs, PKT3(PKT3_DRAW_INDEX_2, 4, false)); - radeon_emit(cmd_buffer->cs, cmd_buffer->state.max_index_count); - radeon_emit(cmd_buffer->cs, index_va); - radeon_emit(cmd_buffer->cs, index_va >> 32); - radeon_emit(cmd_buffer->cs, index_count); - radeon_emit(cmd_buffer->cs, V_0287F0_DI_SRC_SEL_DMA); + RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); + struct radv_draw_info info = {}; + + info.count = vertexCount; + info.instance_count = instanceCount; + info.first_instance = firstInstance; + info.vertex_offset = firstVertex; + + radv_emit_draw_packets(cmd_buffer, &info); } void radv_CmdDrawIndexed( @@ -3000,39 +3073,16 @@ void radv_CmdDrawIndexed( uint32_t firstInstance) { RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); - int index_size = cmd_buffer->state.index_type ? 4 : 2; - uint64_t index_va; - - radv_cmd_buffer_flush_state(cmd_buffer, true, (instanceCount > 1), false, indexCount); - - MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws, cmd_buffer->cs, 26 * MAX_VIEWS); - - assert(cmd_buffer->state.pipeline->graphics.vtx_base_sgpr); - radeon_set_sh_reg_seq(cmd_buffer->cs, cmd_buffer->state.pipeline->graphics.vtx_base_sgpr, - cmd_buffer->state.pipeline->graphics.vtx_emit_num); - radeon_emit(cmd_buffer->cs, vertexOffset); - radeon_emit(cmd_buffer->cs, firstInstance); - if (cmd_buffer->state.pipeline->graphics.vtx_emit_num == 3) - radeon_emit(cmd_buffer->cs, 0); + struct radv_draw_info info = {}; - radeon_emit(cmd_buffer->cs, PKT3(PKT3_NUM_INSTANCES, 0, 0)); - radeon_emit(cmd_buffer->cs, instanceCount); + info.indexed = true; + info.count = indexCount; + info.instance_count = instanceCount; + info.first_index = firstIndex; + info.vertex_offset = vertexOffset; + info.first_instance = firstInstance; - index_va = cmd_buffer->state.index_va; - index_va += firstIndex * index_size; - if (!cmd_buffer->state.subpass->view_mask) { - radv_cs_emit_draw_indexed_packet(cmd_buffer, index_va, indexCount); - } else { - unsigned i; - for_each_bit(i, cmd_buffer->state.subpass->view_mask) { - radv_emit_view_index(cmd_buffer, i); - - radv_cs_emit_draw_indexed_packet(cmd_buffer, index_va, indexCount); - } - } - - assert(cmd_buffer->cs->cdw <= cdw_max); - radv_cmd_buffer_after_draw(cmd_buffer); + radv_emit_draw_packets(cmd_buffer, &info); } static void -- 2.30.2