[Mesa-dev] [PATCH] radv: pre-calculate user_data_0 registers and store in pipeline

Samuel Pitoiset samuel.pitoiset at gmail.com
Mon Nov 6 13:12:54 UTC 2017


Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>

On 11/06/2017 07:58 AM, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
> 
> There's no point recalculating these the whole time on descriptor
> emission, just store them at pipeline creation.
> 
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>   src/amd/vulkan/radv_cmd_buffer.c | 14 ++++++------
>   src/amd/vulkan/radv_pipeline.c   | 49 ++++++++++++++++++++++++++++++++++++++--
>   src/amd/vulkan/radv_private.h    |  1 +
>   src/amd/vulkan/radv_shader.c     | 39 --------------------------------
>   src/amd/vulkan/radv_shader.h     |  4 ----
>   5 files changed, 55 insertions(+), 52 deletions(-)
> 
> diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
> index 7357eadae39..62adbaced10 100644
> --- a/src/amd/vulkan/radv_cmd_buffer.c
> +++ b/src/amd/vulkan/radv_cmd_buffer.c
> @@ -574,7 +574,7 @@ radv_emit_userdata_address(struct radv_cmd_buffer *cmd_buffer,
>   			   int idx, uint64_t va)
>   {
>   	struct ac_userdata_info *loc = radv_lookup_user_sgpr(pipeline, stage, idx);
> -	uint32_t base_reg = radv_shader_stage_to_user_data_0(stage, cmd_buffer->device->physical_device->rad_info.chip_class, radv_pipeline_has_gs(pipeline), radv_pipeline_has_tess(pipeline));
> +	uint32_t base_reg = pipeline->user_data_0[stage];
>   	if (loc->sgpr_idx == -1)
>   		return;
>   	assert(loc->num_sgprs == 2);
> @@ -616,7 +616,7 @@ radv_update_multisample_state(struct radv_cmd_buffer *cmd_buffer,
>   	if (pipeline->shaders[MESA_SHADER_FRAGMENT]->info.info.ps.needs_sample_positions) {
>   		uint32_t offset;
>   		struct ac_userdata_info *loc = radv_lookup_user_sgpr(pipeline, MESA_SHADER_FRAGMENT, AC_UD_PS_SAMPLE_POS_OFFSET);
> -		uint32_t base_reg = radv_shader_stage_to_user_data_0(MESA_SHADER_FRAGMENT, cmd_buffer->device->physical_device->rad_info.chip_class, radv_pipeline_has_gs(pipeline), radv_pipeline_has_tess(pipeline));
> +		uint32_t base_reg = pipeline->user_data_0[MESA_SHADER_FRAGMENT];
>   		if (loc->sgpr_idx == -1)
>   			return;
>   		assert(loc->num_sgprs == 1);
> @@ -838,7 +838,7 @@ radv_emit_tess_shaders(struct radv_cmd_buffer *cmd_buffer,
>   
>   	loc = radv_lookup_user_sgpr(pipeline, MESA_SHADER_TESS_CTRL, AC_UD_TCS_OFFCHIP_LAYOUT);
>   	if (loc->sgpr_idx != -1) {
> -		uint32_t base_reg = radv_shader_stage_to_user_data_0(MESA_SHADER_TESS_CTRL, cmd_buffer->device->physical_device->rad_info.chip_class, radv_pipeline_has_gs(pipeline), radv_pipeline_has_tess(pipeline));
> +		uint32_t base_reg = pipeline->user_data_0[MESA_SHADER_TESS_CTRL];
>   		assert(loc->num_sgprs == 4);
>   		assert(!loc->indirect);
>   		radeon_set_sh_reg_seq(cmd_buffer->cs, base_reg + loc->sgpr_idx * 4, 4);
> @@ -851,7 +851,7 @@ radv_emit_tess_shaders(struct radv_cmd_buffer *cmd_buffer,
>   
>   	loc = radv_lookup_user_sgpr(pipeline, MESA_SHADER_TESS_EVAL, AC_UD_TES_OFFCHIP_LAYOUT);
>   	if (loc->sgpr_idx != -1) {
> -		uint32_t base_reg = radv_shader_stage_to_user_data_0(MESA_SHADER_TESS_EVAL, cmd_buffer->device->physical_device->rad_info.chip_class, radv_pipeline_has_gs(pipeline), radv_pipeline_has_tess(pipeline));
> +		uint32_t base_reg = pipeline->user_data_0[MESA_SHADER_TESS_EVAL];
>   		assert(loc->num_sgprs == 1);
>   		assert(!loc->indirect);
>   
> @@ -861,7 +861,7 @@ radv_emit_tess_shaders(struct radv_cmd_buffer *cmd_buffer,
>   
>   	loc = radv_lookup_user_sgpr(pipeline, MESA_SHADER_VERTEX, AC_UD_VS_LS_TCS_IN_LAYOUT);
>   	if (loc->sgpr_idx != -1) {
> -		uint32_t base_reg = radv_shader_stage_to_user_data_0(MESA_SHADER_VERTEX, cmd_buffer->device->physical_device->rad_info.chip_class, radv_pipeline_has_gs(pipeline), radv_pipeline_has_tess(pipeline));
> +		uint32_t base_reg = pipeline->user_data_0[MESA_SHADER_VERTEX];
>   		assert(loc->num_sgprs == 1);
>   		assert(!loc->indirect);
>   
> @@ -1577,7 +1577,7 @@ emit_stage_descriptor_set_userdata(struct radv_cmd_buffer *cmd_buffer,
>   				   gl_shader_stage stage)
>   {
>   	struct ac_userdata_info *desc_set_loc = &pipeline->shaders[stage]->info.user_sgprs_locs.descriptor_sets[idx];
> -	uint32_t base_reg = radv_shader_stage_to_user_data_0(stage, cmd_buffer->device->physical_device->rad_info.chip_class, radv_pipeline_has_gs(pipeline), radv_pipeline_has_tess(pipeline));
> +	uint32_t base_reg = pipeline->user_data_0[stage];
>   
>   	if (desc_set_loc->sgpr_idx == -1 || desc_set_loc->indirect)
>   		return;
> @@ -2938,7 +2938,7 @@ static void radv_emit_view_index(struct radv_cmd_buffer *cmd_buffer, unsigned in
>   		struct ac_userdata_info *loc = radv_lookup_user_sgpr(pipeline, stage, AC_UD_VIEW_INDEX);
>   		if (loc->sgpr_idx == -1)
>   			continue;
> -		uint32_t base_reg = radv_shader_stage_to_user_data_0(stage, cmd_buffer->device->physical_device->rad_info.chip_class, radv_pipeline_has_gs(pipeline), radv_pipeline_has_tess(pipeline));
> +		uint32_t base_reg = pipeline->user_data_0[stage];
>   		radeon_set_sh_reg(cmd_buffer->cs, base_reg + loc->sgpr_idx * 4, index);
>   
>   	}
> diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
> index f059fa43f99..396361db2ac 100644
> --- a/src/amd/vulkan/radv_pipeline.c
> +++ b/src/amd/vulkan/radv_pipeline.c
> @@ -1966,6 +1966,48 @@ void radv_create_shaders(struct radv_pipeline *pipeline,
>   		ralloc_free(fs_m.nir);
>   }
>   
> +static uint32_t
> +radv_pipeline_stage_to_user_data_0(struct radv_pipeline *pipeline,
> +				   gl_shader_stage stage, enum chip_class chip_class)
> +{
> +	bool has_gs = radv_pipeline_has_gs(pipeline);
> +	bool has_tess = radv_pipeline_has_tess(pipeline);
> +	switch (stage) {
> +	case MESA_SHADER_FRAGMENT:
> +		return R_00B030_SPI_SHADER_USER_DATA_PS_0;
> +	case MESA_SHADER_VERTEX:
> +		if (chip_class >= GFX9) {
> +			return has_tess ? R_00B430_SPI_SHADER_USER_DATA_LS_0 :
> +			       has_gs ? R_00B330_SPI_SHADER_USER_DATA_ES_0 :
> +			       R_00B130_SPI_SHADER_USER_DATA_VS_0;
> +		}
> +		if (has_tess)
> +			return R_00B530_SPI_SHADER_USER_DATA_LS_0;
> +		else
> +			return has_gs ? R_00B330_SPI_SHADER_USER_DATA_ES_0 : R_00B130_SPI_SHADER_USER_DATA_VS_0;
> +	case MESA_SHADER_GEOMETRY:
> +		return chip_class >= GFX9 ? R_00B330_SPI_SHADER_USER_DATA_ES_0 :
> +		                            R_00B230_SPI_SHADER_USER_DATA_GS_0;
> +	case MESA_SHADER_COMPUTE:
> +		return R_00B900_COMPUTE_USER_DATA_0;
> +	case MESA_SHADER_TESS_CTRL:
> +		return chip_class >= GFX9 ? R_00B430_SPI_SHADER_USER_DATA_LS_0 :
> +		                            R_00B430_SPI_SHADER_USER_DATA_HS_0;
> +	case MESA_SHADER_TESS_EVAL:
> +		if (chip_class >= GFX9) {
> +			return has_gs ? R_00B330_SPI_SHADER_USER_DATA_ES_0 :
> +			       R_00B130_SPI_SHADER_USER_DATA_VS_0;
> +		}
> +		if (has_gs)
> +			return R_00B330_SPI_SHADER_USER_DATA_ES_0;
> +		else
> +			return R_00B130_SPI_SHADER_USER_DATA_VS_0;
> +	default:
> +		unreachable("unknown shader");
> +	}
> +}
> +
> +
>   static VkResult
>   radv_pipeline_init(struct radv_pipeline *pipeline,
>   		   struct radv_device *device,
> @@ -2230,10 +2272,13 @@ radv_pipeline_init(struct radv_pipeline *pipeline,
>   		pipeline->binding_stride[desc->binding] = desc->stride;
>   	}
>   
> +	for (uint32_t i = 0; i < MESA_SHADER_STAGES; i++)
> +		pipeline->user_data_0[i] = radv_pipeline_stage_to_user_data_0(pipeline, i, device->physical_device->rad_info.chip_class);
> +
>   	struct ac_userdata_info *loc = radv_lookup_user_sgpr(pipeline, MESA_SHADER_VERTEX,
>   							     AC_UD_VS_BASE_VERTEX_START_INSTANCE);
>   	if (loc->sgpr_idx != -1) {
> -		pipeline->graphics.vtx_base_sgpr = radv_shader_stage_to_user_data_0(MESA_SHADER_VERTEX, device->physical_device->rad_info.chip_class, radv_pipeline_has_gs(pipeline), radv_pipeline_has_tess(pipeline));
> +		pipeline->graphics.vtx_base_sgpr = pipeline->user_data_0[MESA_SHADER_VERTEX];
>   		pipeline->graphics.vtx_base_sgpr += loc->sgpr_idx * 4;
>   		if (radv_get_vertex_shader(pipeline)->info.info.vs.needs_draw_id)
>   			pipeline->graphics.vtx_emit_num = 3;
> @@ -2338,7 +2383,7 @@ static VkResult radv_compute_pipeline_create(
>   	pStages[MESA_SHADER_COMPUTE] = &pCreateInfo->stage;
>   	radv_create_shaders(pipeline, device, cache, (struct radv_pipeline_key) {0}, pStages);
>   
> -
> +	pipeline->user_data_0[MESA_SHADER_COMPUTE] = radv_pipeline_stage_to_user_data_0(pipeline, MESA_SHADER_COMPUTE, device->physical_device->rad_info.chip_class);
>   	pipeline->need_indirect_descriptor_sets |= pipeline->shaders[MESA_SHADER_COMPUTE]->info.need_indirect_descriptor_sets;
>   	result = radv_pipeline_scratch_init(device, pipeline);
>   	if (result != VK_SUCCESS) {
> diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
> index 27746783902..c2c1f6056da 100644
> --- a/src/amd/vulkan/radv_private.h
> +++ b/src/amd/vulkan/radv_private.h
> @@ -1136,6 +1136,7 @@ struct radv_pipeline {
>   
>   	uint32_t                                     binding_stride[MAX_VBS];
>   
> +	uint32_t user_data_0[MESA_SHADER_STAGES];
>   	union {
>   		struct {
>   			struct radv_blend_state blend;
> diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c
> index 9162612284c..ffa0ee07107 100644
> --- a/src/amd/vulkan/radv_shader.c
> +++ b/src/amd/vulkan/radv_shader.c
> @@ -541,45 +541,6 @@ radv_shader_variant_destroy(struct radv_device *device,
>   	free(variant);
>   }
>   
> -uint32_t
> -radv_shader_stage_to_user_data_0(gl_shader_stage stage, enum chip_class chip_class,
> -				 bool has_gs, bool has_tess)
> -{
> -	switch (stage) {
> -	case MESA_SHADER_FRAGMENT:
> -		return R_00B030_SPI_SHADER_USER_DATA_PS_0;
> -	case MESA_SHADER_VERTEX:
> -		if (chip_class >= GFX9) {
> -			return has_tess ? R_00B430_SPI_SHADER_USER_DATA_LS_0 :
> -			       has_gs ? R_00B330_SPI_SHADER_USER_DATA_ES_0 :
> -			       R_00B130_SPI_SHADER_USER_DATA_VS_0;
> -		}
> -		if (has_tess)
> -			return R_00B530_SPI_SHADER_USER_DATA_LS_0;
> -		else
> -			return has_gs ? R_00B330_SPI_SHADER_USER_DATA_ES_0 : R_00B130_SPI_SHADER_USER_DATA_VS_0;
> -	case MESA_SHADER_GEOMETRY:
> -		return chip_class >= GFX9 ? R_00B330_SPI_SHADER_USER_DATA_ES_0 :
> -		                            R_00B230_SPI_SHADER_USER_DATA_GS_0;
> -	case MESA_SHADER_COMPUTE:
> -		return R_00B900_COMPUTE_USER_DATA_0;
> -	case MESA_SHADER_TESS_CTRL:
> -		return chip_class >= GFX9 ? R_00B430_SPI_SHADER_USER_DATA_LS_0 :
> -		                            R_00B430_SPI_SHADER_USER_DATA_HS_0;
> -	case MESA_SHADER_TESS_EVAL:
> -		if (chip_class >= GFX9) {
> -			return has_gs ? R_00B330_SPI_SHADER_USER_DATA_ES_0 :
> -			       R_00B130_SPI_SHADER_USER_DATA_VS_0;
> -		}
> -		if (has_gs)
> -			return R_00B330_SPI_SHADER_USER_DATA_ES_0;
> -		else
> -			return R_00B130_SPI_SHADER_USER_DATA_VS_0;
> -	default:
> -		unreachable("unknown shader");
> -	}
> -}
> -
>   const char *
>   radv_get_shader_name(struct radv_shader_variant *var, gl_shader_stage stage)
>   {
> diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h
> index 27dd87f7ae6..9bdbe848c8f 100644
> --- a/src/amd/vulkan/radv_shader.h
> +++ b/src/amd/vulkan/radv_shader.h
> @@ -103,10 +103,6 @@ void
>   radv_shader_variant_destroy(struct radv_device *device,
>   			    struct radv_shader_variant *variant);
>   
> -uint32_t
> -radv_shader_stage_to_user_data_0(gl_shader_stage stage, enum chip_class chip_class,
> -				 bool has_gs, bool has_tess);
> -
>   const char *
>   radv_get_shader_name(struct radv_shader_variant *var, gl_shader_stage stage);
>   
> 


More information about the mesa-dev mailing list