Mesa (master): radeonsi: don' t load unused compute shader input SGPRs and VGPRs

Marek Olšák mareko at kemper.freedesktop.org
Fri Apr 28 20:29:49 UTC 2017


Module: Mesa
Branch: master
Commit: 7a515a607cf47c5ca3b02856d65dc9b963f94d83
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7a515a607cf47c5ca3b02856d65dc9b963f94d83

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Mon Apr 24 17:27:37 2017 +0200

radeonsi: don't load unused compute shader input SGPRs and VGPRs

Basically, don't load GRID_SIZE or BLOCK_SIZE if they are unused, determine
whether to load BLOCK_ID for each component separately, and set the number
of THREAD_ID VGPRs to load. Now we should get the maximum CS launch wave
rate in most cases.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>

---

 src/gallium/drivers/radeonsi/si_compute.c         | 71 ++++++++++++++---------
 src/gallium/drivers/radeonsi/si_shader.c          | 37 ++++++++----
 src/gallium/drivers/radeonsi/si_shader.h          | 11 ----
 src/gallium/drivers/radeonsi/si_shader_internal.h |  5 ++
 4 files changed, 76 insertions(+), 48 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_compute.c b/src/gallium/drivers/radeonsi/si_compute.c
index 2b2efaeadc..63f1ac92ad 100644
--- a/src/gallium/drivers/radeonsi/si_compute.c
+++ b/src/gallium/drivers/radeonsi/si_compute.c
@@ -48,6 +48,8 @@ struct si_compute {
 	struct pipe_resource *global_buffers[MAX_GLOBAL_BUFFERS];
 	unsigned use_code_object_v2 : 1;
 	unsigned variable_group_size : 1;
+	unsigned uses_grid_size:1;
+	unsigned uses_block_size:1;
 };
 
 struct dispatch_packet {
@@ -121,11 +123,16 @@ static void si_create_compute_state_async(void *job, int thread_index)
 
 	program->shader.selector = &sel;
 	program->shader.is_monolithic = true;
+	program->uses_grid_size = sel.info.uses_grid_size;
+	program->uses_block_size = sel.info.uses_block_size;
 
 	if (si_shader_create(program->screen, tm, &program->shader, debug)) {
 		program->shader.compilation_failed = true;
 	} else {
 		bool scratch_enabled = shader->config.scratch_bytes_per_wave > 0;
+		unsigned user_sgprs = SI_NUM_RESOURCE_SGPRS +
+				      (sel.info.uses_grid_size ? 3 : 0) +
+				      (sel.info.uses_block_size ? 3 : 0);
 
 		shader->config.rsrc1 =
 			S_00B848_VGPRS((shader->config.num_vgprs - 1) / 4) |
@@ -134,10 +141,13 @@ static void si_create_compute_state_async(void *job, int thread_index)
 			S_00B848_FLOAT_MODE(shader->config.float_mode);
 
 		shader->config.rsrc2 =
-			S_00B84C_USER_SGPR(SI_CS_NUM_USER_SGPR) |
+			S_00B84C_USER_SGPR(user_sgprs) |
 			S_00B84C_SCRATCH_EN(scratch_enabled) |
-			S_00B84C_TGID_X_EN(1) | S_00B84C_TGID_Y_EN(1) |
-			S_00B84C_TGID_Z_EN(1) | S_00B84C_TIDIG_COMP_CNT(2) |
+			S_00B84C_TGID_X_EN(sel.info.uses_block_id[0]) |
+			S_00B84C_TGID_Y_EN(sel.info.uses_block_id[1]) |
+			S_00B84C_TGID_Z_EN(sel.info.uses_block_id[2]) |
+			S_00B84C_TIDIG_COMP_CNT(sel.info.uses_thread_id[2] ? 2 :
+						sel.info.uses_thread_id[1] ? 1 : 0) |
 			S_00B84C_LDS_SIZE(shader->config.lds_size);
 
 		program->variable_group_size =
@@ -651,36 +661,43 @@ static bool si_upload_compute_input(struct si_context *sctx,
 static void si_setup_tgsi_grid(struct si_context *sctx,
                                 const struct pipe_grid_info *info)
 {
+	struct si_compute *program = sctx->cs_shader_state.program;
 	struct radeon_winsys_cs *cs = sctx->b.gfx.cs;
 	unsigned grid_size_reg = R_00B900_COMPUTE_USER_DATA_0 +
-	                          4 * SI_SGPR_GRID_SIZE;
+				 4 * SI_NUM_RESOURCE_SGPRS;
+	unsigned block_size_reg = grid_size_reg +
+				  /* 12 bytes = 3 dwords. */
+				  12 * program->uses_grid_size;
 
 	if (info->indirect) {
-		uint64_t base_va = r600_resource(info->indirect)->gpu_address;
-		uint64_t va = base_va + info->indirect_offset;
-		int i;
-
-		radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
-		                 (struct r600_resource *)info->indirect,
-		                 RADEON_USAGE_READ, RADEON_PRIO_DRAW_INDIRECT);
-
-		for (i = 0; i < 3; ++i) {
-			radeon_emit(cs, PKT3(PKT3_COPY_DATA, 4, 0));
-			radeon_emit(cs, COPY_DATA_SRC_SEL(COPY_DATA_MEM) |
-					COPY_DATA_DST_SEL(COPY_DATA_REG));
-			radeon_emit(cs, (va +  4 * i));
-			radeon_emit(cs, (va + 4 * i) >> 32);
-			radeon_emit(cs, (grid_size_reg >> 2) + i);
-			radeon_emit(cs, 0);
+		if (program->uses_grid_size) {
+			uint64_t base_va = r600_resource(info->indirect)->gpu_address;
+			uint64_t va = base_va + info->indirect_offset;
+			int i;
+
+			radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
+					 (struct r600_resource *)info->indirect,
+					 RADEON_USAGE_READ, RADEON_PRIO_DRAW_INDIRECT);
+
+			for (i = 0; i < 3; ++i) {
+				radeon_emit(cs, PKT3(PKT3_COPY_DATA, 4, 0));
+				radeon_emit(cs, COPY_DATA_SRC_SEL(COPY_DATA_MEM) |
+						COPY_DATA_DST_SEL(COPY_DATA_REG));
+				radeon_emit(cs, (va + 4 * i));
+				radeon_emit(cs, (va + 4 * i) >> 32);
+				radeon_emit(cs, (grid_size_reg >> 2) + i);
+				radeon_emit(cs, 0);
+			}
 		}
 	} else {
-		struct si_compute *program = sctx->cs_shader_state.program;
-
-		radeon_set_sh_reg_seq(cs, grid_size_reg, program->variable_group_size ? 6 : 3);
-		radeon_emit(cs, info->grid[0]);
-		radeon_emit(cs, info->grid[1]);
-		radeon_emit(cs, info->grid[2]);
-		if (program->variable_group_size) {
+		if (program->uses_grid_size) {
+			radeon_set_sh_reg_seq(cs, grid_size_reg, 3);
+			radeon_emit(cs, info->grid[0]);
+			radeon_emit(cs, info->grid[1]);
+			radeon_emit(cs, info->grid[2]);
+		}
+		if (program->variable_group_size && program->uses_block_size) {
+			radeon_set_sh_reg_seq(cs, block_size_reg, 3);
 			radeon_emit(cs, info->block[0]);
 			radeon_emit(cs, info->block[1]);
 			radeon_emit(cs, info->block[2]);
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index c0e190c04d..77dd6b1a3a 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -1592,7 +1592,7 @@ static void declare_system_value(struct si_shader_context *ctx,
 		break;
 
 	case TGSI_SEMANTIC_GRID_SIZE:
-		value = LLVMGetParam(ctx->main_fn, SI_PARAM_GRID_SIZE);
+		value = LLVMGetParam(ctx->main_fn, ctx->param_grid_size);
 		break;
 
 	case TGSI_SEMANTIC_BLOCK_SIZE:
@@ -1613,17 +1613,28 @@ static void declare_system_value(struct si_shader_context *ctx,
 
 			value = lp_build_gather_values(gallivm, values, 3);
 		} else {
-			value = LLVMGetParam(ctx->main_fn, SI_PARAM_BLOCK_SIZE);
+			value = LLVMGetParam(ctx->main_fn, ctx->param_block_size);
 		}
 		break;
 	}
 
 	case TGSI_SEMANTIC_BLOCK_ID:
-		value = LLVMGetParam(ctx->main_fn, SI_PARAM_BLOCK_ID);
+	{
+		LLVMValueRef values[3];
+
+		for (int i = 0; i < 3; i++) {
+			values[i] = ctx->i32_0;
+			if (ctx->param_block_id[i] >= 0) {
+				values[i] = LLVMGetParam(ctx->main_fn,
+							 ctx->param_block_id[i]);
+			}
+		}
+		value = lp_build_gather_values(gallivm, values, 3);
 		break;
+	}
 
 	case TGSI_SEMANTIC_THREAD_ID:
-		value = LLVMGetParam(ctx->main_fn, SI_PARAM_THREAD_ID);
+		value = LLVMGetParam(ctx->main_fn, ctx->param_thread_id);
 		break;
 
 	case TGSI_SEMANTIC_HELPER_INVOCATION:
@@ -6185,13 +6196,19 @@ static void create_function(struct si_shader_context *ctx)
 
 	case PIPE_SHADER_COMPUTE:
 		declare_default_desc_pointers(ctx, params, &num_params);
-		params[SI_PARAM_GRID_SIZE] = v3i32;
-		params[SI_PARAM_BLOCK_SIZE] = v3i32;
-		params[SI_PARAM_BLOCK_ID] = v3i32;
-		last_sgpr = SI_PARAM_BLOCK_ID;
+		if (shader->selector->info.uses_grid_size)
+			params[ctx->param_grid_size = num_params++] = v3i32;
+		if (shader->selector->info.uses_block_size)
+			params[ctx->param_block_size = num_params++] = v3i32;
+
+		for (i = 0; i < 3; i++) {
+			ctx->param_block_id[i] = -1;
+			if (shader->selector->info.uses_block_id[i])
+				params[ctx->param_block_id[i] = num_params++] = ctx->i32;
+		}
+		last_sgpr = num_params - 1;
 
-		params[SI_PARAM_THREAD_ID] = v3i32;
-		num_params = SI_PARAM_THREAD_ID + 1;
+		params[ctx->param_thread_id = num_params++] = v3i32;
 		break;
 	default:
 		assert(0 && "unimplemented shader");
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index 8c098ac60a..0988d91de4 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -220,11 +220,6 @@ enum {
 	/* PS only */
 	SI_SGPR_ALPHA_REF	= SI_NUM_RESOURCE_SGPRS,
 	SI_PS_NUM_USER_SGPR,
-
-	/* CS only */
-	SI_SGPR_GRID_SIZE = SI_NUM_RESOURCE_SGPRS,
-	SI_SGPR_BLOCK_SIZE = SI_SGPR_GRID_SIZE + 3,
-	SI_CS_NUM_USER_SGPR = SI_SGPR_BLOCK_SIZE + 3
 };
 
 /* LLVM function parameter indices */
@@ -251,12 +246,6 @@ enum {
 	SI_PARAM_SAMPLE_COVERAGE,
 	SI_PARAM_POS_FIXED_PT,
 
-	/* CS only parameters */
-	SI_PARAM_GRID_SIZE = SI_NUM_RESOURCE_PARAMS,
-	SI_PARAM_BLOCK_SIZE,
-	SI_PARAM_BLOCK_ID,
-	SI_PARAM_THREAD_ID,
-
 	SI_NUM_PARAMS = SI_PARAM_POS_FIXED_PT + 9, /* +8 for COLOR[0..1] */
 };
 
diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h
index 954b83db20..cad2db3551 100644
--- a/src/gallium/drivers/radeonsi/si_shader_internal.h
+++ b/src/gallium/drivers/radeonsi/si_shader_internal.h
@@ -195,6 +195,11 @@ struct si_shader_context {
 	int param_gs_vtx01_offset; /* in dwords (GFX9) */
 	int param_gs_vtx23_offset; /* in dwords (GFX9) */
 	int param_gs_vtx45_offset; /* in dwords (GFX9) */
+	/* CS */
+	int param_grid_size;
+	int param_block_size;
+	int param_block_id[3];
+	int param_thread_id;
 
 	LLVMTargetMachineRef tm;
 




More information about the mesa-commit mailing list