[Mesa-dev] [PATCH 05/24] radeonsi: move llvm.SI.export building to amd/common
Marek Olšák
maraeo at gmail.com
Sat Feb 25 23:58:03 UTC 2017
From: Marek Olšák <marek.olsak at 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
More information about the mesa-dev
mailing list