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 <airlied@redhat.com>
This commit is contained in:
Dave Airlie
2012-02-06 15:35:05 +00:00
parent 66461aa249
commit 141f2c2fc9
4 changed files with 74 additions and 16 deletions
+2 -1
View File
@@ -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()");
+2 -1
View File
@@ -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
@@ -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;
+62 -10
View File
@@ -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;