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