[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:08:35 UTC 2017


Just noticed that I missed the predicate stuff.

On 10/17/2017 11:03 AM, Samuel Pitoiset wrote:
> 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,
> 


More information about the mesa-dev mailing list