Fix up more confusions with count vs end in array functions
authorKeith Whitwell <keith@tungstengraphics.com>
Wed, 14 Jan 2004 10:52:51 +0000 (10:52 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Wed, 14 Jan 2004 10:52:51 +0000 (10:52 +0000)
src/mesa/tnl/t_array_api.c
src/mesa/tnl/t_array_import.c
src/mesa/tnl/t_array_import.h

index 02a9cd03f4659170337ad0fe3dbba92f004230cb..e4f90756c5383ef871504bf44e7ddca31b31728a 100644 (file)
@@ -77,9 +77,14 @@ static void fallback_drawelements( GLcontext *ctx, GLenum mode, GLsizei count,
 }
 
 
+/* Note this function no longer takes a 'start' value, the range is
+ * assumed to start at zero.  The old trick of subtracting 'start'
+ * from each index won't work if the indices are not in writeable
+ * memory.
+ */
 static void _tnl_draw_range_elements( GLcontext *ctx, GLenum mode,
-                                     GLuint start, GLuint end,
-                                     GLsizei count, GLuint *indices )
+                                     GLuint max_index,
+                                     GLsizei index_count, GLuint *indices )
 
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
@@ -89,27 +94,16 @@ static void _tnl_draw_range_elements( GLcontext *ctx, GLenum mode,
    if (tnl->pipeline.build_state_changes)
       _tnl_validate_pipeline( ctx );
 
-   /* XXX is "end" correct?  Looking at the implementation of
-    * _tnl_vb_bind_arrays(), perhaps we should pass end-start.
-    */
-   _tnl_vb_bind_arrays( ctx, start, end );
+   _tnl_vb_bind_arrays( ctx, 0, max_index );
 
    tnl->vb.Primitive = &prim;
    tnl->vb.Primitive[0].mode = mode | PRIM_BEGIN | PRIM_END;
    tnl->vb.Primitive[0].start = 0;
-   tnl->vb.Primitive[0].count = count;
+   tnl->vb.Primitive[0].count = index_count;
    tnl->vb.PrimitiveCount = 1;
 
    tnl->vb.Elts = (GLuint *)indices;
 
-   assert (start == 0);
-   
-/* XXX - indices may be read only 
-   if (start)
-      for (i = 0 ; i < count ; i++)
-        indices[i] -= start;
-*/
-
    if (ctx->Array.LockCount)
       tnl->Driver.RunPipeline( ctx );
    else {
@@ -120,16 +114,10 @@ static void _tnl_draw_range_elements( GLcontext *ctx, GLenum mode,
       GLuint enabledArrays = ctx->Array._Enabled | (ctx->Array._Enabled >> 16);
       /* Note that arrays may have changed before/after execution.
        */
-      tnl->pipeline.run_input_changes |= enabledArrays;
+      tnl->pipeline.run_input_changes |= enabledArrays & 0xffff;
       tnl->Driver.RunPipeline( ctx );
-      tnl->pipeline.run_input_changes |= enabledArrays;
+      tnl->pipeline.run_input_changes |= enabledArrays & 0xffff;
    }
-
-/* XXX - indices may be read only
-   if (start)
-      for (i = 0 ; i < count ; i++)
-        indices[i] += start;
-*/
 }
 
 
@@ -164,8 +152,8 @@ _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count)
       */
       fallback_drawarrays( ctx, mode, start, start + count );
    } 
-   else if (ctx->Array.LockCount && 
-           count <= (GLint) ctx->Const.MaxArrayLockSize) {
+   else if (start >= ctx->Array.LockFirst &&
+           start + count <= ctx->Array.LockFirst + ctx->Array.LockCount) {
       
       struct tnl_prim prim;
 
@@ -173,14 +161,10 @@ _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count)
        */
       FLUSH_CURRENT( ctx, 0 );
 
-      if (start < (GLint) ctx->Array.LockFirst)
-        start = ctx->Array.LockFirst;
-      if (start + count > (GLint) ctx->Array.LockCount)
-        count = ctx->Array.LockCount - start;
-      
       /* Locked drawarrays.  Reuse any previously transformed data.
        */
-      _tnl_vb_bind_arrays( ctx, ctx->Array.LockFirst, ctx->Array.LockCount );
+      _tnl_vb_bind_arrays( ctx, ctx->Array.LockFirst, 
+                          ctx->Array.LockFirst + ctx->Array.LockCount );
 
       tnl->vb.Primitive = &prim;
       tnl->vb.Primitive[0].mode = mode | PRIM_BEGIN | PRIM_END;
@@ -340,34 +324,21 @@ _tnl_DrawRangeElements(GLenum mode,
       /* Are the arrays already locked?  If so we currently have to look
        * at the whole locked range.
        */
-      if (start == 0 &&
-         start >= ctx->Array.LockFirst && end <= ctx->Array.LockCount)
+
+      if (start == 0 && ctx->Array.LockFirst == 0 && 
+         end < (ctx->Array.LockFirst + ctx->Array.LockCount))
         _tnl_draw_range_elements( ctx, mode,
-                                  ctx->Array.LockFirst,
                                   ctx->Array.LockCount,
                                   count, ui_indices );
       else {
-        /* The spec says referencing elements outside the locked
-         * range is undefined.  I'm going to make it a noop this time
-         * round, maybe come up with something beter before 3.6.
-         *
-         * May be able to get away with just setting LockCount==0,
-         * though this raises the problems of dependent state.  May
-         * have to call glUnlockArrays() directly?
-         *
-         * Or scan the list and replace bad indices?
-         */
-        _mesa_problem( ctx,
-                    "DrawRangeElements references "
-                    "elements outside locked range.");
+        fallback_drawelements( ctx, mode, count, ui_indices );
       }
    }
-   else if (start == 0 &&
-           end - start + 1 <= ctx->Const.MaxArrayLockSize) {
+   else if (start == 0 && end < ctx->Const.MaxArrayLockSize) {
       /* The arrays aren't locked but we can still fit them inside a
        * single vertexbuffer.
        */
-      _tnl_draw_range_elements( ctx, mode, start, end + 1, count, ui_indices );
+      _tnl_draw_range_elements( ctx, mode, end + 1, count, ui_indices );
    }
    else {
       /* Range is too big to optimize:
@@ -407,12 +378,13 @@ _tnl_DrawElements(GLenum mode, GLsizei count, GLenum type,
 
    assert(!ctx->CompileFlag);
 
-   if (ctx->Array.LockFirst == 0 &&
-       ctx->Array.LockCount) {
-      _tnl_draw_range_elements( ctx, mode,
-                               ctx->Array.LockFirst,
-                               ctx->Array.LockCount,
-                               count, ui_indices );
+   if (ctx->Array.LockCount) {
+      if (ctx->Array.LockFirst == 0)
+        _tnl_draw_range_elements( ctx, mode,
+                                  ctx->Array.LockCount,
+                                  count, ui_indices );
+      else
+        fallback_drawelements( ctx, mode, count, ui_indices );
    }
    else {
       /* Scan the index list and see if we can use the locked path anyway.
@@ -424,10 +396,9 @@ _tnl_DrawElements(GLenum mode, GLsizei count, GLenum type,
         if (ui_indices[i] > max_elt)
             max_elt = ui_indices[i];
 
-      /* XXX should this < really be <= ??? */
       if (max_elt < ctx->Const.MaxArrayLockSize && /* can we use it? */
          max_elt < (GLuint) count)                /* do we want to use it? */
-        _tnl_draw_range_elements( ctx, mode, 0, max_elt+1, count, ui_indices );
+        _tnl_draw_range_elements( ctx, mode, max_elt+1, count, ui_indices );
       else
         fallback_drawelements( ctx, mode, count, ui_indices );
    }
index bac7936ba5ddcccecee142427b59aa1264e9793c..7baeefe81e2709779494bff4ad5fcd2dc76b80c4 100644 (file)
@@ -79,7 +79,7 @@ static void _tnl_import_normal( GLcontext *ctx,
    inputs->Normal.data = (GLfloat (*)[4]) data;
    inputs->Normal.start = (GLfloat *) data;
    inputs->Normal.stride = tmp->StrideB;
-   inputs->Normal.size = 3; /* XXX is this right? */
+   inputs->Normal.size = 3;
 }
 
 
@@ -238,11 +238,8 @@ static void _tnl_import_attrib( GLcontext *ctx,
 
 
 
-/*
- * XXX Is count correct?  From some of the callers, it appears that
- * this should perhaps be an "end" index, ala the "start" index.
- */
-void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLsizei count )
+
+void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLint end)
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb;
@@ -250,15 +247,10 @@ void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLsizei count )
    struct tnl_vertex_arrays *tmp = &tnl->array_inputs;
    GLuint i, index;
 
-   VB->Count = count - start;
+   VB->Count = end - start;
    VB->Elts = NULL;
 
-   if (ctx->Array.LockCount) {
-      assert(start == (GLint) ctx->Array.LockFirst);
-      assert(count == (GLint) ctx->Array.LockCount);
-   }
-
-   _ac_import_range( ctx, start, count );
+   _ac_import_range( ctx, start, end );
 
    /* When vertex program mode is enabled, the generic vertex program
     * attribute arrays have priority over the conventional attributes.
@@ -339,7 +331,7 @@ void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLsizei count )
     */
    if (inputs & _TNL_BITS_MAT_ANY) {
       for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
-        tmp->Attribs[i].count = count;
+        tmp->Attribs[i].count = VB->Count;
         tmp->Attribs[i].data = (GLfloat (*)[4]) tnl->vtx.current[i];
         tmp->Attribs[i].start = tnl->vtx.current[i];
         tmp->Attribs[i].size = 4; 
index 7bc248f7160a5cd3a1f44b615f3dc381cc48b7d1..39b77641d5381d46bbe28a3842b7c34763e06474 100644 (file)
@@ -29,7 +29,7 @@
 #include "mtypes.h"
 #include "t_context.h"
 
-extern void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLsizei count );
+extern void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLint end );
 
 extern void _tnl_array_import_init( GLcontext *ctx );