Header file clean-up:
[mesa.git] / src / mesa / main / varray.c
index 5a520ca81d76046c9865825ccd84035eb180ec17..1b540eff44749c5b404047a2efb71b6bf2bb847d 100644 (file)
@@ -1,21 +1,21 @@
-/* $Id: varray.c,v 1.18 2000/01/13 00:25:22 brianp Exp $ */
+/* $Id: varray.c,v 1.47 2002/10/24 23:57:21 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.1
- * 
- * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
- * 
+ * Version:  4.1
+ *
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
+ *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  * to deal in the Software without restriction, including without limitation
  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice shall be included
  * in all copies or substantial portions of the Software.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#ifdef PC_HEADER
-#include "all.h"
-#else
 #include "glheader.h"
 #include "context.h"
-#include "cva.h"
 #include "enable.h"
 #include "enums.h"
 #include "dlist.h"
 #include "light.h"
 #include "macros.h"
 #include "mmath.h"
-#include "pipeline.h"
+#include "state.h"
 #include "texstate.h"
-#include "translate.h"
-#include "types.h"
+#include "mtypes.h"
 #include "varray.h"
-#include "vb.h"
-#include "vbfill.h"
-#include "vbrender.h"
-#include "vbindirect.h"
-#include "vbxform.h"
-#include "xform.h"
-#endif
+#include "math/m_translate.h"
 
 
 
@@ -55,49 +44,52 @@ void
 _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
 {
    GET_CURRENT_CONTEXT(ctx);
-   
-   if (size<2 || size>4) {
-      gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" );
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   if (size < 2 || size > 4) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" );
       return;
    }
-   if (stride<0) {
-      gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" );
+   if (stride < 0) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" );
       return;
    }
-   
+
    if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
-      fprintf(stderr, "glVertexPointer( sz %d type %s stride %d )\n", size, 
-             gl_lookup_enum_by_nr( type ),
-             stride);
+      _mesa_debug(ctx, "glVertexPointer( sz %d type %s stride %d )\n", size,
+                  _mesa_lookup_enum_by_nr( type ), stride);
 
-   ctx->Array.Vertex.StrideB = stride;
-   if (!stride) {
-      switch (type) {
+   /* always need to check that <type> is legal */
+   switch (type) {
       case GL_SHORT:
-         ctx->Array.Vertex.StrideB =  size*sizeof(GLshort);
+         ctx->Array.Vertex.StrideB = size * sizeof(GLshort);
          break;
       case GL_INT:
-         ctx->Array.Vertex.StrideB =  size*sizeof(GLint);
+         ctx->Array.Vertex.StrideB = size * sizeof(GLint);
          break;
       case GL_FLOAT:
-         ctx->Array.Vertex.StrideB =  size*sizeof(GLfloat);
+         ctx->Array.Vertex.StrideB = size * sizeof(GLfloat);
          break;
       case GL_DOUBLE:
-         ctx->Array.Vertex.StrideB =  size*sizeof(GLdouble);
+         ctx->Array.Vertex.StrideB = size * sizeof(GLdouble);
          break;
       default:
-         gl_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
          return;
-      }
    }
+
+   if (stride)
+      ctx->Array.Vertex.StrideB = stride;
+
    ctx->Array.Vertex.Size = size;
    ctx->Array.Vertex.Type = type;
    ctx->Array.Vertex.Stride = stride;
    ctx->Array.Vertex.Ptr = (void *) ptr;
-   ctx->Array.VertexFunc = gl_trans_4f_tab[size][TYPE_IDX(type)];
-   ctx->Array.VertexEltFunc = gl_trans_elt_4f_tab[size][TYPE_IDX(type)];
-   ctx->Array.NewArrayState |= VERT_OBJ_ANY;
-   ctx->NewState |= NEW_CLIENT_STATE;
+   ctx->NewState |= _NEW_ARRAY;
+   ctx->Array.NewState |= _NEW_ARRAY_VERTEX;
+
+   if (ctx->Driver.VertexPointer)
+      ctx->Driver.VertexPointer( ctx, size, type, stride, ptr );
 }
 
 
@@ -107,47 +99,49 @@ void
 _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
 {
    GET_CURRENT_CONTEXT(ctx);
-   
-   if (stride<0) {
-      gl_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" );
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   if (stride < 0) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" );
       return;
    }
 
    if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
-      fprintf(stderr, "glNormalPointer( type %s stride %d )\n", 
-             gl_lookup_enum_by_nr( type ),
-             stride);
+      _mesa_debug(ctx, "glNormalPointer( type %s stride %d )\n",
+                  _mesa_lookup_enum_by_nr( type ), stride);
 
-   ctx->Array.Normal.StrideB = stride;
-   if (!stride) {
-      switch (type) {
+   switch (type) {
       case GL_BYTE:
-         ctx->Array.Normal.StrideB =  3*sizeof(GLbyte);
+         ctx->Array.Normal.StrideB = 3 * sizeof(GLbyte);
          break;
       case GL_SHORT:
-         ctx->Array.Normal.StrideB =  3*sizeof(GLshort);
+         ctx->Array.Normal.StrideB = 3 * sizeof(GLshort);
          break;
       case GL_INT:
-         ctx->Array.Normal.StrideB =  3*sizeof(GLint);
+         ctx->Array.Normal.StrideB = 3 * sizeof(GLint);
          break;
       case GL_FLOAT:
-         ctx->Array.Normal.StrideB =  3*sizeof(GLfloat);
+         ctx->Array.Normal.StrideB = 3 * sizeof(GLfloat);
          break;
       case GL_DOUBLE:
-         ctx->Array.Normal.StrideB =  3*sizeof(GLdouble);
+         ctx->Array.Normal.StrideB = 3 * sizeof(GLdouble);
          break;
       default:
-         gl_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
          return;
-      }
    }
+   if (stride)
+      ctx->Array.Normal.StrideB = stride;
+
+   ctx->Array.Normal.Size = 3;
    ctx->Array.Normal.Type = type;
    ctx->Array.Normal.Stride = stride;
    ctx->Array.Normal.Ptr = (void *) ptr;
-   ctx->Array.NormalFunc = gl_trans_3f_tab[TYPE_IDX(type)];
-   ctx->Array.NormalEltFunc = gl_trans_elt_3f_tab[TYPE_IDX(type)];
-   ctx->Array.NewArrayState |= VERT_NORM;
-   ctx->NewState |= NEW_CLIENT_STATE;
+   ctx->NewState |= _NEW_ARRAY;
+   ctx->Array.NewState |= _NEW_ARRAY_NORMAL;
+
+   if (ctx->Driver.NormalPointer)
+      ctx->Driver.NormalPointer( ctx, type, stride, ptr );
 }
 
 
@@ -156,78 +150,117 @@ void
 _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
 {
    GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   if (size<3 || size>4) {
-      gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
+   if (size < 3 || size > 4) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
       return;
    }
    if (stride<0) {
-      gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
+      _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
       return;
    }
 
    if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
-      fprintf(stderr, "glColorPointer( sz %d type %s stride %d )\n", size, 
-         gl_lookup_enum_by_nr( type ),
-         stride);
+      _mesa_debug(ctx, "glColorPointer( sz %d type %s stride %d )\n", size,
+                  _mesa_lookup_enum_by_nr( type ), stride);
 
-   ctx->Array.Color.StrideB = stride;
-   if (!stride) {
-      switch (type) {
+   switch (type) {
       case GL_BYTE:
-         ctx->Array.Color.StrideB =  size*sizeof(GLbyte);
+         ctx->Array.Color.StrideB = size * sizeof(GLbyte);
          break;
       case GL_UNSIGNED_BYTE:
-         ctx->Array.Color.StrideB =  size*sizeof(GLubyte);
+         ctx->Array.Color.StrideB = size * sizeof(GLubyte);
          break;
       case GL_SHORT:
-         ctx->Array.Color.StrideB =  size*sizeof(GLshort);
+         ctx->Array.Color.StrideB = size * sizeof(GLshort);
          break;
       case GL_UNSIGNED_SHORT:
-         ctx->Array.Color.StrideB =  size*sizeof(GLushort);
+         ctx->Array.Color.StrideB = size * sizeof(GLushort);
          break;
       case GL_INT:
-         ctx->Array.Color.StrideB =  size*sizeof(GLint);
+         ctx->Array.Color.StrideB = size * sizeof(GLint);
          break;
       case GL_UNSIGNED_INT:
-         ctx->Array.Color.StrideB =  size*sizeof(GLuint);
+         ctx->Array.Color.StrideB = size * sizeof(GLuint);
          break;
       case GL_FLOAT:
-         ctx->Array.Color.StrideB =  size*sizeof(GLfloat);
+         ctx->Array.Color.StrideB = size * sizeof(GLfloat);
          break;
       case GL_DOUBLE:
-         ctx->Array.Color.StrideB =  size*sizeof(GLdouble);
+         ctx->Array.Color.StrideB = size * sizeof(GLdouble);
          break;
       default:
-         gl_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
          return;
-      }
    }
+
+   if (stride)
+      ctx->Array.Color.StrideB = stride;
+
    ctx->Array.Color.Size = size;
    ctx->Array.Color.Type = type;
    ctx->Array.Color.Stride = stride;
    ctx->Array.Color.Ptr = (void *) ptr;
-   ctx->Array.ColorFunc = gl_trans_4ub_tab[size][TYPE_IDX(type)];
-   ctx->Array.ColorEltFunc = gl_trans_elt_4ub_tab[size][TYPE_IDX(type)];
-   ctx->Array.NewArrayState |= VERT_RGBA;
-   ctx->NewState |= NEW_CLIENT_STATE;
+   ctx->NewState |= _NEW_ARRAY;
+   ctx->Array.NewState |= _NEW_ARRAY_COLOR0;
+
+   if (ctx->Driver.ColorPointer)
+      ctx->Driver.ColorPointer( ctx, size, type, stride, ptr );
 }
 
 
 
+void
+_mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   if (stride < 0) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glFogCoordPointer(stride)" );
+      return;
+   }
+
+   switch (type) {
+      case GL_FLOAT:
+         ctx->Array.FogCoord.StrideB =  sizeof(GLfloat);
+         break;
+      case GL_DOUBLE:
+         ctx->Array.FogCoord.StrideB =  sizeof(GLdouble);
+         break;
+      default:
+         _mesa_error( ctx, GL_INVALID_ENUM, "glFogCoordPointer(type)" );
+         return;
+   }
+
+   if (stride)
+      ctx->Array.FogCoord.StrideB = stride;
+
+   ctx->Array.FogCoord.Size = 1;
+   ctx->Array.FogCoord.Type = type;
+   ctx->Array.FogCoord.Stride = stride;
+   ctx->Array.FogCoord.Ptr = (void *) ptr;
+   ctx->NewState |= _NEW_ARRAY;
+   ctx->Array.NewState |= _NEW_ARRAY_FOGCOORD;
+
+   if (ctx->Driver.FogCoordPointer)
+      ctx->Driver.FogCoordPointer( ctx, type, stride, ptr );
+}
+
+
 void
 _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
 {
    GET_CURRENT_CONTEXT(ctx);
-   
-   if (stride<0) {
-      gl_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" );
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   if (stride < 0) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" );
       return;
    }
 
-   ctx->Array.Index.StrideB = stride;
-   if (!stride) {
-      switch (type) {
+   switch (type) {
       case GL_UNSIGNED_BYTE:
          ctx->Array.Index.StrideB =  sizeof(GLubyte);
          break;
@@ -244,677 +277,284 @@ _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
          ctx->Array.Index.StrideB =  sizeof(GLdouble);
          break;
       default:
-         gl_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" );
          return;
-      }
    }
+
+   if (stride)
+      ctx->Array.Index.StrideB = stride;
+
+   ctx->Array.Index.Size = 1;
    ctx->Array.Index.Type = type;
    ctx->Array.Index.Stride = stride;
    ctx->Array.Index.Ptr = (void *) ptr;
-   ctx->Array.IndexFunc = gl_trans_1ui_tab[TYPE_IDX(type)];
-   ctx->Array.IndexEltFunc = gl_trans_elt_1ui_tab[TYPE_IDX(type)];
-   ctx->Array.NewArrayState |= VERT_INDEX;
-   ctx->NewState |= NEW_CLIENT_STATE;
-}
+   ctx->NewState |= _NEW_ARRAY;
+   ctx->Array.NewState |= _NEW_ARRAY_INDEX;
 
+   if (ctx->Driver.IndexPointer)
+      ctx->Driver.IndexPointer( ctx, type, stride, ptr );
+}
 
 
 void
-_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
+_mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
+                              GLsizei stride, const GLvoid *ptr)
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLuint texUnit;
-   
-   texUnit = ctx->Array.ActiveTexture;
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   if (size<1 || size>4) {
-      gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" );
+   if (size != 3 && size != 4) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(size)" );
       return;
    }
-   if (stride<0) {
-      gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" );
+   if (stride < 0) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(stride)" );
       return;
    }
 
    if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
-      fprintf(stderr, "glTexCoordPointer( unit %u sz %d type %s stride %d )\n", 
-         texUnit,
-         size, 
-         gl_lookup_enum_by_nr( type ),
-         stride);
-
-   ctx->Array.TexCoord[texUnit].StrideB = stride;
-   if (!stride) {
-      switch (type) {
+      _mesa_debug(ctx, "glSecondaryColorPointer( sz %d type %s stride %d )\n",
+                  size, _mesa_lookup_enum_by_nr( type ), stride);
+
+   switch (type) {
+      case GL_BYTE:
+         ctx->Array.SecondaryColor.StrideB = size * sizeof(GLbyte);
+         break;
+      case GL_UNSIGNED_BYTE:
+         ctx->Array.SecondaryColor.StrideB = size * sizeof(GLubyte);
+         break;
       case GL_SHORT:
-         ctx->Array.TexCoord[texUnit].StrideB =  size*sizeof(GLshort);
+         ctx->Array.SecondaryColor.StrideB = size * sizeof(GLshort);
+         break;
+      case GL_UNSIGNED_SHORT:
+         ctx->Array.SecondaryColor.StrideB = size * sizeof(GLushort);
          break;
       case GL_INT:
-         ctx->Array.TexCoord[texUnit].StrideB =  size*sizeof(GLint);
+         ctx->Array.SecondaryColor.StrideB = size * sizeof(GLint);
+         break;
+      case GL_UNSIGNED_INT:
+         ctx->Array.SecondaryColor.StrideB = size * sizeof(GLuint);
          break;
       case GL_FLOAT:
-         ctx->Array.TexCoord[texUnit].StrideB =  size*sizeof(GLfloat);
+         ctx->Array.SecondaryColor.StrideB = size * sizeof(GLfloat);
          break;
       case GL_DOUBLE:
-         ctx->Array.TexCoord[texUnit].StrideB =  size*sizeof(GLdouble);
+         ctx->Array.SecondaryColor.StrideB = size * sizeof(GLdouble);
          break;
       default:
-         gl_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" );
          return;
-      }
    }
-   ctx->Array.TexCoord[texUnit].Size = size;
-   ctx->Array.TexCoord[texUnit].Type = type;
-   ctx->Array.TexCoord[texUnit].Stride = stride;
-   ctx->Array.TexCoord[texUnit].Ptr = (void *) ptr;
 
-   ctx->Array.TexCoordFunc[texUnit] = gl_trans_4f_tab[size][TYPE_IDX(type)];
-   ctx->Array.TexCoordEltFunc[texUnit] = gl_trans_elt_4f_tab[size][TYPE_IDX(type)];
-   ctx->Array.NewArrayState |= PIPE_TEX(texUnit);
-   ctx->NewState |= NEW_CLIENT_STATE;
-}
+   if (stride)
+      ctx->Array.SecondaryColor.StrideB = stride;
+
+   ctx->Array.SecondaryColor.Size = 3; /* hardwire */
+   ctx->Array.SecondaryColor.Type = type;
+   ctx->Array.SecondaryColor.Stride = stride;
+   ctx->Array.SecondaryColor.Ptr = (void *) ptr;
+   ctx->NewState |= _NEW_ARRAY;
+   ctx->Array.NewState |= _NEW_ARRAY_COLOR1;
 
+   if (ctx->Driver.SecondaryColorPointer)
+      ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr );
+}
 
 
 
 void
-_mesa_EdgeFlagPointer(GLsizei stride, const void *vptr)
+_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
+                      const GLvoid *ptr)
 {
    GET_CURRENT_CONTEXT(ctx);
-   const GLboolean *ptr = (GLboolean *)vptr;
+   GLuint texUnit = ctx->Array.ActiveTexture;
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   if (stride<0) {
-      gl_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" );
+   if (size < 1 || size > 4) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" );
       return;
    }
-   ctx->Array.EdgeFlag.Stride = stride;
-   ctx->Array.EdgeFlag.StrideB = stride ? stride : sizeof(GLboolean);
-   ctx->Array.EdgeFlag.Ptr = (GLboolean *) ptr;
-   if (stride != sizeof(GLboolean)) {
-      ctx->Array.EdgeFlagFunc = gl_trans_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)];
-   } else {
-      ctx->Array.EdgeFlagFunc = 0;
+   if (stride < 0) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" );
+      return;
    }
-   ctx->Array.EdgeFlagEltFunc = gl_trans_elt_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)];
-   ctx->Array.NewArrayState |= VERT_EDGE;
-   ctx->NewState |= NEW_CLIENT_STATE;
-}
 
+   if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
+      _mesa_debug(ctx, "glTexCoordPointer(unit %u sz %d type %s stride %d)\n",
+                  texUnit, size, _mesa_lookup_enum_by_nr( type ), stride);
 
-#if 0
-/* Called only from gl_DrawElements
- */
-static void gl_CVAEltPointer( GLcontext *ctx, GLenum type, const GLvoid *ptr )
-{
+   /* always need to check that <type> is legal */
    switch (type) {
-      case GL_UNSIGNED_BYTE:
-         ctx->CVA.Elt.StrideB = sizeof(GLubyte);
+      case GL_SHORT:
+         ctx->Array.TexCoord[texUnit].StrideB = size * sizeof(GLshort);
          break;
-      case GL_UNSIGNED_SHORT:
-         ctx->CVA.Elt.StrideB = sizeof(GLushort);
+      case GL_INT:
+         ctx->Array.TexCoord[texUnit].StrideB = size * sizeof(GLint);
          break;
-      case GL_UNSIGNED_INT:
-         ctx->CVA.Elt.StrideB = sizeof(GLuint);
+      case GL_FLOAT:
+         ctx->Array.TexCoord[texUnit].StrideB = size * sizeof(GLfloat);
+         break;
+      case GL_DOUBLE:
+         ctx->Array.TexCoord[texUnit].StrideB = size * sizeof(GLdouble);
          break;
       default:
-         gl_error( ctx, GL_INVALID_ENUM, "glEltPointer(type)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
          return;
    }
-   ctx->CVA.Elt.Type = type;
-   ctx->CVA.Elt.Stride = 0;
-   ctx->CVA.Elt.Ptr = (void *) ptr;
-   ctx->CVA.EltFunc = gl_trans_1ui_tab[TYPE_IDX(type)];
-   ctx->Array.NewArrayState |= VERT_ELT; /* ??? */
-}
-#endif
-
-
-/* KW: Batch function to exec all the array elements in the input
- *     buffer prior to transform.  Done only the first time a vertex
- *     buffer is executed or compiled.
- *
- * KW: Have to do this after each glEnd if cva isn't active.  (also
- *     have to do it after each full buffer)
- */
-void gl_exec_array_elements( GLcontext *ctx, struct immediate *IM,
-                            GLuint start, 
-                            GLuint count)
-{
-   GLuint *flags = IM->Flag;
-   GLuint *elts = IM->Elt;
-   GLuint translate = ctx->Array.Flags;
-   GLuint i;
-
-   if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
-      fprintf(stderr, "exec_array_elements %d .. %d\n", start, count);
-   
-   if (translate & VERT_OBJ_ANY) 
-      (ctx->Array.VertexEltFunc)( IM->Obj, 
-                                 &ctx->Array.Vertex, 
-                                 flags, elts, (VERT_ELT|VERT_OBJ_ANY),
-                                 start, count);
-   
-   if (translate & VERT_NORM) 
-      (ctx->Array.NormalEltFunc)( IM->Normal, 
-                                 &ctx->Array.Normal, 
-                                 flags, elts, (VERT_ELT|VERT_NORM),
-                                 start, count);
-
-   if (translate & VERT_EDGE) 
-      (ctx->Array.EdgeFlagEltFunc)( IM->EdgeFlag, 
-                                   &ctx->Array.EdgeFlag, 
-                                   flags, elts, (VERT_ELT|VERT_EDGE),
-                                   start, count);
-   
-   if (translate & VERT_RGBA)
-      (ctx->Array.ColorEltFunc)( IM->Color, 
-                                &ctx->Array.Color, 
-                                flags, elts, (VERT_ELT|VERT_RGBA),
-                                start, count);
-
-   if (translate & VERT_INDEX)
-      (ctx->Array.IndexEltFunc)( IM->Index, 
-                                &ctx->Array.Index, 
-                                flags, elts, (VERT_ELT|VERT_INDEX),
-                                start, count);
-
-   if (translate & VERT_TEX0_ANY)
-      (ctx->Array.TexCoordEltFunc[0])( IM->TexCoord[0], 
-                                      &ctx->Array.TexCoord[0], 
-                                      flags, elts, (VERT_ELT|VERT_TEX0_ANY),
-                                      start, count);
-
-   if (translate & VERT_TEX1_ANY)
-      (ctx->Array.TexCoordEltFunc[1])( IM->TexCoord[1], 
-                                      &ctx->Array.TexCoord[1], 
-                                      flags, elts, (VERT_ELT|VERT_TEX1_ANY),
-                                      start, count);
-
-
-   for (i = start ; i < count ; i++) 
-      if (flags[i] & VERT_ELT) 
-        flags[i] |= translate;
-
-}
 
+   if (stride)
+      ctx->Array.TexCoord[texUnit].StrideB = stride;
 
+   ctx->Array.TexCoord[texUnit].Size = size;
+   ctx->Array.TexCoord[texUnit].Type = type;
+   ctx->Array.TexCoord[texUnit].Stride = stride;
+   ctx->Array.TexCoord[texUnit].Ptr = (void *) ptr;
+   ctx->NewState |= _NEW_ARRAY;
+   ctx->Array.NewState |= _NEW_ARRAY_TEXCOORD(texUnit);
 
-/* Enough funny business going on in here it might be quicker to use a
- * function pointer.
- */
-#define ARRAY_ELT( IM, i )                                     \
-{                                                              \
-   GLuint count = IM->Count;                                   \
-   IM->Elt[count] = i;                                         \
-   IM->Flag[count] = ((IM->Flag[count] & IM->ArrayAndFlags) |  \
-                     VERT_ELT);                                \
-   IM->FlushElt |= IM->ArrayEltFlush;                          \
-   IM->Count = count += IM->ArrayIncr;                         \
-   if (count == VB_MAX)                                                \
-      IM->maybe_transform_vb( IM );                            \
+   if (ctx->Driver.TexCoordPointer)
+      ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr );
 }
 
 
 void
-_mesa_ArrayElement( GLint i )
+_mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *vptr)
 {
-   GET_IMMEDIATE;
-   ARRAY_ELT( IM, i );
-}
+   GET_CURRENT_CONTEXT(ctx);
+   const GLboolean *ptr = (GLboolean *)vptr;
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
+   if (stride<0) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" );
+      return;
+   }
+   ctx->Array.EdgeFlag.Stride = stride;
+   ctx->Array.EdgeFlag.StrideB = stride ? stride : sizeof(GLboolean);
+   ctx->Array.EdgeFlag.Ptr = (GLboolean *) ptr;
+   ctx->NewState |= _NEW_ARRAY;
+   ctx->Array.NewState |= _NEW_ARRAY_EDGEFLAG;
 
-static void
-gl_ArrayElement( GLcontext *CC, GLint i )
-{
-   struct immediate *im = CC->input;
-   ARRAY_ELT( im, i );
+   if (ctx->Driver.EdgeFlagPointer)
+      ctx->Driver.EdgeFlagPointer( ctx, stride, ptr );
 }
 
 
-
-void
-_mesa_DrawArrays(GLenum mode, GLint start, GLsizei count)
+void _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
+                                 GLsizei stride, const GLvoid *ptr)
 {
    GET_CURRENT_CONTEXT(ctx);
-   struct vertex_buffer *VB = ctx->VB;
-   GLint i;
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawArrays");
-
-   if (count<0) {
-      gl_error( ctx, GL_INVALID_VALUE, "glDrawArrays(count)" );
+   if (index >= VERT_ATTRIB_MAX) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)");
       return;
    }
 
-   if (!ctx->CompileFlag && ctx->Array.Vertex.Enabled)
-   {
-      GLint remaining = count;
-      GLint i;
-      struct gl_client_array *Normal;
-      struct gl_client_array *Color;
-      struct gl_client_array *Index;
-      struct gl_client_array *TexCoord[MAX_TEXTURE_UNITS];
-      struct gl_client_array *EdgeFlag;
-      struct immediate *IM = VB->IM;
-      struct gl_pipeline *elt = &ctx->CVA.elt;
-      GLboolean relock;
-      GLuint fallback, required;
-
-      if (ctx->NewState)
-        gl_update_state( ctx );        
-
-      /* Just turn off cva on this path.  Could be useful for multipass
-       * rendering to keep it turned on.
-       */
-      relock = ctx->CompileCVAFlag;
-
-      if (relock) {
-        ctx->CompileCVAFlag = 0;
-        elt->pipeline_valid = 0;
-      }
-
-      if (!elt->pipeline_valid)
-        gl_build_immediate_pipeline( ctx );
-
-      required = elt->inputs;
-      fallback = (elt->inputs & ~ctx->Array.Summary);
-
-      /* The translate function doesn't do anything about size.  It
-       * just ensures that type and stride come out right.
-       */
-      IM->v.Obj.size = ctx->Array.Vertex.Size;
-
-      if (required & VERT_RGBA) 
-      {
-        Color = &ctx->Array.Color;
-        if (fallback & VERT_RGBA) {
-           Color = &ctx->Fallback.Color;
-           ctx->Array.ColorFunc = 
-              gl_trans_4ub_tab[4][TYPE_IDX(GL_UNSIGNED_BYTE)];
-        }
-      }
-   
-      if (required & VERT_INDEX) 
-      {
-        Index = &ctx->Array.Index;
-        if (fallback & VERT_INDEX) {
-           Index = &ctx->Fallback.Index;
-           ctx->Array.IndexFunc = gl_trans_1ui_tab[TYPE_IDX(GL_UNSIGNED_INT)];
-        }
-      }
-
-      for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) 
-      {
-        GLuint flag = VERT_TEX_ANY(i);
-
-        if (required & flag) {
-           TexCoord[i] = &ctx->Array.TexCoord[i];
+   if (size < 1 || size > 4) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size)");
+      return;
+   }
 
-           if (fallback & flag) 
-           {
-              TexCoord[i] = &ctx->Fallback.TexCoord[i];
-              TexCoord[i]->Size = gl_texcoord_size( ctx->Current.Flag, i );
+   if (stride < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(stride)");
+      return;
+   }
 
-              ctx->Array.TexCoordFunc[i] = 
-                 gl_trans_4f_tab[TexCoord[i]->Size][TYPE_IDX(GL_FLOAT)];
-           }
-        }
-      }
+   if (type == GL_UNSIGNED_BYTE && size != 4) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)");
+      return;
+   }
 
-      if (ctx->Array.Flags != ctx->Array.Flag[0])
-        for (i = 0 ; i < VB_MAX ; i++) 
-           ctx->Array.Flag[i] = ctx->Array.Flags;
+   /* check for valid 'type' and compute StrideB right away */
+   switch (type) {
+      case GL_UNSIGNED_BYTE:
+         ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLubyte);
+         break;
+      case GL_SHORT:
+         ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLshort);
+         break;
+      case GL_FLOAT:
+         ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLfloat);
+         break;
+      case GL_DOUBLE:
+         ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLdouble);
+         break;
+      default:
+         _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type)" );
+         return;
+   }
 
+   if (stride)
+      ctx->Array.VertexAttrib[index].StrideB = stride;
 
-      if (required & VERT_NORM) 
-      {
-        Normal = &ctx->Array.Normal;
-        if (fallback & VERT_NORM) {
-           Normal = &ctx->Fallback.Normal;
-           ctx->Array.NormalFunc = gl_trans_3f_tab[TYPE_IDX(GL_FLOAT)];
-        }
-      }
+   ctx->Array.VertexAttrib[index].Stride = stride;
+   ctx->Array.VertexAttrib[index].Size = size;
+   ctx->Array.VertexAttrib[index].Type = type;
+   ctx->Array.VertexAttrib[index].Ptr = (void *) ptr;
 
-      if ( required & VERT_EDGE )
-      {
-        if (mode == GL_TRIANGLES || 
-            mode == GL_QUADS || 
-            mode == GL_POLYGON)
-        {
-           EdgeFlag = &ctx->Array.EdgeFlag;
-           if (fallback & VERT_EDGE) {
-              EdgeFlag = &ctx->Fallback.EdgeFlag;
-              ctx->Array.EdgeFlagFunc = 
-                 gl_trans_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)];
-           }
-        }
-        else
-           required &= ~VERT_EDGE;
-      }
+   ctx->NewState |= _NEW_ARRAY;
+   ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
 
-      VB->Primitive = IM->Primitive; 
-      VB->NextPrimitive = IM->NextPrimitive; 
-      VB->MaterialMask = IM->MaterialMask;
-      VB->Material = IM->Material;
-      VB->BoundsPtr = 0;
-
-      while (remaining > 0) {
-         GLint vbspace = VB_MAX - VB_START;
-        GLuint count, n;
-        
-        if (vbspace >= remaining) {
-           n = remaining;
-           VB->LastPrimitive = VB_START + n;
-        } else {
-           n = vbspace;
-           VB->LastPrimitive = VB_START;
-        }
-        
-        VB->CullMode = 0;
-        
-        ctx->Array.VertexFunc( IM->Obj + VB_START, 
-                               &ctx->Array.Vertex, start, n );
-        
-        if (required & VERT_NORM) {
-           ctx->Array.NormalFunc( IM->Normal + VB_START, 
-                                  Normal, start, n );
-        }
-        
-        if (required & VERT_EDGE) {
-           ctx->Array.EdgeFlagFunc( IM->EdgeFlag + VB_START, 
-                                    EdgeFlag, start, n );
-        }
-        
-        if (required & VERT_RGBA) {
-           ctx->Array.ColorFunc( IM->Color + VB_START, 
-                                 Color, start, n );
-        }
-        
-        if (required & VERT_INDEX) {
-           ctx->Array.IndexFunc( IM->Index + VB_START, 
-                                 Index, start, n );
-        }
-        
-        if (required & VERT_TEX0_ANY) {
-           IM->v.TexCoord[0].size = TexCoord[0]->Size;
-           ctx->Array.TexCoordFunc[0]( IM->TexCoord[0] + VB_START, 
-                                       TexCoord[0], start, n );
-        }
-        
-        if (required & VERT_TEX1_ANY) {
-           IM->v.TexCoord[1].size = TexCoord[1]->Size;
-           ctx->Array.TexCoordFunc[1]( IM->TexCoord[1] + VB_START, 
-                                       TexCoord[1], start, n );
-        }
-
-        VB->ObjPtr = &IM->v.Obj;
-        VB->NormalPtr = &IM->v.Normal;
-        VB->ColorPtr = &IM->v.Color;
-        VB->Color[0] = VB->Color[1] = VB->ColorPtr;
-        VB->IndexPtr = &IM->v.Index;
-        VB->EdgeFlagPtr = &IM->v.EdgeFlag;
-        VB->TexCoordPtr[0] = &IM->v.TexCoord[0];
-        VB->TexCoordPtr[1] = &IM->v.TexCoord[1];
-
-        VB->Flag = ctx->Array.Flag;
-        VB->OrFlag = ctx->Array.Flags;
-
-        VB->Start = IM->Start = VB_START;
-        count = VB->Count = IM->Count = VB_START + n;
-
-#define RESET_VEC(v, t, s, c) (v.start = t v.data[s], v.count = c)  
-
-        RESET_VEC(IM->v.Obj, (GLfloat *), VB_START, count);
-        RESET_VEC(IM->v.Normal, (GLfloat *), VB_START, count);
-        RESET_VEC(IM->v.TexCoord[0], (GLfloat *), VB_START, count);
-        RESET_VEC(IM->v.TexCoord[1], (GLfloat *), VB_START, count);
-        RESET_VEC(IM->v.Index, &, VB_START, count);
-        RESET_VEC(IM->v.Elt, &, VB_START, count);
-        RESET_VEC(IM->v.EdgeFlag, &, VB_START, count);
-        RESET_VEC(IM->v.Color, (GLubyte *), VB_START, count);
-        RESET_VEC(VB->Clip, (GLfloat *), VB_START, count);
-        RESET_VEC(VB->Eye, (GLfloat *), VB_START, count);
-        RESET_VEC(VB->Win, (GLfloat *), VB_START, count);
-        RESET_VEC(VB->BColor, (GLubyte *), VB_START, count); 
-        RESET_VEC(VB->BIndex, &, VB_START, count);
-
-        VB->NextPrimitive[VB->CopyStart] = VB->Count;
-        VB->Primitive[VB->CopyStart] = mode;
-
-         /* Transform and render.
-         */
-         gl_run_pipeline( VB );
-        gl_reset_vb( VB );
-
-        ctx->Array.Flag[count] = ctx->Array.Flags;
-        ctx->Array.Flag[VB_START] = ctx->Array.Flags;
-
-         start += n;
-         remaining -= n;
-      }
+   if (ctx->Driver.VertexAttribPointer)
+      ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr );
+}
 
-      gl_reset_input( ctx );
 
-      if (relock) {
-        ctx->CompileCVAFlag = relock;
-        elt->pipeline_valid = 0;
-      }
-   }
-   else if (ctx->Array.Vertex.Enabled) 
-   {
-      /* The GL_COMPILE and GL_COMPILE_AND_EXECUTE cases.  These
-       * could be handled by the above code, but it gets a little
-       * complex.  The generated list is still of good quality
-       * this way.
-       */
-      gl_Begin( ctx, mode );
-      for (i=0;i<count;i++) {
-         gl_ArrayElement( ctx, start+i );
-      }
-      gl_End( ctx );
-   }
-   else
-   {
-      /* The degenerate case where vertices are not enabled - only
-       * need to process the very final array element, as all of the
-       * preceding ones would be overwritten anyway. 
-       */
-      gl_Begin( ctx, mode );
-      gl_ArrayElement( ctx, start+count );
-      gl_End( ctx );
-   }
+void
+_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
+                       GLsizei count, const GLvoid *ptr)
+{
+   (void) count;
+   _mesa_VertexPointer(size, type, stride, ptr);
 }
 
 
-
-/* KW: Exactly fakes the effects of calling glArrayElement multiple times.
- *     Compilation is handled via. the IM->maybe_transform_vb() callback.
- */
-#if 1
-#define DRAW_ELT(FUNC, TYPE)                           \
-static void FUNC( GLcontext *ctx, GLenum mode,         \
-                 TYPE *indices, GLuint count )         \
-{                                                      \
-   GLuint i,j;                                         \
-                                                       \
-   gl_Begin( ctx, mode );                              \
-                                                       \
-   for (j = 0 ; j < count ; ) {                                \
-      struct immediate *IM = ctx->input;               \
-      GLuint start = IM->Start;                                \
-      GLuint nr = MIN2( VB_MAX, count - j + start );   \
-      GLuint sf = IM->Flag[start];                     \
-      IM->FlushElt |= IM->ArrayEltFlush;               \
-                                                       \
-      for (i = start ; i < nr ; i++) {                 \
-        IM->Elt[i] = (GLuint) *indices++;              \
-        IM->Flag[i] = VERT_ELT;                        \
-      }                                                        \
-                                                       \
-      if (j == 0) IM->Flag[start] |= sf;               \
-                                                       \
-      IM->Count = nr;                                  \
-      j += nr - start;                                 \
-                                                       \
-      if (j == count) gl_End( ctx );                   \
-      IM->maybe_transform_vb( IM );                    \
-   }                                                   \
-}
-#else 
-#define DRAW_ELT(FUNC, TYPE)                           \
-static void FUNC( GLcontext *ctx, GLenum mode,         \
-                  TYPE *indices, GLuint count )        \
-{                                                      \
-  int i;                                               \
-  glBegin(mode);                                       \
-  for (i = 0 ; i < count ; i++)                                \
-    glArrayElement( indices[i] );                      \
-  glEnd();                                             \
+void
+_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
+                       const GLvoid *ptr)
+{
+   (void) count;
+   _mesa_NormalPointer(type, stride, ptr);
 }
-#endif
-       
-
-DRAW_ELT( draw_elt_ubyte, GLubyte )
-DRAW_ELT( draw_elt_ushort, GLushort )
-DRAW_ELT( draw_elt_uint, GLuint )
 
 
-static GLuint natural_stride[0x10] = 
+void
+_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
+                      const GLvoid *ptr)
 {
-   sizeof(GLbyte),             /* 0 */
-   sizeof(GLubyte),            /* 1 */
-   sizeof(GLshort),            /* 2 */
-   sizeof(GLushort),           /* 3 */
-   sizeof(GLint),              /* 4 */
-   sizeof(GLuint),             /* 5 */
-   sizeof(GLfloat),            /* 6 */
-   2 * sizeof(GLbyte),         /* 7 */
-   3 * sizeof(GLbyte),         /* 8 */
-   4 * sizeof(GLbyte),         /* 9 */
-   sizeof(GLdouble),           /* a */
-   0,                          /* b */
-   0,                          /* c */
-   0,                          /* d */
-   0,                          /* e */
-   0                           /* f */
-};
+   (void) count;
+   _mesa_ColorPointer(size, type, stride, ptr);
+}
 
 
 void
-_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
+_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
+                      const GLvoid *ptr)
 {
-   GET_CURRENT_CONTEXT(ctx);
-   struct gl_cva *cva;
-      
-   cva = &ctx->CVA;
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawElements");
-
-   if (count <= 0) {
-      if (count < 0)
-        gl_error( ctx, GL_INVALID_VALUE, "glDrawElements(count)" );
-      return;
-   }
-
-   if (mode > GL_POLYGON) {
-      gl_error( ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" );
-      return;
-   }
-   
-   if (type != GL_UNSIGNED_INT && type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT)
-   {
-       gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
-       return;
-   }
+   (void) count;
+   _mesa_IndexPointer(type, stride, ptr);
+}
 
-   if (ctx->NewState)
-      gl_update_state(ctx);
-
-   if (ctx->CompileCVAFlag) 
-   {
-#if defined(MESA_CVA_PROF)
-      force_init_prof(); 
-#endif
-
-      /* Treat VERT_ELT like a special client array.
-       */
-      ctx->Array.NewArrayState |= VERT_ELT;
-      ctx->Array.Summary |= VERT_ELT;
-      ctx->Array.Flags |= VERT_ELT;
-
-      cva->elt_mode = mode;
-      cva->elt_count = count;
-      cva->Elt.Type = type;
-      cva->Elt.Ptr = (void *) indices;
-      cva->Elt.StrideB = natural_stride[TYPE_IDX(type)];
-      cva->EltFunc = gl_trans_1ui_tab[TYPE_IDX(type)];
-
-      if (!cva->pre.pipeline_valid) 
-        gl_build_precalc_pipeline( ctx );
-      else if (MESA_VERBOSE & VERBOSE_PIPELINE)
-        fprintf(stderr, ": dont rebuild\n");
-
-      gl_cva_force_precalc( ctx );
-
-      /* Did we 'precalculate' the render op?
-       */
-      if (ctx->CVA.pre.ops & PIPE_OP_RENDER) {
-        ctx->Array.NewArrayState |= VERT_ELT;
-        ctx->Array.Summary &= ~VERT_ELT;
-        ctx->Array.Flags &= ~VERT_ELT;
-        return;
-      } 
-
-      if ( (MESA_VERBOSE&VERBOSE_VARRAY) )
-        printf("using immediate\n");
-   }
 
+void
+_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
+                         GLsizei count, const GLvoid *ptr)
+{
+   (void) count;
+   _mesa_TexCoordPointer(size, type, stride, ptr);
+}
 
-   /* Otherwise, have to use the immediate path to render.
-    */
-   switch (type) {
-   case GL_UNSIGNED_BYTE:
-   {
-      GLubyte *ub_indices = (GLubyte *) indices;
-      if (ctx->Array.Summary & VERT_OBJ_ANY) {
-        draw_elt_ubyte( ctx, mode, ub_indices, count );
-      } else {
-        gl_ArrayElement( ctx, (GLuint) ub_indices[count-1] );
-      }
-   }
-   break;
-   case GL_UNSIGNED_SHORT:
-   {
-      GLushort *us_indices = (GLushort *) indices;
-      if (ctx->Array.Summary & VERT_OBJ_ANY) {
-        draw_elt_ushort( ctx, mode, us_indices, count );
-      } else {
-        gl_ArrayElement( ctx, (GLuint) us_indices[count-1] );
-      }
-   }
-   break;
-   case GL_UNSIGNED_INT:
-   {
-      GLuint *ui_indices = (GLuint *) indices;
-      if (ctx->Array.Summary & VERT_OBJ_ANY) {
-        draw_elt_uint( ctx, mode, ui_indices, count );
-      } else {
-        gl_ArrayElement( ctx, ui_indices[count-1] );
-      }
-   }
-   break;
-   default:
-      gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
-      break;
-   }
 
-   if (ctx->CompileCVAFlag) {
-      ctx->Array.NewArrayState |= VERT_ELT;
-      ctx->Array.Summary &= ~VERT_ELT;
-   }
+void
+_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
+{
+   (void) count;
+   _mesa_EdgeFlagPointer(stride, ptr);
 }
 
 
 
+
 void
 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
 {
@@ -922,17 +562,19 @@ _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
    GLboolean tflag, cflag, nflag;  /* enable/disable flags */
    GLint tcomps, ccomps, vcomps;   /* components per texcoord, color, vertex */
 
-   GLenum ctype;                   /* color type */
-   GLint coffset, noffset, voffset;/* color, normal, vertex offsets */
+   GLenum ctype = 0;               /* color type */
+   GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
    GLint defstride;                /* default stride */
    GLint c, f;
    GLint coordUnitSave;
-   
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
    f = sizeof(GLfloat);
    c = f * ((4*sizeof(GLubyte) + (f-1)) / f);
 
    if (stride<0) {
-      gl_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
+      _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
       return;
    }
 
@@ -1043,7 +685,7 @@ _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
          defstride = 15*f;
          break;
       default:
-         gl_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
          return;
    }
 
@@ -1062,17 +704,17 @@ _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
       for (i = 0; i < factor; i++) {
          _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
          _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
-         glTexCoordPointer( tcomps, GL_FLOAT, stride,
-                             (GLubyte *) pointer + i * coffset );
+         _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
+                               (GLubyte *) pointer + i * coffset );
       }
-      for (i = factor; i < ctx->Const.MaxTextureUnits; i++) {
+      for (i = factor; i < (GLint) ctx->Const.MaxTextureUnits; i++) {
          _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
          _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
       }
    }
    else {
       GLint i;
-      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+      for (i = 0; i < (GLint) ctx->Const.MaxTextureUnits; i++) {
          _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
          _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
       }
@@ -1084,8 +726,8 @@ _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
    /* Color */
    if (cflag) {
       _mesa_EnableClientState( GL_COLOR_ARRAY );
-      glColorPointer( ccomps, ctype, stride,
-                       (GLubyte*) pointer + coffset );
+      _mesa_ColorPointer( ccomps, ctype, stride,
+                         (GLubyte*) pointer + coffset );
    }
    else {
       _mesa_DisableClientState( GL_COLOR_ARRAY );
@@ -1095,80 +737,99 @@ _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
    /* Normals */
    if (nflag) {
       _mesa_EnableClientState( GL_NORMAL_ARRAY );
-      glNormalPointer( GL_FLOAT, stride,
-                        (GLubyte*) pointer + noffset );
+      _mesa_NormalPointer( GL_FLOAT, stride,
+                          (GLubyte*) pointer + noffset );
    }
    else {
       _mesa_DisableClientState( GL_NORMAL_ARRAY );
    }
 
    _mesa_EnableClientState( GL_VERTEX_ARRAY );
-   glVertexPointer( vcomps, GL_FLOAT, stride,
-                     (GLubyte *) pointer + voffset );
+   _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
+                       (GLubyte *) pointer + voffset );
 }
 
 
 
 void
-_mesa_DrawRangeElements(GLenum mode, GLuint start,
-                        GLuint end, GLsizei count,
-                        GLenum type, const GLvoid *indices)
+_mesa_LockArraysEXT(GLint first, GLsizei count)
 {
    GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
-   if (end < start) {
-      gl_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements( end < start )");
-      return;
-   }
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
 
-   if (!ctx->Array.LockCount && 2*count > (GLint) 3*(end-start)) {
-      glLockArraysEXT( start, end );
-      glDrawElements( mode, count, type, indices );
-      glUnlockArraysEXT();
-   } else {
-      glDrawElements( mode, count, type, indices );
+   if (first == 0 && count > 0 &&
+       count <= (GLint) ctx->Const.MaxArrayLockSize) {
+      ctx->Array.LockFirst = first;
+      ctx->Array.LockCount = count;
+   }
+   else {
+      ctx->Array.LockFirst = 0;
+      ctx->Array.LockCount = 0;
    }
+
+   ctx->NewState |= _NEW_ARRAY;
+   ctx->Array.NewState |= _NEW_ARRAY_ALL;
+
+   if (ctx->Driver.LockArraysEXT)
+      ctx->Driver.LockArraysEXT( ctx, first, count );
 }
 
 
+void
+_mesa_UnlockArraysEXT( void )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glUnlockArrays\n");
+
+   ctx->Array.LockFirst = 0;
+   ctx->Array.LockCount = 0;
+   ctx->NewState |= _NEW_ARRAY;
+   ctx->Array.NewState |= _NEW_ARRAY_ALL;
+
+   if (ctx->Driver.UnlockArraysEXT)
+      ctx->Driver.UnlockArraysEXT( ctx );
+}
+
 
-void gl_update_client_state( GLcontext *ctx )
+
+/* GL_EXT_multi_draw_arrays */
+/* Somebody forgot to spec the first and count parameters as const! <sigh> */
+void
+_mesa_MultiDrawArraysEXT( GLenum mode, GLint *first,
+                          GLsizei *count, GLsizei primcount )
 {
-   static GLuint sz_flags[5] = { 0, 
-                                0,
-                                VERT_OBJ_2, 
-                                VERT_OBJ_23, 
-                                VERT_OBJ_234 };
-
-   static GLuint tc_flags[5] = { 0, 
-                                VERT_TEX0_1,
-                                VERT_TEX0_12, 
-                                VERT_TEX0_123, 
-                                VERT_TEX0_1234 };
-
-   ctx->Array.Flags = 0;
-   ctx->Array.Summary = 0;
-   ctx->input->ArrayIncr = 0;
-   
-   if (ctx->Array.Normal.Enabled)      ctx->Array.Flags |= VERT_NORM;
-   if (ctx->Array.Color.Enabled)       ctx->Array.Flags |= VERT_RGBA;
-   if (ctx->Array.Index.Enabled)       ctx->Array.Flags |= VERT_INDEX;
-   if (ctx->Array.EdgeFlag.Enabled)    ctx->Array.Flags |= VERT_EDGE;
-   if (ctx->Array.Vertex.Enabled) {
-      ctx->Array.Flags |= sz_flags[ctx->Array.Vertex.Size];
-      ctx->input->ArrayIncr = 1;
-   }
-   if (ctx->Array.TexCoord[0].Enabled) {
-      ctx->Array.Flags |= tc_flags[ctx->Array.TexCoord[0].Size];
-   }
-   if (ctx->Array.TexCoord[1].Enabled) {
-      ctx->Array.Flags |= (tc_flags[ctx->Array.TexCoord[1].Size] << NR_TEXSIZE_BITS);
-   }
+   GET_CURRENT_CONTEXT(ctx);
+   GLint i;
 
-   /* Not really important any more:
-    */
-   ctx->Array.Summary = ctx->Array.Flags & VERT_DATA;
-   ctx->input->ArrayAndFlags = ~ctx->Array.Flags;
-   ctx->input->ArrayEltFlush = !(ctx->CompileCVAFlag);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   for (i = 0; i < primcount; i++) {
+      if (count[i] > 0) {
+         (ctx->Exec->DrawArrays)(mode, first[i], count[i]);
+      }
+   }
 }
 
+
+/* GL_EXT_multi_draw_arrays */
+void
+_mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
+                            const GLvoid **indices, GLsizei primcount )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLint i;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   for (i = 0; i < primcount; i++) {
+      if (count[i] > 0) {
+         (ctx->Exec->DrawElements)(mode, count[i], type, indices[i]);
+      }
+   }
+}