Mesa (master): gallivm: fix indirect addressing of constant buffer

Brian Paul brianp at kemper.freedesktop.org
Wed Jul 21 00:51:03 UTC 2010


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

Author: Brian Paul <brianp at vmware.com>
Date:   Tue Jul 20 18:48:53 2010 -0600

gallivm: fix indirect addressing of constant buffer

The previous code assumed that all elements of the address register
were the same.  But it can vary from pixel to pixel or vertex to
vertex so we must use a gather operation when dynamically indexing
the constant buffer.

Still need to fix this for the temporary register file...

---

 src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c |  108 +++++++++++++++++-----
 1 files changed, 83 insertions(+), 25 deletions(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index dec7556..3515d26 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -49,6 +49,7 @@
 #include "lp_bld_type.h"
 #include "lp_bld_const.h"
 #include "lp_bld_arit.h"
+#include "lp_bld_gather.h"
 #include "lp_bld_logic.h"
 #include "lp_bld_swizzle.h"
 #include "lp_bld_flow.h"
@@ -423,6 +424,38 @@ get_temp_ptr(struct lp_build_tgsi_soa_context *bld,
    }
 }
 
+
+/**
+ * Gather vector.
+ * XXX the lp_build_gather() function should be capable of doing this
+ * with a little work.
+ */
+static LLVMValueRef
+build_gather(struct lp_build_tgsi_soa_context *bld,
+             LLVMValueRef base_ptr,
+             LLVMValueRef indexes)
+{
+   LLVMValueRef res = bld->base.undef;
+   unsigned i;
+
+   /*
+    * Loop over elements of index_vec, load scalar value, insert it into 'res'.
+    */
+   for (i = 0; i < bld->base.type.length; i++) {
+      LLVMValueRef ii = LLVMConstInt(LLVMInt32Type(), i, 0);
+      LLVMValueRef index = LLVMBuildExtractElement(bld->base.builder,
+                                                   indexes, ii, "");
+      LLVMValueRef scalar_ptr = LLVMBuildGEP(bld->base.builder, base_ptr,
+                                             &index, 1, "");
+      LLVMValueRef scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
+
+      res = LLVMBuildInsertElement(bld->base.builder, res, scalar, ii, "");
+   }
+
+   return res;
+}
+
+
 /**
  * Register fetch.
  */
@@ -437,7 +470,7 @@ emit_fetch(
    const unsigned swizzle =
       tgsi_util_get_full_src_register_swizzle(reg, chan_index);
    LLVMValueRef res;
-   LLVMValueRef addr = NULL;
+   LLVMValueRef addr_vec = NULL;
 
    if (swizzle > 3) {
       assert(0 && "invalid swizzle in emit_fetch()");
@@ -447,35 +480,51 @@ emit_fetch(
    if (reg->Register.Indirect) {
       LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->base.type);
       unsigned swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect, chan_index );
-      addr = LLVMBuildLoad(bld->base.builder,
-                           bld->addr[reg->Indirect.Index][swizzle],
-                           "");
+
+      LLVMValueRef vec4 = lp_build_const_int_vec(bld->int_bld.type, 4); 
+
+      assert(bld->has_indirect_addressing);
+
+      addr_vec = LLVMBuildLoad(bld->base.builder,
+                               bld->addr[reg->Indirect.Index][swizzle],
+                               "load addr");
+
       /* for indexing we want integers */
-      addr = LLVMBuildFPToSI(bld->base.builder, addr,
-                             int_vec_type, "");
-      addr = LLVMBuildExtractElement(bld->base.builder,
-                                     addr, LLVMConstInt(LLVMInt32Type(), 0, 0),
-                                     "");
-      addr = lp_build_mul(&bld->base, addr, LLVMConstInt(LLVMInt32Type(), 4, 0));
+      addr_vec = LLVMBuildFPToSI(bld->base.builder, addr_vec,
+                                 int_vec_type, "");
+
+      /* addr_vec = addr_vec * 4 */
+      addr_vec = lp_build_mul(&bld->base, addr_vec, vec4);
    }
 
    switch (reg->Register.File) {
    case TGSI_FILE_CONSTANT:
       {
-         LLVMValueRef index = LLVMConstInt(LLVMInt32Type(),
-                                           reg->Register.Index*4 + swizzle, 0);
-         LLVMValueRef scalar, scalar_ptr;
-
          if (reg->Register.Indirect) {
-            /*lp_build_printf(bld->base.builder,
-              "\taddr = %d\n", addr);*/
-            index = lp_build_add(&bld->base, index, addr);
+            LLVMValueRef index_vec;  /* index into the const buffer */
+
+            /* 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 = index_vec + addr_vec */
+            index_vec = lp_build_add(&bld->base, index_vec, addr_vec);
+
+            /* Gather values from the constant buffer */
+            res = build_gather(bld, bld->consts_ptr, index_vec);
          }
-         scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr,
-                                   &index, 1, "");
-         scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
+         else {
+            LLVMValueRef index;  /* index into the const buffer */
+            LLVMValueRef scalar, scalar_ptr;
+
+            index = lp_build_const_int32(reg->Register.Index*4 + swizzle);
+
+            scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr,
+                                      &index, 1, "");
+            scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
 
-         res = lp_build_broadcast_scalar(&bld->base, scalar);
+            res = lp_build_broadcast_scalar(&bld->base, scalar);
+         }
       }
       break;
 
@@ -491,10 +540,19 @@ emit_fetch(
 
    case TGSI_FILE_TEMPORARY:
       {
-         LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index,
-                                              swizzle,
-                                              reg->Register.Indirect,
-                                              addr);
+         LLVMValueRef addr = NULL;
+         LLVMValueRef temp_ptr;
+
+         if (reg->Register.Indirect) {
+            LLVMValueRef zero = lp_build_const_int32(0);
+            addr = LLVMBuildExtractElement(bld->base.builder,
+                                           addr_vec, zero, "");
+         }
+
+         temp_ptr = get_temp_ptr(bld, reg->Register.Index,
+                                 swizzle,
+                                 reg->Register.Indirect,
+                                 addr);
          res = LLVMBuildLoad(bld->base.builder, temp_ptr, "");
          if(!res)
             return bld->base.undef;




More information about the mesa-commit mailing list