[Mesa-dev] [PATCH 7/9] radeonsi: move color clamping to si_llvm_export_vs to unify the code
Marek Olšák
maraeo at gmail.com
Tue Jun 4 00:02:56 UTC 2019
From: Marek Olšák <marek.olsak at amd.com>
---
src/gallium/drivers/radeonsi/si_shader.c | 147 +++++++++++------------
1 file changed, 67 insertions(+), 80 deletions(-)
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);
--
2.17.1
More information about the mesa-dev
mailing list