summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorVadim Girlin <[email protected]>2012-05-07 20:22:29 +0400
committerVadim Girlin <[email protected]>2012-05-08 01:18:21 +0400
commit2a88dfc521bff7255e27e2ef8efcd08f9db53747 (patch)
tree4abb8a7257cdcb5f157003501e562dcfc1387557 /src/gallium
parent3f8c37967a66da6bc63b283b3eba69fd48eba2f6 (diff)
radeon/llvm: use bitcasts for integers
We're using float as default type, so basically for every instruction that wants other types for dst/src operands we need to perform the bitcast to/from default float. Currently bitcast produces no-op MOV instruction, will be eliminated later. Signed-off-by: Vadim Girlin <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/r600/r600_llvm.c4
-rw-r--r--src/gallium/drivers/radeon/radeon_llvm.h31
-rw-r--r--src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c43
3 files changed, 73 insertions, 5 deletions
diff --git a/src/gallium/drivers/r600/r600_llvm.c b/src/gallium/drivers/r600/r600_llvm.c
index d467baf60fb..a36760cb56f 100644
--- a/src/gallium/drivers/r600/r600_llvm.c
+++ b/src/gallium/drivers/r600/r600_llvm.c
@@ -21,10 +21,12 @@ static LLVMValueRef llvm_fetch_const(
enum tgsi_opcode_type type,
unsigned swizzle)
{
- return lp_build_intrinsic_unary(bld_base->base.gallivm->builder,
+ LLVMValueRef cval = lp_build_intrinsic_unary(bld_base->base.gallivm->builder,
"llvm.AMDGPU.load.const", bld_base->base.elem_type,
lp_build_const_int32(bld_base->base.gallivm,
radeon_llvm_reg_index_soa(reg->Register.Index, swizzle)));
+
+ return bitcast(bld_base, type, cval);
}
static void llvm_load_input(
diff --git a/src/gallium/drivers/radeon/radeon_llvm.h b/src/gallium/drivers/radeon/radeon_llvm.h
index 9be7f90c3e6..39b1214e836 100644
--- a/src/gallium/drivers/radeon/radeon_llvm.h
+++ b/src/gallium/drivers/radeon/radeon_llvm.h
@@ -105,6 +105,37 @@ struct radeon_llvm_context {
struct gallivm_state gallivm;
};
+static inline LLVMValueRef bitcast(
+ struct lp_build_tgsi_context * bld_base,
+ enum tgsi_opcode_type type,
+ LLVMValueRef value
+)
+{
+ LLVMBuilderRef builder = bld_base->base.gallivm->builder;
+ LLVMContextRef ctx = bld_base->base.gallivm->context;
+ LLVMTypeRef dst_type;
+
+ switch (type) {
+ case TGSI_TYPE_UNSIGNED:
+ case TGSI_TYPE_SIGNED:
+ dst_type = LLVMInt32TypeInContext(ctx);
+ break;
+ case TGSI_TYPE_UNTYPED:
+ case TGSI_TYPE_FLOAT:
+ dst_type = LLVMFloatTypeInContext(ctx);
+ break;
+ default:
+ dst_type = 0;
+ break;
+ }
+
+ if (dst_type)
+ return LLVMBuildBitCast(builder, value, dst_type, "");
+ else
+ return value;
+}
+
+
void radeon_llvm_context_init(struct radeon_llvm_context * ctx);
void radeon_llvm_dispose(struct radeon_llvm_context * ctx);
diff --git a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
index d3c493cca01..06af1348605 100644
--- a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
+++ b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
@@ -113,8 +113,25 @@ emit_fetch_immediate(
enum tgsi_opcode_type type,
unsigned swizzle)
{
+ LLVMTypeRef ctype;
+ LLVMContextRef ctx = bld_base->base.gallivm->context;
+
+ switch (type) {
+ case TGSI_TYPE_UNSIGNED:
+ case TGSI_TYPE_SIGNED:
+ ctype = LLVMInt32TypeInContext(ctx);
+ break;
+ case TGSI_TYPE_UNTYPED:
+ case TGSI_TYPE_FLOAT:
+ ctype = LLVMFloatTypeInContext(ctx);
+ break;
+ default:
+ ctype = 0;
+ break;
+ }
+
struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
- return bld->immediates[reg->Register.Index][swizzle];
+ return LLVMConstBitCast(bld->immediates[reg->Register.Index][swizzle], ctype);
}
static LLVMValueRef
@@ -135,7 +152,7 @@ emit_fetch_input(
return lp_build_gather_values(bld_base->base.gallivm, values,
TGSI_NUM_CHANNELS);
} else {
- return ctx->inputs[radeon_llvm_reg_index_soa(reg->Register.Index, swizzle)];
+ return bitcast(bld_base, type, ctx->inputs[radeon_llvm_reg_index_soa(reg->Register.Index, swizzle)]);
}
}
@@ -156,7 +173,7 @@ emit_fetch_temporary(
} else {
LLVMValueRef temp_ptr;
temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle);
- return LLVMBuildLoad(builder, temp_ptr, "");
+ return bitcast(bld_base,type,LLVMBuildLoad(builder, temp_ptr, ""));
}
}
@@ -305,6 +322,9 @@ emit_store(
default:
return;
}
+
+ value = bitcast(bld_base, TGSI_TYPE_FLOAT, value);
+
LLVMBuildStore(builder, value, temp_ptr);
}
}
@@ -502,6 +522,20 @@ static void tex_fetch_args(
emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4);
}
+static void emit_immediate(struct lp_build_tgsi_context * bld_base,
+ const struct tgsi_full_immediate *imm)
+{
+ unsigned i;
+ struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
+
+ for (i = 0; i < 4; ++i) {
+ ctx->soa.immediates[ctx->soa.num_immediates][i] =
+ LLVMConstInt(bld_base->uint_bld.elem_type, imm->u[i].Uint, false );
+ }
+
+ ctx->soa.num_immediates++;
+}
+
void radeon_llvm_context_init(struct radeon_llvm_context * ctx)
{
struct lp_type type;
@@ -541,12 +575,13 @@ void radeon_llvm_context_init(struct radeon_llvm_context * ctx)
lp_build_context_init(&bld_base->base, &ctx->gallivm, type);
lp_build_context_init(&ctx->soa.bld_base.uint_bld, &ctx->gallivm, lp_uint_type(type));
+ lp_build_context_init(&ctx->soa.bld_base.int_bld, &ctx->gallivm, lp_int_type(type));
bld_base->soa = 1;
bld_base->emit_store = emit_store;
bld_base->emit_swizzle = emit_swizzle;
bld_base->emit_declaration = emit_declaration;
- bld_base->emit_immediate = lp_emit_immediate_soa;
+ bld_base->emit_immediate = emit_immediate;
bld_base->emit_fetch_funcs[TGSI_FILE_IMMEDIATE] = emit_fetch_immediate;
bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = emit_fetch_input;