[Mesa-dev] [PATCH 1/9] radv: refactor simple and indexed draws with radv_draw_info

Samuel Pitoiset samuel.pitoiset at gmail.com
Tue Oct 17 09:03:32 UTC 2017


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 <samuel.pitoiset at gmail.com>
---
 src/amd/vulkan/radv_cmd_buffer.c | 202 ++++++++++++++++++++++++---------------
 1 file changed, 127 insertions(+), 75 deletions(-)

diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index 9d59028bfd..f0abafad3b 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -2856,47 +2856,6 @@ 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)
-{
-	RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
-
-	radv_cmd_buffer_flush_state(cmd_buffer, false, (instanceCount > 1), false, vertexCount);
-
-	MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws, cmd_buffer->cs, 20 * 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, firstVertex);
-	radeon_emit(cmd_buffer->cs, firstInstance);
-	if (cmd_buffer->state.pipeline->graphics.vtx_emit_num == 3)
-		radeon_emit(cmd_buffer->cs, 0);
-
-	radeon_emit(cmd_buffer->cs, PKT3(PKT3_NUM_INSTANCES, 0, cmd_buffer->state.predicating));
-	radeon_emit(cmd_buffer->cs, instanceCount);
-
-	if (!cmd_buffer->state.subpass->view_mask) {
-		radv_cs_emit_draw_packet(cmd_buffer, vertexCount);
-	} else {
-		unsigned i;
-		for_each_bit(i, cmd_buffer->state.subpass->view_mask) {
-			radv_emit_view_index(cmd_buffer, i);
-
-			radv_cs_emit_draw_packet(cmd_buffer, vertexCount);
-		}
-	}
-
-	assert(cmd_buffer->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,
@@ -2910,58 +2869,151 @@ radv_cs_emit_draw_indexed_packet(struct radv_cmd_buffer *cmd_buffer,
 	radeon_emit(cmd_buffer->cs, V_0287F0_DI_SRC_SEL_DMA);
 }
 
-void radv_CmdDrawIndexed(
-	VkCommandBuffer                             commandBuffer,
-	uint32_t                                    indexCount,
-	uint32_t                                    instanceCount,
-	uint32_t                                    firstIndex,
-	int32_t                                     vertexOffset,
-	uint32_t                                    firstInstance)
+struct radv_draw_info {
+	/**
+	 * Number of vertices.
+	 */
+	uint32_t count;
+
+	/**
+	 * Index of the first vertex.
+	 */
+	int32_t vertex_offset;
+
+	/**
+	 * First instance id.
+	 */
+	uint32_t first_instance;
+
+	/**
+	 * Number of instances.
+	 */
+	uint32_t instance_count;
+
+	/**
+	 * First index (indexed draws only).
+	 */
+	uint32_t first_index;
+
+	/**
+	 * Whether it's an indexed draw.
+	 */
+	bool indexed;
+};
+
+static void
+radv_emit_draw_packets(struct radv_cmd_buffer *cmd_buffer,
+		       const struct radv_draw_info *info)
 {
-	RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
-	int index_size = cmd_buffer->state.index_type ? 4 : 2;
-	uint64_t index_va;
+	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, true, (instanceCount > 1), false, indexCount);
+	radv_cmd_buffer_flush_state(cmd_buffer, info->indexed,
+				    info->instance_count > 1, false,
+				    info->count);
 
-	MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws, cmd_buffer->cs, 26 * MAX_VIEWS);
+	MAYBE_UNUSED unsigned cdw_max = radeon_check_space(device->ws, cs,
+							   26 * MAX_VIEWS);
 
-	if (cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9) {
-		radeon_set_uconfig_reg_idx(cmd_buffer->cs, R_03090C_VGT_INDEX_TYPE,
-					   2, cmd_buffer->state.index_type);
-	} else {
-		radeon_emit(cmd_buffer->cs, PKT3(PKT3_INDEX_TYPE, 0, 0));
-		radeon_emit(cmd_buffer->cs, cmd_buffer->state.index_type);
+	if (info->indexed) {
+		if (device->physical_device->rad_info.chip_class >= GFX9) {
+			radeon_set_uconfig_reg_idx(cs, R_03090C_VGT_INDEX_TYPE,
+						   2, state->index_type);
+		} else {
+			radeon_emit(cs, PKT3(PKT3_INDEX_TYPE, 0, 0));
+			radeon_emit(cs, state->index_type);
+		}
 	}
 
 	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);
+	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(cmd_buffer->cs, PKT3(PKT3_NUM_INSTANCES, 0, 0));
-	radeon_emit(cmd_buffer->cs, instanceCount);
+	radeon_emit(cmd_buffer->cs, info->instance_count);
 
-	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);
+	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_indexed_packet(cmd_buffer, index_va, indexCount);
+				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);
 }
 
+void radv_CmdDraw(
+	VkCommandBuffer                             commandBuffer,
+	uint32_t                                    vertexCount,
+	uint32_t                                    instanceCount,
+	uint32_t                                    firstVertex,
+	uint32_t                                    firstInstance)
+{
+	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(
+	VkCommandBuffer                             commandBuffer,
+	uint32_t                                    indexCount,
+	uint32_t                                    instanceCount,
+	uint32_t                                    firstIndex,
+	int32_t                                     vertexOffset,
+	uint32_t                                    firstInstance)
+{
+	RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+	struct radv_draw_info info = {};
+
+	info.indexed = true;
+	info.count = indexCount;
+	info.instance_count = instanceCount;
+	info.first_index = firstIndex;
+	info.vertex_offset = vertexOffset;
+	info.first_instance = firstInstance;
+
+	radv_emit_draw_packets(cmd_buffer, &info);
+}
+
 static void
 radv_cs_emit_indirect_draw_packet(struct radv_cmd_buffer *cmd_buffer,
                                   bool indexed,
-- 
2.14.2



More information about the mesa-dev mailing list