From: Marek Olšák <marek.ol...@amd.com>

---
 src/amd/common/ac_llvm_build.c           |  15 ++
 src/amd/common/ac_llvm_build.h           |  11 ++
 src/gallium/drivers/radeonsi/si_shader.c | 306 +++++++++++++++----------------
 3 files changed, 170 insertions(+), 162 deletions(-)

diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c
index 114cb0c..fae5510 100644
--- a/src/amd/common/ac_llvm_build.c
+++ b/src/amd/common/ac_llvm_build.c
@@ -879,10 +879,25 @@ LLVMValueRef ac_emit_clamp(struct ac_llvm_context *ctx, 
LLVMValueRef value)
        LLVMValueRef args[3] = {
                value,
                LLVMConstReal(ctx->f32, 0),
                LLVMConstReal(ctx->f32, 1),
        };
 
        return ac_emit_llvm_intrinsic(ctx, intr, ctx->f32, args, 3,
                                      AC_FUNC_ATTR_READNONE |
                                      AC_FUNC_ATTR_LEGACY);
 }
+
+void ac_emit_export(struct ac_llvm_context *ctx, struct ac_export_args *a)
+{
+       LLVMValueRef args[9];
+
+       args[0] = LLVMConstInt(ctx->i32, a->enabled_channels, 0);
+       args[1] = LLVMConstInt(ctx->i32, a->valid_mask, 0);
+       args[2] = LLVMConstInt(ctx->i32, a->done, 0);
+       args[3] = LLVMConstInt(ctx->i32, a->target, 0);
+       args[4] = LLVMConstInt(ctx->i32, a->compr, 0);
+       memcpy(args + 5, a->out, sizeof(a->out[0]) * 4);
+
+       ac_emit_llvm_intrinsic(ctx, "llvm.SI.export", ctx->voidt, args, 9,
+                              AC_FUNC_ATTR_LEGACY);
+}
diff --git a/src/amd/common/ac_llvm_build.h b/src/amd/common/ac_llvm_build.h
index 46da79e..27f2097 100644
--- a/src/amd/common/ac_llvm_build.h
+++ b/src/amd/common/ac_llvm_build.h
@@ -187,15 +187,26 @@ void ac_emit_sendmsg(struct ac_llvm_context *ctx,
 LLVMValueRef ac_emit_imsb(struct ac_llvm_context *ctx,
                          LLVMValueRef arg,
                          LLVMTypeRef dst_type);
 
 LLVMValueRef ac_emit_umsb(struct ac_llvm_context *ctx,
                          LLVMValueRef arg,
                          LLVMTypeRef dst_type);
 
 LLVMValueRef ac_emit_clamp(struct ac_llvm_context *ctx, LLVMValueRef value);
 
+struct ac_export_args {
+       LLVMValueRef out[4];
+        unsigned target;
+        unsigned enabled_channels;
+        bool compr;
+        bool done;
+        bool valid_mask;
+};
+
+void ac_emit_export(struct ac_llvm_context *ctx, struct ac_export_args *a);
+
 #ifdef __cplusplus
 }
 #endif
 
 #endif
diff --git a/src/gallium/drivers/radeonsi/si_shader.c 
b/src/gallium/drivers/radeonsi/si_shader.c
index 21efaa4..61e05d5 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -1742,120 +1742,119 @@ static LLVMValueRef 
si_llvm_pack_two_int32_as_int16(struct gallivm_state *galliv
                             lp_build_const_int32(gallivm, 0xffff), ""),
                val[1],
        };
        return si_llvm_pack_two_int16(gallivm, v);
 }
 
 /* Initialize arguments for the shader export intrinsic */
 static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base,
                                     LLVMValueRef *values,
                                     unsigned target,
-                                    LLVMValueRef *args)
+                                    struct ac_export_args *args)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
-       struct lp_build_context *uint = &ctx->bld_base.uint_bld;
        struct lp_build_context *base = &bld_base->base;
        struct gallivm_state *gallivm = base->gallivm;
        LLVMBuilderRef builder = base->gallivm->builder;
        LLVMValueRef val[4];
        unsigned spi_shader_col_format = V_028714_SPI_SHADER_32_ABGR;
        unsigned chan;
        bool is_int8, is_int10;
 
        /* Default is 0xf. Adjusted below depending on the format. */
-       args[0] = lp_build_const_int32(base->gallivm, 0xf); /* writemask */
+       args->enabled_channels = 0xf; /* writemask */
 
        /* Specify whether the EXEC mask represents the valid mask */
-       args[1] = uint->zero;
+       args->valid_mask = 0;
 
        /* Specify whether this is the last export */
-       args[2] = uint->zero;
+       args->done = 0;
 
        /* Specify the target we are exporting */
-       args[3] = lp_build_const_int32(base->gallivm, target);
+       args->target = target;
 
        if (ctx->type == PIPE_SHADER_FRAGMENT) {
                const struct si_shader_key *key = &ctx->shader->key;
                unsigned col_formats = 
key->part.ps.epilog.spi_shader_col_format;
                int cbuf = target - V_008DFC_SQ_EXP_MRT;
 
                assert(cbuf >= 0 && cbuf < 8);
                spi_shader_col_format = (col_formats >> (cbuf * 4)) & 0xf;
                is_int8 = (key->part.ps.epilog.color_is_int8 >> cbuf) & 0x1;
                is_int10 = (key->part.ps.epilog.color_is_int10 >> cbuf) & 0x1;
        }
 
-       args[4] = uint->zero; /* COMPR flag */
-       args[5] = base->undef;
-       args[6] = base->undef;
-       args[7] = base->undef;
-       args[8] = base->undef;
+       args->compr = false;
+       args->out[0] = base->undef;
+       args->out[1] = base->undef;
+       args->out[2] = base->undef;
+       args->out[3] = base->undef;
 
        switch (spi_shader_col_format) {
        case V_028714_SPI_SHADER_ZERO:
-               args[0] = uint->zero; /* writemask */
-               args[3] = lp_build_const_int32(base->gallivm, 
V_008DFC_SQ_EXP_NULL);
+               args->enabled_channels = 0; /* writemask */
+               args->target = V_008DFC_SQ_EXP_NULL;
                break;
 
        case V_028714_SPI_SHADER_32_R:
-               args[0] = uint->one; /* writemask */
-               args[5] = values[0];
+               args->enabled_channels = 1; /* writemask */
+               args->out[0] = values[0];
                break;
 
        case V_028714_SPI_SHADER_32_GR:
-               args[0] = lp_build_const_int32(base->gallivm, 0x3); /* 
writemask */
-               args[5] = values[0];
-               args[6] = values[1];
+               args->enabled_channels = 0x3; /* writemask */
+               args->out[0] = values[0];
+               args->out[1] = values[1];
                break;
 
        case V_028714_SPI_SHADER_32_AR:
-               args[0] = lp_build_const_int32(base->gallivm, 0x9); /* 
writemask */
-               args[5] = values[0];
-               args[8] = values[3];
+               args->enabled_channels = 0x9; /* writemask */
+               args->out[0] = values[0];
+               args->out[3] = values[3];
                break;
 
        case V_028714_SPI_SHADER_FP16_ABGR:
-               args[4] = uint->one; /* COMPR flag */
+               args->compr = 1; /* COMPR flag */
 
                for (chan = 0; chan < 2; chan++) {
                        LLVMValueRef pack_args[2] = {
                                values[2 * chan],
                                values[2 * chan + 1]
                        };
                        LLVMValueRef packed;
 
                        packed = lp_build_intrinsic(base->gallivm->builder,
                                                    "llvm.SI.packf16",
                                                    ctx->i32, pack_args, 2,
                                                    LP_FUNC_ATTR_READNONE |
                                                    LP_FUNC_ATTR_LEGACY);
-                       args[chan + 5] =
+                       args->out[chan] =
                                LLVMBuildBitCast(base->gallivm->builder,
                                                 packed, ctx->f32, "");
                }
                break;
 
        case V_028714_SPI_SHADER_UNORM16_ABGR:
                for (chan = 0; chan < 4; chan++) {
                        val[chan] = ac_emit_clamp(&ctx->ac, values[chan]);
                        val[chan] = LLVMBuildFMul(builder, val[chan],
                                                  lp_build_const_float(gallivm, 
65535), "");
                        val[chan] = LLVMBuildFAdd(builder, val[chan],
                                                  lp_build_const_float(gallivm, 
0.5), "");
                        val[chan] = LLVMBuildFPToUI(builder, val[chan],
                                                    ctx->i32, "");
                }
 
-               args[4] = uint->one; /* COMPR flag */
-               args[5] = bitcast(bld_base, TGSI_TYPE_FLOAT,
+               args->compr = 1; /* COMPR flag */
+               args->out[0] = bitcast(bld_base, TGSI_TYPE_FLOAT,
                                  si_llvm_pack_two_int16(gallivm, val));
-               args[6] = bitcast(bld_base, TGSI_TYPE_FLOAT,
+               args->out[1] = bitcast(bld_base, TGSI_TYPE_FLOAT,
                                  si_llvm_pack_two_int16(gallivm, val+2));
                break;
 
        case V_028714_SPI_SHADER_SNORM16_ABGR:
                for (chan = 0; chan < 4; chan++) {
                        /* Clamp between [-1, 1]. */
                        val[chan] = lp_build_emit_llvm_binary(bld_base, 
TGSI_OPCODE_MIN,
                                                              values[chan],
                                                              
lp_build_const_float(gallivm, 1));
                        val[chan] = lp_build_emit_llvm_binary(bld_base, 
TGSI_OPCODE_MAX,
@@ -1867,45 +1866,45 @@ static void si_llvm_init_export_args(struct 
lp_build_tgsi_context *bld_base,
                        /* If positive, add 0.5, else add -0.5. */
                        val[chan] = LLVMBuildFAdd(builder, val[chan],
                                        LLVMBuildSelect(builder,
                                                LLVMBuildFCmp(builder, 
LLVMRealOGE,
                                                              val[chan], 
base->zero, ""),
                                                lp_build_const_float(gallivm, 
0.5),
                                                lp_build_const_float(gallivm, 
-0.5), ""), "");
                        val[chan] = LLVMBuildFPToSI(builder, val[chan], 
ctx->i32, "");
                }
 
-               args[4] = uint->one; /* COMPR flag */
-               args[5] = bitcast(bld_base, TGSI_TYPE_FLOAT,
+               args->compr = 1; /* COMPR flag */
+               args->out[0] = bitcast(bld_base, TGSI_TYPE_FLOAT,
                                  si_llvm_pack_two_int32_as_int16(gallivm, 
val));
-               args[6] = bitcast(bld_base, TGSI_TYPE_FLOAT,
+               args->out[1] = bitcast(bld_base, TGSI_TYPE_FLOAT,
                                  si_llvm_pack_two_int32_as_int16(gallivm, 
val+2));
                break;
 
        case V_028714_SPI_SHADER_UINT16_ABGR: {
                LLVMValueRef max_rgb = lp_build_const_int32(gallivm,
                        is_int8 ? 255 : is_int10 ? 1023 : 65535);
                LLVMValueRef max_alpha =
                        !is_int10 ? max_rgb : lp_build_const_int32(gallivm, 3);
 
                /* Clamp. */
                for (chan = 0; chan < 4; chan++) {
                        val[chan] = bitcast(bld_base, TGSI_TYPE_UNSIGNED, 
values[chan]);
                        val[chan] = lp_build_emit_llvm_binary(bld_base, 
TGSI_OPCODE_UMIN,
                                        val[chan],
                                        chan == 3 ? max_alpha : max_rgb);
                }
 
-               args[4] = uint->one; /* COMPR flag */
-               args[5] = bitcast(bld_base, TGSI_TYPE_FLOAT,
+               args->compr = 1; /* COMPR flag */
+               args->out[0] = bitcast(bld_base, TGSI_TYPE_FLOAT,
                                  si_llvm_pack_two_int16(gallivm, val));
-               args[6] = bitcast(bld_base, TGSI_TYPE_FLOAT,
+               args->out[1] = bitcast(bld_base, TGSI_TYPE_FLOAT,
                                  si_llvm_pack_two_int16(gallivm, val+2));
                break;
        }
 
        case V_028714_SPI_SHADER_SINT16_ABGR: {
                LLVMValueRef max_rgb = lp_build_const_int32(gallivm,
                        is_int8 ? 127 : is_int10 ? 511 : 32767);
                LLVMValueRef min_rgb = lp_build_const_int32(gallivm,
                        is_int8 ? -128 : is_int10 ? -512 : -32768);
                LLVMValueRef max_alpha =
@@ -1917,30 +1916,30 @@ static void si_llvm_init_export_args(struct 
lp_build_tgsi_context *bld_base,
                for (chan = 0; chan < 4; chan++) {
                        val[chan] = bitcast(bld_base, TGSI_TYPE_UNSIGNED, 
values[chan]);
                        val[chan] = lp_build_emit_llvm_binary(bld_base,
                                        TGSI_OPCODE_IMIN,
                                        val[chan], chan == 3 ? max_alpha : 
max_rgb);
                        val[chan] = lp_build_emit_llvm_binary(bld_base,
                                        TGSI_OPCODE_IMAX,
                                        val[chan], chan == 3 ? min_alpha : 
min_rgb);
                }
 
-               args[4] = uint->one; /* COMPR flag */
-               args[5] = bitcast(bld_base, TGSI_TYPE_FLOAT,
+               args->compr = 1; /* COMPR flag */
+               args->out[0] = bitcast(bld_base, TGSI_TYPE_FLOAT,
                                  si_llvm_pack_two_int32_as_int16(gallivm, 
val));
-               args[6] = bitcast(bld_base, TGSI_TYPE_FLOAT,
+               args->out[1] = bitcast(bld_base, TGSI_TYPE_FLOAT,
                                  si_llvm_pack_two_int32_as_int16(gallivm, 
val+2));
                break;
        }
 
        case V_028714_SPI_SHADER_32_ABGR:
-               memcpy(&args[5], values, sizeof(values[0]) * 4);
+               memcpy(&args->out[0], values, sizeof(values[0]) * 4);
                break;
        }
 }
 
 static void si_alpha_test(struct lp_build_tgsi_context *bld_base,
                          LLVMValueRef alpha)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct gallivm_state *gallivm = bld_base->base.gallivm;
 
@@ -1987,63 +1986,61 @@ static LLVMValueRef 
si_scale_alpha_by_sample_mask(struct lp_build_tgsi_context *
                                   ctx->f32, "");
 
        coverage = LLVMBuildFMul(gallivm->builder, coverage,
                                 lp_build_const_float(gallivm,
                                        1.0 / SI_NUM_SMOOTH_AA_SAMPLES), "");
 
        return LLVMBuildFMul(gallivm->builder, alpha, coverage, "");
 }
 
 static void si_llvm_emit_clipvertex(struct lp_build_tgsi_context *bld_base,
-                                   LLVMValueRef (*pos)[9], LLVMValueRef 
*out_elts)
+                                   struct ac_export_args *pos, LLVMValueRef 
*out_elts)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct lp_build_context *base = &bld_base->base;
-       struct lp_build_context *uint = &ctx->bld_base.uint_bld;
        unsigned reg_index;
        unsigned chan;
        unsigned const_chan;
        LLVMValueRef base_elt;
        LLVMValueRef ptr = LLVMGetParam(ctx->main_fn, SI_PARAM_RW_BUFFERS);
        LLVMValueRef constbuf_index = lp_build_const_int32(base->gallivm,
                                                           
SI_VS_CONST_CLIP_PLANES);
        LLVMValueRef const_resource = ac_build_indexed_load_const(&ctx->ac, 
ptr, constbuf_index);
 
        for (reg_index = 0; reg_index < 2; reg_index ++) {
-               LLVMValueRef *args = pos[2 + reg_index];
+               struct ac_export_args *args = &pos[2 + reg_index];
 
-               args[5] =
-               args[6] =
-               args[7] =
-               args[8] = lp_build_const_float(base->gallivm, 0.0f);
+               args->out[0] =
+               args->out[1] =
+               args->out[2] =
+               args->out[3] = lp_build_const_float(base->gallivm, 0.0f);
 
                /* Compute dot products of position and user clip plane vectors 
*/
                for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
                        for (const_chan = 0; const_chan < TGSI_NUM_CHANNELS; 
const_chan++) {
-                               args[1] = lp_build_const_int32(base->gallivm,
-                                                              ((reg_index * 4 
+ chan) * 4 +
-                                                               const_chan) * 
4);
+                               LLVMValueRef addr =
+                                       LLVMConstInt(ctx->i32, ((reg_index * 4 
+ chan) * 4 +
+                                                               const_chan) * 
4, 0);
                                base_elt = buffer_load_const(ctx, 
const_resource,
-                                                            args[1]);
-                               args[5 + chan] =
-                                       lp_build_add(base, args[5 + chan],
+                                                            addr);
+                               args->out[chan] =
+                                       lp_build_add(base, args->out[chan],
                                                     lp_build_mul(base, 
base_elt,
                                                                  
out_elts[const_chan]));
                        }
                }
 
-               args[0] = lp_build_const_int32(base->gallivm, 0xf);
-               args[1] = uint->zero;
-               args[2] = uint->zero;
-               args[3] = lp_build_const_int32(base->gallivm,
-                                              V_008DFC_SQ_EXP_POS + 2 + 
reg_index);
-               args[4] = uint->zero;
+               args->enabled_channels = 0xf;
+               args->valid_mask = 0;
+               args->done = 0;
+               args->target = V_008DFC_SQ_EXP_POS + 2 + reg_index;
+               args->compr = 0;
        }
 }
 
 static void si_dump_streamout(struct pipe_stream_output_info *so)
 {
        unsigned i;
 
        if (so->num_outputs)
                fprintf(stderr, "STREAMOUT\n");
 
@@ -2199,23 +2196,21 @@ static void si_llvm_emit_streamout(struct 
si_shader_context *ctx,
 
 
 /* Generate export instructions for hardware VS shader stage */
 static void si_llvm_export_vs(struct lp_build_tgsi_context *bld_base,
                              struct si_shader_output_values *outputs,
                              unsigned noutput)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct si_shader *shader = ctx->shader;
        struct lp_build_context *base = &bld_base->base;
-       struct lp_build_context *uint = &ctx->bld_base.uint_bld;
-       LLVMValueRef args[9];
-       LLVMValueRef pos_args[4][9] = { { 0 } };
+       struct ac_export_args args, pos_args[4] = {};
        LLVMValueRef psize_value = NULL, edgeflag_value = NULL, layer_value = 
NULL, viewport_index_value = NULL;
        unsigned semantic_name, semantic_index;
        unsigned target;
        unsigned param_count = 0;
        unsigned pos_idx;
        int i;
 
        for (i = 0; i < noutput; i++) {
                semantic_name = outputs[i].semantic_name;
                semantic_index = outputs[i].semantic_index;
@@ -2291,117 +2286,112 @@ handle_semantic:
                        shader->info.vs_output_param_offset[i] = param_count;
                        param_count++;
                        break;
                default:
                        target = 0;
                        fprintf(stderr,
                                "Warning: SI unhandled vs output type:%d\n",
                                semantic_name);
                }
 
-               si_llvm_init_export_args(bld_base, outputs[i].values, target, 
args);
+               si_llvm_init_export_args(bld_base, outputs[i].values, target, 
&args);
 
                if (target >= V_008DFC_SQ_EXP_POS &&
                    target <= (V_008DFC_SQ_EXP_POS + 3)) {
-                       memcpy(pos_args[target - V_008DFC_SQ_EXP_POS],
-                              args, sizeof(args));
+                       memcpy(&pos_args[target - V_008DFC_SQ_EXP_POS],
+                              &args, sizeof(args));
                } else {
-                       lp_build_intrinsic(base->gallivm->builder,
-                                          "llvm.SI.export", ctx->voidt,
-                                          args, 9, LP_FUNC_ATTR_LEGACY);
+                       ac_emit_export(&ctx->ac, &args);
                }
 
                if (semantic_name == TGSI_SEMANTIC_CLIPDIST) {
                        semantic_name = TGSI_SEMANTIC_GENERIC;
                        goto handle_semantic;
                }
        }
 
        shader->info.nr_param_exports = param_count;
 
        /* We need to add the position output manually if it's missing. */
-       if (!pos_args[0][0]) {
-               pos_args[0][0] = lp_build_const_int32(base->gallivm, 0xf); /* 
writemask */
-               pos_args[0][1] = uint->zero; /* EXEC mask */
-               pos_args[0][2] = uint->zero; /* last export? */
-               pos_args[0][3] = lp_build_const_int32(base->gallivm, 
V_008DFC_SQ_EXP_POS);
-               pos_args[0][4] = uint->zero; /* COMPR flag */
-               pos_args[0][5] = base->zero; /* X */
-               pos_args[0][6] = base->zero; /* Y */
-               pos_args[0][7] = base->zero; /* Z */
-               pos_args[0][8] = base->one;  /* W */
+       if (!pos_args[0].out[0]) {
+               pos_args[0].enabled_channels = 0xf; /* writemask */
+               pos_args[0].valid_mask = 0; /* EXEC mask */
+               pos_args[0].done = 0; /* last export? */
+               pos_args[0].target = V_008DFC_SQ_EXP_POS;
+               pos_args[0].compr = 0; /* COMPR flag */
+               pos_args[0].out[0] = base->zero; /* X */
+               pos_args[0].out[1] = base->zero; /* Y */
+               pos_args[0].out[2] = base->zero; /* Z */
+               pos_args[0].out[3] = base->one;  /* W */
        }
 
        /* Write the misc vector (point size, edgeflag, layer, viewport). */
        if (shader->selector->info.writes_psize ||
            shader->selector->info.writes_edgeflag ||
            shader->selector->info.writes_viewport_index ||
            shader->selector->info.writes_layer) {
-               pos_args[1][0] = lp_build_const_int32(base->gallivm, /* 
writemask */
-                                                     
shader->selector->info.writes_psize |
-                                                     
(shader->selector->info.writes_edgeflag << 1) |
-                                                     
(shader->selector->info.writes_layer << 2) |
-                                                     
(shader->selector->info.writes_viewport_index << 3));
-               pos_args[1][1] = uint->zero; /* EXEC mask */
-               pos_args[1][2] = uint->zero; /* last export? */
-               pos_args[1][3] = lp_build_const_int32(base->gallivm, 
V_008DFC_SQ_EXP_POS + 1);
-               pos_args[1][4] = uint->zero; /* COMPR flag */
-               pos_args[1][5] = base->zero; /* X */
-               pos_args[1][6] = base->zero; /* Y */
-               pos_args[1][7] = base->zero; /* Z */
-               pos_args[1][8] = base->zero; /* W */
+               pos_args[1].enabled_channels = 
shader->selector->info.writes_psize |
+                                              
(shader->selector->info.writes_edgeflag << 1) |
+                                              
(shader->selector->info.writes_layer << 2) |
+                                              
(shader->selector->info.writes_viewport_index << 3);
+               pos_args[1].valid_mask = 0; /* EXEC mask */
+               pos_args[1].done = 0; /* last export? */
+               pos_args[1].target = V_008DFC_SQ_EXP_POS + 1;
+               pos_args[1].compr = 0; /* COMPR flag */
+               pos_args[1].out[0] = base->zero; /* X */
+               pos_args[1].out[1] = base->zero; /* Y */
+               pos_args[1].out[2] = base->zero; /* Z */
+               pos_args[1].out[3] = base->zero; /* W */
 
                if (shader->selector->info.writes_psize)
-                       pos_args[1][5] = psize_value;
+                       pos_args[1].out[0] = psize_value;
 
                if (shader->selector->info.writes_edgeflag) {
                        /* The output is a float, but the hw expects an integer
                         * with the first bit containing the edge flag. */
                        edgeflag_value = LLVMBuildFPToUI(base->gallivm->builder,
                                                         edgeflag_value,
                                                         ctx->i32, "");
                        edgeflag_value = lp_build_min(&bld_base->int_bld,
                                                      edgeflag_value,
                                                      bld_base->int_bld.one);
 
                        /* The LLVM intrinsic expects a float. */
-                       pos_args[1][6] = 
LLVMBuildBitCast(base->gallivm->builder,
+                       pos_args[1].out[1] = 
LLVMBuildBitCast(base->gallivm->builder,
                                                          edgeflag_value,
                                                          ctx->f32, "");
                }
 
                if (shader->selector->info.writes_layer)
-                       pos_args[1][7] = layer_value;
+                       pos_args[1].out[2] = layer_value;
 
                if (shader->selector->info.writes_viewport_index)
-                       pos_args[1][8] = viewport_index_value;
+                       pos_args[1].out[3] = viewport_index_value;
        }
 
        for (i = 0; i < 4; i++)
-               if (pos_args[i][0])
+               if (pos_args[i].out[0])
                        shader->info.nr_pos_exports++;
 
        pos_idx = 0;
        for (i = 0; i < 4; i++) {
-               if (!pos_args[i][0])
+               if (!pos_args[i].out[0])
                        continue;
 
                /* Specify the target we are exporting */
-               pos_args[i][3] = lp_build_const_int32(base->gallivm, 
V_008DFC_SQ_EXP_POS + pos_idx++);
+               pos_args[i].target = V_008DFC_SQ_EXP_POS + pos_idx++;
 
                if (pos_idx == shader->info.nr_pos_exports)
                        /* Specify that this is the last export */
-                       pos_args[i][2] = uint->one;
+                       pos_args[i].done = 1;
 
-               lp_build_intrinsic(base->gallivm->builder, "llvm.SI.export",
-                                  ctx->voidt, pos_args[i], 9,
-                                  LP_FUNC_ATTR_LEGACY);
+               ac_emit_export(&ctx->ac, &pos_args[i]);
        }
 }
 
 /**
  * Forward all outputs from the vertex shader to the TES. This is only used
  * for the fixed function TCS.
  */
 static void si_copy_tcs_inputs(struct lp_build_tgsi_context *bld_base)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
@@ -2811,21 +2801,21 @@ static void si_llvm_emit_vs_epilogue(struct 
lp_build_tgsi_context *bld_base)
                                     VS_EPILOG_PRIMID_LOC, "");
 
        if (ctx->shader->selector->so.num_outputs)
                si_llvm_emit_streamout(ctx, outputs, i, 0);
        si_llvm_export_vs(bld_base, outputs, i);
        FREE(outputs);
 }
 
 struct si_ps_exports {
        unsigned num;
-       LLVMValueRef args[10][9];
+       struct ac_export_args args[10];
 };
 
 unsigned si_get_spi_shader_z_format(bool writes_z, bool writes_stencil,
                                    bool writes_samplemask)
 {
        if (writes_z) {
                /* Z needs 32 bits. */
                if (writes_samplemask)
                        return V_028710_SPI_SHADER_32_ABGR;
                else if (writes_stencil)
@@ -2839,84 +2829,83 @@ unsigned si_get_spi_shader_z_format(bool writes_z, bool 
writes_stencil,
                return V_028710_SPI_SHADER_ZERO;
        }
 }
 
 static void si_export_mrt_z(struct lp_build_tgsi_context *bld_base,
                            LLVMValueRef depth, LLVMValueRef stencil,
                            LLVMValueRef samplemask, struct si_ps_exports *exp)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct lp_build_context *base = &bld_base->base;
-       struct lp_build_context *uint = &bld_base->uint_bld;
-       LLVMValueRef args[9];
+       struct ac_export_args args;
        unsigned mask = 0;
        unsigned format = si_get_spi_shader_z_format(depth != NULL,
                                                     stencil != NULL,
                                                     samplemask != NULL);
 
        assert(depth || stencil || samplemask);
 
-       args[1] = uint->one; /* whether the EXEC mask is valid */
-       args[2] = uint->one; /* DONE bit */
+       args.valid_mask = 1; /* whether the EXEC mask is valid */
+       args.done = 1; /* DONE bit */
 
        /* Specify the target we are exporting */
-       args[3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_MRTZ);
+       args.target = V_008DFC_SQ_EXP_MRTZ;
 
-       args[4] = uint->zero; /* COMP flag */
-       args[5] = base->undef; /* R, depth */
-       args[6] = base->undef; /* G, stencil test value[0:7], stencil op 
value[8:15] */
-       args[7] = base->undef; /* B, sample mask */
-       args[8] = base->undef; /* A, alpha to mask */
+       args.compr = 0; /* COMP flag */
+       args.out[0] = base->undef; /* R, depth */
+       args.out[1] = base->undef; /* G, stencil test value[0:7], stencil op 
value[8:15] */
+       args.out[2] = base->undef; /* B, sample mask */
+       args.out[3] = base->undef; /* A, alpha to mask */
 
        if (format == V_028710_SPI_SHADER_UINT16_ABGR) {
                assert(!depth);
-               args[4] = uint->one; /* COMPR flag */
+               args.compr = 1; /* COMPR flag */
 
                if (stencil) {
                        /* Stencil should be in X[23:16]. */
                        stencil = bitcast(bld_base, TGSI_TYPE_UNSIGNED, 
stencil);
                        stencil = LLVMBuildShl(base->gallivm->builder, stencil,
                                               LLVMConstInt(ctx->i32, 16, 0), 
"");
-                       args[5] = bitcast(bld_base, TGSI_TYPE_FLOAT, stencil);
+                       args.out[0] = bitcast(bld_base, TGSI_TYPE_FLOAT, 
stencil);
                        mask |= 0x3;
                }
                if (samplemask) {
                        /* SampleMask should be in Y[15:0]. */
-                       args[6] = samplemask;
+                       args.out[1] = samplemask;
                        mask |= 0xc;
                }
        } else {
                if (depth) {
-                       args[5] = depth;
+                       args.out[0] = depth;
                        mask |= 0x1;
                }
                if (stencil) {
-                       args[6] = stencil;
+                       args.out[1] = stencil;
                        mask |= 0x2;
                }
                if (samplemask) {
-                       args[7] = samplemask;
+                       args.out[2] = samplemask;
                        mask |= 0x4;
                }
        }
 
        /* SI (except OLAND and HAINAN) has a bug that it only looks
         * at the X writemask component. */
        if (ctx->screen->b.chip_class == SI &&
            ctx->screen->b.family != CHIP_OLAND &&
            ctx->screen->b.family != CHIP_HAINAN)
                mask |= 0x1;
 
        /* Specify which components to enable */
-       args[0] = lp_build_const_int32(base->gallivm, mask);
+       args.enabled_channels = mask;
 
-       memcpy(exp->args[exp->num++], args, sizeof(args));
+       memcpy(&exp->args[exp->num++], &args, sizeof(args));
 }
 
 static void si_export_mrt_color(struct lp_build_tgsi_context *bld_base,
                                LLVMValueRef *color, unsigned index,
                                unsigned samplemask_param,
                                bool is_last, struct si_ps_exports *exp)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct lp_build_context *base = &bld_base->base;
        int i;
@@ -2935,85 +2924,81 @@ static void si_export_mrt_color(struct 
lp_build_tgsi_context *bld_base,
            ctx->shader->key.part.ps.epilog.alpha_func != PIPE_FUNC_ALWAYS)
                si_alpha_test(bld_base, color[3]);
 
        /* Line & polygon smoothing */
        if (ctx->shader->key.part.ps.epilog.poly_line_smoothing)
                color[3] = si_scale_alpha_by_sample_mask(bld_base, color[3],
                                                         samplemask_param);
 
        /* If last_cbuf > 0, FS_COLOR0_WRITES_ALL_CBUFS is true. */
        if (ctx->shader->key.part.ps.epilog.last_cbuf > 0) {
-               LLVMValueRef args[8][9];
+               struct ac_export_args args[8];
                int c, last = -1;
 
                /* Get the export arguments, also find out what the last one 
is. */
                for (c = 0; c <= ctx->shader->key.part.ps.epilog.last_cbuf; 
c++) {
                        si_llvm_init_export_args(bld_base, color,
-                                                V_008DFC_SQ_EXP_MRT + c, 
args[c]);
-                       if (args[c][0] != bld_base->uint_bld.zero)
+                                                V_008DFC_SQ_EXP_MRT + c, 
&args[c]);
+                       if (args[c].enabled_channels)
                                last = c;
                }
 
                /* Emit all exports. */
                for (c = 0; c <= ctx->shader->key.part.ps.epilog.last_cbuf; 
c++) {
                        if (is_last && last == c) {
-                               args[c][1] = bld_base->uint_bld.one; /* whether 
the EXEC mask is valid */
-                               args[c][2] = bld_base->uint_bld.one; /* DONE 
bit */
-                       } else if (args[c][0] == bld_base->uint_bld.zero)
+                               args[c].valid_mask = 1; /* whether the EXEC 
mask is valid */
+                               args[c].done = 1; /* DONE bit */
+                       } else if (!args[c].enabled_channels)
                                continue; /* unnecessary NULL export */
 
-                       memcpy(exp->args[exp->num++], args[c], sizeof(args[c]));
+                       memcpy(&exp->args[exp->num++], &args[c], 
sizeof(args[c]));
                }
        } else {
-               LLVMValueRef args[9];
+               struct ac_export_args args;
 
                /* Export */
                si_llvm_init_export_args(bld_base, color, V_008DFC_SQ_EXP_MRT + 
index,
-                                        args);
+                                        &args);
                if (is_last) {
-                       args[1] = bld_base->uint_bld.one; /* whether the EXEC 
mask is valid */
-                       args[2] = bld_base->uint_bld.one; /* DONE bit */
-               } else if (args[0] == bld_base->uint_bld.zero)
+                       args.valid_mask = 1; /* whether the EXEC mask is valid 
*/
+                       args.done = 1; /* DONE bit */
+               } else if (!args.enabled_channels)
                        return; /* unnecessary NULL export */
 
-               memcpy(exp->args[exp->num++], args, sizeof(args));
+               memcpy(&exp->args[exp->num++], &args, sizeof(args));
        }
 }
 
 static void si_emit_ps_exports(struct si_shader_context *ctx,
                               struct si_ps_exports *exp)
 {
        for (unsigned i = 0; i < exp->num; i++)
-               lp_build_intrinsic(ctx->gallivm.builder,
-                                  "llvm.SI.export", ctx->voidt,
-                                  exp->args[i], 9, LP_FUNC_ATTR_LEGACY);
+               ac_emit_export(&ctx->ac, &exp->args[i]);
 }
 
 static void si_export_null(struct lp_build_tgsi_context *bld_base)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct lp_build_context *base = &bld_base->base;
-       struct lp_build_context *uint = &bld_base->uint_bld;
-       LLVMValueRef args[9];
+       struct ac_export_args args;
 
-       args[0] = lp_build_const_int32(base->gallivm, 0x0); /* enabled channels 
*/
-       args[1] = uint->one; /* whether the EXEC mask is valid */
-       args[2] = uint->one; /* DONE bit */
-       args[3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_NULL);
-       args[4] = uint->zero; /* COMPR flag (0 = 32-bit export) */
-       args[5] = base->undef; /* R */
-       args[6] = base->undef; /* G */
-       args[7] = base->undef; /* B */
-       args[8] = base->undef; /* A */
+       args.enabled_channels = 0x0; /* enabled channels */
+       args.valid_mask = 1; /* whether the EXEC mask is valid */
+       args.done = 1; /* DONE bit */
+       args.target = V_008DFC_SQ_EXP_NULL;
+       args.compr = 0; /* COMPR flag (0 = 32-bit export) */
+       args.out[0] = base->undef; /* R */
+       args.out[1] = base->undef; /* G */
+       args.out[2] = base->undef; /* B */
+       args.out[3] = base->undef; /* A */
 
-       lp_build_intrinsic(base->gallivm->builder, "llvm.SI.export",
-                          ctx->voidt, args, 9, LP_FUNC_ATTR_LEGACY);
+       ac_emit_export(&ctx->ac, &args);
 }
 
 /**
  * Return PS outputs in this order:
  *
  * v[0:3] = color0.xyzw
  * v[4:7] = color1.xyzw
  * ...
  * vN+0 = Depth
  * vN+1 = Stencil
@@ -7638,38 +7623,35 @@ static void si_build_vs_epilog_function(struct 
si_shader_context *ctx,
 
        for (i = 0; i < num_params; i++)
                params[i] = ctx->f32;
 
        /* Create the function. */
        si_create_function(ctx, "vs_epilog", NULL, 0, params, num_params, -1);
 
        /* Emit exports. */
        if (key->vs_epilog.states.export_prim_id) {
                struct lp_build_context *base = &bld_base->base;
-               struct lp_build_context *uint = &bld_base->uint_bld;
-               LLVMValueRef args[9];
-
-               args[0] = lp_build_const_int32(base->gallivm, 0x0); /* enabled 
channels */
-               args[1] = uint->zero; /* whether the EXEC mask is valid */
-               args[2] = uint->zero; /* DONE bit */
-               args[3] = lp_build_const_int32(base->gallivm, 
V_008DFC_SQ_EXP_PARAM +
-                                              
key->vs_epilog.prim_id_param_offset);
-               args[4] = uint->zero; /* COMPR flag (0 = 32-bit export) */
-               args[5] = LLVMGetParam(ctx->main_fn,
+               struct ac_export_args args;
+
+               args.enabled_channels = 0x1; /* enabled channels */
+               args.valid_mask = 0; /* whether the EXEC mask is valid */
+               args.done = 0; /* DONE bit */
+               args.target = V_008DFC_SQ_EXP_PARAM +
+                             key->vs_epilog.prim_id_param_offset;
+               args.compr = 0; /* COMPR flag (0 = 32-bit export) */
+               args.out[0] = LLVMGetParam(ctx->main_fn,
                                       VS_EPILOG_PRIMID_LOC); /* X */
-               args[6] = base->undef; /* Y */
-               args[7] = base->undef; /* Z */
-               args[8] = base->undef; /* W */
+               args.out[1] = base->undef; /* Y */
+               args.out[2] = base->undef; /* Z */
+               args.out[3] = base->undef; /* W */
 
-               lp_build_intrinsic(base->gallivm->builder, "llvm.SI.export",
-                                  
LLVMVoidTypeInContext(base->gallivm->context),
-                                  args, 9, LP_FUNC_ATTR_LEGACY);
+               ac_emit_export(&ctx->ac, &args);
        }
 
        LLVMBuildRetVoid(gallivm->builder);
 }
 
 /**
  * Create & compile a vertex shader epilog. This a helper used by VS and TES.
  */
 static bool si_get_vs_epilog(struct si_screen *sscreen,
                             LLVMTargetMachineRef tm,
-- 
2.7.4

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to