Mesa (master): gallivm/soa: implement indirect addressing in immediates

Zack Rusin zack at kemper.freedesktop.org
Tue May 14 18:51:50 UTC 2013


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

Author: Zack Rusin <zackr at vmware.com>
Date:   Tue May  7 15:59:56 2013 -0400

gallivm/soa: implement indirect addressing in immediates

The support is analogous to the way we handle indirect addressing
in temporaries, except that we don't have to worry about storing
(after declarations) and thus we'll able to keep using the old
code when indirect addressing isn't used. In other words we're
still using constants directly, unless the instruction has
immediate register with indirect addressing.

Signed-off-by: Zack Rusin <zackr at vmware.com>
Reviewed-by: José Fonseca <jfonseca at vmware.com>
Reviewed-by: Roland Scheidegger <sroland at vmware.com>

---

 src/gallium/auxiliary/gallivm/lp_bld_tgsi.h     |    6 ++
 src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c |   78 ++++++++++++++++++++++-
 2 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
index 9d9c742..fd566b1 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
@@ -453,6 +453,12 @@ struct lp_build_tgsi_soa_context
     */
    LLVMValueRef inputs_array;
 
+   /* We allocate/use this array of temps if (1 << TGSI_FILE_IMMEDIATE) is
+    * set in the indirect_files field.
+    */
+   LLVMValueRef imms_array;
+
+
    struct lp_bld_tgsi_system_values system_values;
 
    /** bitmask indicating which register files are accessed indirectly */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 733f0ed..066f64a 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -972,8 +972,58 @@ emit_fetch_immediate(
    unsigned swizzle)
 {
    struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
-   LLVMValueRef res = bld->immediates[reg->Register.Index][swizzle];
-   assert(res);
+   struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
+   LLVMBuilderRef builder = gallivm->builder;
+   struct lp_build_context *uint_bld = &bld_base->uint_bld;
+   struct lp_build_context *float_bld = &bld_base->base;
+   LLVMValueRef res = NULL;
+   LLVMValueRef indirect_index = NULL;
+
+   if (reg->Register.Indirect) {
+      indirect_index = get_indirect_index(bld,
+                                          reg->Register.File,
+                                          reg->Register.Index,
+                                          &reg->Indirect);
+   }
+
+   if (reg->Register.Indirect) {
+      LLVMValueRef swizzle_vec =
+         lp_build_const_int_vec(bld->bld_base.base.gallivm,
+                                uint_bld->type, swizzle);
+      LLVMValueRef length_vec =
+         lp_build_const_int_vec(bld->bld_base.base.gallivm, uint_bld->type,
+                                bld->bld_base.base.type.length);
+      LLVMValueRef index_vec;  /* index into the const buffer */
+      LLVMValueRef imms_array;
+      LLVMValueRef pixel_offsets;
+      LLVMValueRef offsets[LP_MAX_VECTOR_LENGTH];
+      LLVMTypeRef float4_ptr_type;
+      int i;
+
+      /* build pixel offset vector: {0, 1, 2, 3, ...} */
+      for (i = 0; i < float_bld->type.length; i++) {
+         offsets[i] = lp_build_const_int32(gallivm, i);
+      }
+      pixel_offsets = LLVMConstVector(offsets, float_bld->type.length);
+
+      /* index_vec = (indirect_index * 4 + swizzle) * length */
+      index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
+      index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
+      index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
+      index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
+
+      /* cast imms_array pointer to float* */
+      float4_ptr_type = LLVMPointerType(
+         LLVMFloatTypeInContext(bld->bld_base.base.gallivm->context), 0);
+      imms_array = LLVMBuildBitCast(builder, bld->imms_array,
+                                    float4_ptr_type, "");
+
+      /* Gather values from the temporary register array */
+      res = build_gather(&bld_base->base, imms_array, index_vec);
+   }
+   else {
+      res = bld->immediates[reg->Register.Index][swizzle];
+   }
 
    if (stype == TGSI_TYPE_UNSIGNED) {
       res = LLVMConstBitCast(res, bld_base->uint_bld.vec_type);
@@ -2222,6 +2272,21 @@ void lp_emit_immediate_soa(
    for( i = size; i < 4; ++i )
       bld->immediates[bld->num_immediates][i] = bld_base->base.undef;
 
+   if (bld->indirect_files & (1 << TGSI_FILE_IMMEDIATE)) {
+      unsigned index = bld->num_immediates;
+      struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
+      LLVMBuilderRef builder = gallivm->builder;
+      for (i = 0; i < 4; ++i ) {
+         LLVMValueRef lindex = lp_build_const_int32(
+            bld->bld_base.base.gallivm, index * 4 + i);
+         LLVMValueRef imm_ptr = LLVMBuildGEP(builder,
+                                             bld->imms_array, &lindex, 1, "");
+         LLVMBuildStore(builder, 
+                        bld->immediates[index][i],
+                        imm_ptr);
+      }
+   }
+
    bld->num_immediates++;
 }
 
@@ -2934,6 +2999,15 @@ static void emit_prologue(struct lp_build_tgsi_context * bld_base)
                                                 "output_array");
    }
 
+   if (bld->indirect_files & (1 << TGSI_FILE_IMMEDIATE)) {
+      LLVMValueRef array_size =
+         lp_build_const_int32(gallivm,
+                         bld_base->info->file_max[TGSI_FILE_IMMEDIATE] * 4 + 4);
+      bld->imms_array = lp_build_array_alloca(gallivm,
+                                              bld_base->base.vec_type, array_size,
+                                              "imms_array");
+   }
+
    /* If we have indirect addressing in inputs we need to copy them into
     * our alloca array to be able to iterate over them */
    if (bld->indirect_files & (1 << TGSI_FILE_INPUT) && !bld->gs_iface) {




More information about the mesa-commit mailing list