radeonsi: move color clamping to si_llvm_export_vs to unify the code
authorMarek Olšák <marek.olsak@amd.com>
Mon, 3 Jun 2019 18:51:08 +0000 (14:51 -0400)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 12 Jun 2019 00:05:21 +0000 (20:05 -0400)
src/gallium/drivers/radeonsi/si_shader.c

index 3610ec90a89c9cd2aa8566cb3d8a70a75996e6d8..8c4f4e756535086b99d40450a3a0dbb217632b91 100644 (file)
@@ -2790,6 +2790,70 @@ static void si_build_param_exports(struct si_shader_context *ctx,
        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,
@@ -2801,6 +2865,8 @@ static void si_llvm_export_vs(struct si_shader_context *ctx,
        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) {
@@ -3510,42 +3576,6 @@ static void si_llvm_emit_vs_epilogue(struct ac_shader_abi *abi,
 
        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];
@@ -5640,51 +5670,8 @@ si_generate_gs_copy_shader(struct si_screen *sscreen,
                                               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);
        }