[7/9] radeonsi: move color clamping to si_llvm_export_vs to unify the code

Submitted by Marek Olšák on June 4, 2019, 12:02 a.m.

Details

Message ID 20190604000258.9143-7-maraeo@gmail.com
State New
Headers show
Series "Series without cover letter" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Marek Olšák June 4, 2019, 12:02 a.m.
From: Marek Olšák <marek.olsak@amd.com>

---
 src/gallium/drivers/radeonsi/si_shader.c | 147 +++++++++++------------
 1 file changed, 67 insertions(+), 80 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 3610ec90a89..8c4f4e75653 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -2783,31 +2783,97 @@  static void si_build_param_exports(struct si_shader_context *ctx,
 
 		si_export_param(ctx, param_count, outputs[i].values);
 
 		assert(i < ARRAY_SIZE(shader->info.vs_output_param_offset));
 		shader->info.vs_output_param_offset[i] = param_count++;
 	}
 
 	shader->info.nr_param_exports = param_count;
 }
 
+/**
+ * Vertex color clamping.
+ *
+ * This uses a state constant loaded in a user data SGPR and
+ * an IF statement is added that clamps all colors if the constant
+ * is true.
+ */
+static void si_vertex_color_clamping(struct si_shader_context *ctx,
+				     struct si_shader_output_values *outputs,
+				     unsigned noutput)
+{
+	LLVMValueRef addr[SI_MAX_VS_OUTPUTS][4];
+	bool has_colors = false;
+
+	/* Store original colors to alloca variables. */
+	for (unsigned i = 0; i < noutput; i++) {
+		if (outputs[i].semantic_name != TGSI_SEMANTIC_COLOR &&
+		    outputs[i].semantic_name != TGSI_SEMANTIC_BCOLOR)
+			continue;
+
+		for (unsigned j = 0; j < 4; j++) {
+			addr[i][j] = ac_build_alloca_undef(&ctx->ac, ctx->f32, "");
+			LLVMBuildStore(ctx->ac.builder, outputs[i].values[j], addr[i][j]);
+		}
+		has_colors = true;
+	}
+
+	if (!has_colors)
+		return;
+
+	/* The state is in the first bit of the user SGPR. */
+	LLVMValueRef cond = LLVMGetParam(ctx->main_fn, ctx->param_vs_state_bits);
+	cond = LLVMBuildTrunc(ctx->ac.builder, cond, ctx->i1, "");
+
+	struct lp_build_if_state if_ctx;
+	lp_build_if(&if_ctx, &ctx->gallivm, cond);
+
+	/* Store clamped colors to alloca variables within the conditional block. */
+	for (unsigned i = 0; i < noutput; i++) {
+		if (outputs[i].semantic_name != TGSI_SEMANTIC_COLOR &&
+		    outputs[i].semantic_name != TGSI_SEMANTIC_BCOLOR)
+			continue;
+
+		for (unsigned j = 0; j < 4; j++) {
+			LLVMBuildStore(ctx->ac.builder,
+				       ac_build_clamp(&ctx->ac, outputs[i].values[j]),
+				       addr[i][j]);
+		}
+	}
+	lp_build_endif(&if_ctx);
+
+	/* Load clamped colors */
+	for (unsigned i = 0; i < noutput; i++) {
+		if (outputs[i].semantic_name != TGSI_SEMANTIC_COLOR &&
+		    outputs[i].semantic_name != TGSI_SEMANTIC_BCOLOR)
+			continue;
+
+		for (unsigned j = 0; j < 4; j++) {
+			outputs[i].values[j] =
+				LLVMBuildLoad(ctx->ac.builder, addr[i][j], "");
+		}
+	}
+}
+
 /* Generate export instructions for hardware VS shader stage */
 static void si_llvm_export_vs(struct si_shader_context *ctx,
 			      struct si_shader_output_values *outputs,
 			      unsigned noutput)
 {
 	struct si_shader *shader = ctx->shader;
 	struct ac_export_args pos_args[4] = {};
 	LLVMValueRef psize_value = NULL, edgeflag_value = NULL, layer_value = NULL, viewport_index_value = NULL;
 	unsigned pos_idx;
 	int i;
 
+	si_vertex_color_clamping(ctx, outputs, noutput);
+
 	/* Build position exports. */
 	for (i = 0; i < noutput; i++) {
 		switch (outputs[i].semantic_name) {
 		case TGSI_SEMANTIC_POSITION:
 			si_llvm_init_export_args(ctx, outputs[i].values,
 						 V_008DFC_SQ_EXP_POS, &pos_args[0]);
 			break;
 		case TGSI_SEMANTIC_PSIZE:
 			psize_value = outputs[i].values[0];
 			break;
@@ -3503,56 +3569,20 @@  static void si_llvm_emit_vs_epilogue(struct ac_shader_abi *abi,
 	struct si_shader_context *ctx = si_shader_context_from_abi(abi);
 	struct tgsi_shader_info *info = &ctx->shader->selector->info;
 	struct si_shader_output_values *outputs = NULL;
 	int i,j;
 
 	assert(!ctx->shader->is_gs_copy_shader);
 	assert(info->num_outputs <= max_outputs);
 
 	outputs = MALLOC((info->num_outputs + 1) * sizeof(outputs[0]));
 
-	/* Vertex color clamping.
-	 *
-	 * This uses a state constant loaded in a user data SGPR and
-	 * an IF statement is added that clamps all colors if the constant
-	 * is true.
-	 */
-	struct lp_build_if_state if_ctx;
-	LLVMValueRef cond = NULL;
-	LLVMValueRef addr, val;
-
-	for (i = 0; i < info->num_outputs; i++) {
-		if (info->output_semantic_name[i] != TGSI_SEMANTIC_COLOR &&
-		    info->output_semantic_name[i] != TGSI_SEMANTIC_BCOLOR)
-			continue;
-
-		/* We've found a color. */
-		if (!cond) {
-			/* The state is in the first bit of the user SGPR. */
-			cond = LLVMGetParam(ctx->main_fn,
-					    ctx->param_vs_state_bits);
-			cond = LLVMBuildTrunc(ctx->ac.builder, cond,
-					      ctx->i1, "");
-			lp_build_if(&if_ctx, &ctx->gallivm, cond);
-		}
-
-		for (j = 0; j < 4; j++) {
-			addr = addrs[4 * i + j];
-			val = LLVMBuildLoad(ctx->ac.builder, addr, "");
-			val = ac_build_clamp(&ctx->ac, val);
-			LLVMBuildStore(ctx->ac.builder, val, addr);
-		}
-	}
-
-	if (cond)
-		lp_build_endif(&if_ctx);
-
 	for (i = 0; i < info->num_outputs; i++) {
 		outputs[i].semantic_name = info->output_semantic_name[i];
 		outputs[i].semantic_index = info->output_semantic_index[i];
 
 		for (j = 0; j < 4; j++) {
 			outputs[i].values[j] =
 				LLVMBuildLoad(ctx->ac.builder,
 					      addrs[4 * i + j],
 					      "");
 			outputs[i].vertex_stream[j] =
@@ -5633,65 +5663,22 @@  si_generate_gs_copy_shader(struct si_screen *sscreen,
 			}
 		}
 
 		/* Streamout and exports. */
 		if (gs_selector->so.num_outputs) {
 			si_llvm_emit_streamout(&ctx, outputs,
 					       gsinfo->num_outputs,
 					       stream);
 		}
 
-		if (stream == 0) {
-			/* Vertex color clamping.
-			 *
-			 * This uses a state constant loaded in a user data SGPR and
-			 * an IF statement is added that clamps all colors if the constant
-			 * is true.
-			 */
-			struct lp_build_if_state if_ctx;
-			LLVMValueRef v[2], cond = NULL;
-			LLVMBasicBlockRef blocks[2];
-
-			for (unsigned i = 0; i < gsinfo->num_outputs; i++) {
-				if (gsinfo->output_semantic_name[i] != TGSI_SEMANTIC_COLOR &&
-				    gsinfo->output_semantic_name[i] != TGSI_SEMANTIC_BCOLOR)
-					continue;
-
-				/* We've found a color. */
-				if (!cond) {
-					/* The state is in the first bit of the user SGPR. */
-					cond = LLVMGetParam(ctx.main_fn,
-							    ctx.param_vs_state_bits);
-					cond = LLVMBuildTrunc(ctx.ac.builder, cond,
-							      ctx.i1, "");
-					lp_build_if(&if_ctx, &ctx.gallivm, cond);
-					/* Remember blocks for Phi. */
-					blocks[0] = if_ctx.true_block;
-					blocks[1] = if_ctx.entry_block;
-				}
-
-				for (unsigned j = 0; j < 4; j++) {
-					/* Insert clamp into the true block. */
-					v[0] = ac_build_clamp(&ctx.ac, outputs[i].values[j]);
-					v[1] = outputs[i].values[j];
-
-					/* Insert Phi into the endif block. */
-					LLVMPositionBuilderAtEnd(ctx.ac.builder, if_ctx.merge_block);
-					outputs[i].values[j] = ac_build_phi(&ctx.ac, ctx.f32, 2, v, blocks);
-					LLVMPositionBuilderAtEnd(ctx.ac.builder, if_ctx.true_block);
-				}
-			}
-			if (cond)
-				lp_build_endif(&if_ctx);
-
+		if (stream == 0)
 			si_llvm_export_vs(&ctx, outputs, gsinfo->num_outputs);
-		}
 
 		LLVMBuildBr(builder, end_bb);
 	}
 
 	LLVMPositionBuilderAtEnd(builder, end_bb);
 
 	LLVMBuildRetVoid(ctx.ac.builder);
 
 	ctx.type = PIPE_SHADER_GEOMETRY; /* override for shader dumping */
 	si_llvm_optimize_module(&ctx);