draw: implement support for the VERTEXID_NOBASE and BASEVERTEX semantics.
authorRoland Scheidegger <sroland@vmware.com>
Fri, 12 Dec 2014 03:13:54 +0000 (04:13 +0100)
committerRoland Scheidegger <sroland@vmware.com>
Tue, 16 Dec 2014 03:23:00 +0000 (04:23 +0100)
This fixes 4 vertexid related piglit tests with llvmpipe due to switching
behavior of vertexid to the one gl expects.
(Won't fix non-llvm draw path since we don't get the basevertex currently.)

src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/draw/draw_vs_exec.c
src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c

index 832607251d7f7e3d16cd7096775655aeda30a147..e7a72f9f1a25837f28201134262820786840b409 100644 (file)
@@ -1653,6 +1653,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
       LLVMValueRef aos_attribs[PIPE_MAX_SHADER_INPUTS][LP_MAX_VECTOR_WIDTH / 32] = { { 0 } };
       LLVMValueRef io;
       LLVMValueRef clipmask;   /* holds the clipmask value */
+      LLVMValueRef true_index_array = lp_build_zero(gallivm,
+                                                    lp_type_uint_vec(32, 32*vector_length));
       const LLVMValueRef (*ptr_aos)[TGSI_NUM_CHANNELS];
 
       io_itr = lp_loop.counter;
@@ -1662,7 +1664,6 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
       lp_build_printf(gallivm, " --- io %d = %p, loop counter %d\n",
                       io_itr, io, lp_loop.counter);
 #endif
-      system_values.vertex_id = lp_build_zero(gallivm, lp_type_uint_vec(32, 32*vector_length));
       for (i = 0; i < vector_length; ++i) {
          LLVMValueRef vert_index =
             LLVMBuildAdd(builder,
@@ -1670,7 +1671,6 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
                          lp_build_const_int32(gallivm, i), "");
          LLVMValueRef true_index =
             LLVMBuildAdd(builder, start, vert_index, "");
-         LLVMValueRef vertex_id;
 
          /* make sure we're not out of bounds which can happen
           * if fetch_count % 4 != 0, because on the last iteration
@@ -1713,22 +1713,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
             lp_build_endif(&if_ctx);
             true_index = LLVMBuildLoad(builder, index_ptr, "true_index");
          }
-         /* in the paths with elts vertex id has to be unaffected by the
-          * index bias and because indices inside our elements array have
-          * already had index bias applied we need to subtract it here to
-          * get back to the original index.
-          * in the linear paths vertex id has to be unaffected by the
-          * original start index and because we abuse the 'start' variable
-          * to either represent the actual start index or the index at which
-          * the primitive was split (we split rendering into chunks of at
-          * most 4095-vertices) we need to back out the original start
-          * index out of our vertex id here.
-          */
-         vertex_id = LLVMBuildSub(builder, true_index, vertex_id_offset, "");
-
-         system_values.vertex_id = LLVMBuildInsertElement(
-            gallivm->builder,
-            system_values.vertex_id, vertex_id,
+         true_index_array = LLVMBuildInsertElement(
+            gallivm->builder, true_index_array, true_index,
             lp_build_const_int32(gallivm, i), "");
 
          for (j = 0; j < draw->pt.nr_vertex_elements; ++j) {
@@ -1744,6 +1730,24 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
       convert_to_soa(gallivm, aos_attribs, inputs,
                      draw->pt.nr_vertex_elements, vs_type);
 
+      /* In the paths with elts vertex id has to be unaffected by the
+       * index bias and because indices inside our elements array have
+       * already had index bias applied we need to subtract it here to
+       * get back to the original index.
+       * in the linear paths vertex id has to be unaffected by the
+       * original start index and because we abuse the 'start' variable
+       * to either represent the actual start index or the index at which
+       * the primitive was split (we split rendering into chunks of at
+       * most 4095-vertices) we need to back out the original start
+       * index out of our vertex id here.
+       */
+      system_values.basevertex = lp_build_broadcast(gallivm, lp_build_vec_type(gallivm,
+                                                       lp_type_uint_vec(32, 32*vector_length)),
+                                                    vertex_id_offset);
+      system_values.vertex_id = true_index_array;
+      system_values.vertex_id_nobase = LLVMBuildSub(builder, true_index_array,
+                                                      system_values.basevertex, "");
+
       ptr_aos = (const LLVMValueRef (*)[TGSI_NUM_CHANNELS]) inputs;
       generate_vs(variant,
                   builder,
index 277d739e2c51f01ba2330ad5efdae61c236b83f4..17b54b6fe742c663d6d5cec28fea269f8620516b 100644 (file)
@@ -129,6 +129,18 @@ vs_exec_run_linear( struct draw_vertex_shader *shader,
             unsigned vid = machine->SysSemanticToIndex[TGSI_SEMANTIC_VERTEXID];
             assert(vid < Elements(machine->SystemValue));
             machine->SystemValue[vid].i[j] = i + j;
+            /* XXX this should include base vertex. Where to get it??? */
+         }
+         if (shader->info.uses_basevertex) {
+            unsigned vid = machine->SysSemanticToIndex[TGSI_SEMANTIC_BASEVERTEX];
+            assert(vid < Elements(machine->SystemValue));
+            machine->SystemValue[vid].i[j] = 0;
+            /* XXX Where to get it??? */
+         }
+         if (shader->info.uses_vertexid_nobase) {
+            unsigned vid = machine->SysSemanticToIndex[TGSI_SEMANTIC_VERTEXID_NOBASE];
+            assert(vid < Elements(machine->SystemValue));
+            machine->SystemValue[vid].i[j] = i + j;
          }
 
          for (slot = 0; slot < shader->info.num_inputs; slot++) {
@@ -144,7 +156,7 @@ vs_exec_run_linear( struct draw_vertex_shader *shader,
             machine->Inputs[slot].xyzw[3].f[j] = input[slot][3];
          }
 
-        input = (const float (*)[4])((const char *)input + input_stride);
+         input = (const float (*)[4])((const char *)input + input_stride);
       } 
 
       tgsi_set_exec_mask(machine,
index 029ca3c8410c8361fafc666c7308480e13040ca9..b411f05674d2e3c2fda56d616c4f71161974c8b1 100644 (file)
@@ -162,7 +162,9 @@ struct lp_tgsi_info
 struct lp_bld_tgsi_system_values {
    LLVMValueRef instance_id;
    LLVMValueRef vertex_id;
+   LLVMValueRef vertex_id_nobase;
    LLVMValueRef prim_id;
+   LLVMValueRef basevertex;
 };
 
 
index 76b9d69264ff6208c956a7ff53fff394d863423e..3dfff05c22baa129bac280eb99addc77dac505a6 100644 (file)
@@ -1538,6 +1538,16 @@ emit_fetch_system_value(
       atype = TGSI_TYPE_UNSIGNED;
       break;
 
+   case TGSI_SEMANTIC_VERTEXID_NOBASE:
+      res = bld->system_values.vertex_id_nobase;
+      atype = TGSI_TYPE_UNSIGNED;
+      break;
+
+   case TGSI_SEMANTIC_BASEVERTEX:
+      res = bld->system_values.basevertex;
+      atype = TGSI_TYPE_UNSIGNED;
+      break;
+
    case TGSI_SEMANTIC_PRIMID:
       res = bld->system_values.prim_id;
       atype = TGSI_TYPE_UNSIGNED;