[Mesa-dev] [PATCH] gallivm/radeonsi: allow to pass two swizzles into fetches.
Marek Olšák
maraeo at gmail.com
Wed Aug 29 22:00:33 UTC 2018
Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Marek
On Mon, Aug 27, 2018 at 5:16 PM, Dave Airlie <airlied at gmail.com> wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> This hijacks the top 16-bits of swizzle, to pass in the swizzle
> for the second channel.
>
> This fixes handling .yx swizzles of 64-bit values.
>
> This should fixup radeonsi and llvmpipe.
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107524
> ---
> src/gallium/auxiliary/gallivm/lp_bld_tgsi.c | 9 ++
> .../auxiliary/gallivm/lp_bld_tgsi_soa.c | 86 ++++++++++++-------
> src/gallium/drivers/radeonsi/si_shader.c | 7 +-
> .../drivers/radeonsi/si_shader_tgsi_setup.c | 18 ++--
> 4 files changed, 79 insertions(+), 41 deletions(-)
>
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c
> index 64d2cd703be..2c3be8fb127 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c
> @@ -353,6 +353,15 @@ lp_build_emit_fetch_src(
> assert(0 && "invalid swizzle in emit_fetch()");
> return bld_base->base.undef;
> }
> + if (tgsi_type_is_64bit(stype)) {
> + unsigned swizzle2;
> + swizzle2 = tgsi_util_get_full_src_register_swizzle(reg, chan_index + 1);
> + if (swizzle2 > 3) {
> + assert(0 && "invalid swizzle in emit_fetch()");
> + return bld_base->base.undef;
> + }
> + swizzle |= (swizzle2 << 16);
> + }
> }
>
> assert(reg->Register.Index <= bld_base->info->file_max[reg->Register.File]);
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> index 83d7dbea9a2..79ece639e35 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> @@ -1190,7 +1190,7 @@ emit_fetch_constant(
> struct lp_build_tgsi_context * bld_base,
> const struct tgsi_full_src_register * reg,
> enum tgsi_opcode_type stype,
> - unsigned swizzle)
> + unsigned swizzle_in)
> {
> struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
> struct gallivm_state *gallivm = bld_base->base.gallivm;
> @@ -1200,6 +1200,7 @@ emit_fetch_constant(
> LLVMValueRef consts_ptr;
> LLVMValueRef num_consts;
> LLVMValueRef res;
> + unsigned swizzle = swizzle_in & 0xffff;
>
> /* XXX: Handle fetching xyzw components as a vector */
> assert(swizzle != ~0u);
> @@ -1241,7 +1242,7 @@ emit_fetch_constant(
>
> if (tgsi_type_is_64bit(stype)) {
> LLVMValueRef swizzle_vec2;
> - swizzle_vec2 = lp_build_const_int_vec(gallivm, uint_bld->type, swizzle + 1);
> + swizzle_vec2 = lp_build_const_int_vec(gallivm, uint_bld->type, swizzle_in >> 16);
> index_vec2 = lp_build_shl_imm(uint_bld, indirect_index, 2);
> index_vec2 = lp_build_add(uint_bld, index_vec2, swizzle_vec2);
> }
> @@ -1256,21 +1257,42 @@ emit_fetch_constant(
>
> scalar_ptr = LLVMBuildGEP(builder, consts_ptr,
> &index, 1, "");
> - if (stype == TGSI_TYPE_DOUBLE) {
> - LLVMTypeRef dptr_type = LLVMPointerType(LLVMDoubleTypeInContext(gallivm->context), 0);
> - scalar_ptr = LLVMBuildBitCast(builder, scalar_ptr, dptr_type, "");
> - bld_broad = &bld_base->dbl_bld;
> - } else if (stype == TGSI_TYPE_UNSIGNED64) {
> - LLVMTypeRef u64ptr_type = LLVMPointerType(LLVMInt64TypeInContext(gallivm->context), 0);
> - scalar_ptr = LLVMBuildBitCast(builder, scalar_ptr, u64ptr_type, "");
> - bld_broad = &bld_base->uint64_bld;
> - } else if (stype == TGSI_TYPE_SIGNED64) {
> - LLVMTypeRef i64ptr_type = LLVMPointerType(LLVMInt64TypeInContext(gallivm->context), 0);
> - scalar_ptr = LLVMBuildBitCast(builder, scalar_ptr, i64ptr_type, "");
> - bld_broad = &bld_base->int64_bld;
> +
> + if (tgsi_type_is_64bit(stype) && ((swizzle_in >> 16) != swizzle + 1)) {
> +
> + LLVMValueRef scalar2, scalar2_ptr;
> + LLVMValueRef shuffles[2];
> + index = lp_build_const_int32(gallivm, reg->Register.Index * 4 + (swizzle_in >> 16));
> +
> + scalar2_ptr = LLVMBuildGEP(builder, consts_ptr,
> + &index, 1, "");
> +
> + scalar = LLVMBuildLoad(builder, scalar_ptr, "");
> + scalar2 = LLVMBuildLoad(builder, scalar2_ptr, "");
> + shuffles[0] = lp_build_const_int32(gallivm, 0);
> + shuffles[1] = lp_build_const_int32(gallivm, 1);
> +
> + res = LLVMGetUndef(LLVMVectorType(LLVMFloatTypeInContext(gallivm->context), bld_base->base.type.length * 2));
> + res = LLVMBuildInsertElement(builder, res, scalar, shuffles[0], "");
> + res = LLVMBuildInsertElement(builder, res, scalar2, shuffles[1], "");
> + } else {
> + if (stype == TGSI_TYPE_DOUBLE) {
> + LLVMTypeRef dptr_type = LLVMPointerType(LLVMDoubleTypeInContext(gallivm->context), 0);
> + scalar_ptr = LLVMBuildBitCast(builder, scalar_ptr, dptr_type, "");
> + bld_broad = &bld_base->dbl_bld;
> + } else if (stype == TGSI_TYPE_UNSIGNED64) {
> + LLVMTypeRef u64ptr_type = LLVMPointerType(LLVMInt64TypeInContext(gallivm->context), 0);
> + scalar_ptr = LLVMBuildBitCast(builder, scalar_ptr, u64ptr_type, "");
> + bld_broad = &bld_base->uint64_bld;
> + } else if (stype == TGSI_TYPE_SIGNED64) {
> + LLVMTypeRef i64ptr_type = LLVMPointerType(LLVMInt64TypeInContext(gallivm->context), 0);
> + scalar_ptr = LLVMBuildBitCast(builder, scalar_ptr, i64ptr_type, "");
> + bld_broad = &bld_base->int64_bld;
> + }
> + scalar = LLVMBuildLoad(builder, scalar_ptr, "");
> + res = lp_build_broadcast_scalar(bld_broad, scalar);
> }
> - scalar = LLVMBuildLoad(builder, scalar_ptr, "");
> - res = lp_build_broadcast_scalar(bld_broad, scalar);
> +
> }
>
> if (stype == TGSI_TYPE_SIGNED || stype == TGSI_TYPE_UNSIGNED || stype == TGSI_TYPE_DOUBLE || stype == TGSI_TYPE_SIGNED64 || stype == TGSI_TYPE_UNSIGNED64) {
> @@ -1319,12 +1341,13 @@ emit_fetch_immediate(
> struct lp_build_tgsi_context * bld_base,
> const struct tgsi_full_src_register * reg,
> enum tgsi_opcode_type stype,
> - unsigned swizzle)
> + unsigned swizzle_in)
> {
> struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
> struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
> LLVMBuilderRef builder = gallivm->builder;
> LLVMValueRef res = NULL;
> + unsigned swizzle = swizzle_in & 0xffff;
>
> if (bld->use_immediates_array || reg->Register.Indirect) {
> LLVMValueRef imms_array;
> @@ -1355,7 +1378,7 @@ emit_fetch_immediate(
> if (tgsi_type_is_64bit(stype))
> index_vec2 = get_soa_array_offsets(&bld_base->uint_bld,
> indirect_index,
> - swizzle + 1,
> + swizzle_in >> 16,
> FALSE);
> /* Gather values from the immediate register array */
> res = build_gather(bld_base, imms_array, index_vec, NULL, index_vec2);
> @@ -1371,7 +1394,7 @@ emit_fetch_immediate(
> LLVMValueRef imms_ptr2;
> LLVMValueRef res2;
> gep[1] = lp_build_const_int32(gallivm,
> - reg->Register.Index * 4 + swizzle + 1);
> + reg->Register.Index * 4 + (swizzle_in >> 16));
> imms_ptr2 = LLVMBuildGEP(builder,
> bld->imms_array, gep, 2, "");
> res2 = LLVMBuildLoad(builder, imms_ptr2, "");
> @@ -1382,7 +1405,7 @@ emit_fetch_immediate(
> else {
> res = bld->immediates[reg->Register.Index][swizzle];
> if (tgsi_type_is_64bit(stype))
> - res = emit_fetch_64bit(bld_base, stype, res, bld->immediates[reg->Register.Index][swizzle + 1]);
> + res = emit_fetch_64bit(bld_base, stype, res, bld->immediates[reg->Register.Index][swizzle_in >> 16]);
> }
>
> if (stype == TGSI_TYPE_SIGNED || stype == TGSI_TYPE_UNSIGNED || tgsi_type_is_64bit(stype)) {
> @@ -1397,12 +1420,13 @@ emit_fetch_input(
> struct lp_build_tgsi_context * bld_base,
> const struct tgsi_full_src_register * reg,
> enum tgsi_opcode_type stype,
> - unsigned swizzle)
> + unsigned swizzle_in)
> {
> struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
> struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
> LLVMBuilderRef builder = gallivm->builder;
> LLVMValueRef res;
> + unsigned swizzle = swizzle_in & 0xffff;
>
> if (reg->Register.Indirect) {
> LLVMValueRef indirect_index;
> @@ -1423,7 +1447,7 @@ emit_fetch_input(
> if (tgsi_type_is_64bit(stype)) {
> index_vec2 = get_soa_array_offsets(&bld_base->uint_bld,
> indirect_index,
> - swizzle + 1,
> + swizzle_in >> 16,
> TRUE);
> }
> /* cast inputs_array pointer to float* */
> @@ -1446,7 +1470,7 @@ emit_fetch_input(
> LLVMValueRef res2;
>
> lindex1 = lp_build_const_int32(gallivm,
> - reg->Register.Index * 4 + swizzle + 1);
> + reg->Register.Index * 4 + (swizzle_in >> 16));
> input_ptr2 = LLVMBuildGEP(builder,
> bld->inputs_array, &lindex1, 1, "");
> res2 = LLVMBuildLoad(builder, input_ptr2, "");
> @@ -1456,7 +1480,7 @@ emit_fetch_input(
> else {
> res = bld->inputs[reg->Register.Index][swizzle];
> if (tgsi_type_is_64bit(stype))
> - res = emit_fetch_64bit(bld_base, stype, res, bld->inputs[reg->Register.Index][swizzle + 1]);
> + res = emit_fetch_64bit(bld_base, stype, res, bld->inputs[reg->Register.Index][swizzle_in >> 16]);
> }
> }
>
> @@ -1476,7 +1500,7 @@ emit_fetch_gs_input(
> struct lp_build_tgsi_context * bld_base,
> const struct tgsi_full_src_register * reg,
> enum tgsi_opcode_type stype,
> - unsigned swizzle)
> + unsigned swizzle_in)
> {
> struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
> struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
> @@ -1484,6 +1508,7 @@ emit_fetch_gs_input(
> LLVMBuilderRef builder = gallivm->builder;
> LLVMValueRef attrib_index = NULL;
> LLVMValueRef vertex_index = NULL;
> + unsigned swizzle = swizzle_in & 0xffff;
> LLVMValueRef swizzle_index = lp_build_const_int32(gallivm, swizzle);
> LLVMValueRef res;
>
> @@ -1525,7 +1550,7 @@ emit_fetch_gs_input(
>
> assert(res);
> if (tgsi_type_is_64bit(stype)) {
> - LLVMValueRef swizzle_index = lp_build_const_int32(gallivm, swizzle + 1);
> + LLVMValueRef swizzle_index = lp_build_const_int32(gallivm, swizzle_in >> 16);
> LLVMValueRef res2;
> res2 = bld->gs_iface->fetch_input(bld->gs_iface, bld_base,
> reg->Dimension.Indirect,
> @@ -1549,12 +1574,13 @@ emit_fetch_temporary(
> struct lp_build_tgsi_context * bld_base,
> const struct tgsi_full_src_register * reg,
> enum tgsi_opcode_type stype,
> - unsigned swizzle)
> + unsigned swizzle_in)
> {
> struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
> struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
> LLVMBuilderRef builder = gallivm->builder;
> LLVMValueRef res;
> + unsigned swizzle = swizzle_in & 0xffff;
>
> if (reg->Register.Indirect) {
> LLVMValueRef indirect_index;
> @@ -1574,7 +1600,7 @@ emit_fetch_temporary(
> if (tgsi_type_is_64bit(stype)) {
> index_vec2 = get_soa_array_offsets(&bld_base->uint_bld,
> indirect_index,
> - swizzle + 1,
> + swizzle_in >> 16,
> TRUE);
> }
>
> @@ -1593,7 +1619,7 @@ emit_fetch_temporary(
> if (tgsi_type_is_64bit(stype)) {
> LLVMValueRef temp_ptr2, res2;
>
> - temp_ptr2 = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle + 1);
> + temp_ptr2 = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle_in >> 16);
> res2 = LLVMBuildLoad(builder, temp_ptr2, "");
> res = emit_fetch_64bit(bld_base, stype, res, res2);
> }
> @@ -1616,7 +1642,7 @@ emit_fetch_system_value(
> struct lp_build_tgsi_context * bld_base,
> const struct tgsi_full_src_register * reg,
> enum tgsi_opcode_type stype,
> - unsigned swizzle)
> + unsigned swizzle_in)
> {
> struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
> struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
> diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
> index cfd99b61601..c7530c5ffbd 100644
> --- a/src/gallium/drivers/radeonsi/si_shader.c
> +++ b/src/gallium/drivers/radeonsi/si_shader.c
> @@ -2393,16 +2393,17 @@ static LLVMValueRef fetch_constant(
> struct lp_build_tgsi_context *bld_base,
> const struct tgsi_full_src_register *reg,
> enum tgsi_opcode_type type,
> - unsigned swizzle)
> + unsigned swizzle_in)
> {
> struct si_shader_context *ctx = si_shader_context(bld_base);
> struct si_shader_selector *sel = ctx->shader->selector;
> const struct tgsi_ind_register *ireg = ®->Indirect;
> unsigned buf, idx;
> + unsigned swizzle = swizzle_in & 0xffff;
>
> LLVMValueRef addr, bufp;
>
> - if (swizzle == LP_CHAN_ALL) {
> + if (swizzle_in == LP_CHAN_ALL) {
> unsigned chan;
> LLVMValueRef values[4];
> for (chan = 0; chan < TGSI_NUM_CHANNELS; ++chan)
> @@ -2416,7 +2417,7 @@ static LLVMValueRef fetch_constant(
> LLVMValueRef lo, hi;
>
> lo = fetch_constant(bld_base, reg, TGSI_TYPE_UNSIGNED, swizzle);
> - hi = fetch_constant(bld_base, reg, TGSI_TYPE_UNSIGNED, swizzle + 1);
> + hi = fetch_constant(bld_base, reg, TGSI_TYPE_UNSIGNED, (swizzle_in >> 16));
> return si_llvm_emit_fetch_64bit(bld_base, tgsi2llvmtype(bld_base, type),
> lo, hi);
> }
> diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
> index 20164939cb7..d48eda1b100 100644
> --- a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
> +++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
> @@ -445,13 +445,14 @@ get_output_ptr(struct lp_build_tgsi_context *bld_base, unsigned index,
> LLVMValueRef si_llvm_emit_fetch(struct lp_build_tgsi_context *bld_base,
> const struct tgsi_full_src_register *reg,
> enum tgsi_opcode_type type,
> - unsigned swizzle)
> + unsigned swizzle_in)
> {
> struct si_shader_context *ctx = si_shader_context(bld_base);
> LLVMBuilderRef builder = ctx->ac.builder;
> LLVMValueRef result = NULL, ptr, ptr2;
> + unsigned swizzle = swizzle_in & 0xffff;
>
> - if (swizzle == ~0) {
> + if (swizzle_in == ~0) {
> LLVMValueRef values[TGSI_NUM_CHANNELS];
> unsigned chan;
> for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
> @@ -476,7 +477,7 @@ LLVMValueRef si_llvm_emit_fetch(struct lp_build_tgsi_context *bld_base,
> ctx->imms[reg->Register.Index * TGSI_NUM_CHANNELS + swizzle],
> ctx->i32_0);
> result = LLVMConstInsertElement(result,
> - ctx->imms[reg->Register.Index * TGSI_NUM_CHANNELS + swizzle + 1],
> + ctx->imms[reg->Register.Index * TGSI_NUM_CHANNELS + (swizzle_in >> 16)],
> ctx->i32_1);
> return LLVMConstBitCast(result, ctype);
> } else {
> @@ -503,7 +504,7 @@ LLVMValueRef si_llvm_emit_fetch(struct lp_build_tgsi_context *bld_base,
>
> if (tgsi_type_is_64bit(type)) {
> ptr = result;
> - ptr2 = input[swizzle + 1];
> + ptr2 = input[swizzle_in >> 16];
> return si_llvm_emit_fetch_64bit(bld_base, tgsi2llvmtype(bld_base, type),
> ptr, ptr2);
> }
> @@ -515,7 +516,7 @@ LLVMValueRef si_llvm_emit_fetch(struct lp_build_tgsi_context *bld_base,
> return LLVMGetUndef(tgsi2llvmtype(bld_base, type));
> ptr = ctx->temps[reg->Register.Index * TGSI_NUM_CHANNELS + swizzle];
> if (tgsi_type_is_64bit(type)) {
> - ptr2 = ctx->temps[reg->Register.Index * TGSI_NUM_CHANNELS + swizzle + 1];
> + ptr2 = ctx->temps[reg->Register.Index * TGSI_NUM_CHANNELS + (swizzle_in >> 16)];
> return si_llvm_emit_fetch_64bit(bld_base, tgsi2llvmtype(bld_base, type),
> LLVMBuildLoad(builder, ptr, ""),
> LLVMBuildLoad(builder, ptr2, ""));
> @@ -526,7 +527,7 @@ LLVMValueRef si_llvm_emit_fetch(struct lp_build_tgsi_context *bld_base,
> case TGSI_FILE_OUTPUT:
> ptr = get_output_ptr(bld_base, reg->Register.Index, swizzle);
> if (tgsi_type_is_64bit(type)) {
> - ptr2 = get_output_ptr(bld_base, reg->Register.Index, swizzle + 1);
> + ptr2 = get_output_ptr(bld_base, reg->Register.Index, (swizzle_in >> 16));
> return si_llvm_emit_fetch_64bit(bld_base, tgsi2llvmtype(bld_base, type),
> LLVMBuildLoad(builder, ptr, ""),
> LLVMBuildLoad(builder, ptr2, ""));
> @@ -544,11 +545,12 @@ LLVMValueRef si_llvm_emit_fetch(struct lp_build_tgsi_context *bld_base,
> static LLVMValueRef fetch_system_value(struct lp_build_tgsi_context *bld_base,
> const struct tgsi_full_src_register *reg,
> enum tgsi_opcode_type type,
> - unsigned swizzle)
> + unsigned swizzle_in)
> {
> struct si_shader_context *ctx = si_shader_context(bld_base);
> LLVMBuilderRef builder = ctx->ac.builder;
> LLVMValueRef cval = ctx->system_values[reg->Register.Index];
> + unsigned swizzle = swizzle_in & 0xffff;
>
> if (tgsi_type_is_64bit(type)) {
> LLVMValueRef lo, hi;
> @@ -558,7 +560,7 @@ static LLVMValueRef fetch_system_value(struct lp_build_tgsi_context *bld_base,
> lo = LLVMBuildExtractElement(
> builder, cval, LLVMConstInt(ctx->i32, swizzle, 0), "");
> hi = LLVMBuildExtractElement(
> - builder, cval, LLVMConstInt(ctx->i32, swizzle + 1, 0), "");
> + builder, cval, LLVMConstInt(ctx->i32, (swizzle_in >> 16), 0), "");
>
> return si_llvm_emit_fetch_64bit(bld_base, tgsi2llvmtype(bld_base, type),
> lo, hi);
> --
> 2.17.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list