added GL_SGIX/SGIS_pixel_texture
[mesa.git] / src / mesa / main / eval.c
index 74604a21c4dfe9d559684e72b85a7471cfa9eaa8..e20180d13886518d910e5c28c1770c821a6021ab 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: eval.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+/* $Id: eval.c,v 1.8 2000/01/13 00:30:41 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.1
+ * Version:  3.3
  * 
- * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2000  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"),
@@ -25,9 +25,6 @@
  */
 
 
-
-
-
 /*
  * eval.c was written by
  * Bernd Barsuhn (bdbarsuh@cip.informatik.uni-erlangen.de) and
 #ifdef PC_HEADER
 #include "all.h"
 #else
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
+#include "glheader.h"
 #include "context.h"
 #include "eval.h"
 #include "macros.h"
+#include "mem.h"
 #include "mmath.h"
 #include "types.h"
 #include "vbcull.h"
 #include "vbfill.h"
 #include "vbxform.h"
-#ifdef XFree86Server
-#include "GL/xf86glx.h"
-#endif
 #endif
 
 
@@ -530,9 +523,9 @@ de_casteljau_surf(GLfloat *cn, GLfloat *out, GLfloat *du, GLfloat *dv,
 /*
  * Return the number of components per control point for any type of
  * evaluator.  Return 0 if bad target.
+ * See table 5.1 in the OpenGL 1.2 spec.
  */
-
-static GLint components( GLenum target )
+GLuint _mesa_evaluator_components( GLenum target )
 {
    switch (target) {
       case GL_MAP1_VERTEX_3:           return 3;
@@ -570,18 +563,17 @@ static GLint components( GLenum target )
  * Return:  pointer to buffer of contiguous control points or NULL if out
  *          of memory.
  */
-GLfloat *gl_copy_map_points1f( GLenum target,
-                               GLint ustride, GLint uorder,
+GLfloat *gl_copy_map_points1f( GLenum target, GLint ustride, GLint uorder,
                                const GLfloat *points )
 {
    GLfloat *buffer, *p;
-   GLint i, k, size = components(target);
+   GLint i, k, size = _mesa_evaluator_components(target);
 
    if (!points || size==0) {
       return NULL;
    }
 
-   buffer = (GLfloat *) malloc(uorder * size * sizeof(GLfloat));
+   buffer = (GLfloat *) MALLOC(uorder * size * sizeof(GLfloat));
 
    if(buffer) 
       for(i=0, p=buffer; i<uorder; i++, points+=ustride)
@@ -596,18 +588,17 @@ GLfloat *gl_copy_map_points1f( GLenum target,
 /*
  * Same as above but convert doubles to floats.
  */
-GLfloat *gl_copy_map_points1d( GLenum target,
-                               GLint ustride, GLint uorder,
-                               const GLdouble *points )
+GLfloat *gl_copy_map_points1d( GLenum target, GLint ustride, GLint uorder,
+                               const GLdouble *points )
 {
    GLfloat *buffer, *p;
-   GLint i, k, size = components(target);
+   GLint i, k, size = _mesa_evaluator_components(target);
 
    if (!points || size==0) {
       return NULL;
    }
 
-   buffer = (GLfloat *) malloc(uorder * size * sizeof(GLfloat));
+   buffer = (GLfloat *) MALLOC(uorder * size * sizeof(GLfloat));
 
    if(buffer)
       for(i=0, p=buffer; i<uorder; i++, points+=ustride)
@@ -630,15 +621,15 @@ GLfloat *gl_copy_map_points1d( GLenum target,
  *          of memory.
  */
 GLfloat *gl_copy_map_points2f( GLenum target,
-                               GLint ustride, GLint uorder,
-                               GLint vstride, GLint vorder,
-                               const GLfloat *points )
+                               GLint ustride, GLint uorder,
+                               GLint vstride, GLint vorder,
+                               const GLfloat *points )
 {
    GLfloat *buffer, *p;
    GLint i, j, k, size, dsize, hsize;
    GLint uinc;
 
-   size = components(target);
+   size = _mesa_evaluator_components(target);
 
    if (!points || size==0) {
       return NULL;
@@ -651,9 +642,9 @@ GLfloat *gl_copy_map_points2f( GLenum target,
    hsize = (uorder > vorder ? uorder : vorder)*size;
 
    if(hsize>dsize)
-     buffer = (GLfloat *) malloc((uorder*vorder*size+hsize)*sizeof(GLfloat));
+     buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat));
    else
-     buffer = (GLfloat *) malloc((uorder*vorder*size+dsize)*sizeof(GLfloat));
+     buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat));
 
    /* compute the increment value for the u-loop */
    uinc = ustride - vorder*vstride;
@@ -681,7 +672,7 @@ GLfloat *gl_copy_map_points2d(GLenum target,
    GLint i, j, k, size, hsize, dsize;
    GLint uinc;
 
-   size = components(target);
+   size = _mesa_evaluator_components(target);
 
    if (!points || size==0) {
       return NULL;
@@ -694,9 +685,9 @@ GLfloat *gl_copy_map_points2d(GLenum target,
    hsize = (uorder > vorder ? uorder : vorder)*size;
 
    if(hsize>dsize)
-     buffer = (GLfloat *) malloc((uorder*vorder*size+hsize)*sizeof(GLfloat));
+     buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat));
    else
-     buffer = (GLfloat *) malloc((uorder*vorder*size+dsize)*sizeof(GLfloat));
+     buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat));
 
    /* compute the increment value for the u-loop */
    uinc = ustride - vorder*vstride;
@@ -711,6 +702,7 @@ GLfloat *gl_copy_map_points2d(GLenum target,
 }
 
 
+#if 00
 /*
  * This function is called by the display list deallocator function to
  * specify that a given set of control points are no longer needed.
@@ -789,7 +781,7 @@ void gl_free_control_points( GLcontext* ctx, GLenum target, GLfloat *data )
       else {
          /* The control points in the display list are not currently */
          /* being used. */
-         free( data );
+         FREE( data );
       }
    }
    if (map2) {
@@ -801,11 +793,12 @@ void gl_free_control_points( GLcontext* ctx, GLenum target, GLfloat *data )
       else {
          /* The control points in the display list are not currently */
          /* being used. */
-         free( data );
+         FREE( data );
       }
    }
 
 }
+#endif
 
 
 
@@ -815,154 +808,130 @@ void gl_free_control_points( GLcontext* ctx, GLenum target, GLfloat *data )
 
 
 /*
- * Note that the array of control points must be 'unpacked' at this time.
- * Input:  retain - if TRUE, this control point data is also in a display
- *                  list and can't be freed until the list is freed.
+ * This does the work of glMap1[fd].
  */
-void gl_Map1f( GLcontext* ctx, GLenum target,
-               GLfloat u1, GLfloat u2, GLint stride,
-               GLint order, const GLfloat *points, GLboolean retain )
+static void
+map1(GLenum target, GLfloat u1, GLfloat u2, GLint ustride,
+     GLint uorder, const GLvoid *points, GLenum type )
 {
+   GET_CURRENT_CONTEXT(ctx);
    GLint k;
-
-   if (!points) {
-      gl_error( ctx, GL_OUT_OF_MEMORY, "glMap1f" );
-      return;
-   }
-
-   /* may be a new stride after copying control points */
-   stride = components( target );
+   GLfloat *pnts;
 
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMap1");
 
-   if (u1==u2) {
+   assert(type == GL_FLOAT || type == GL_DOUBLE);
+
+   if (u1 == u2) {
       gl_error( ctx, GL_INVALID_VALUE, "glMap1(u1,u2)" );
       return;
    }
-
-   if (order<1 || order>MAX_EVAL_ORDER) {
+   if (uorder < 1 || uorder > MAX_EVAL_ORDER) {
       gl_error( ctx, GL_INVALID_VALUE, "glMap1(order)" );
       return;
    }
+   if (!points) {
+      gl_error( ctx, GL_INVALID_VALUE, "glMap1(points)" );
+      return;
+   }
 
-   k = components( target );
-   if (k==0) {
+   k = _mesa_evaluator_components( target );
+   if (k == 0) {
       gl_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
    }
 
-   if (stride < k) {
+   if (ustride < k) {
       gl_error( ctx, GL_INVALID_VALUE, "glMap1(stride)" );
       return;
    }
 
+   /* make copy of the control points */
+   if (type == GL_FLOAT)
+      pnts = gl_copy_map_points1f(target, ustride, uorder, (GLfloat*) points);
+   else
+      pnts = gl_copy_map_points1d(target, ustride, uorder, (GLdouble*) points);
+
    switch (target) {
       case GL_MAP1_VERTEX_3:
-         ctx->EvalMap.Map1Vertex3.Order = order;
+         ctx->EvalMap.Map1Vertex3.Order = uorder;
         ctx->EvalMap.Map1Vertex3.u1 = u1;
         ctx->EvalMap.Map1Vertex3.u2 = u2;
         ctx->EvalMap.Map1Vertex3.du = 1.0 / (u2 - u1);
-        if (ctx->EvalMap.Map1Vertex3.Points
-             && !ctx->EvalMap.Map1Vertex3.Retain) {
-           free( ctx->EvalMap.Map1Vertex3.Points );
-        }
-        ctx->EvalMap.Map1Vertex3.Points = (GLfloat *) points;
-         ctx->EvalMap.Map1Vertex3.Retain = retain;
+        if (ctx->EvalMap.Map1Vertex3.Points)
+           FREE( ctx->EvalMap.Map1Vertex3.Points );
+        ctx->EvalMap.Map1Vertex3.Points = pnts;
         break;
       case GL_MAP1_VERTEX_4:
-         ctx->EvalMap.Map1Vertex4.Order = order;
+         ctx->EvalMap.Map1Vertex4.Order = uorder;
         ctx->EvalMap.Map1Vertex4.u1 = u1;
         ctx->EvalMap.Map1Vertex4.u2 = u2;
         ctx->EvalMap.Map1Vertex4.du = 1.0 / (u2 - u1);
-        if (ctx->EvalMap.Map1Vertex4.Points
-             && !ctx->EvalMap.Map1Vertex4.Retain) {
-           free( ctx->EvalMap.Map1Vertex4.Points );
-        }
-        ctx->EvalMap.Map1Vertex4.Points = (GLfloat *) points;
-        ctx->EvalMap.Map1Vertex4.Retain = retain;
+        if (ctx->EvalMap.Map1Vertex4.Points)
+           FREE( ctx->EvalMap.Map1Vertex4.Points );
+        ctx->EvalMap.Map1Vertex4.Points = pnts;
         break;
       case GL_MAP1_INDEX:
-         ctx->EvalMap.Map1Index.Order = order;
+         ctx->EvalMap.Map1Index.Order = uorder;
         ctx->EvalMap.Map1Index.u1 = u1;
         ctx->EvalMap.Map1Index.u2 = u2;
         ctx->EvalMap.Map1Index.du = 1.0 / (u2 - u1);
-        if (ctx->EvalMap.Map1Index.Points
-             && !ctx->EvalMap.Map1Index.Retain) {
-           free( ctx->EvalMap.Map1Index.Points );
-        }
-        ctx->EvalMap.Map1Index.Points = (GLfloat *) points;
-        ctx->EvalMap.Map1Index.Retain = retain;
+        if (ctx->EvalMap.Map1Index.Points)
+           FREE( ctx->EvalMap.Map1Index.Points );
+        ctx->EvalMap.Map1Index.Points = pnts;
         break;
       case GL_MAP1_COLOR_4:
-         ctx->EvalMap.Map1Color4.Order = order;
+         ctx->EvalMap.Map1Color4.Order = uorder;
         ctx->EvalMap.Map1Color4.u1 = u1;
         ctx->EvalMap.Map1Color4.u2 = u2;
         ctx->EvalMap.Map1Color4.du = 1.0 / (u2 - u1);
-        if (ctx->EvalMap.Map1Color4.Points
-             && !ctx->EvalMap.Map1Color4.Retain) {
-           free( ctx->EvalMap.Map1Color4.Points );
-        }
-        ctx->EvalMap.Map1Color4.Points = (GLfloat *) points;
-        ctx->EvalMap.Map1Color4.Retain = retain;
+        if (ctx->EvalMap.Map1Color4.Points)
+           FREE( ctx->EvalMap.Map1Color4.Points );
+        ctx->EvalMap.Map1Color4.Points = pnts;
         break;
       case GL_MAP1_NORMAL:
-         ctx->EvalMap.Map1Normal.Order = order;
+         ctx->EvalMap.Map1Normal.Order = uorder;
         ctx->EvalMap.Map1Normal.u1 = u1;
         ctx->EvalMap.Map1Normal.u2 = u2;
         ctx->EvalMap.Map1Normal.du = 1.0 / (u2 - u1);
-        if (ctx->EvalMap.Map1Normal.Points
-             && !ctx->EvalMap.Map1Normal.Retain) {
-           free( ctx->EvalMap.Map1Normal.Points );
-        }
-        ctx->EvalMap.Map1Normal.Points = (GLfloat *) points;
-        ctx->EvalMap.Map1Normal.Retain = retain;
+        if (ctx->EvalMap.Map1Normal.Points)
+           FREE( ctx->EvalMap.Map1Normal.Points );
+        ctx->EvalMap.Map1Normal.Points = pnts;
         break;
       case GL_MAP1_TEXTURE_COORD_1:
-         ctx->EvalMap.Map1Texture1.Order = order;
+         ctx->EvalMap.Map1Texture1.Order = uorder;
         ctx->EvalMap.Map1Texture1.u1 = u1;
         ctx->EvalMap.Map1Texture1.u2 = u2;
         ctx->EvalMap.Map1Texture1.du = 1.0 / (u2 - u1);
-        if (ctx->EvalMap.Map1Texture1.Points
-             && !ctx->EvalMap.Map1Texture1.Retain) {
-           free( ctx->EvalMap.Map1Texture1.Points );
-        }
-        ctx->EvalMap.Map1Texture1.Points = (GLfloat *) points;
-        ctx->EvalMap.Map1Texture1.Retain = retain;
+        if (ctx->EvalMap.Map1Texture1.Points)
+           FREE( ctx->EvalMap.Map1Texture1.Points );
+        ctx->EvalMap.Map1Texture1.Points = pnts;
         break;
       case GL_MAP1_TEXTURE_COORD_2:
-         ctx->EvalMap.Map1Texture2.Order = order;
+         ctx->EvalMap.Map1Texture2.Order = uorder;
         ctx->EvalMap.Map1Texture2.u1 = u1;
         ctx->EvalMap.Map1Texture2.u2 = u2;
         ctx->EvalMap.Map1Texture2.du = 1.0 / (u2 - u1);
-        if (ctx->EvalMap.Map1Texture2.Points
-             && !ctx->EvalMap.Map1Texture2.Retain) {
-           free( ctx->EvalMap.Map1Texture2.Points );
-        }
-        ctx->EvalMap.Map1Texture2.Points = (GLfloat *) points;
-        ctx->EvalMap.Map1Texture2.Retain = retain;
+        if (ctx->EvalMap.Map1Texture2.Points)
+           FREE( ctx->EvalMap.Map1Texture2.Points );
+        ctx->EvalMap.Map1Texture2.Points = pnts;
         break;
       case GL_MAP1_TEXTURE_COORD_3:
-         ctx->EvalMap.Map1Texture3.Order = order;
+         ctx->EvalMap.Map1Texture3.Order = uorder;
         ctx->EvalMap.Map1Texture3.u1 = u1;
         ctx->EvalMap.Map1Texture3.u2 = u2;
         ctx->EvalMap.Map1Texture3.du = 1.0 / (u2 - u1);
-        if (ctx->EvalMap.Map1Texture3.Points
-             && !ctx->EvalMap.Map1Texture3.Retain) {
-           free( ctx->EvalMap.Map1Texture3.Points );
-        }
-        ctx->EvalMap.Map1Texture3.Points = (GLfloat *) points;
-        ctx->EvalMap.Map1Texture3.Retain = retain;
+        if (ctx->EvalMap.Map1Texture3.Points)
+           FREE( ctx->EvalMap.Map1Texture3.Points );
+        ctx->EvalMap.Map1Texture3.Points = pnts;
         break;
       case GL_MAP1_TEXTURE_COORD_4:
-         ctx->EvalMap.Map1Texture4.Order = order;
+         ctx->EvalMap.Map1Texture4.Order = uorder;
         ctx->EvalMap.Map1Texture4.u1 = u1;
         ctx->EvalMap.Map1Texture4.u2 = u2;
         ctx->EvalMap.Map1Texture4.du = 1.0 / (u2 - u1);
-        if (ctx->EvalMap.Map1Texture4.Points
-             && !ctx->EvalMap.Map1Texture4.Retain) {
-           free( ctx->EvalMap.Map1Texture4.Points );
-        }
-        ctx->EvalMap.Map1Texture4.Points = (GLfloat *) points;
-        ctx->EvalMap.Map1Texture4.Retain = retain;
+        if (ctx->EvalMap.Map1Texture4.Points)
+           FREE( ctx->EvalMap.Map1Texture4.Points );
+        ctx->EvalMap.Map1Texture4.Points = pnts;
         break;
       default:
          gl_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
@@ -971,18 +940,30 @@ void gl_Map1f( GLcontext* ctx, GLenum target,
 
 
 
+void
+_mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride,
+             GLint order, const GLfloat *points )
+{
+   map1(target, u1, u2, stride, order, points, GL_FLOAT);
+}
 
-/*
- * Note that the array of control points must be 'unpacked' at this time.
- * Input:  retain - if TRUE, this control point data is also in a display
- *                  list and can't be freed until the list is freed.
- */
-void gl_Map2f( GLcontext* ctx, GLenum target,
-             GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
-             GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
-             const GLfloat *points, GLboolean retain )
+
+void
+_mesa_Map1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride,
+             GLint order, const GLdouble *points )
+{
+   map1(target, u1, u2, stride, order, points, GL_DOUBLE);
+}
+
+
+static void
+map2( GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
+      GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
+      const GLvoid *points, GLenum type )
 {
+   GET_CURRENT_CONTEXT(ctx);
    GLint k;
+   GLfloat *pnts;
 
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMap2");
 
@@ -1006,7 +987,7 @@ void gl_Map2f( GLcontext* ctx, GLenum target,
       return;
    }
 
-   k = components( target );
+   k = _mesa_evaluator_components( target );
    if (k==0) {
       gl_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
    }
@@ -1020,6 +1001,14 @@ void gl_Map2f( GLcontext* ctx, GLenum target,
       return;
    }
 
+   /* make copy of the control points */
+   if (type == GL_FLOAT)
+      pnts = gl_copy_map_points2f(target, ustride, uorder,
+                                  vstride, vorder, (GLfloat*) points);
+   else
+      pnts = gl_copy_map_points2d(target, ustride, uorder,
+                                  vstride, vorder, (GLdouble*) points);
+
    switch (target) {
       case GL_MAP2_VERTEX_3:
          ctx->EvalMap.Map2Vertex3.Uorder = uorder;
@@ -1030,12 +1019,9 @@ void gl_Map2f( GLcontext* ctx, GLenum target,
         ctx->EvalMap.Map2Vertex3.v1 = v1;
         ctx->EvalMap.Map2Vertex3.v2 = v2;
         ctx->EvalMap.Map2Vertex3.dv = 1.0 / (v2 - v1);
-        if (ctx->EvalMap.Map2Vertex3.Points
-             && !ctx->EvalMap.Map2Vertex3.Retain) {
-           free( ctx->EvalMap.Map2Vertex3.Points );
-        }
-        ctx->EvalMap.Map2Vertex3.Retain = retain;
-        ctx->EvalMap.Map2Vertex3.Points = (GLfloat *) points;
+        if (ctx->EvalMap.Map2Vertex3.Points)
+           FREE( ctx->EvalMap.Map2Vertex3.Points );
+        ctx->EvalMap.Map2Vertex3.Points = pnts;
         break;
       case GL_MAP2_VERTEX_4:
          ctx->EvalMap.Map2Vertex4.Uorder = uorder;
@@ -1046,12 +1032,9 @@ void gl_Map2f( GLcontext* ctx, GLenum target,
         ctx->EvalMap.Map2Vertex4.v1 = v1;
         ctx->EvalMap.Map2Vertex4.v2 = v2;
         ctx->EvalMap.Map2Vertex4.dv = 1.0 / (v2 - v1);
-        if (ctx->EvalMap.Map2Vertex4.Points
-             && !ctx->EvalMap.Map2Vertex4.Retain) {
-           free( ctx->EvalMap.Map2Vertex4.Points );
-        }
-        ctx->EvalMap.Map2Vertex4.Points = (GLfloat *) points;
-        ctx->EvalMap.Map2Vertex4.Retain = retain;
+        if (ctx->EvalMap.Map2Vertex4.Points)
+           FREE( ctx->EvalMap.Map2Vertex4.Points );
+        ctx->EvalMap.Map2Vertex4.Points = pnts;
         break;
       case GL_MAP2_INDEX:
          ctx->EvalMap.Map2Index.Uorder = uorder;
@@ -1062,12 +1045,9 @@ void gl_Map2f( GLcontext* ctx, GLenum target,
         ctx->EvalMap.Map2Index.v1 = v1;
         ctx->EvalMap.Map2Index.v2 = v2;
         ctx->EvalMap.Map2Index.dv = 1.0 / (v2 - v1);
-        if (ctx->EvalMap.Map2Index.Points
-             && !ctx->EvalMap.Map2Index.Retain) {
-           free( ctx->EvalMap.Map2Index.Points );
-        }
-        ctx->EvalMap.Map2Index.Retain = retain;
-        ctx->EvalMap.Map2Index.Points = (GLfloat *) points;
+        if (ctx->EvalMap.Map2Index.Points)
+           FREE( ctx->EvalMap.Map2Index.Points );
+        ctx->EvalMap.Map2Index.Points = pnts;
         break;
       case GL_MAP2_COLOR_4:
          ctx->EvalMap.Map2Color4.Uorder = uorder;
@@ -1078,12 +1058,9 @@ void gl_Map2f( GLcontext* ctx, GLenum target,
         ctx->EvalMap.Map2Color4.v1 = v1;
         ctx->EvalMap.Map2Color4.v2 = v2;
         ctx->EvalMap.Map2Color4.dv = 1.0 / (v2 - v1);
-        if (ctx->EvalMap.Map2Color4.Points
-             && !ctx->EvalMap.Map2Color4.Retain) {
-           free( ctx->EvalMap.Map2Color4.Points );
-        }
-        ctx->EvalMap.Map2Color4.Retain = retain;
-        ctx->EvalMap.Map2Color4.Points = (GLfloat *) points;
+        if (ctx->EvalMap.Map2Color4.Points)
+           FREE( ctx->EvalMap.Map2Color4.Points );
+        ctx->EvalMap.Map2Color4.Points = pnts;
         break;
       case GL_MAP2_NORMAL:
          ctx->EvalMap.Map2Normal.Uorder = uorder;
@@ -1094,12 +1071,9 @@ void gl_Map2f( GLcontext* ctx, GLenum target,
         ctx->EvalMap.Map2Normal.v1 = v1;
         ctx->EvalMap.Map2Normal.v2 = v2;
         ctx->EvalMap.Map2Normal.dv = 1.0 / (v2 - v1);
-        if (ctx->EvalMap.Map2Normal.Points
-             && !ctx->EvalMap.Map2Normal.Retain) {
-           free( ctx->EvalMap.Map2Normal.Points );
-        }
-        ctx->EvalMap.Map2Normal.Retain = retain;
-        ctx->EvalMap.Map2Normal.Points = (GLfloat *) points;
+        if (ctx->EvalMap.Map2Normal.Points)
+           FREE( ctx->EvalMap.Map2Normal.Points );
+        ctx->EvalMap.Map2Normal.Points = pnts;
         break;
       case GL_MAP2_TEXTURE_COORD_1:
          ctx->EvalMap.Map2Texture1.Uorder = uorder;
@@ -1110,12 +1084,9 @@ void gl_Map2f( GLcontext* ctx, GLenum target,
         ctx->EvalMap.Map2Texture1.v1 = v1;
         ctx->EvalMap.Map2Texture1.v2 = v2;
         ctx->EvalMap.Map2Texture1.dv = 1.0 / (v2 - v1);
-        if (ctx->EvalMap.Map2Texture1.Points
-             && !ctx->EvalMap.Map2Texture1.Retain) {
-           free( ctx->EvalMap.Map2Texture1.Points );
-        }
-        ctx->EvalMap.Map2Texture1.Retain = retain;
-        ctx->EvalMap.Map2Texture1.Points = (GLfloat *) points;
+        if (ctx->EvalMap.Map2Texture1.Points)
+           FREE( ctx->EvalMap.Map2Texture1.Points );
+        ctx->EvalMap.Map2Texture1.Points = pnts;
         break;
       case GL_MAP2_TEXTURE_COORD_2:
          ctx->EvalMap.Map2Texture2.Uorder = uorder;
@@ -1126,12 +1097,9 @@ void gl_Map2f( GLcontext* ctx, GLenum target,
         ctx->EvalMap.Map2Texture2.v1 = v1;
         ctx->EvalMap.Map2Texture2.v2 = v2;
         ctx->EvalMap.Map2Texture2.dv = 1.0 / (v2 - v1);
-        if (ctx->EvalMap.Map2Texture2.Points
-             && !ctx->EvalMap.Map2Texture2.Retain) {
-           free( ctx->EvalMap.Map2Texture2.Points );
-        }
-        ctx->EvalMap.Map2Texture2.Retain = retain;
-        ctx->EvalMap.Map2Texture2.Points = (GLfloat *) points;
+        if (ctx->EvalMap.Map2Texture2.Points)
+           FREE( ctx->EvalMap.Map2Texture2.Points );
+        ctx->EvalMap.Map2Texture2.Points = pnts;
         break;
       case GL_MAP2_TEXTURE_COORD_3:
          ctx->EvalMap.Map2Texture3.Uorder = uorder;
@@ -1142,12 +1110,9 @@ void gl_Map2f( GLcontext* ctx, GLenum target,
         ctx->EvalMap.Map2Texture3.v1 = v1;
         ctx->EvalMap.Map2Texture3.v2 = v2;
         ctx->EvalMap.Map2Texture3.dv = 1.0 / (v2 - v1);
-        if (ctx->EvalMap.Map2Texture3.Points
-             && !ctx->EvalMap.Map2Texture3.Retain) {
-           free( ctx->EvalMap.Map2Texture3.Points );
-        }
-        ctx->EvalMap.Map2Texture3.Retain = retain;
-        ctx->EvalMap.Map2Texture3.Points = (GLfloat *) points;
+        if (ctx->EvalMap.Map2Texture3.Points)
+           FREE( ctx->EvalMap.Map2Texture3.Points );
+        ctx->EvalMap.Map2Texture3.Points = pnts;
         break;
       case GL_MAP2_TEXTURE_COORD_4:
          ctx->EvalMap.Map2Texture4.Uorder = uorder;
@@ -1158,12 +1123,9 @@ void gl_Map2f( GLcontext* ctx, GLenum target,
         ctx->EvalMap.Map2Texture4.v1 = v1;
         ctx->EvalMap.Map2Texture4.v2 = v2;
         ctx->EvalMap.Map2Texture4.dv = 1.0 / (v2 - v1);
-        if (ctx->EvalMap.Map2Texture4.Points
-             && !ctx->EvalMap.Map2Texture4.Retain) {
-           free( ctx->EvalMap.Map2Texture4.Points );
-        }
-        ctx->EvalMap.Map2Texture4.Retain = retain;
-        ctx->EvalMap.Map2Texture4.Points = (GLfloat *) points;
+        if (ctx->EvalMap.Map2Texture4.Points)
+           FREE( ctx->EvalMap.Map2Texture4.Points );
+        ctx->EvalMap.Map2Texture4.Points = pnts;
         break;
       default:
          gl_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
@@ -1171,11 +1133,33 @@ void gl_Map2f( GLcontext* ctx, GLenum target,
 }
 
 
-   
+void
+_mesa_Map2f( GLenum target,
+             GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
+             GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
+             const GLfloat *points)
+{
+   map2(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder,
+        points, GL_FLOAT);
+}
 
 
-void gl_GetMapdv( GLcontext* ctx, GLenum target, GLenum query, GLdouble *v )
+void
+_mesa_Map2d( GLenum target,
+             GLdouble u1, GLdouble u2, GLint ustride, GLint uorder,
+             GLdouble v1, GLdouble v2, GLint vstride, GLint vorder,
+             const GLdouble *points )
 {
+   map2(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder,
+        points, GL_DOUBLE);
+}
+
+
+   
+void
+_mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v )
+{
+   GET_CURRENT_CONTEXT(ctx);
    GLint i, n;
    GLfloat *data;
 
@@ -1445,8 +1429,10 @@ void gl_GetMapdv( GLcontext* ctx, GLenum target, GLenum query, GLdouble *v )
 }
 
 
-void gl_GetMapfv( GLcontext* ctx, GLenum target, GLenum query, GLfloat *v )
+void
+_mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v )
 {
+   GET_CURRENT_CONTEXT(ctx);
    GLint i, n;
    GLfloat *data;
 
@@ -1716,8 +1702,10 @@ void gl_GetMapfv( GLcontext* ctx, GLenum target, GLenum query, GLfloat *v )
 }
 
 
-void gl_GetMapiv( GLcontext* ctx, GLenum target, GLenum query, GLint *v )
+void
+_mesa_GetMapiv( GLenum target, GLenum query, GLint *v )
 {
+   GET_CURRENT_CONTEXT(ctx);
    GLuint i, n;
    GLfloat *data;
 
@@ -1988,13 +1976,14 @@ void gl_GetMapiv( GLcontext* ctx, GLenum target, GLenum query, GLint *v )
 
 
 
-void eval_points1( GLfloat outcoord[][4], 
-                  GLfloat coord[][4],
-                  const GLuint *flags,
-                  GLfloat du, GLfloat u1 )
+static void eval_points1( GLfloat outcoord[][4], 
+                         GLfloat coord[][4],
+                         const GLuint *flags,
+                         GLuint start,
+                         GLfloat du, GLfloat u1 )
 {
    GLuint i;
-   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
       if (flags[i] & VERT_EVAL_P1) 
         outcoord[i][0] = coord[i][0] * du + u1;
       else if (flags[i] & VERT_EVAL_ANY) {
@@ -2003,14 +1992,15 @@ void eval_points1( GLfloat outcoord[][4],
       }
 }
 
-void eval_points2( GLfloat outcoord[][4], 
-                  GLfloat coord[][4],
-                  const GLuint *flags,
-                  GLfloat du, GLfloat u1,
-                  GLfloat dv, GLfloat v1 )
+static void eval_points2( GLfloat outcoord[][4], 
+                         GLfloat coord[][4],
+                         const GLuint *flags,
+                         GLuint start,
+                         GLfloat du, GLfloat u1,
+                         GLfloat dv, GLfloat v1 )
 {
    GLuint i;
-   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
       if (flags[i] & VERT_EVAL_P2) {
         outcoord[i][0] = coord[i][0] * du + u1;
         outcoord[i][1] = coord[i][1] * dv + v1;
@@ -2030,18 +2020,19 @@ static const GLubyte dirty_flags[5] = {
 };
 
 
-GLvector4f *eval1_4f( GLvector4f *dest, 
-                     GLfloat coord[][4], 
-                     const GLuint *flags, 
-                     GLuint dimension,
-                     struct gl_1d_map *map )
+static GLvector4f *eval1_4f( GLvector4f *dest, 
+                            GLfloat coord[][4], 
+                            const GLuint *flags,
+                            GLuint start,
+                            GLuint dimension,
+                            struct gl_1d_map *map )
 {
    const GLfloat u1 = map->u1;
    const GLfloat du = map->du;
    GLfloat (*to)[4] = dest->data;
    GLuint i;
    
-   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
       if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
         GLfloat u = (coord[i][0] - u1) * du;
         ASSIGN_4V(to[i], 0,0,0,1);
@@ -2049,23 +2040,25 @@ GLvector4f *eval1_4f( GLvector4f *dest,
       }
 
    dest->count = i;
+   dest->start = VEC_ELT(dest, GLfloat, start);
    dest->size = MAX2(dest->size, dimension);
    dest->flags |= dirty_flags[dimension];
    return dest;
 }
 
 
-GLvector1ui *eval1_1ui( GLvector1ui *dest, 
-                      GLfloat coord[][4], 
-                      const GLuint *flags, 
-                      struct gl_1d_map *map )
+static GLvector1ui *eval1_1ui( GLvector1ui *dest, 
+                              GLfloat coord[][4], 
+                              const GLuint *flags,
+                              GLuint start,
+                              struct gl_1d_map *map )
 {
    const GLfloat u1 = map->u1;
    const GLfloat du = map->du;
    GLuint *to = dest->data;
    GLuint i;
 
-   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
       if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
         GLfloat u = (coord[i][0] - u1) * du;
         GLfloat tmp;
@@ -2073,42 +2066,46 @@ GLvector1ui *eval1_1ui( GLvector1ui *dest,
         to[i] = (GLuint) (GLint) tmp;
       }
 
+   dest->start = VEC_ELT(dest, GLuint, start);
    dest->count = i;
    return dest;
 }
 
-GLvector3f *eval1_norm( GLvector3f *dest, 
-                       GLfloat coord[][4],
-                       GLuint *flags, /* not const */
-                       struct gl_1d_map *map )
+static GLvector3f *eval1_norm( GLvector3f *dest, 
+                              GLfloat coord[][4],
+                              GLuint *flags, /* not const */
+                              GLuint start,
+                              struct gl_1d_map *map )
 {
    const GLfloat u1 = map->u1;
    const GLfloat du = map->du;
    GLfloat (*to)[3] = dest->data;
    GLuint i;
 
-   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
       if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
         GLfloat u = (coord[i][0] - u1) * du;
         horner_bezier_curve(map->Points, to[i], u, 3, map->Order);
         flags[i+1] |= VERT_NORM; /* reset */
       }
 
+   dest->start = VEC_ELT(dest, GLfloat, start);
    dest->count = i;
    return dest;
 }
 
-GLvector4ub *eval1_color( GLvector4ub *dest, 
-                         GLfloat coord[][4],
-                         GLuint *flags, /* not const */
-                         struct gl_1d_map *map )
+static GLvector4ub *eval1_color( GLvector4ub *dest, 
+                                GLfloat coord[][4],
+                                GLuint *flags, /* not const */
+                                GLuint start,
+                                struct gl_1d_map *map )
 {   
    const GLfloat u1 = map->u1;
    const GLfloat du = map->du;
    GLubyte (*to)[4] = dest->data;
    GLuint i;
 
-   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
       if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) {
         GLfloat u = (coord[i][0] - u1) * du;
         GLfloat fcolor[4];
@@ -2117,6 +2114,7 @@ GLvector4ub *eval1_color( GLvector4ub *dest,
         flags[i+1] |= VERT_RGBA; /* reset */
       }
 
+   dest->start = VEC_ELT(dest, GLubyte, start);
    dest->count = i;
    return dest;
 }
@@ -2124,12 +2122,13 @@ GLvector4ub *eval1_color( GLvector4ub *dest,
 
 
 
-GLvector4f *eval2_obj_norm( GLvector4f *obj_ptr, 
-                           GLvector3f *norm_ptr,
-                           GLfloat coord[][4], 
-                           GLuint *flags, 
-                           GLuint dimension,
-                           struct gl_2d_map *map )
+static GLvector4f *eval2_obj_norm( GLvector4f *obj_ptr, 
+                                  GLvector3f *norm_ptr,
+                                  GLfloat coord[][4], 
+                                  GLuint *flags, 
+                                  GLuint start,
+                                  GLuint dimension,
+                                  struct gl_2d_map *map )
 {
    const GLfloat u1 = map->u1;
    const GLfloat du = map->du;
@@ -2139,7 +2138,7 @@ GLvector4f *eval2_obj_norm( GLvector4f *obj_ptr,
    GLfloat (*normal)[3] = norm_ptr->data;
    GLuint i;
    
-   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
       if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
         GLfloat u = (coord[i][0] - u1) * du;
         GLfloat v = (coord[i][1] - v1) * dv;
@@ -2154,6 +2153,7 @@ GLvector4f *eval2_obj_norm( GLvector4f *obj_ptr,
         flags[i+1] |= VERT_NORM;
       }
  
+   obj_ptr->start = VEC_ELT(obj_ptr, GLfloat, start);
    obj_ptr->count = i;
    obj_ptr->size = MAX2(obj_ptr->size, dimension);
    obj_ptr->flags |= dirty_flags[dimension];
@@ -2161,11 +2161,12 @@ GLvector4f *eval2_obj_norm( GLvector4f *obj_ptr,
 }
 
 
-GLvector4f *eval2_4f( GLvector4f *dest, 
-                     GLfloat coord[][4], 
-                     const GLuint *flags, 
-                     GLuint dimension,
-                     struct gl_2d_map *map )
+static GLvector4f *eval2_4f( GLvector4f *dest, 
+                            GLfloat coord[][4], 
+                            const GLuint *flags,
+                            GLuint start,
+                            GLuint dimension,
+                            struct gl_2d_map *map )
 {
    const GLfloat u1 = map->u1;
    const GLfloat du = map->du;
@@ -2174,7 +2175,7 @@ GLvector4f *eval2_4f( GLvector4f *dest,
    GLfloat (*to)[4] = dest->data;
    GLuint i;
 
-   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
       if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
         GLfloat u = (coord[i][0] - u1) * du;
         GLfloat v = (coord[i][1] - v1) * dv;
@@ -2182,6 +2183,7 @@ GLvector4f *eval2_4f( GLvector4f *dest,
                            map->Uorder, map->Vorder);
       }
 
+   dest->start = VEC_ELT(dest, GLfloat, start);
    dest->count = i;
    dest->size = MAX2(dest->size, dimension);
    dest->flags |= dirty_flags[dimension];
@@ -2189,10 +2191,11 @@ GLvector4f *eval2_4f( GLvector4f *dest,
 }
 
 
-GLvector3f *eval2_norm( GLvector3f *dest, 
-                       GLfloat coord[][4], 
-                       GLuint *flags, 
-                       struct gl_2d_map *map )
+static GLvector3f *eval2_norm( GLvector3f *dest, 
+                              GLfloat coord[][4], 
+                              GLuint *flags, 
+                              GLuint start,
+                              struct gl_2d_map *map )
 {
    const GLfloat u1 = map->u1;
    const GLfloat du = map->du;
@@ -2201,7 +2204,7 @@ GLvector3f *eval2_norm( GLvector3f *dest,
    GLfloat (*to)[3] = dest->data;
    GLuint i;
 
-   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
       if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
         GLfloat u = (coord[i][0] - u1) * du;
         GLfloat v = (coord[i][1] - v1) * dv;
@@ -2210,15 +2213,17 @@ GLvector3f *eval2_norm( GLvector3f *dest,
         flags[i+1] |= VERT_NORM; /* reset */
      }
 
+   dest->start = VEC_ELT(dest, GLfloat, start);
    dest->count = i;
    return dest;
 }
 
 
-GLvector1ui *eval2_1ui( GLvector1ui *dest, 
-                      GLfloat coord[][4], 
-                      const GLuint *flags, 
-                      struct gl_2d_map *map )
+static GLvector1ui *eval2_1ui( GLvector1ui *dest, 
+                              GLfloat coord[][4], 
+                              const GLuint *flags,
+                              GLuint start,
+                              struct gl_2d_map *map )
 {
    const GLfloat u1 = map->u1;
    const GLfloat du = map->du;
@@ -2227,7 +2232,7 @@ GLvector1ui *eval2_1ui( GLvector1ui *dest,
    GLuint *to = dest->data;
    GLuint i;
 
-   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
       if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
         GLfloat u = (coord[i][0] - u1) * du;
         GLfloat v = (coord[i][1] - v1) * dv;
@@ -2238,16 +2243,18 @@ GLvector1ui *eval2_1ui( GLvector1ui *dest,
         to[i] = (GLuint) (GLint) tmp;
       }
 
+   dest->start = VEC_ELT(dest, GLuint, start);
    dest->count = i;
    return dest;
 }
 
 
 
-GLvector4ub *eval2_color( GLvector4ub *dest,
-                         GLfloat coord[][4], 
-                         GLuint *flags,
-                         struct gl_2d_map *map )
+static GLvector4ub *eval2_color( GLvector4ub *dest,
+                                GLfloat coord[][4], 
+                                GLuint *flags,
+                                GLuint start,
+                                struct gl_2d_map *map )
 {
    const GLfloat u1 = map->u1;
    const GLfloat du = map->du;
@@ -2256,7 +2263,7 @@ GLvector4ub *eval2_color( GLvector4ub *dest,
    GLubyte (*to)[4] = dest->data;
    GLuint i;
 
-   for (i = VB_START ; !(flags[i] & VERT_END_VB) ; i++)
+   for (i = start ; !(flags[i] & VERT_END_VB) ; i++)
       if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) {
         GLfloat u = (coord[i][0] - u1) * du;
         GLfloat v = (coord[i][1] - v1) * dv;
@@ -2267,64 +2274,75 @@ GLvector4ub *eval2_color( GLvector4ub *dest,
         flags[i+1] |= VERT_RGBA; /* reset */
       }
 
+   dest->start = VEC_ELT(dest, GLubyte, start);
    dest->count = i;
    return dest;
 }
 
 
-GLvector4f *copy_4f( GLvector4f *out, CONST GLvector4f *in, 
-                    const GLuint *flags)
+static GLvector4f *copy_4f( GLvector4f *out, CONST GLvector4f *in, 
+                           const GLuint *flags,
+                           GLuint start )
 {
    GLfloat (*to)[4] = out->data;
    GLfloat (*from)[4] = in->data;
    GLuint i;
    
-   for ( i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 
+   for ( i = start ; !(flags[i] & VERT_END_VB) ; i++) 
       if (!(flags[i] & VERT_EVAL_ANY)) 
         COPY_4FV( to[i], from[i] );
    
+   out->start = VEC_ELT(out, GLfloat, start);
    return out;
 }
 
-GLvector3f *copy_3f( GLvector3f *out, CONST GLvector3f *in, 
-                    const GLuint *flags)
+static GLvector3f *copy_3f( GLvector3f *out, CONST GLvector3f *in, 
+                           const GLuint *flags,
+                           GLuint start )
 {
    GLfloat (*to)[3] = out->data;
    GLfloat (*from)[3] = in->data;
    GLuint i;
    
-   for ( i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 
+   for ( i = start ; !(flags[i] & VERT_END_VB) ; i++) 
       if (!(flags[i] & VERT_EVAL_ANY)) 
         COPY_3V( to[i], from[i] );
    
+   out->start = VEC_ELT(out, GLfloat, start);
    return out;
 }
 
-GLvector4ub *copy_4ub( GLvector4ub *out, CONST GLvector4ub *in, 
-                      const GLuint *flags )
+static GLvector4ub *copy_4ub( GLvector4ub *out, 
+                             CONST GLvector4ub *in, 
+                             const GLuint *flags,
+                             GLuint start )
 {
    GLubyte (*to)[4] = out->data;
    GLubyte (*from)[4] = in->data;
    GLuint i;
    
-   for ( i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 
+   for ( i = start ; !(flags[i] & VERT_END_VB) ; i++) 
       if (!(flags[i] & VERT_EVAL_ANY)) 
         COPY_4UBV( to[i], from[i] );
 
+   out->start = VEC_ELT(out, GLubyte, start);
    return out;
 }
 
-GLvector1ui *copy_1ui( GLvector1ui *out, CONST GLvector1ui *in, 
-                      const GLuint *flags )
+static GLvector1ui *copy_1ui( GLvector1ui *out, 
+                             CONST GLvector1ui *in, 
+                             const GLuint *flags,
+                             GLuint start )
 {
    GLuint *to = out->data;
    CONST GLuint *from = in->data;
    GLuint i;
    
-   for ( i = VB_START ; !(flags[i] & VERT_END_VB) ; i++) 
+   for ( i = start ; !(flags[i] & VERT_END_VB) ; i++) 
       if (!(flags[i] & VERT_EVAL_ANY)) 
         to[i] = from[i];
 
+   out->start = VEC_ELT(out, GLuint, start);
    return out;
 }
 
@@ -2353,7 +2371,7 @@ void gl_eval_vb( struct vertex_buffer *VB )
 
    GLuint any_eval1 = VB->OrFlag & (VERT_EVAL_C1|VERT_EVAL_P1);
    GLuint any_eval2 = VB->OrFlag & (VERT_EVAL_C2|VERT_EVAL_P2);
-   GLuint all_eval = VB->AndFlag & VERT_EVAL_ANY;
+   GLuint all_eval = IM->AndFlag & VERT_EVAL_ANY;
 
    /* Handle the degenerate cases.
     */
@@ -2378,7 +2396,7 @@ void gl_eval_vb( struct vertex_buffer *VB )
     * work on useful changes.
     */
    if (VB->PurgeFlags) {
-      if (!any_eval1 && !any_eval2 && all_eval) VB->Count = VB_START;
+      if (!any_eval1 && !any_eval2 && all_eval) VB->Count = VB->Start;
       gl_purge_vertices( VB );
       if (!any_eval1 && !any_eval2) return;
    } else
@@ -2388,7 +2406,7 @@ void gl_eval_vb( struct vertex_buffer *VB )
     */
    if (any_eval1 && (VB->OrFlag & VERT_EVAL_P1)) 
    {
-      eval_points1( IM->Obj, coord, flags, 
+      eval_points1( IM->Obj, coord, flags, IM->Start,
                    ctx->Eval.MapGrid1du,
                    ctx->Eval.MapGrid1u1);
 
@@ -2397,7 +2415,7 @@ void gl_eval_vb( struct vertex_buffer *VB )
 
    if (any_eval2 && (VB->OrFlag & VERT_EVAL_P2)) 
    {
-      eval_points2( IM->Obj, coord, flags, 
+      eval_points2( IM->Obj, coord, flags, IM->Start,
                    ctx->Eval.MapGrid2du,
                    ctx->Eval.MapGrid2u1,
                    ctx->Eval.MapGrid2dv,
@@ -2414,17 +2432,17 @@ void gl_eval_vb( struct vertex_buffer *VB )
       GLvector1ui  *out_index = &IM->v.Index;
 
       if (ctx->Eval.Map1Index && any_eval1) 
-        VB->IndexPtr = eval1_1ui( out_index, coord, flags, 
+        VB->IndexPtr = eval1_1ui( out_index, coord, flags, IM->Start,
                                   &ctx->EvalMap.Map1Index );
       
       if (ctx->Eval.Map2Index && any_eval2)
-        VB->IndexPtr = eval2_1ui( out_index, coord, flags, 
+        VB->IndexPtr = eval2_1ui( out_index, coord, flags, IM->Start,
                                   &ctx->EvalMap.Map2Index );
         
       if (VB->IndexPtr != in_index) {
         new_flags |= VERT_INDEX;
         if (!all_eval)
-           VB->IndexPtr = copy_1ui( out_index, in_index, flags );
+           VB->IndexPtr = copy_1ui( out_index, in_index, flags, IM->Start );
       }
    }
 
@@ -2434,17 +2452,17 @@ void gl_eval_vb( struct vertex_buffer *VB )
       GLvector4ub  *out_color = &IM->v.Color;
 
       if (ctx->Eval.Map1Color4 && any_eval1) 
-        VB->ColorPtr = eval1_color( out_color, coord, flags, 
+        VB->ColorPtr = eval1_color( out_color, coord, flags, IM->Start,
                                   &ctx->EvalMap.Map1Color4 );
       
       if (ctx->Eval.Map2Color4 && any_eval2)
-        VB->ColorPtr = eval2_color( out_color, coord, flags, 
+        VB->ColorPtr = eval2_color( out_color, coord, flags, IM->Start,
                                     &ctx->EvalMap.Map2Color4 );
         
       if (VB->ColorPtr != in_color) {
         new_flags |= VERT_RGBA;
         if (!all_eval)
-           VB->ColorPtr = copy_4ub( out_color, in_color, flags );
+           VB->ColorPtr = copy_4ub( out_color, in_color, flags, IM->Start );
       }
 
       VB->Color[0] = VB->Color[1] = VB->ColorPtr;
@@ -2457,17 +2475,17 @@ void gl_eval_vb( struct vertex_buffer *VB )
       GLvector3f  *out_normal = &IM->v.Normal;
 
       if (ctx->Eval.Map1Normal && any_eval1) 
-        VB->NormalPtr = eval1_norm( out_normal, coord, flags, 
+        VB->NormalPtr = eval1_norm( out_normal, coord, flags, IM->Start,
                                     &ctx->EvalMap.Map1Normal );
       
       if (ctx->Eval.Map2Normal && any_eval2)
-        VB->NormalPtr = eval2_norm( out_normal, coord, flags, 
+        VB->NormalPtr = eval2_norm( out_normal, coord, flags, IM->Start,
                                     &ctx->EvalMap.Map2Normal );
         
       if (VB->NormalPtr != in_normal) {
         new_flags |= VERT_NORM;
         if (!all_eval)
-           VB->NormalPtr = copy_3f( out_normal, in_normal, flags );
+           VB->NormalPtr = copy_3f( out_normal, in_normal, flags, IM->Start );
       }
    }
 
@@ -2480,30 +2498,38 @@ void gl_eval_vb( struct vertex_buffer *VB )
 
       if (any_eval1) {
         if (ctx->Eval.Map1TextureCoord4) 
-           tc = eval1_4f( out, coord, flags, 4, &ctx->EvalMap.Map1Texture4);
+           tc = eval1_4f( out, coord, flags, IM->Start, 
+                          4, &ctx->EvalMap.Map1Texture4);
         else if (ctx->Eval.Map1TextureCoord3) 
-           tc = eval1_4f( out, coord, flags, 3, &ctx->EvalMap.Map1Texture3);
+           tc = eval1_4f( out, coord, flags, IM->Start, 3,
+                          &ctx->EvalMap.Map1Texture3);
         else if (ctx->Eval.Map1TextureCoord2) 
-           tc = eval1_4f( out, coord, flags, 2, &ctx->EvalMap.Map1Texture2);
+           tc = eval1_4f( out, coord, flags, IM->Start, 2,
+                          &ctx->EvalMap.Map1Texture2);
         else if (ctx->Eval.Map1TextureCoord1) 
-           tc = eval1_4f( out, coord, flags, 1, &ctx->EvalMap.Map1Texture1);
+           tc = eval1_4f( out, coord, flags, IM->Start, 1,
+                          &ctx->EvalMap.Map1Texture1);
       }
 
       if (any_eval2) {
         if (ctx->Eval.Map2TextureCoord4) 
-           tc = eval2_4f( out, coord, flags, 4, &ctx->EvalMap.Map2Texture4);
+           tc = eval2_4f( out, coord, flags, IM->Start,
+                          4, &ctx->EvalMap.Map2Texture4);
         else if (ctx->Eval.Map2TextureCoord3) 
-           tc = eval2_4f( out, coord, flags, 3, &ctx->EvalMap.Map2Texture3);
+           tc = eval2_4f( out, coord, flags, IM->Start,
+                          3, &ctx->EvalMap.Map2Texture3);
         else if (ctx->Eval.Map2TextureCoord2) 
-           tc = eval2_4f( out, coord, flags, 2, &ctx->EvalMap.Map2Texture2);
+           tc = eval2_4f( out, coord, flags, IM->Start,
+                          2, &ctx->EvalMap.Map2Texture2);
         else if (ctx->Eval.Map2TextureCoord1) 
-           tc = eval2_4f( out, coord, flags, 1, &ctx->EvalMap.Map2Texture1);
+           tc = eval2_4f( out, coord, flags, IM->Start,
+                          1, &ctx->EvalMap.Map2Texture1);
       }
 
       if (tc != in) {
         new_flags |= VERT_TEX_ANY(0); /* fix for sizes.. */
         if (!all_eval)
-           tc = copy_4f( out, in, flags );
+           tc = copy_4f( out, in, flags, IM->Start );
       }
 
       VB->TexCoordPtr[0] = tc;
@@ -2517,34 +2543,36 @@ void gl_eval_vb( struct vertex_buffer *VB )
    
       if (any_eval1) {
         if (ctx->Eval.Map1Vertex4) 
-           obj = eval1_4f( out, coord, flags, 4, &ctx->EvalMap.Map1Vertex4);
+           obj = eval1_4f( out, coord, flags, IM->Start,
+                           4, &ctx->EvalMap.Map1Vertex4);
         else 
-           obj = eval1_4f( out, coord, flags, 3, &ctx->EvalMap.Map1Vertex3);
+           obj = eval1_4f( out, coord, flags, IM->Start,
+                           3, &ctx->EvalMap.Map1Vertex3);
       }
 
       if (any_eval2) {
         if (ctx->Eval.Map2Vertex4) 
         {
            if (ctx->Eval.AutoNormal && (req & VERT_NORM)) 
-              obj = eval2_obj_norm( out, VB->NormalPtr, coord, flags, 4,
-                                   &ctx->EvalMap.Map2Vertex4 );
+              obj = eval2_obj_norm( out, VB->NormalPtr, coord, flags, IM->Start,
+                                    4, &ctx->EvalMap.Map2Vertex4 );
            else
-              obj = eval2_4f( out, coord, flags, 4, 
-                              &ctx->EvalMap.Map2Vertex4);
+              obj = eval2_4f( out, coord, flags, IM->Start,
+                              4, &ctx->EvalMap.Map2Vertex4);
         }
         else if (ctx->Eval.Map2Vertex3) 
         {
            if (ctx->Eval.AutoNormal && (req & VERT_NORM)) 
-              obj = eval2_obj_norm( out, VB->NormalPtr, coord, flags, 3,
-                                   &ctx->EvalMap.Map2Vertex3 );
+              obj = eval2_obj_norm( out, VB->NormalPtr, coord, flags, IM->Start,
+                                    3, &ctx->EvalMap.Map2Vertex3 );
            else
-              obj = eval2_4f( out, coord, flags, 3, 
-                              &ctx->EvalMap.Map2Vertex3 );
+              obj = eval2_4f( out, coord, flags, IM->Start,
+                              3, &ctx->EvalMap.Map2Vertex3 );
         }
       }
 
       if (obj != in && !all_eval)
-        obj = copy_4f( out, in, flags );
+        obj = copy_4f( out, in, flags, IM->Start );
 
       VB->ObjPtr = obj;
    }
@@ -2556,14 +2584,13 @@ void gl_eval_vb( struct vertex_buffer *VB )
       GLuint count = VB->Count;
 
       if (!flags) {
-        VB->EvaluatedFlags = (GLuint *)malloc(VB->Size * sizeof(GLuint));
+        VB->EvaluatedFlags = (GLuint *) MALLOC(VB->Size * sizeof(GLuint));
         flags = VB->Flag = VB->EvaluatedFlags;
       }
 
       if (all_eval) {
         for (i = 0 ; i < count ; i++) 
            flags[i] = oldflags[i] | new_flags;
-        VB->AndFlag |= new_flags; 
       } else {
         GLuint andflag = ~0;
         for (i = 0 ; i < count ; i++) {
@@ -2571,14 +2598,15 @@ void gl_eval_vb( struct vertex_buffer *VB )
               flags[i] = oldflags[i] | new_flags;
            andflag &= flags[i];
         }
-        VB->AndFlag = andflag;
       }
    }
 }
 
 
-void gl_MapGrid1f( GLcontext* ctx, GLint un, GLfloat u1, GLfloat u2 )
+void
+_mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 )
 {
+   GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMapGrid1f");
 
    if (un<1) {
@@ -2592,9 +2620,18 @@ void gl_MapGrid1f( GLcontext* ctx, GLint un, GLfloat u1, GLfloat u2 )
 }
 
 
-void gl_MapGrid2f( GLcontext* ctx, GLint un, GLfloat u1, GLfloat u2,
-                 GLint vn, GLfloat v1, GLfloat v2 )
+void
+_mesa_MapGrid1d( GLint un, GLdouble u1, GLdouble u2 )
 {
+   _mesa_MapGrid1f( un, u1, u2 );
+}
+
+
+void
+_mesa_MapGrid2f( GLint un, GLfloat u1, GLfloat u2,
+                 GLint vn, GLfloat v1, GLfloat v2 )
+{
+   GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMapGrid2f");
    if (un<1) {
       gl_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(un)" );
@@ -2615,9 +2652,187 @@ void gl_MapGrid2f( GLcontext* ctx, GLint un, GLfloat u1, GLfloat u2,
 }
 
 
+void
+_mesa_MapGrid2d( GLint un, GLdouble u1, GLdouble u2,
+                 GLint vn, GLdouble v1, GLdouble v2 )
+{
+   _mesa_MapGrid2f( un, u1, u2, vn, v1, v2 );
+}
+
+
+
+
+/* KW: If are compiling, we don't know whether eval will produce a
+ *     vertex when it is run in the future.  If this is pure immediate
+ *     mode, eval is a noop if neither vertex map is enabled.
+ *
+ *     Thus we need to have a check in the display list code or
+ *     elsewhere for eval(1,2) vertices in the case where
+ *     map(1,2)_vertex is disabled, and to purge those vertices from
+ *     the vb.  This is currently done
+ *     via  modifications to the cull_vb and render_vb operations, and
+ *     by using the existing cullmask mechanism for all other operations.  
+ */
+
+
+/* KW: Because the eval values don't become 'current', fixup will flow
+ *     through these vertices, and then evaluation will write on top
+ *     of the fixup results.  
+ *
+ *     This is a little inefficient, but at least it is correct.  This
+ *     could be short-circuited in the case where all vertices are
+ *     eval-vertices, or more generally by a cullmask in fixup.
+ *
+ *     Note: using Obj to hold eval coord data.  This data is actually
+ *     transformed if eval is disabled.  But disabling eval & sending
+ *     eval coords is stupid, right?
+ */
+
+
+#define EVALCOORD1(IM, x)                              \
+{                                                      \
+   GLuint count = IM->Count++;                         \
+   IM->Flag[count] |= VERT_EVAL_C1;                    \
+   ASSIGN_4V(IM->Obj[count], x, 0, 0, 1);              \
+   if (count == VB_MAX-1)                              \
+      IM->maybe_transform_vb( IM );                    \
+}
+
+#define EVALCOORD2(IM, x, y)                           \
+{                                                      \
+   GLuint count = IM->Count++;                         \
+   IM->Flag[count] |= VERT_EVAL_C2;                    \
+   ASSIGN_4V(IM->Obj[count], x, y, 0, 1);              \
+   if (count == VB_MAX-1)                              \
+      IM->maybe_transform_vb( IM );                    \
+}
+
+#define EVALPOINT1(IM, x)                              \
+{                                                      \
+   GLuint count = IM->Count++;                         \
+   IM->Flag[count] |= VERT_EVAL_P1;                    \
+   ASSIGN_4V(IM->Obj[count], x, 0, 0, 1);              \
+   if (count == VB_MAX-1)                              \
+      IM->maybe_transform_vb( IM );                    \
+}
+#define EVALPOINT2(IM, x, y)                           \
+{                                                      \
+   GLuint count = IM->Count++;                         \
+   IM->Flag[count] |= VERT_EVAL_P2;                    \
+   ASSIGN_4V(IM->Obj[count], x, y, 0, 1);              \
+   if (count == VB_MAX-1)                              \
+      IM->maybe_transform_vb( IM );                    \
+}
+
+
+/* Lame internal function:
+ */
+static void
+eval_coord1f( GLcontext *CC, GLfloat u )
+{
+   struct immediate *i = CC->input;
+   EVALCOORD1( i, u );
+}
+
 
-void gl_EvalMesh1( GLcontext* ctx, GLenum mode, GLint i1, GLint i2 )
+void
+_mesa_EvalCoord1d( GLdouble u )
 {
+   GET_IMMEDIATE;
+   EVALCOORD1( IM, (GLfloat) u );
+}
+
+
+void
+_mesa_EvalCoord1f( GLfloat u )
+{
+   GET_IMMEDIATE;
+   EVALCOORD1( IM, u );
+}
+
+
+void
+_mesa_EvalCoord1dv( const GLdouble *u )
+{
+   GET_IMMEDIATE;
+   EVALCOORD1( IM, (GLfloat) *u );
+}
+
+
+void
+_mesa_EvalCoord1fv( const GLfloat *u )
+{
+   GET_IMMEDIATE;
+   EVALCOORD1( IM, (GLfloat) *u );
+}
+
+
+void
+_mesa_EvalCoord2d( GLdouble u, GLdouble v )
+{
+   GET_IMMEDIATE;
+   EVALCOORD2( IM, (GLfloat) u, (GLfloat) v );
+}
+
+
+void
+_mesa_EvalCoord2f( GLfloat u, GLfloat v )
+{
+   GET_IMMEDIATE;
+   EVALCOORD2( IM, u, v );
+}
+
+
+/* Lame internal function:
+ */
+static void
+eval_coord2f( GLcontext *CC, GLfloat u, GLfloat v )
+{
+   struct immediate *i = CC->input;
+   EVALCOORD2( i, u, v );
+}
+
+
+void
+_mesa_EvalCoord2dv( const GLdouble *u )
+{
+   GET_IMMEDIATE;
+   EVALCOORD2( IM, (GLfloat) u[0], (GLfloat) u[1] );
+}
+
+
+void
+_mesa_EvalCoord2fv( const GLfloat *u )
+{
+   GET_IMMEDIATE;
+   EVALCOORD2( IM, u[0], u[1] );
+}
+
+
+void
+_mesa_EvalPoint1( GLint i )
+{
+   GET_IMMEDIATE;
+   EVALPOINT1( IM, i );
+}
+
+
+void
+_mesa_EvalPoint2( GLint i, GLint j )
+{
+   GET_IMMEDIATE;
+   EVALPOINT2( IM, i, j );
+}
+
+
+
+
+
+void
+_mesa_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
+{
+   GET_CURRENT_CONTEXT(ctx);
    GLint i;
    GLfloat u, du;
    GLenum prim;
@@ -2650,18 +2865,17 @@ void gl_EvalMesh1( GLcontext* ctx, GLenum mode, GLint i1, GLint i2 )
 
    gl_Begin( ctx, prim );
    for (i=i1;i<=i2;i++,u+=du) {
-      gl_EvalCoord1f( ctx, u );
+      eval_coord1f( ctx, u );
    }
    gl_End(ctx);
 }
 
 
 
-void gl_EvalMesh2( GLcontext* ctx, 
-                  GLenum mode, 
-                  GLint i1, GLint i2, 
-                  GLint j1, GLint j2 )
+void
+_mesa_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 )
 {
+   GET_CURRENT_CONTEXT(ctx);
    GLint i, j;
    GLfloat u, du, v, dv, v1, u1;
 
@@ -2684,7 +2898,7 @@ void gl_EvalMesh2( GLcontext* ctx,
       gl_Begin( ctx, GL_POINTS );
       for (v=v1,j=j1;j<=j2;j++,v+=dv) {
         for (u=u1,i=i1;i<=i2;i++,u+=du) {
-           gl_EvalCoord2f( ctx, u, v );
+           eval_coord2f( ctx, u, v );
         }
       }
       gl_End(ctx);
@@ -2693,14 +2907,14 @@ void gl_EvalMesh2( GLcontext* ctx,
       for (v=v1,j=j1;j<=j2;j++,v+=dv) {
         gl_Begin( ctx, GL_LINE_STRIP );
         for (u=u1,i=i1;i<=i2;i++,u+=du) {
-           gl_EvalCoord2f( ctx, u, v );
+           eval_coord2f( ctx, u, v );
         }
         gl_End(ctx);
       }
       for (u=u1,i=i1;i<=i2;i++,u+=du) {
         gl_Begin( ctx, GL_LINE_STRIP );
         for (v=v1,j=j1;j<=j2;j++,v+=dv) {
-           gl_EvalCoord2f( ctx, u, v );
+           eval_coord2f( ctx, u, v );
         }
         gl_End(ctx);
       }
@@ -2711,8 +2925,8 @@ void gl_EvalMesh2( GLcontext* ctx,
         /* can't be guaranteed to be coplanar! */
         gl_Begin( ctx, GL_TRIANGLE_STRIP );
         for (u=u1,i=i1;i<=i2;i++,u+=du) {
-           gl_EvalCoord2f( ctx, u, v );
-           gl_EvalCoord2f( ctx, u, v+dv );
+           eval_coord2f( ctx, u, v );
+           eval_coord2f( ctx, u, v+dv );
         }
         gl_End(ctx);
       }
@@ -2723,3 +2937,5 @@ void gl_EvalMesh2( GLcontext* ctx,
    }
 }
 
+
+