radeonsi: only use LLVMBuildLoad once when updating color outputs at the end
authorMarek Olšák <marek.olsak@amd.com>
Sun, 27 Dec 2015 16:53:44 +0000 (17:53 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 7 Jan 2016 17:26:06 +0000 (18:26 +0100)
without LLVMBuildStore.

So:
- do LLVMBuildLoad
- update the values as necessary
- export

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeonsi/si_shader.c

index 73a34ac254e6d55825dc49bb08aadae94ad87123..13e5140d4db1898d5946dc860e1c7f6292fe2d2c 100644 (file)
@@ -1334,24 +1334,8 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base,
                memcpy(&args[5], values, sizeof(values[0]) * 4);
 }
 
-/* Load from output pointers and initialize arguments for the shader export intrinsic */
-static void si_llvm_init_export_args_load(struct lp_build_tgsi_context *bld_base,
-                                         LLVMValueRef *out_ptr,
-                                         unsigned target,
-                                         LLVMValueRef *args)
-{
-       struct gallivm_state *gallivm = bld_base->base.gallivm;
-       LLVMValueRef values[4];
-       int i;
-
-       for (i = 0; i < 4; i++)
-               values[i] = LLVMBuildLoad(gallivm->builder, out_ptr[i], "");
-
-       si_llvm_init_export_args(bld_base, values, target, args);
-}
-
 static void si_alpha_test(struct lp_build_tgsi_context *bld_base,
-                         LLVMValueRef alpha_ptr)
+                         LLVMValueRef alpha)
 {
        struct si_shader_context *si_shader_ctx = si_shader_context(bld_base);
        struct gallivm_state *gallivm = bld_base->base.gallivm;
@@ -1363,8 +1347,7 @@ static void si_alpha_test(struct lp_build_tgsi_context *bld_base,
                LLVMValueRef alpha_pass =
                        lp_build_cmp(&bld_base->base,
                                     si_shader_ctx->shader->key.ps.alpha_func,
-                                    LLVMBuildLoad(gallivm->builder, alpha_ptr, ""),
-                                    alpha_ref);
+                                    alpha, alpha_ref);
                LLVMValueRef arg =
                        lp_build_select(&bld_base->base,
                                        alpha_pass,
@@ -1383,12 +1366,12 @@ static void si_alpha_test(struct lp_build_tgsi_context *bld_base,
        }
 }
 
-static void si_scale_alpha_by_sample_mask(struct lp_build_tgsi_context *bld_base,
-                                         LLVMValueRef alpha_ptr)
+static LLVMValueRef si_scale_alpha_by_sample_mask(struct lp_build_tgsi_context *bld_base,
+                                                 LLVMValueRef alpha)
 {
        struct si_shader_context *si_shader_ctx = si_shader_context(bld_base);
        struct gallivm_state *gallivm = bld_base->base.gallivm;
-       LLVMValueRef coverage, alpha;
+       LLVMValueRef coverage;
 
        /* alpha = alpha * popcount(coverage) / SI_NUM_SMOOTH_AA_SAMPLES */
        coverage = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn,
@@ -1406,9 +1389,7 @@ static void si_scale_alpha_by_sample_mask(struct lp_build_tgsi_context *bld_base
                                 lp_build_const_float(gallivm,
                                        1.0 / SI_NUM_SMOOTH_AA_SAMPLES), "");
 
-       alpha = LLVMBuildLoad(gallivm->builder, alpha_ptr, "");
-       alpha = LLVMBuildFMul(gallivm->builder, alpha, coverage, "");
-       LLVMBuildStore(gallivm->builder, alpha, alpha_ptr);
+       return LLVMBuildFMul(gallivm->builder, alpha, coverage, "");
 }
 
 static void si_llvm_emit_clipvertex(struct lp_build_tgsi_context * bld_base,
@@ -2196,8 +2177,8 @@ static void si_llvm_emit_fs_epilogue(struct lp_build_tgsi_context * bld_base)
        for (i = 0; i < info->num_outputs; i++) {
                unsigned semantic_name = info->output_semantic_name[i];
                unsigned semantic_index = info->output_semantic_index[i];
-               unsigned target;
-               LLVMValueRef alpha_ptr;
+               unsigned target, j;
+               LLVMValueRef color[4] = {};
 
                /* Select the correct target */
                switch (semantic_name) {
@@ -2215,29 +2196,24 @@ static void si_llvm_emit_fs_epilogue(struct lp_build_tgsi_context * bld_base)
                        continue;
                case TGSI_SEMANTIC_COLOR:
                        target = V_008DFC_SQ_EXP_MRT + semantic_index;
-                       alpha_ptr = si_shader_ctx->radeon_bld.soa.outputs[i][3];
 
-                       if (si_shader_ctx->shader->key.ps.clamp_color) {
-                               for (int j = 0; j < 4; j++) {
-                                       LLVMValueRef ptr = si_shader_ctx->radeon_bld.soa.outputs[i][j];
-                                       LLVMValueRef result = LLVMBuildLoad(builder, ptr, "");
+                       for (j = 0; j < 4; j++)
+                               color[j] = LLVMBuildLoad(builder,
+                                                        si_shader_ctx->radeon_bld.soa.outputs[i][j], "");
 
-                                       result = radeon_llvm_saturate(bld_base, result);
-                                       LLVMBuildStore(builder, result, ptr);
-                               }
-                       }
+                       if (si_shader_ctx->shader->key.ps.clamp_color)
+                               for (j = 0; j < 4; j++)
+                                       color[j] = radeon_llvm_saturate(bld_base, color[j]);
 
                        if (si_shader_ctx->shader->key.ps.alpha_to_one)
-                               LLVMBuildStore(base->gallivm->builder,
-                                              base->one, alpha_ptr);
+                               color[3] = base->one;
 
                        if (semantic_index == 0 &&
                            si_shader_ctx->shader->key.ps.alpha_func != PIPE_FUNC_ALWAYS)
-                               si_alpha_test(bld_base, alpha_ptr);
+                               si_alpha_test(bld_base, color[3]);
 
                        if (si_shader_ctx->shader->key.ps.poly_line_smoothing)
-                               si_scale_alpha_by_sample_mask(bld_base, alpha_ptr);
-
+                               color[3] = si_scale_alpha_by_sample_mask(bld_base, color[3]);
                        break;
                default:
                        fprintf(stderr,
@@ -2250,18 +2226,15 @@ static void si_llvm_emit_fs_epilogue(struct lp_build_tgsi_context * bld_base)
                if (semantic_index == 0 &&
                    si_shader_ctx->shader->key.ps.last_cbuf > 0) {
                        for (int c = 1; c <= si_shader_ctx->shader->key.ps.last_cbuf; c++) {
-                               si_llvm_init_export_args_load(bld_base,
-                                                             si_shader_ctx->radeon_bld.soa.outputs[i],
-                                                             V_008DFC_SQ_EXP_MRT + c, args);
+                               si_llvm_init_export_args(bld_base, color,
+                                                        V_008DFC_SQ_EXP_MRT + c, args);
                                lp_build_intrinsic(base->gallivm->builder, "llvm.SI.export",
                                                   LLVMVoidTypeInContext(base->gallivm->context),
                                                   args, 9, 0);
                        }
                }
 
-               si_llvm_init_export_args_load(bld_base,
-                                             si_shader_ctx->radeon_bld.soa.outputs[i],
-                                             target, args);
+               si_llvm_init_export_args(bld_base, color, target, args);
                if (last_color_export == i) {
                        args[1] = uint->one; /* whether the EXEC mask is valid */
                        args[2] = uint->one; /* DONE bit */