[Mesa-dev] [PATCH 2/3] draw: fix vertex id computation

Zack Rusin zackr at vmware.com
Tue Jul 23 09:20:50 PDT 2013


vertex id has to be unaffected by the start index (i.e. when calling
draw arrays with start_index = 5, the first vertex_id has to still
be 0, not 5) and it has to be equal to the index when performing
indexed rendering (in which case it has to be unaffected by the
index bias). This fixes our behavior.

Signed-off-by: Zack Rusin <zackr at vmware.com>
---
 src/gallium/auxiliary/draw/draw_llvm.c    |   37 ++++++++++++++++++++++-------
 src/gallium/auxiliary/draw/draw_private.h |    1 +
 src/gallium/auxiliary/draw/draw_pt.c      |    1 +
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index a3174b4..adf3941 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -1646,22 +1646,19 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
 #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 true_index =
+         LLVMValueRef vert_index =
             LLVMBuildAdd(builder,
                          lp_loop.counter,
                          lp_build_const_int32(gallivm, i), "");
-         true_index = LLVMBuildAdd(builder, start, true_index, "");
+         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
           * a few of the 4 vertex fetches will be out of bounds */
          true_index = lp_build_min(&bld, true_index, fetch_max);
 
-         system_values.vertex_id = LLVMBuildInsertElement(
-            gallivm->builder,
-            system_values.vertex_id, true_index,
-            lp_build_const_int32(gallivm, i), "");
-
          if (elts) {
             LLVMValueRef fetch_ptr;
             LLVMValueRef index_overflowed;
@@ -1673,7 +1670,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
             index_overflowed = LLVMBuildICmp(builder, LLVMIntUGT,
                                              true_index, fetch_elt_max,
                                              "index_overflowed");
-            
+
             lp_build_if(&if_ctx, gallivm, index_overflowed);
             {
                /* Generate maximum possible index so that
@@ -1697,8 +1694,32 @@ 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");
+            /* 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.
+             */
+            vertex_id = LLVMBuildSub(
+               builder, true_index,
+               lp_build_const_int32(gallivm, draw->pt.user.eltBias), "");
+         } else {
+            /* 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,
+               lp_build_const_int32(gallivm, draw->start_index), "");
          }
 
+         system_values.vertex_id = LLVMBuildInsertElement(
+            gallivm->builder,
+            system_values.vertex_id, vertex_id,
+            lp_build_const_int32(gallivm, i), "");
+
          for (j = 0; j < draw->pt.nr_vertex_elements; ++j) {
             struct pipe_vertex_element *velem = &draw->pt.vertex_element[j];
             LLVMValueRef vb_index =
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index d8cd8eb..868b6c7 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -311,6 +311,7 @@ struct draw_context
 
    unsigned instance_id;
    unsigned start_instance;
+   unsigned start_index;
 
 #ifdef HAVE_LLVM
    struct draw_llvm *llvm;
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index fcc2405..5b16bc7 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -535,6 +535,7 @@ draw_vbo(struct draw_context *draw,
    }
 
    draw->pt.max_index = index_limit - 1;
+   draw->start_index = info->start;
 
    /*
     * TODO: We could use draw->pt.max_index to further narrow
-- 
1.7.10.4


More information about the mesa-dev mailing list