gallivm: enable fetch for integer opcodes. (v2)
authorDave Airlie <airlied@redhat.com>
Mon, 6 Feb 2012 15:35:05 +0000 (15:35 +0000)
committerDave Airlie <airlied@redhat.com>
Fri, 17 Feb 2012 17:39:02 +0000 (17:39 +0000)
The infers the type of data required using the opcode,
and casts the input to the appropriate type.

So far this only handles non-indirect constant and temporaries.

v2: as per Jose suggestion, fetch immediates via floats

Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/auxiliary/gallivm/lp_bld_tgsi.c
src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c
src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c

index 261301ce542ed7ef1a99acdec168cc2b8a163672..e05ad81c302ca53e6af5ff3241a618430d313a89 100644 (file)
@@ -298,6 +298,7 @@ lp_build_emit_fetch(
    const struct tgsi_full_src_register *reg = &inst->Src[src_op];
    unsigned swizzle;
    LLVMValueRef res;
+   enum tgsi_opcode_type stype = tgsi_opcode_infer_src_type(inst->Instruction.Opcode);
 
    if (chan_index == LP_CHAN_ALL) {
       swizzle = ~0;
@@ -312,7 +313,7 @@ lp_build_emit_fetch(
    assert(reg->Register.Index <= bld_base->info->file_max[reg->Register.File]);
 
    if (bld_base->emit_fetch_funcs[reg->Register.File]) {
-      res = bld_base->emit_fetch_funcs[reg->Register.File](bld_base, reg,
+      res = bld_base->emit_fetch_funcs[reg->Register.File](bld_base, reg, stype,
                                                            swizzle);
    } else {
       assert(0 && "invalid src register in emit_fetch()");
index a36a09a8fa4124f7b6aed24b9bfcc93f37c9b4cf..b799900bfd7e209ea9f910c0ea1ec3028084cbf2 100644 (file)
@@ -45,7 +45,7 @@
 #include "pipe/p_state.h"
 #include "tgsi/tgsi_exec.h"
 #include "tgsi/tgsi_scan.h"
-
+#include "tgsi/tgsi_info.h"
 
 #define LP_CHAN_ALL ~0
 
@@ -273,6 +273,7 @@ struct lp_build_tgsi_context;
 
 typedef LLVMValueRef (*lp_build_emit_fetch_fn)(struct lp_build_tgsi_context *,
                                         const struct tgsi_full_src_register *,
+                                        enum tgsi_opcode_type,
                                         unsigned);
 
 struct lp_build_tgsi_context
index 2c2c820708a6785275f2d4e0d8e8b54f89403830..80c148124ee2daa9a96b899e1438e8cc13df37ae 100644 (file)
@@ -101,7 +101,8 @@ static LLVMValueRef
 emit_fetch_constant(
    struct lp_build_tgsi_context * bld_base,
    const struct tgsi_full_src_register * reg,
-   const unsigned swizzle)
+   enum tgsi_opcode_type stype,
+   unsigned swizzle)
 {
    struct lp_build_tgsi_aos_context * bld = lp_aos_context(bld_base);
    LLVMBuilderRef builder = bld_base->base.gallivm->builder;
@@ -171,7 +172,8 @@ static LLVMValueRef
 emit_fetch_immediate(
    struct lp_build_tgsi_context * bld_base,
    const struct tgsi_full_src_register * reg,
-   const unsigned swizzle)
+   enum tgsi_opcode_type stype,
+   unsigned swizzle)
 {
    struct lp_build_tgsi_aos_context * bld = lp_aos_context(bld_base);
    LLVMValueRef res = bld->immediates[reg->Register.Index];
@@ -183,7 +185,8 @@ static LLVMValueRef
 emit_fetch_input(
    struct lp_build_tgsi_context * bld_base,
    const struct tgsi_full_src_register * reg,
-   const unsigned swizzle)
+   enum tgsi_opcode_type stype,
+   unsigned swizzle)
 {
    struct lp_build_tgsi_aos_context * bld = lp_aos_context(bld_base);
    LLVMValueRef res = bld->inputs[reg->Register.Index];
@@ -196,7 +199,8 @@ static LLVMValueRef
 emit_fetch_temporary(
    struct lp_build_tgsi_context * bld_base,
    const struct tgsi_full_src_register * reg,
-   const unsigned swizzle)
+   enum tgsi_opcode_type stype,
+   unsigned swizzle)
 {
    struct lp_build_tgsi_aos_context * bld = lp_aos_context(bld_base);
    LLVMBuilderRef builder = bld_base->base.gallivm->builder;
index bc063253bcd1926bfc464ccb5e3f3df62b46e739..920fed22c816aed43b4b716bc80c435d20fda1bb 100644 (file)
@@ -519,18 +519,47 @@ get_indirect_index(struct lp_build_tgsi_soa_context *bld,
    return index;
 }
 
+static struct lp_build_context *
+stype_to_fetch(struct lp_build_tgsi_context * bld_base,
+              enum tgsi_opcode_type stype)
+{
+   struct lp_build_context *bld_fetch;
+
+   switch (stype) {
+   case TGSI_TYPE_FLOAT:
+   case TGSI_TYPE_UNTYPED:
+      bld_fetch = &bld_base->base;
+      break;
+   case TGSI_TYPE_UNSIGNED:
+      bld_fetch = &bld_base->uint_bld;
+      break;
+   case TGSI_TYPE_SIGNED:
+      bld_fetch = &bld_base->int_bld;
+      break;
+   case TGSI_TYPE_VOID:
+   case TGSI_TYPE_DOUBLE:
+   default:
+      assert(0);
+      bld_fetch = NULL;
+      break;
+   }
+   return bld_fetch;
+}
+
 static LLVMValueRef
 emit_fetch_constant(
    struct lp_build_tgsi_context * bld_base,
    const struct tgsi_full_src_register * reg,
-   const unsigned swizzle)
+   enum tgsi_opcode_type stype,
+   unsigned swizzle)
 {
    struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
    struct gallivm_state *gallivm = bld_base->base.gallivm;
    LLVMBuilderRef builder = gallivm->builder;
    struct lp_build_context *uint_bld = &bld_base->uint_bld;
    LLVMValueRef indirect_index = NULL;
-
+   struct lp_build_context *bld_fetch = stype_to_fetch(bld_base, stype);
+   
    /* XXX: Handle fetching xyzw components as a vector */
    assert(swizzle != ~0);
 
@@ -551,7 +580,7 @@ emit_fetch_constant(
       index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
 
       /* Gather values from the constant buffer */
-      return build_gather(&bld_base->base, bld->consts_ptr, index_vec);
+      return build_gather(bld_fetch, bld->consts_ptr, index_vec);
    }
    else {
       LLVMValueRef index;  /* index into the const buffer */
@@ -561,9 +590,16 @@ emit_fetch_constant(
 
       scalar_ptr = LLVMBuildGEP(builder, bld->consts_ptr,
                                    &index, 1, "");
-      scalar = LLVMBuildLoad(builder, scalar_ptr, "");
 
-      return lp_build_broadcast_scalar(&bld->bld_base.base, scalar);
+      if (stype != TGSI_TYPE_FLOAT && stype != TGSI_TYPE_UNTYPED) {
+         LLVMTypeRef ivtype = LLVMPointerType(LLVMInt32TypeInContext(gallivm->context), 0);
+         LLVMValueRef temp_ptr;
+         temp_ptr = LLVMBuildBitCast(builder, scalar_ptr, ivtype, "");
+         scalar = LLVMBuildLoad(builder, temp_ptr, "");
+      } else
+         scalar = LLVMBuildLoad(builder, scalar_ptr, "");
+
+      return lp_build_broadcast_scalar(bld_fetch, scalar);
    }
 }
 
@@ -571,11 +607,18 @@ static LLVMValueRef
 emit_fetch_immediate(
    struct lp_build_tgsi_context * bld_base,
    const struct tgsi_full_src_register * reg,
-   const unsigned swizzle)
+   enum tgsi_opcode_type stype,
+   unsigned swizzle)
 {
    struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
    LLVMValueRef res = bld->immediates[reg->Register.Index][swizzle];
    assert(res);
+
+   if (stype == TGSI_TYPE_UNSIGNED) {
+      res = LLVMConstBitCast(res, bld_base->uint_bld.vec_type);
+   } else if (stype == TGSI_TYPE_SIGNED) {
+      res = LLVMConstBitCast(res, bld_base->int_bld.vec_type);
+   }
    return res;
 }
 
@@ -583,7 +626,8 @@ static LLVMValueRef
 emit_fetch_input(
    struct lp_build_tgsi_context * bld_base,
    const struct tgsi_full_src_register * reg,
-   const unsigned swizzle)
+   enum tgsi_opcode_type stype,
+   unsigned swizzle)
 {
    struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
    struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
@@ -640,7 +684,8 @@ static LLVMValueRef
 emit_fetch_temporary(
    struct lp_build_tgsi_context * bld_base,
    const struct tgsi_full_src_register * reg,
-   const unsigned swizzle)
+   enum tgsi_opcode_type stype,
+   unsigned swizzle)
 {
    struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
    struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
@@ -681,7 +726,13 @@ emit_fetch_temporary(
    }
    else {
       LLVMValueRef temp_ptr;
-      temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle);
+      if (stype != TGSI_TYPE_FLOAT && stype != TGSI_TYPE_UNTYPED) {
+         LLVMTypeRef itype = LLVMPointerType(LLVMVectorType(LLVMInt32TypeInContext(gallivm->context), 4), 0);
+         LLVMValueRef tint_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index,
+                                                     swizzle);
+         temp_ptr = LLVMBuildBitCast(builder, tint_ptr, itype, "");
+      } else
+         temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle);
       res = LLVMBuildLoad(builder, temp_ptr, "");
       if (!res)
          return bld->bld_base.base.undef;
@@ -694,7 +745,8 @@ static LLVMValueRef
 emit_fetch_system_value(
    struct lp_build_tgsi_context * bld_base,
    const struct tgsi_full_src_register * reg,
-   const unsigned swizzle)
+   enum tgsi_opcode_type stype,
+   unsigned swizzle)
 {
    struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
    struct gallivm_state *gallivm = bld->bld_base.base.gallivm;