summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2010-07-21 09:10:49 -0600
committerBrian Paul <brianp@vmware.com>2010-07-21 10:16:32 -0600
commit105ed7dfd4abc94db1ce0cba2967ac0491158389 (patch)
treea796cd7fba19388b7106b1095b80be31bde20446 /src/gallium
parent695814a15b4d64e1fa829d51f18c4089837929c3 (diff)
gallivm: implement correct indirect addressing of temp registers
As with indexing the const buffer, the ADDR reg may have totally different values for each element. Need to use a gather operation.
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 4e640f5903..0e45d748f4 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -549,22 +549,40 @@ emit_fetch(
break;
case TGSI_FILE_TEMPORARY:
- {
- LLVMValueRef addr = NULL;
- LLVMValueRef temp_ptr;
+ if (reg->Register.Indirect) {
+ LLVMValueRef vec_len =
+ lp_build_const_int_vec(bld->int_bld.type, bld->base.type.length);
+ LLVMValueRef index_vec; /* index into the const buffer */
+ LLVMValueRef temps_array;
+ LLVMTypeRef float4_ptr_type;
- if (reg->Register.Indirect) {
- LLVMValueRef zero = lp_build_const_int32(0);
- addr = LLVMBuildExtractElement(bld->base.builder,
- addr_vec, zero, "");
- }
+ assert(bld->has_indirect_addressing);
+
+ /* index_vec = broadcast(reg->Register.Index * 4 + swizzle) */
+ index_vec = lp_build_const_int_vec(bld->int_bld.type,
+ reg->Register.Index * 4 + swizzle);
+ /* index_vec += addr_vec */
+ index_vec = lp_build_add(&bld->int_bld, index_vec, addr_vec);
+
+ /* index_vec *= vector_length */
+ index_vec = lp_build_mul(&bld->int_bld, index_vec, vec_len);
+
+ /* cast temps_array pointer to float* */
+ float4_ptr_type = LLVMPointerType(LLVMFloatType(), 0);
+ temps_array = LLVMBuildBitCast(bld->int_bld.builder, bld->temps_array,
+ float4_ptr_type, "");
+
+ /* Gather values from the temporary register array */
+ res = build_gather(bld, temps_array, index_vec);
+ }
+ else {
+ LLVMValueRef temp_ptr;
temp_ptr = get_temp_ptr(bld, reg->Register.Index,
swizzle,
- reg->Register.Indirect,
- addr);
+ FALSE, NULL);
res = LLVMBuildLoad(bld->base.builder, temp_ptr, "");
- if(!res)
+ if (!res)
return bld->base.undef;
}
break;