summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2012-02-06 15:35:05 +0000
committerDave Airlie <[email protected]>2012-02-17 17:39:02 +0000
commit141f2c2fc9325a5d30629373bb962f42517967ae (patch)
tree330b563e5d2bab51b3b2e39b17f85f7235aee646
parent66461aa249a95053fd5887df75ab791558c3a486 (diff)
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 <[email protected]>
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi.c3
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi.h3
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c12
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c72
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;