nir: Store gl_shader_stage in nir_shader.
[mesa.git] / src / mesa / vbo / vbo_exec_api.c
index 53889d082b341d5b44ba49f77519bdc061957122..138cd60513dd0f4a2faec5eee251e04c2bc37346 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
 
-Copyright 2002-2008 Tungsten Graphics Inc., Cedar Park, Texas.
+Copyright 2002-2008 VMware, Inc.
 
 All Rights Reserved.
 
@@ -18,7 +18,7 @@ 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 NON-INFRINGEMENT. IN NO EVENT SHALL
-TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -27,7 +27,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 /*
  * Authors:
- *   Keith Whitwell <keith@tungstengraphics.com>
+ *   Keith Whitwell <keithw@vmware.com>
  */
 
 #include "main/glheader.h"
@@ -115,7 +115,7 @@ static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec )
  */
 void vbo_exec_vtx_wrap( struct vbo_exec_context *exec )
 {
-   GLfloat *data = exec->vtx.copied.buffer;
+   fi_type *data = exec->vtx.copied.buffer;
    GLuint i;
 
    /* Run pipeline on current vertices, copy wrapped vertices
@@ -159,27 +159,36 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )
           * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays.
           */
         GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
-         GLfloat tmp[4];
+         fi_type tmp[8]; /* space for doubles */
+         int dmul = exec->vtx.attrtype[i] == GL_DOUBLE ? 2 : 1;
+
+         if (exec->vtx.attrtype[i] == GL_DOUBLE) {
+            memset(tmp, 0, sizeof(tmp));
+            memcpy(tmp, exec->vtx.attrptr[i], exec->vtx.attrsz[i] * sizeof(GLfloat));
+         } else {
+            COPY_CLEAN_4V_TYPE_AS_UNION(tmp,
+                                        exec->vtx.attrsz[i],
+                                        exec->vtx.attrptr[i],
+                                        exec->vtx.attrtype[i]);
+         }
 
-         COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp,
-                                     exec->vtx.attrsz[i],
-                                     exec->vtx.attrptr[i],
-                                     exec->vtx.attrtype[i]);
-         
          if (exec->vtx.attrtype[i] != vbo->currval[i].Type ||
-             memcmp(current, tmp, sizeof(tmp)) != 0) {
-            memcpy(current, tmp, sizeof(tmp));
+             memcmp(current, tmp, 4 * sizeof(GLfloat) * dmul) != 0) {
+            memcpy(current, tmp, 4 * sizeof(GLfloat) * dmul);
         
             /* Given that we explicitly state size here, there is no need
              * for the COPY_CLEAN above, could just copy 16 bytes and be
              * done.  The only problem is when Mesa accesses ctx->Current
              * directly.
              */
-            vbo->currval[i].Size = exec->vtx.attrsz[i];
-            vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat);
+            /* Size here is in components - not bytes */
+            vbo->currval[i].Size = exec->vtx.attrsz[i] / dmul;
+            vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat) * dmul;
             vbo->currval[i].Type = exec->vtx.attrtype[i];
             vbo->currval[i].Integer =
                   vbo_attrtype_to_integer_flag(exec->vtx.attrtype[i]);
+            vbo->currval[i].Doubles =
+                  vbo_attrtype_to_double_flag(exec->vtx.attrtype[i]);
 
             /* This triggers rather too much recalculation of Mesa state
              * that doesn't get used (eg light positions).
@@ -214,13 +223,17 @@ vbo_exec_copy_from_current(struct vbo_exec_context *exec)
    GLint i;
 
    for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
-      const GLfloat *current = (GLfloat *) vbo->currval[i].Ptr;
-      switch (exec->vtx.attrsz[i]) {
-      case 4: exec->vtx.attrptr[i][3] = current[3];
-      case 3: exec->vtx.attrptr[i][2] = current[2];
-      case 2: exec->vtx.attrptr[i][1] = current[1];
-      case 1: exec->vtx.attrptr[i][0] = current[0];
-        break;
+      if (exec->vtx.attrtype[i] == GL_DOUBLE) {
+         memcpy(exec->vtx.attrptr[i], vbo->currval[i].Ptr, exec->vtx.attrsz[i] * sizeof(GLfloat));
+      } else {
+         const fi_type *current = (fi_type *) vbo->currval[i].Ptr;
+         switch (exec->vtx.attrsz[i]) {
+         case 4: exec->vtx.attrptr[i][3] = current[3];
+         case 3: exec->vtx.attrptr[i][2] = current[2];
+         case 2: exec->vtx.attrptr[i][1] = current[1];
+         case 1: exec->vtx.attrptr[i][0] = current[0];
+            break;
+         }
       }
    }
 }
@@ -240,7 +253,7 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
    struct gl_context *ctx = exec->ctx;
    struct vbo_context *vbo = vbo_context(ctx);
    const GLint lastcount = exec->vtx.vert_count;
-   GLfloat *old_attrptr[VBO_ATTRIB_MAX];
+   fi_type *old_attrptr[VBO_ATTRIB_MAX];
    const GLuint old_vtx_size = exec->vtx.vertex_size; /* floats per vertex */
    const GLuint oldSize = exec->vtx.attrsz[attr];
    GLuint i;
@@ -287,7 +300,7 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
    if (unlikely(oldSize)) {
       /* Size changed, recalculate all the attrptr[] values
        */
-      GLfloat *tmp = exec->vtx.vertex;
+      fi_type *tmp = exec->vtx.vertex;
 
       for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
         if (exec->vtx.attrsz[i]) {
@@ -306,7 +319,7 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
    else {
       /* Just have to append the new attribute at the end */
       exec->vtx.attrptr[attr] = exec->vtx.vertex +
-        exec->vtx.vertex_size - newSize;
+        exec->vtx.vertex_size - newSize;
    }
 
    /* Replay stored vertices to translate them
@@ -315,8 +328,8 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
     * -- No need to replay - just copy piecewise
     */
    if (unlikely(exec->vtx.copied.nr)) {
-      GLfloat *data = exec->vtx.copied.buffer;
-      GLfloat *dest = exec->vtx.buffer_ptr;
+      fi_type *data = exec->vtx.copied.buffer;
+      fi_type *dest = exec->vtx.buffer_ptr;
       GLuint j;
 
       assert(exec->vtx.buffer_ptr == exec->vtx.buffer_map);
@@ -331,13 +344,13 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
 
               if (j == attr) {
                  if (oldSize) {
-                    GLfloat tmp[4];
-                     COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp, oldSize,
+                    fi_type tmp[4];
+                    COPY_CLEAN_4V_TYPE_AS_UNION(tmp, oldSize,
                                                  data + old_offset,
                                                  exec->vtx.attrtype[j]);
                     COPY_SZ_4V(dest + new_offset, newSize, tmp);
                  } else {
-                    GLfloat *current = (GLfloat *)vbo->currval[j].Ptr;
+                    fi_type *current = (fi_type *)vbo->currval[j].Ptr;
                     COPY_SZ_4V(dest + new_offset, sz, current);
                  }
               }
@@ -364,11 +377,11 @@ vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
  * glTexCoord4f() call.  We promote the array from size=2 to size=4.
  */
 static void
-vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint newSize)
+vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint newSize, GLenum newType)
 {
    struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
 
-   if (newSize > exec->vtx.attrsz[attr]) {
+   if (newSize > exec->vtx.attrsz[attr] || newType != exec->vtx.attrtype[attr]) {
       /* New size is larger.  Need to flush existing vertices and get
        * an enlarged vertex format.
        */
@@ -376,14 +389,14 @@ vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint newSize)
    }
    else if (newSize < exec->vtx.active_sz[attr]) {
       GLuint i;
-      const GLfloat *id =
-            vbo_get_default_vals_as_float(exec->vtx.attrtype[attr]);
+      const fi_type *id =
+            vbo_get_default_vals_as_union(exec->vtx.attrtype[attr]);
 
       /* New size is smaller - just need to fill in some
        * zeros.  Don't need to flush or wrap.
        */
       for (i = newSize; i <= exec->vtx.attrsz[attr]; i++)
-        exec->vtx.attrptr[attr][i-1] = id[i-1];
+        exec->vtx.attrptr[attr][i-1] = id[i-1];
    }
 
    exec->vtx.active_sz[attr] = newSize;
@@ -401,23 +414,24 @@ vbo_exec_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint newSize)
  * This macro is used to implement all the glVertex, glColor, glTexCoord,
  * glVertexAttrib, etc functions.
  */
-#define ATTR( A, N, T, V0, V1, V2, V3 )                                        \
+#define ATTR_UNION( A, N, T, C, V0, V1, V2, V3 )                        \
 do {                                                                   \
    struct vbo_exec_context *exec = &vbo_context(ctx)->exec;            \
-                                                                       \
+   int sz = (sizeof(C) / sizeof(GLfloat));                              \
    if (unlikely(!(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT)))      \
       ctx->Driver.BeginVertices( ctx );                                        \
-                                                                       \
-   if (unlikely(exec->vtx.active_sz[A] != N))                          \
-      vbo_exec_fixup_vertex(ctx, A, N);                                        \
-                                                                       \
+                                                                        \
+   if (unlikely(exec->vtx.active_sz[A] != N * sz) ||                    \
+       unlikely(exec->vtx.attrtype[A] != T))                            \
+      vbo_exec_fixup_vertex(ctx, A, N * sz, T);                         \
+                                                                        \
    {                                                                   \
-      GLfloat *dest = exec->vtx.attrptr[A];                            \
+      C *dest = (C *)exec->vtx.attrptr[A];                              \
       if (N>0) dest[0] = V0;                                           \
       if (N>1) dest[1] = V1;                                           \
       if (N>2) dest[2] = V2;                                           \
       if (N>3) dest[3] = V3;                                           \
-      exec->vtx.attrtype[A] = T;                                        \
+      exec->vtx.attrtype[A] = T;                                       \
    }                                                                   \
                                                                        \
    if ((A) == 0) {                                                     \
@@ -438,8 +452,7 @@ do {                                                                        \
    }                                                                   \
 } while (0)
 
-
-#define ERROR(err) _mesa_error( ctx, err, __FUNCTION__ )
+#define ERROR(err) _mesa_error( ctx, err, __func__ )
 #define TAG(x) vbo_##x
 
 #include "vbo_attrib_tmp.h"
@@ -575,7 +588,7 @@ static void GLAPIENTRY vbo_exec_EvalCoord1f( GLfloat u )
       for (i = 0; i <= VBO_ATTRIB_TEX7; i++) {
         if (exec->eval.map1[i].map) 
            if (exec->vtx.active_sz[i] != exec->eval.map1[i].sz)
-              vbo_exec_fixup_vertex( ctx, i, exec->eval.map1[i].sz );
+              vbo_exec_fixup_vertex( ctx, i, exec->eval.map1[i].sz, GL_FLOAT );
       }
    }
 
@@ -602,12 +615,12 @@ static void GLAPIENTRY vbo_exec_EvalCoord2f( GLfloat u, GLfloat v )
       for (i = 0; i <= VBO_ATTRIB_TEX7; i++) {
         if (exec->eval.map2[i].map) 
            if (exec->vtx.active_sz[i] != exec->eval.map2[i].sz)
-              vbo_exec_fixup_vertex( ctx, i, exec->eval.map2[i].sz );
+              vbo_exec_fixup_vertex( ctx, i, exec->eval.map2[i].sz, GL_FLOAT );
       }
 
       if (ctx->Eval.AutoNormal) 
         if (exec->vtx.active_sz[VBO_ATTRIB_NORMAL] != 3)
-           vbo_exec_fixup_vertex( ctx, VBO_ATTRIB_NORMAL, 3 );
+           vbo_exec_fixup_vertex( ctx, VBO_ATTRIB_NORMAL, 3, GL_FLOAT );
    }
 
    memcpy( exec->vtx.copied.buffer, exec->vtx.vertex, 
@@ -654,132 +667,6 @@ static void GLAPIENTRY vbo_exec_EvalPoint2( GLint i, GLint j )
 }
 
 
-static void GLAPIENTRY
-vbo_exec_EvalMesh1(GLenum mode, GLint i1, GLint i2)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLint i;
-   GLfloat u, du;
-   GLenum prim;
-
-   switch (mode) {
-   case GL_POINT:
-      prim = GL_POINTS;
-      break;
-   case GL_LINE:
-      prim = GL_LINE_STRIP;
-      break;
-   default:
-      _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" );
-      return;
-   }
-
-   /* No effect if vertex maps disabled.
-    */
-   if (!ctx->Eval.Map1Vertex4 && 
-       !ctx->Eval.Map1Vertex3)
-      return;
-
-   du = ctx->Eval.MapGrid1du;
-   u = ctx->Eval.MapGrid1u1 + i1 * du;
-
-   CALL_Begin(GET_DISPATCH(), (prim));
-   for (i=i1;i<=i2;i++,u+=du) {
-      CALL_EvalCoord1f(GET_DISPATCH(), (u));
-   }
-   CALL_End(GET_DISPATCH(), ());
-}
-
-
-static void GLAPIENTRY
-vbo_exec_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLfloat u, du, v, dv, v1, u1;
-   GLint i, j;
-
-   switch (mode) {
-   case GL_POINT:
-   case GL_LINE:
-   case GL_FILL:
-      break;
-   default:
-      _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" );
-      return;
-   }
-
-   /* No effect if vertex maps disabled.
-    */
-   if (!ctx->Eval.Map2Vertex4 && 
-       !ctx->Eval.Map2Vertex3)
-      return;
-
-   du = ctx->Eval.MapGrid2du;
-   dv = ctx->Eval.MapGrid2dv;
-   v1 = ctx->Eval.MapGrid2v1 + j1 * dv;
-   u1 = ctx->Eval.MapGrid2u1 + i1 * du;
-
-   switch (mode) {
-   case GL_POINT:
-      CALL_Begin(GET_DISPATCH(), (GL_POINTS));
-      for (v=v1,j=j1;j<=j2;j++,v+=dv) {
-        for (u=u1,i=i1;i<=i2;i++,u+=du) {
-           CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
-        }
-      }
-      CALL_End(GET_DISPATCH(), ());
-      break;
-   case GL_LINE:
-      for (v=v1,j=j1;j<=j2;j++,v+=dv) {
-        CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP));
-        for (u=u1,i=i1;i<=i2;i++,u+=du) {
-           CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
-        }
-        CALL_End(GET_DISPATCH(), ());
-      }
-      for (u=u1,i=i1;i<=i2;i++,u+=du) {
-        CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP));
-        for (v=v1,j=j1;j<=j2;j++,v+=dv) {
-           CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
-        }
-        CALL_End(GET_DISPATCH(), ());
-      }
-      break;
-   case GL_FILL:
-      for (v=v1,j=j1;j<j2;j++,v+=dv) {
-        CALL_Begin(GET_DISPATCH(), (GL_TRIANGLE_STRIP));
-        for (u=u1,i=i1;i<=i2;i++,u+=du) {
-           CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
-           CALL_EvalCoord2f(GET_DISPATCH(), (u, v+dv));
-        }
-        CALL_End(GET_DISPATCH(), ());
-      }
-      break;
-   }
-}
-
-
-/**
- * Execute a glRectf() function.  This is not suitable for GL_COMPILE
- * modes (as the test for outside begin/end is not compiled),
- * but may be useful for drivers in circumstances which exclude
- * display list interactions.
- *
- * (None of the functions in this file are suitable for GL_COMPILE
- * modes).
- */
-static void GLAPIENTRY
-vbo_exec_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
-{
-   CALL_Begin(GET_DISPATCH(), (GL_QUADS));
-   CALL_Vertex2f(GET_DISPATCH(), (x1, y1));
-   CALL_Vertex2f(GET_DISPATCH(), (x2, y1));
-   CALL_Vertex2f(GET_DISPATCH(), (x2, y2));
-   CALL_Vertex2f(GET_DISPATCH(), (x1, y2));
-   CALL_End(GET_DISPATCH(), ());
-}
-
-
 /**
  * Called via glBegin.
  */
@@ -811,7 +698,7 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
       return;
    }
 
-   /* Heuristic: attempt to isolate attributes occuring outside
+   /* Heuristic: attempt to isolate attributes occurring outside
     * begin/end pairs.
     */
    if (exec->vtx.vertex_size && !exec->vtx.attrsz[0])
@@ -828,6 +715,7 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
    exec->vtx.prim[i].count = 0;
    exec->vtx.prim[i].num_instances = 1;
    exec->vtx.prim[i].base_instance = 0;
+   exec->vtx.prim[i].is_indirect = 0;
 
    ctx->Driver.CurrentExecPrimitive = mode;
 
@@ -844,6 +732,34 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
 }
 
 
+/**
+ * Try to merge / concatenate the two most recent VBO primitives.
+ */
+static void
+try_vbo_merge(struct vbo_exec_context *exec)
+{
+   struct _mesa_prim *cur =  &exec->vtx.prim[exec->vtx.prim_count - 1];
+
+   assert(exec->vtx.prim_count >= 1);
+
+   vbo_try_prim_conversion(cur);
+
+   if (exec->vtx.prim_count >= 2) {
+      struct _mesa_prim *prev = &exec->vtx.prim[exec->vtx.prim_count - 2];
+      assert(prev == cur - 1);
+
+      if (vbo_can_merge_prims(prev, cur)) {
+         assert(cur->begin);
+         assert(cur->end);
+         assert(prev->begin);
+         assert(prev->end);
+         vbo_merge_prims(prev, cur);
+         exec->vtx.prim_count--;  /* drop the last primitive */
+      }
+   }
+}
+
+
 /**
  * Called via glEnd.
  */
@@ -870,6 +786,8 @@ static void GLAPIENTRY vbo_exec_End( void )
 
       exec->vtx.prim[i].end = 1;
       exec->vtx.prim[i].count = idx - exec->vtx.prim[i].start;
+
+      try_vbo_merge(exec);
    }
 
    ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
@@ -910,16 +828,21 @@ static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec )
    struct gl_context *ctx = exec->ctx;
    GLvertexformat *vfmt = &exec->vtxfmt;
 
-   _MESA_INIT_ARRAYELT_VTXFMT(vfmt, _ae_);
+   vfmt->ArrayElement = _ae_ArrayElement;
 
    vfmt->Begin = vbo_exec_Begin;
    vfmt->End = vbo_exec_End;
    vfmt->PrimitiveRestartNV = vbo_exec_PrimitiveRestartNV;
 
-   _MESA_INIT_DLIST_VTXFMT(vfmt, _mesa_);
-   _MESA_INIT_EVAL_VTXFMT(vfmt, vbo_exec_);
+   vfmt->CallList = _mesa_CallList;
+   vfmt->CallLists = _mesa_CallLists;
 
-   vfmt->Rectf = vbo_exec_Rectf;
+   vfmt->EvalCoord1f = vbo_exec_EvalCoord1f;
+   vfmt->EvalCoord1fv = vbo_exec_EvalCoord1fv;
+   vfmt->EvalCoord2f = vbo_exec_EvalCoord2f;
+   vfmt->EvalCoord2fv = vbo_exec_EvalCoord2fv;
+   vfmt->EvalPoint1 = vbo_exec_EvalPoint1;
+   vfmt->EvalPoint2 = vbo_exec_EvalPoint2;
 
    /* from attrib_tmp.h:
     */
@@ -1058,6 +981,16 @@ static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec )
    vfmt->VertexAttribP3uiv = vbo_VertexAttribP3uiv;
    vfmt->VertexAttribP4ui = vbo_VertexAttribP4ui;
    vfmt->VertexAttribP4uiv = vbo_VertexAttribP4uiv;
+
+   vfmt->VertexAttribL1d = vbo_VertexAttribL1d;
+   vfmt->VertexAttribL2d = vbo_VertexAttribL2d;
+   vfmt->VertexAttribL3d = vbo_VertexAttribL3d;
+   vfmt->VertexAttribL4d = vbo_VertexAttribL4d;
+
+   vfmt->VertexAttribL1dv = vbo_VertexAttribL1dv;
+   vfmt->VertexAttribL2dv = vbo_VertexAttribL2dv;
+   vfmt->VertexAttribL3dv = vbo_VertexAttribL3dv;
+   vfmt->VertexAttribL4dv = vbo_VertexAttribL4dv;
 }
 
 
@@ -1080,16 +1013,19 @@ void vbo_use_buffer_objects(struct gl_context *ctx)
 
    /* Make sure this func is only used once */
    assert(exec->vtx.bufferobj == ctx->Shared->NullBufferObj);
-   if (exec->vtx.buffer_map) {
-      _mesa_align_free(exec->vtx.buffer_map);
-      exec->vtx.buffer_map = NULL;
-      exec->vtx.buffer_ptr = NULL;
-   }
+
+   _mesa_align_free(exec->vtx.buffer_map);
+   exec->vtx.buffer_map = NULL;
+   exec->vtx.buffer_ptr = NULL;
 
    /* Allocate a real buffer object now */
    _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL);
-   exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName, target);
-   if (!ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj)) {
+   exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName);
+   if (!ctx->Driver.BufferData(ctx, target, size, NULL, usage,
+                               GL_MAP_WRITE_BIT |
+                               GL_DYNAMIC_STORAGE_BIT |
+                               GL_CLIENT_STORAGE_BIT,
+                               exec->vtx.bufferobj)) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "VBO allocation");
    }
 }
@@ -1123,7 +1059,7 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec )
                                  &exec->vtx.bufferobj,
                                  ctx->Shared->NullBufferObj);
 
-   ASSERT(!exec->vtx.buffer_map);
+   assert(!exec->vtx.buffer_map);
    exec->vtx.buffer_map = _mesa_align_malloc(VBO_VERT_BUFFER_SIZE, 64);
    exec->vtx.buffer_ptr = exec->vtx.buffer_map;
 
@@ -1131,16 +1067,16 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec )
    _mesa_noop_vtxfmt_init(&exec->vtxfmt_noop);
 
    for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
-      ASSERT(i < Elements(exec->vtx.attrsz));
+      assert(i < ARRAY_SIZE(exec->vtx.attrsz));
       exec->vtx.attrsz[i] = 0;
-      ASSERT(i < Elements(exec->vtx.attrtype));
+      assert(i < ARRAY_SIZE(exec->vtx.attrtype));
       exec->vtx.attrtype[i] = GL_FLOAT;
-      ASSERT(i < Elements(exec->vtx.active_sz));
+      assert(i < ARRAY_SIZE(exec->vtx.active_sz));
       exec->vtx.active_sz[i] = 0;
    }
    for (i = 0 ; i < VERT_ATTRIB_MAX; i++) {
-      ASSERT(i < Elements(exec->vtx.inputs));
-      ASSERT(i < Elements(exec->vtx.arrays));
+      assert(i < ARRAY_SIZE(exec->vtx.inputs));
+      assert(i < ARRAY_SIZE(exec->vtx.arrays));
       exec->vtx.inputs[i] = &exec->vtx.arrays[i];
    }
    
@@ -1154,7 +1090,7 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec )
          struct gl_client_array *array;
          array = &arrays[VERT_ATTRIB_FF(i)];
          array->BufferObj = NULL;
-         _mesa_reference_buffer_object(ctx, &arrays->BufferObj,
+         _mesa_reference_buffer_object(ctx, &array->BufferObj,
                                  vbo->currval[VBO_ATTRIB_POS+i].BufferObj);
       }
 
@@ -1186,7 +1122,7 @@ void vbo_exec_vtx_destroy( struct vbo_exec_context *exec )
    /* True VBOs should already be unmapped
     */
    if (exec->vtx.buffer_map) {
-      ASSERT(exec->vtx.bufferobj->Name == 0 ||
+      assert(exec->vtx.bufferobj->Name == 0 ||
              exec->vtx.bufferobj->Name == IMM_BUFFER_NAME);
       if (exec->vtx.bufferobj->Name == 0) {
          _mesa_align_free(exec->vtx.buffer_map);
@@ -1197,7 +1133,7 @@ void vbo_exec_vtx_destroy( struct vbo_exec_context *exec )
 
    /* Drop any outstanding reference to the vertex buffer
     */
-   for (i = 0; i < Elements(exec->vtx.arrays); i++) {
+   for (i = 0; i < ARRAY_SIZE(exec->vtx.arrays); i++) {
       _mesa_reference_buffer_object(ctx,
                                     &exec->vtx.arrays[i].BufferObj,
                                     NULL);
@@ -1205,8 +1141,8 @@ void vbo_exec_vtx_destroy( struct vbo_exec_context *exec )
 
    /* Free the vertex buffer.  Unmap first if needed.
     */
-   if (_mesa_bufferobj_mapped(exec->vtx.bufferobj)) {
-      ctx->Driver.UnmapBuffer(ctx, exec->vtx.bufferobj);
+   if (_mesa_bufferobj_mapped(exec->vtx.bufferobj, MAP_INTERNAL)) {
+      ctx->Driver.UnmapBuffer(ctx, exec->vtx.bufferobj, MAP_INTERNAL);
    }
    _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL);
 }
@@ -1326,7 +1262,7 @@ VertexAttrib4f_nopos(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
 {
    GET_CURRENT_CONTEXT(ctx);
    if (index < MAX_VERTEX_GENERIC_ATTRIBS)
-      ATTR(VBO_ATTRIB_GENERIC0 + index, 4, GL_FLOAT, x, y, z, w);
+      ATTRF(VBO_ATTRIB_GENERIC0 + index, 4, x, y, z, w);
    else
       ERROR(GL_INVALID_VALUE);
 }