From 141f2c2fc9325a5d30629373bb962f42517967ae Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 6 Feb 2012 15:35:05 +0000 Subject: [PATCH] gallivm: enable fetch for integer opcodes. (v2) The infers the type of data required using the opcode, and casts the input to the appropriate type. So far this only handles non-indirect constant and temporaries. v2: as per Jose suggestion, fetch immediates via floats Signed-off-by: Dave Airlie --- src/gallium/auxiliary/gallivm/lp_bld_tgsi.c | 3 +- src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 3 +- .../auxiliary/gallivm/lp_bld_tgsi_aos.c | 12 ++-- .../auxiliary/gallivm/lp_bld_tgsi_soa.c | 72 ++++++++++++++++--- 4 files changed, 74 insertions(+), 16 deletions(-) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c index 261301ce542..e05ad81c302 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c @@ -298,6 +298,7 @@ lp_build_emit_fetch( const struct tgsi_full_src_register *reg = &inst->Src[src_op]; unsigned swizzle; LLVMValueRef res; + enum tgsi_opcode_type stype = tgsi_opcode_infer_src_type(inst->Instruction.Opcode); if (chan_index == LP_CHAN_ALL) { swizzle = ~0; @@ -312,7 +313,7 @@ lp_build_emit_fetch( assert(reg->Register.Index <= bld_base->info->file_max[reg->Register.File]); if (bld_base->emit_fetch_funcs[reg->Register.File]) { - res = bld_base->emit_fetch_funcs[reg->Register.File](bld_base, reg, + res = bld_base->emit_fetch_funcs[reg->Register.File](bld_base, reg, stype, swizzle); } else { assert(0 && "invalid src register in emit_fetch()"); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index a36a09a8fa4..b799900bfd7 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -45,7 +45,7 @@ #include "pipe/p_state.h" #include "tgsi/tgsi_exec.h" #include "tgsi/tgsi_scan.h" - +#include "tgsi/tgsi_info.h" #define LP_CHAN_ALL ~0 @@ -273,6 +273,7 @@ struct lp_build_tgsi_context; typedef LLVMValueRef (*lp_build_emit_fetch_fn)(struct lp_build_tgsi_context *, const struct tgsi_full_src_register *, + enum tgsi_opcode_type, unsigned); struct lp_build_tgsi_context diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c index 2c2c820708a..80c148124ee 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c @@ -101,7 +101,8 @@ static LLVMValueRef emit_fetch_constant( struct lp_build_tgsi_context * bld_base, const struct tgsi_full_src_register * reg, - const unsigned swizzle) + enum tgsi_opcode_type stype, + unsigned swizzle) { struct lp_build_tgsi_aos_context * bld = lp_aos_context(bld_base); LLVMBuilderRef builder = bld_base->base.gallivm->builder; @@ -171,7 +172,8 @@ static LLVMValueRef emit_fetch_immediate( struct lp_build_tgsi_context * bld_base, const struct tgsi_full_src_register * reg, - const unsigned swizzle) + enum tgsi_opcode_type stype, + unsigned swizzle) { struct lp_build_tgsi_aos_context * bld = lp_aos_context(bld_base); LLVMValueRef res = bld->immediates[reg->Register.Index]; @@ -183,7 +185,8 @@ static LLVMValueRef emit_fetch_input( struct lp_build_tgsi_context * bld_base, const struct tgsi_full_src_register * reg, - const unsigned swizzle) + enum tgsi_opcode_type stype, + unsigned swizzle) { struct lp_build_tgsi_aos_context * bld = lp_aos_context(bld_base); LLVMValueRef res = bld->inputs[reg->Register.Index]; @@ -196,7 +199,8 @@ static LLVMValueRef emit_fetch_temporary( struct lp_build_tgsi_context * bld_base, const struct tgsi_full_src_register * reg, - const unsigned swizzle) + enum tgsi_opcode_type stype, + unsigned swizzle) { struct lp_build_tgsi_aos_context * bld = lp_aos_context(bld_base); LLVMBuilderRef builder = bld_base->base.gallivm->builder; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index bc063253bcd..920fed22c81 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -519,18 +519,47 @@ get_indirect_index(struct lp_build_tgsi_soa_context *bld, return index; } +static struct lp_build_context * +stype_to_fetch(struct lp_build_tgsi_context * bld_base, + enum tgsi_opcode_type stype) +{ + struct lp_build_context *bld_fetch; + + switch (stype) { + case TGSI_TYPE_FLOAT: + case TGSI_TYPE_UNTYPED: + bld_fetch = &bld_base->base; + break; + case TGSI_TYPE_UNSIGNED: + bld_fetch = &bld_base->uint_bld; + break; + case TGSI_TYPE_SIGNED: + bld_fetch = &bld_base->int_bld; + break; + case TGSI_TYPE_VOID: + case TGSI_TYPE_DOUBLE: + default: + assert(0); + bld_fetch = NULL; + break; + } + return bld_fetch; +} + static LLVMValueRef emit_fetch_constant( struct lp_build_tgsi_context * bld_base, const struct tgsi_full_src_register * reg, - const unsigned swizzle) + enum tgsi_opcode_type stype, + unsigned swizzle) { struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); struct gallivm_state *gallivm = bld_base->base.gallivm; LLVMBuilderRef builder = gallivm->builder; struct lp_build_context *uint_bld = &bld_base->uint_bld; LLVMValueRef indirect_index = NULL; - + struct lp_build_context *bld_fetch = stype_to_fetch(bld_base, stype); + /* XXX: Handle fetching xyzw components as a vector */ assert(swizzle != ~0); @@ -551,7 +580,7 @@ emit_fetch_constant( index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec); /* Gather values from the constant buffer */ - return build_gather(&bld_base->base, bld->consts_ptr, index_vec); + return build_gather(bld_fetch, bld->consts_ptr, index_vec); } else { LLVMValueRef index; /* index into the const buffer */ @@ -561,9 +590,16 @@ emit_fetch_constant( scalar_ptr = LLVMBuildGEP(builder, bld->consts_ptr, &index, 1, ""); - scalar = LLVMBuildLoad(builder, scalar_ptr, ""); - return lp_build_broadcast_scalar(&bld->bld_base.base, scalar); + if (stype != TGSI_TYPE_FLOAT && stype != TGSI_TYPE_UNTYPED) { + LLVMTypeRef ivtype = LLVMPointerType(LLVMInt32TypeInContext(gallivm->context), 0); + LLVMValueRef temp_ptr; + temp_ptr = LLVMBuildBitCast(builder, scalar_ptr, ivtype, ""); + scalar = LLVMBuildLoad(builder, temp_ptr, ""); + } else + scalar = LLVMBuildLoad(builder, scalar_ptr, ""); + + return lp_build_broadcast_scalar(bld_fetch, scalar); } } @@ -571,11 +607,18 @@ static LLVMValueRef emit_fetch_immediate( struct lp_build_tgsi_context * bld_base, const struct tgsi_full_src_register * reg, - const unsigned swizzle) + enum tgsi_opcode_type stype, + unsigned swizzle) { struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); LLVMValueRef res = bld->immediates[reg->Register.Index][swizzle]; assert(res); + + if (stype == TGSI_TYPE_UNSIGNED) { + res = LLVMConstBitCast(res, bld_base->uint_bld.vec_type); + } else if (stype == TGSI_TYPE_SIGNED) { + res = LLVMConstBitCast(res, bld_base->int_bld.vec_type); + } return res; } @@ -583,7 +626,8 @@ static LLVMValueRef emit_fetch_input( struct lp_build_tgsi_context * bld_base, const struct tgsi_full_src_register * reg, - const unsigned swizzle) + enum tgsi_opcode_type stype, + unsigned swizzle) { struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); struct gallivm_state *gallivm = bld->bld_base.base.gallivm; @@ -640,7 +684,8 @@ static LLVMValueRef emit_fetch_temporary( struct lp_build_tgsi_context * bld_base, const struct tgsi_full_src_register * reg, - const unsigned swizzle) + enum tgsi_opcode_type stype, + unsigned swizzle) { struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); struct gallivm_state *gallivm = bld->bld_base.base.gallivm; @@ -681,7 +726,13 @@ emit_fetch_temporary( } else { LLVMValueRef temp_ptr; - temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle); + if (stype != TGSI_TYPE_FLOAT && stype != TGSI_TYPE_UNTYPED) { + LLVMTypeRef itype = LLVMPointerType(LLVMVectorType(LLVMInt32TypeInContext(gallivm->context), 4), 0); + LLVMValueRef tint_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, + swizzle); + temp_ptr = LLVMBuildBitCast(builder, tint_ptr, itype, ""); + } else + temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle); res = LLVMBuildLoad(builder, temp_ptr, ""); if (!res) return bld->bld_base.base.undef; @@ -694,7 +745,8 @@ static LLVMValueRef emit_fetch_system_value( struct lp_build_tgsi_context * bld_base, const struct tgsi_full_src_register * reg, - const unsigned swizzle) + enum tgsi_opcode_type stype, + unsigned swizzle) { struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); struct gallivm_state *gallivm = bld->bld_base.base.gallivm; -- 2.30.2