llvmpipe: Simplify and fix system variables fetch.
authorOlivier Galibert <galibert@pobox.com>
Tue, 19 Jun 2012 18:51:20 +0000 (20:51 +0200)
committerBrian Paul <brianp@vmware.com>
Tue, 19 Jun 2012 20:40:44 +0000 (14:40 -0600)
The system array values concept doesn't really because it expects the
system values to be fixed per call, which is wrong for gl_VertexID and
iffy for gl_SampleID.  So this patch does two things:

- kill the array, have emit_fetch_system_value directly pick the
  values it needs (only gl_InstanceID for now, as the previous code)

- correctly handle the expected type in emit_fetch_system_value

Signed-off-by: Olivier Galibert <galibert@pobox.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
src/gallium/drivers/llvmpipe/lp_state_fs.c

index e1df2f1c267bdc86bb5b6e9f5ab0b6753bd2d79a..8e787c580dbf7f5403506c47ab03a2330c9b6d4c 100644 (file)
@@ -459,7 +459,7 @@ generate_vs(struct draw_llvm *llvm,
             LLVMBuilderRef builder,
             LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS],
             const LLVMValueRef (*inputs)[TGSI_NUM_CHANNELS],
-            LLVMValueRef system_values_array,
+            LLVMValueRef instance_id,
             LLVMValueRef context_ptr,
             struct lp_build_sampler_soa *draw_sampler,
             boolean clamp_vertex_color)
@@ -491,7 +491,7 @@ generate_vs(struct draw_llvm *llvm,
                      vs_type,
                      NULL /*struct lp_build_mask_context *mask*/,
                      consts_ptr,
-                     system_values_array,
+                     instance_id,
                      NULL /*pos*/,
                      inputs,
                      outputs,
@@ -1249,7 +1249,6 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
    LLVMValueRef stride, step, io_itr;
    LLVMValueRef io_ptr, vbuffers_ptr, vb_ptr;
    LLVMValueRef instance_id;
-   LLVMValueRef system_values_array;
    LLVMValueRef zero = lp_build_const_int32(gallivm, 0);
    LLVMValueRef one = lp_build_const_int32(gallivm, 1);
    struct draw_context *draw = llvm->draw;
@@ -1340,9 +1339,6 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
 
    lp_build_context_init(&bld, gallivm, lp_type_int(32));
 
-   system_values_array = lp_build_system_values_array(gallivm, vs_info,
-                                                      instance_id, NULL);
-
    /* function will return non-zero i32 value if any clipped vertices */
    ret_ptr = lp_build_alloca(gallivm, int32_type, "");
    LLVMBuildStore(builder, zero, ret_ptr);
@@ -1418,7 +1414,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
                   builder,
                   outputs,
                   ptr_aos,
-                  system_values_array,
+                  instance_id,
                   context_ptr,
                   sampler,
                   variant->key.clamp_vertex_color);
index 141e799c4e4b1900005ad18a294ba80f5197a9d8..c4e690c43c6611eef5f8abbd96164c94e0009cac 100644 (file)
@@ -205,7 +205,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm,
                   struct lp_type type,
                   struct lp_build_mask_context *mask,
                   LLVMValueRef consts_ptr,
-                  LLVMValueRef system_values_array,
+                  LLVMValueRef instance_id,
                   const LLVMValueRef *pos,
                   const LLVMValueRef (*inputs)[4],
                   LLVMValueRef (*outputs)[4],
@@ -225,13 +225,6 @@ lp_build_tgsi_aos(struct gallivm_state *gallivm,
                   const struct tgsi_shader_info *info);
 
 
-LLVMValueRef
-lp_build_system_values_array(struct gallivm_state *gallivm,
-                             const struct tgsi_shader_info *info,
-                             LLVMValueRef instance_id,
-                             LLVMValueRef facing);
-
-
 struct lp_exec_mask {
    struct lp_build_context *bld;
 
@@ -388,7 +381,7 @@ struct lp_build_tgsi_soa_context
     */
    LLVMValueRef inputs_array;
 
-   LLVMValueRef system_values_array;
+   LLVMValueRef instance_id;
 
    /** bitmask indicating which register files are accessed indirectly */
    unsigned indirect_files;
index 412dc0c622a68222930affd3dc28accb01816db5..26be9021fdf38eb5b8e082095ad2ff2c0cc62324 100644 (file)
@@ -786,18 +786,37 @@ emit_fetch_system_value(
 {
    struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
    struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
+   const struct tgsi_shader_info *info = bld->bld_base.info;
    LLVMBuilderRef builder = gallivm->builder;
-   LLVMValueRef index;  /* index into the system value array */
-   LLVMValueRef scalar, scalar_ptr;
+   LLVMValueRef res;
+   enum tgsi_opcode_type atype; // Actual type of the value
 
    assert(!reg->Register.Indirect);
 
-   index = lp_build_const_int32(gallivm, reg->Register.Index * 4 + swizzle);
+   switch (info->system_value_semantic_name[reg->Register.Index]) {
+   case TGSI_SEMANTIC_INSTANCEID:
+      res = lp_build_broadcast_scalar(&bld_base->uint_bld, bld->instance_id);
+      atype = TGSI_TYPE_UNSIGNED;
+      break;
 
-   scalar_ptr = LLVMBuildGEP(builder, bld->system_values_array, &index, 1, "");
-   scalar = LLVMBuildLoad(builder, scalar_ptr, "");
+   default:
+      assert(!"unexpected semantic in emit_fetch_system_value");
+      res = bld_base->base.zero;
+      atype = TGSI_TYPE_FLOAT;
+      break;
+   }
+
+   if (atype != stype) {
+      if (stype == TGSI_TYPE_FLOAT) {
+         res = LLVMBuildBitCast(builder, res, bld_base->base.vec_type, "");
+      } else if (stype == TGSI_TYPE_UNSIGNED) {
+         res = LLVMBuildBitCast(builder, res, bld_base->uint_bld.vec_type, "");
+      } else if (stype == TGSI_TYPE_SIGNED) {
+         res = LLVMBuildBitCast(builder, res, bld_base->int_bld.vec_type, "");
+      }
+   }
 
-   return lp_build_broadcast_scalar(&bld->bld_base.base, scalar);
+   return res;
 }
 
 /**
@@ -1976,7 +1995,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm,
                   struct lp_type type,
                   struct lp_build_mask_context *mask,
                   LLVMValueRef consts_ptr,
-                  LLVMValueRef system_values_array,
+                  LLVMValueRef instance_id,
                   const LLVMValueRef *pos,
                   const LLVMValueRef (*inputs)[TGSI_NUM_CHANNELS],
                   LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS],
@@ -2051,8 +2070,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm,
 
    lp_exec_mask_init(&bld.exec_mask, &bld.bld_base.base);
 
-
-   bld.system_values_array = system_values_array;
+   bld.instance_id = instance_id;
 
    lp_build_tgsi_llvm(&bld.bld_base, tokens);
 
@@ -2072,55 +2090,3 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm,
 
    }
 }
-
-
-/**
- * Build up the system values array out of individual values such as
- * the instance ID, front-face, primitive ID, etc.  The shader info is
- * used to determine which system values are needed and where to put
- * them in the system values array.
- *
- * XXX only instance ID is implemented at this time.
- *
- * The system values register file is similar to the constants buffer.
- * Example declaration:
- *    DCL SV[0], INSTANCEID
- * Example instruction:
- *    MOVE foo, SV[0].xxxx;
- *
- * \return  LLVM float array (interpreted as float [][4])
- */
-LLVMValueRef
-lp_build_system_values_array(struct gallivm_state *gallivm,
-                             const struct tgsi_shader_info *info,
-                             LLVMValueRef instance_id,
-                             LLVMValueRef facing)
-{
-   LLVMValueRef size = lp_build_const_int32(gallivm, 4 * info->num_system_values);
-   LLVMTypeRef float_t = LLVMFloatTypeInContext(gallivm->context);
-   LLVMValueRef array = lp_build_array_alloca(gallivm, float_t,
-                                              size, "sysvals_array");
-   unsigned i;
-
-   for (i = 0; i < info->num_system_values; i++) {
-      LLVMValueRef index = lp_build_const_int32(gallivm, i * 4);
-      LLVMValueRef ptr, value = 0;
-
-      switch (info->system_value_semantic_name[i]) {
-      case TGSI_SEMANTIC_INSTANCEID:
-         /* convert instance ID from int to float */
-         value = LLVMBuildSIToFP(gallivm->builder, instance_id, float_t,
-                                 "sysval_instanceid");
-         break;
-      case TGSI_SEMANTIC_FACE:
-         /* fall-through */
-      default:
-         assert(0 && "unexpected semantic in build_system_values_array()");
-      }
-
-      ptr = LLVMBuildGEP(gallivm->builder, array, &index, 1, "");
-      LLVMBuildStore(gallivm->builder, value, ptr);
-   }
-      
-   return array;
-}
index 7dd4969105173fe6f244fcfecf91b2c544fcd644..2fa5d2ccc0d7b4a97413c611909d36b632c62793 100644 (file)
@@ -334,7 +334,7 @@ generate_fs(struct gallivm_state *gallivm,
    
    /* Build the actual shader */
    lp_build_tgsi_soa(gallivm, tokens, type, &mask,
-                     consts_ptr, NULL, /* sys values array */
+                     consts_ptr, NULL, /* instance id */
                      interp->pos, interp->inputs,
                      outputs, sampler, &shader->info.base);