Mesa (master): gallivm: implement correct indirect addressing of temp registers

Brian Paul brianp at kemper.freedesktop.org
Wed Jul 21 16:19:54 UTC 2010


Module: Mesa
Branch: master
Commit: 105ed7dfd4abc94db1ce0cba2967ac0491158389
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=105ed7dfd4abc94db1ce0cba2967ac0491158389

Author: Brian Paul <brianp at vmware.com>
Date:   Wed Jul 21 09:10:49 2010 -0600

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.

---

 src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c |   40 ++++++++++++++++------
 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 4e640f5..0e45d74 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;




More information about the mesa-commit mailing list