From: Marek Olšák <[email protected]>

---
 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

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to