[Mesa-dev] [PATCH 20/31] radeonsi: use TCS epilog for monolithic shaders

Nicolai Hähnle nhaehnle at gmail.com
Mon Oct 31 22:11:07 UTC 2016


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

For fixed function TCS, we keep the copying of VS outputs to TES inputs inside
the main function; the call to si_copy_tcs_inputs is moved accordingly.
---
 src/gallium/drivers/radeonsi/si_shader.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index b33f54a..b7678e1 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -68,20 +68,22 @@ static void si_llvm_emit_barrier(const struct lp_build_tgsi_action *action,
 				 struct lp_build_tgsi_context *bld_base,
 				 struct lp_build_emit_data *emit_data);
 
 static void si_dump_shader_key(unsigned shader, union si_shader_key *key,
 			       FILE *f);
 
 static void si_build_vs_prolog_function(struct si_shader_context *ctx,
 					union si_shader_part_key *key);
 static void si_build_vs_epilog_function(struct si_shader_context *ctx,
 					union si_shader_part_key *key);
+static void si_build_tcs_epilog_function(struct si_shader_context *ctx,
+					 union si_shader_part_key *key);
 static void si_build_ps_prolog_function(struct si_shader_context *ctx,
 					union si_shader_part_key *key);
 static void si_build_ps_epilog_function(struct si_shader_context *ctx,
 					union si_shader_part_key *key);
 
 /* Ideally pass the sample mask input to the PS epilog as v13, which
  * is its usual location, so that the shader doesn't have to add v_mov.
  */
 #define PS_EPILOG_SAMPLEMASK_MIN_LOC 13
 
@@ -2476,20 +2478,24 @@ handle_semantic:
 
 		if (pos_idx == shader->info.nr_pos_exports)
 			/* Specify that this is the last export */
 			pos_args[i][2] = uint->one;
 
 		lp_build_intrinsic(base->gallivm->builder, "llvm.SI.export",
 				   ctx->voidt, pos_args[i], 9, 0);
 	}
 }
 
+/**
+ * Forward all outputs from the vertex shader to the TES. This is only used
+ * for the fixed function TCS.
+ */
 static void si_copy_tcs_inputs(struct lp_build_tgsi_context *bld_base)
 {
 	struct si_shader_context *ctx = si_shader_context(bld_base);
 	struct gallivm_state *gallivm = bld_base->base.gallivm;
 	LLVMValueRef invocation_id, rw_buffers, buffer, buffer_offset;
 	LLVMValueRef lds_vertex_stride, lds_vertex_offset, lds_base;
 	uint64_t inputs;
 
 	invocation_id = unpack_param(ctx, SI_PARAM_REL_IDS, 8, 5);
 
@@ -2630,20 +2636,22 @@ static void si_write_tess_factors(struct lp_build_tgsi_context *bld_base,
 					   stride - 4, byteoffset, tf_base, 20);
 	lp_build_endif(&if_ctx);
 }
 
 /* This only writes the tessellation factor levels. */
 static void si_llvm_emit_tcs_epilogue(struct lp_build_tgsi_context *bld_base)
 {
 	struct si_shader_context *ctx = si_shader_context(bld_base);
 	LLVMValueRef rel_patch_id, invocation_id, tf_lds_offset;
 
+	si_copy_tcs_inputs(bld_base);
+
 	rel_patch_id = get_rel_patch_id(ctx);
 	invocation_id = unpack_param(ctx, SI_PARAM_REL_IDS, 8, 5);
 	tf_lds_offset = get_tcs_out_current_patch_data_offset(ctx);
 
 	if (!ctx->no_epilog) {
 		/* Return epilog parameters from this function. */
 		LLVMBuilderRef builder = bld_base->base.gallivm->builder;
 		LLVMValueRef ret = ctx->return_value;
 		LLVMValueRef rw_buffers, rw0, rw1, tf_soffset;
 		unsigned vgpr;
@@ -2672,21 +2680,20 @@ static void si_llvm_emit_tcs_epilogue(struct lp_build_tgsi_context *bld_base)
 		tf_lds_offset = bitcast(bld_base, TGSI_TYPE_FLOAT, tf_lds_offset);
 
 		vgpr = SI_TCS_NUM_USER_SGPR + 2;
 		ret = LLVMBuildInsertValue(builder, ret, rel_patch_id, vgpr++, "");
 		ret = LLVMBuildInsertValue(builder, ret, invocation_id, vgpr++, "");
 		ret = LLVMBuildInsertValue(builder, ret, tf_lds_offset, vgpr++, "");
 		ctx->return_value = ret;
 		return;
 	}
 
-	si_copy_tcs_inputs(bld_base);
 	si_write_tess_factors(bld_base, rel_patch_id, invocation_id, tf_lds_offset);
 }
 
 static void si_llvm_emit_ls_epilogue(struct lp_build_tgsi_context *bld_base)
 {
 	struct si_shader_context *ctx = si_shader_context(bld_base);
 	struct si_shader *shader = ctx->shader;
 	struct tgsi_shader_info *info = &shader->selector->info;
 	struct gallivm_state *gallivm = bld_base->base.gallivm;
 	unsigned i, chan;
@@ -7172,20 +7179,21 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
 		tgsi_dump(sel->tokens, 0);
 		si_dump_streamout(&sel->so);
 	}
 
 	si_init_shader_ctx(&ctx, sscreen, shader, tm);
 	ctx.no_prolog = is_monolithic;
 	ctx.no_epilog = is_monolithic;
 	ctx.separate_prolog = !is_monolithic;
 
 	if (ctx.type == PIPE_SHADER_VERTEX ||
+	    ctx.type == PIPE_SHADER_TESS_CTRL ||
 	    ctx.type == PIPE_SHADER_TESS_EVAL ||
 	    ctx.type == PIPE_SHADER_FRAGMENT) {
 		ctx.no_prolog = false;
 		ctx.no_epilog = false;
 	}
 
 	memset(shader->info.vs_output_param_offset, 0xff,
 	       sizeof(shader->info.vs_output_param_offset));
 
 	shader->info.uses_instanceid = sel->info.uses_instanceid;
@@ -7217,20 +7225,32 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
 
 		if (need_epilog) {
 			union si_shader_part_key epilog_key;
 			si_get_vs_epilog_key(shader, &shader->key.vs.epilog, &epilog_key);
 			si_build_vs_epilog_function(&ctx, &epilog_key);
 			parts[need_prolog ? 2 : 1] = ctx.main_fn;
 		}
 
 		si_build_wrapper_function(&ctx, parts, 1 + need_prolog + need_epilog,
 					  need_prolog ? 1 : 0);
+	} else if (is_monolithic && ctx.type == PIPE_SHADER_TESS_CTRL) {
+		LLVMValueRef parts[2];
+		union si_shader_part_key epilog_key;
+
+		parts[0] = ctx.main_fn;
+
+		memset(&epilog_key, 0, sizeof(epilog_key));
+		epilog_key.tcs_epilog.states = shader->key.tcs.epilog;
+		si_build_tcs_epilog_function(&ctx, &epilog_key);
+		parts[1] = ctx.main_fn;
+
+		si_build_wrapper_function(&ctx, parts, 2, 0);
 	} else if (is_monolithic && ctx.type == PIPE_SHADER_TESS_EVAL &&
 		   !shader->key.tes.as_es) {
 		LLVMValueRef parts[2];
 		union si_shader_part_key epilog_key;
 
 		parts[0] = ctx.main_fn;
 
 		si_get_vs_epilog_key(shader, &shader->key.tes.epilog, &epilog_key);
 		si_build_vs_epilog_function(&ctx, &epilog_key);
 		parts[1] = ctx.main_fn;
-- 
2.7.4



More information about the mesa-dev mailing list