[Mesa-dev] [PATCH 11/31] radeonsi: extract si_build_ps_epilog_function

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


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

---
 src/gallium/drivers/radeonsi/si_shader.c | 95 ++++++++++++++++++++------------
 1 file changed, 60 insertions(+), 35 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 81c361e..ec5f950 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -6751,20 +6751,36 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx,
 
 	if (!lp_build_tgsi_llvm(bld_base, sel->tokens)) {
 		fprintf(stderr, "Failed to translate shader from TGSI to LLVM\n");
 		return false;
 	}
 
 	si_llvm_build_ret(ctx, ctx->return_value);
 	return true;
 }
 
+/**
+ * Compute the PS epilog key, which contains all the information needed to
+ * build the PS epilog function.
+ */
+static void si_get_ps_epilog_key(struct si_shader *shader,
+				 union si_shader_part_key *key)
+{
+	struct tgsi_shader_info *info = &shader->selector->info;
+	memset(key, 0, sizeof(*key));
+	key->ps_epilog.colors_written = info->colors_written;
+	key->ps_epilog.writes_z = info->writes_z;
+	key->ps_epilog.writes_stencil = info->writes_stencil;
+	key->ps_epilog.writes_samplemask = info->writes_samplemask;
+	key->ps_epilog.states = shader->key.ps.epilog;
+}
+
 int si_compile_tgsi_shader(struct si_screen *sscreen,
 			   LLVMTargetMachineRef tm,
 			   struct si_shader *shader,
 			   bool is_monolithic,
 			   struct pipe_debug_callback *debug)
 {
 	struct si_shader_selector *sel = shader->selector;
 	struct si_shader_context ctx;
 	struct lp_build_tgsi_context *bld_base;
 	LLVMModuleRef mod;
@@ -7591,71 +7607,61 @@ static bool si_compile_ps_prolog(struct si_screen *sscreen,
 	if (si_compile_llvm(sscreen, &out->binary, &out->config, tm,
 			    gallivm->module, debug, ctx.type,
 			    "Fragment Shader Prolog"))
 		status = false;
 
 	si_llvm_dispose(&ctx);
 	return status;
 }
 
 /**
- * Compile the pixel shader epilog. This handles everything that must be
+ * Build the pixel shader epilog function. This handles everything that must be
  * emulated for pixel shader exports. (alpha-test, format conversions, etc)
  */
-static bool si_compile_ps_epilog(struct si_screen *sscreen,
-				 LLVMTargetMachineRef tm,
-				 struct pipe_debug_callback *debug,
-				 struct si_shader_part *out)
+static void si_build_ps_epilog_function(struct si_shader_context *ctx,
+					union si_shader_part_key *key)
 {
-	union si_shader_part_key *key = &out->key;
-	struct si_shader shader = {};
-	struct si_shader_context ctx;
-	struct gallivm_state *gallivm = &ctx.gallivm;
-	struct lp_build_tgsi_context *bld_base = &ctx.soa.bld_base;
+	struct gallivm_state *gallivm = &ctx->gallivm;
+	struct lp_build_tgsi_context *bld_base = &ctx->soa.bld_base;
 	LLVMTypeRef params[16+8*4+3];
 	LLVMValueRef depth = NULL, stencil = NULL, samplemask = NULL;
 	int last_sgpr, num_params, i;
-	bool status = true;
 	struct si_ps_exports exp = {};
 
-	si_init_shader_ctx(&ctx, sscreen, &shader, tm);
-	ctx.type = PIPE_SHADER_FRAGMENT;
-	shader.key.ps.epilog = key->ps_epilog.states;
-
 	/* Declare input SGPRs. */
-	params[SI_PARAM_RW_BUFFERS] = ctx.i64;
-	params[SI_PARAM_CONST_BUFFERS] = ctx.i64;
-	params[SI_PARAM_SAMPLERS] = ctx.i64;
-	params[SI_PARAM_IMAGES] = ctx.i64;
-	params[SI_PARAM_SHADER_BUFFERS] = ctx.i64;
-	params[SI_PARAM_ALPHA_REF] = ctx.f32;
+	params[SI_PARAM_RW_BUFFERS] = ctx->i64;
+	params[SI_PARAM_CONST_BUFFERS] = ctx->i64;
+	params[SI_PARAM_SAMPLERS] = ctx->i64;
+	params[SI_PARAM_IMAGES] = ctx->i64;
+	params[SI_PARAM_SHADER_BUFFERS] = ctx->i64;
+	params[SI_PARAM_ALPHA_REF] = ctx->f32;
 	last_sgpr = SI_PARAM_ALPHA_REF;
 
 	/* Declare input VGPRs. */
 	num_params = (last_sgpr + 1) +
 		     util_bitcount(key->ps_epilog.colors_written) * 4 +
 		     key->ps_epilog.writes_z +
 		     key->ps_epilog.writes_stencil +
 		     key->ps_epilog.writes_samplemask;
 
 	num_params = MAX2(num_params,
 			  last_sgpr + 1 + PS_EPILOG_SAMPLEMASK_MIN_LOC + 1);
 
 	assert(num_params <= ARRAY_SIZE(params));
 
 	for (i = last_sgpr + 1; i < num_params; i++)
-		params[i] = ctx.f32;
+		params[i] = ctx->f32;
 
 	/* Create the function. */
-	si_create_function(&ctx, "ps_epilog", NULL, 0, params, num_params, last_sgpr);
+	si_create_function(ctx, "ps_epilog", NULL, 0, params, num_params, last_sgpr);
 	/* Disable elimination of unused inputs. */
-	si_llvm_add_attribute(ctx.main_fn,
+	si_llvm_add_attribute(ctx->main_fn,
 				  "InitialPSInputAddr", 0xffffff);
 
 	/* Process colors. */
 	unsigned vgpr = last_sgpr + 1;
 	unsigned colors_written = key->ps_epilog.colors_written;
 	int last_color_export = -1;
 
 	/* Find the last color export. */
 	if (!key->ps_epilog.writes_z &&
 	    !key->ps_epilog.writes_stencil &&
@@ -7674,45 +7680,69 @@ static bool si_compile_ps_epilog(struct si_screen *sscreen,
 				    (spi_format >> (i * 4)) & 0xf)
 					last_color_export = i;
 		}
 	}
 
 	while (colors_written) {
 		LLVMValueRef color[4];
 		int mrt = u_bit_scan(&colors_written);
 
 		for (i = 0; i < 4; i++)
-			color[i] = LLVMGetParam(ctx.main_fn, vgpr++);
+			color[i] = LLVMGetParam(ctx->main_fn, vgpr++);
 
 		si_export_mrt_color(bld_base, color, mrt,
 				    num_params - 1,
 				    mrt == last_color_export, &exp);
 	}
 
 	/* Process depth, stencil, samplemask. */
 	if (key->ps_epilog.writes_z)
-		depth = LLVMGetParam(ctx.main_fn, vgpr++);
+		depth = LLVMGetParam(ctx->main_fn, vgpr++);
 	if (key->ps_epilog.writes_stencil)
-		stencil = LLVMGetParam(ctx.main_fn, vgpr++);
+		stencil = LLVMGetParam(ctx->main_fn, vgpr++);
 	if (key->ps_epilog.writes_samplemask)
-		samplemask = LLVMGetParam(ctx.main_fn, vgpr++);
+		samplemask = LLVMGetParam(ctx->main_fn, vgpr++);
 
 	if (depth || stencil || samplemask)
 		si_export_mrt_z(bld_base, depth, stencil, samplemask, &exp);
 	else if (last_color_export == -1)
 		si_export_null(bld_base);
 
 	if (exp.num)
-		si_emit_ps_exports(&ctx, &exp);
+		si_emit_ps_exports(ctx, &exp);
 
 	/* Compile. */
 	LLVMBuildRetVoid(gallivm->builder);
+}
+
+
+/**
+ * Compile the pixel shader epilog to a binary for concatenation.
+ */
+static bool si_compile_ps_epilog(struct si_screen *sscreen,
+				 LLVMTargetMachineRef tm,
+				 struct pipe_debug_callback *debug,
+				 struct si_shader_part *out)
+{
+	union si_shader_part_key *key = &out->key;
+	struct si_shader shader = {};
+	struct si_shader_context ctx;
+	struct gallivm_state *gallivm = &ctx.gallivm;
+	bool status = true;
+
+	si_init_shader_ctx(&ctx, sscreen, &shader, tm);
+	ctx.type = PIPE_SHADER_FRAGMENT;
+	shader.key.ps.epilog = key->ps_epilog.states;
+
+	si_build_ps_epilog_function(&ctx, key);
+
+	/* Compile. */
 	si_llvm_finalize_module(&ctx,
 		r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_FRAGMENT));
 
 	if (si_compile_llvm(sscreen, &out->binary, &out->config, tm,
 			    gallivm->module, debug, ctx.type,
 			    "Fragment Shader Epilog"))
 		status = false;
 
 	si_llvm_dispose(&ctx);
 	return status;
@@ -7845,26 +7875,21 @@ static bool si_shader_select_ps_parts(struct si_screen *sscreen,
 	    prolog_key.ps_prolog.states.poly_stipple) {
 		shader->prolog =
 			si_get_shader_part(sscreen, &sscreen->ps_prologs,
 					   &prolog_key, tm, debug,
 					   si_compile_ps_prolog);
 		if (!shader->prolog)
 			return false;
 	}
 
 	/* Get the epilog. */
-	memset(&epilog_key, 0, sizeof(epilog_key));
-	epilog_key.ps_epilog.colors_written = info->colors_written;
-	epilog_key.ps_epilog.writes_z = info->writes_z;
-	epilog_key.ps_epilog.writes_stencil = info->writes_stencil;
-	epilog_key.ps_epilog.writes_samplemask = info->writes_samplemask;
-	epilog_key.ps_epilog.states = shader->key.ps.epilog;
+	si_get_ps_epilog_key(shader, &epilog_key);
 
 	shader->epilog =
 		si_get_shader_part(sscreen, &sscreen->ps_epilogs,
 				   &epilog_key, tm, debug,
 				   si_compile_ps_epilog);
 	if (!shader->epilog)
 		return false;
 
 	/* Enable POS_FIXED_PT if polygon stippling is enabled. */
 	if (shader->key.ps.prolog.poly_stipple) {
-- 
2.7.4



More information about the mesa-dev mailing list