glsl: Add IsCentroid bitfield to gl_fragment_program.
[mesa.git] / src / mesa / main / dlist.c
index 4e463dd06a119f4b64010f27997a2854a4228cd7..a0d84cfdc55857c9073ce456ac32fb57911838bd 100644 (file)
 #include "api_arrayelt.h"
 #include "api_exec.h"
 #include "api_loopback.h"
+#include "api_validate.h"
 #if FEATURE_ATI_fragment_shader
 #include "atifragshader.h"
 #endif
 #include "config.h"
 #include "mfeatures.h"
-#if FEATURE_ARB_vertex_buffer_object
 #include "bufferobj.h"
-#endif
 #include "arrayobj.h"
 #include "context.h"
 #include "dlist.h"
 #include "enums.h"
 #include "eval.h"
+#if FEATURE_EXT_framebuffer_object
+#include "fbobject.h"
+#endif
 #include "framebuffer.h"
 #include "glapi/glapi.h"
 #include "hash.h"
 #include "pack.h"
 #include "pbo.h"
 #include "queryobj.h"
+#include "samplerobj.h"
+#include "shaderapi.h"
+#include "syncobj.h"
 #include "teximage.h"
+#include "texstorage.h"
 #include "mtypes.h"
 #include "varray.h"
 #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
@@ -65,6 +71,9 @@
 #if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
 #include "nvprogram.h"
 #endif
+#if FEATURE_EXT_transform_feedback
+#include "transformfeedback.h"
+#endif
 
 #include "math/m_matrix.h"
 
@@ -125,7 +134,7 @@ do {                                                \
 do {                                                                   \
    if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON ||               \
        ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \
-      _mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" );   \
+      _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glBegin/End" ); \
       return retval;                                                   \
    }                                                                   \
 } while (0)
@@ -140,7 +149,7 @@ do {                                                                        \
 do {                                                                   \
    if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON ||               \
        ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \
-      _mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" );   \
+      _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glBegin/End" ); \
       return;                                                          \
    }                                                                   \
 } while (0)
@@ -388,6 +397,9 @@ typedef enum
    OPCODE_UNIFORM_3UIV,
    OPCODE_UNIFORM_4UIV,
 
+   /* GL_ARB_color_buffer_float */
+   OPCODE_CLAMP_COLOR,
+
    /* GL_EXT_framebuffer_blit */
    OPCODE_BLIT_FRAMEBUFFER,
 
@@ -417,6 +429,10 @@ typedef enum
    /* GL_EXT_transform_feedback */
    OPCODE_BEGIN_TRANSFORM_FEEDBACK,
    OPCODE_END_TRANSFORM_FEEDBACK,
+   OPCODE_BIND_TRANSFORM_FEEDBACK,
+   OPCODE_PAUSE_TRANSFORM_FEEDBACK,
+   OPCODE_RESUME_TRANSFORM_FEEDBACK,
+   OPCODE_DRAW_TRANSFORM_FEEDBACK,
 
    /* GL_EXT_texture_integer */
    OPCODE_CLEARCOLOR_I,
@@ -431,6 +447,28 @@ typedef enum
    /* GL_ARB_instanced_arrays */
    OPCODE_VERTEX_ATTRIB_DIVISOR,
 
+   /* GL_NV_texture_barrier */
+   OPCODE_TEXTURE_BARRIER_NV,
+
+   /* GL_ARB_sampler_object */
+   OPCODE_BIND_SAMPLER,
+   OPCODE_SAMPLER_PARAMETERIV,
+   OPCODE_SAMPLER_PARAMETERFV,
+   OPCODE_SAMPLER_PARAMETERIIV,
+   OPCODE_SAMPLER_PARAMETERUIV,
+
+   /* GL_ARB_geometry_shader4 */
+   OPCODE_PROGRAM_PARAMETERI,
+   OPCODE_FRAMEBUFFER_TEXTURE,
+   OPCODE_FRAMEBUFFER_TEXTURE_FACE,
+
+   /* GL_ARB_sync */
+   OPCODE_WAIT_SYNC,
+
+   /* GL_NV_conditional_render */
+   OPCODE_BEGIN_CONDITIONAL_RENDER,
+   OPCODE_END_CONDITIONAL_RENDER,
+
    /* The following three are meta instructions */
    OPCODE_ERROR,                /* raise compiled-in error */
    OPCODE_CONTINUE,
@@ -471,6 +509,17 @@ union gl_dlist_node
 typedef union gl_dlist_node Node;
 
 
+/**
+ * Used to store a 64-bit uint in a pair of "Nodes" for the sake of 32-bit
+ * environment.  In 64-bit env, sizeof(Node)==8 anyway.
+ */
+union uint64_pair
+{
+   GLuint64 uint64;
+   GLuint uint32[2];
+};
+
+
 /**
  * How many nodes to allocate at a time.
  *
@@ -516,7 +565,7 @@ make_list(GLuint name, GLuint count)
 /**
  * Lookup function to just encapsulate casting.
  */
-static INLINE struct gl_display_list *
+static inline struct gl_display_list *
 lookup_list(struct gl_context *ctx, GLuint list)
 {
    return (struct gl_display_list *)
@@ -525,7 +574,7 @@ lookup_list(struct gl_context *ctx, GLuint list)
 
 
 /** Is the given opcode an extension code? */
-static INLINE GLboolean
+static inline GLboolean
 is_ext_opcode(OpCode opcode)
 {
    return (opcode >= OPCODE_EXT_0);
@@ -831,8 +880,12 @@ translate_id(GLsizei n, GLenum type, const GLvoid * list)
 /**********************************************************************/
 
 /**
- * Wrapper for _mesa_unpack_image() that handles pixel buffer objects.
- * If we run out of memory, GL_OUT_OF_MEMORY will be recorded.
+ * Wrapper for _mesa_unpack_image/bitmap() that handles pixel buffer objects.
+ * If width < 0 or height < 0 or format or type are invalid we'll just
+ * return NULL.  We will not generate an error since OpenGL command
+ * arguments aren't error-checked until the command is actually executed
+ * (not when they're compiled).
+ * But if we run out of memory, GL_OUT_OF_MEMORY will be recorded.
  */
 static GLvoid *
 unpack_image(struct gl_context *ctx, GLuint dimensions,
@@ -840,23 +893,37 @@ unpack_image(struct gl_context *ctx, GLuint dimensions,
              GLenum format, GLenum type, const GLvoid * pixels,
              const struct gl_pixelstore_attrib *unpack)
 {
+   if (width <= 0 || height <= 0) {
+      return NULL;
+   }
+
+   if (_mesa_bytes_per_pixel(format, type) < 0) {
+      /* bad format and/or type */
+      return NULL;
+   }
+
    if (!_mesa_is_bufferobj(unpack->BufferObj)) {
       /* no PBO */
-      GLvoid *image = _mesa_unpack_image(dimensions, width, height, depth,
-                                         format, type, pixels, unpack);
+      GLvoid *image;
+
+      if (type == GL_BITMAP)
+         image = _mesa_unpack_bitmap(width, height, pixels, unpack);
+      else
+         image = _mesa_unpack_image(dimensions, width, height, depth,
+                                    format, type, pixels, unpack);
       if (pixels && !image) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
       }
       return image;
    }
-   else if (_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
-                                      format, type, pixels)) {
+   else if (_mesa_validate_pbo_access(dimensions, unpack, width, height,
+                                      depth, format, type, INT_MAX, pixels)) {
       const GLubyte *map, *src;
       GLvoid *image;
 
       map = (GLubyte *)
-         ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
-                               GL_READ_ONLY_ARB, unpack->BufferObj);
+         ctx->Driver.MapBufferRange(ctx, 0, unpack->BufferObj->Size,
+                                   GL_MAP_READ_BIT, unpack->BufferObj);
       if (!map) {
          /* unable to map src buffer! */
          _mesa_error(ctx, GL_INVALID_OPERATION, "unable to map PBO");
@@ -864,22 +931,25 @@ unpack_image(struct gl_context *ctx, GLuint dimensions,
       }
 
       src = ADD_POINTERS(map, pixels);
-      image = _mesa_unpack_image(dimensions, width, height, depth,
-                                 format, type, src, unpack);
+      if (type == GL_BITMAP)
+         image = _mesa_unpack_bitmap(width, height, src, unpack);
+      else
+         image = _mesa_unpack_image(dimensions, width, height, depth,
+                                    format, type, src, unpack);
 
-      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
-                              unpack->BufferObj);
+      ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj);
 
       if (!image) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
       }
       return image;
    }
+
    /* bad access! */
+   _mesa_error(ctx, GL_INVALID_OPERATION, "invalid PBO access");
    return NULL;
 }
 
-
 /**
  * Allocate space for a display list instruction (opcode + payload space).
  * \param opcode  the instruction opcode (OPCODE_* value)
@@ -987,7 +1057,7 @@ _mesa_dlist_alloc_opcode(struct gl_context *ctx,
  * \param nparams  number of function parameters
  * \return  pointer to start of instruction space
  */
-static INLINE Node *
+static inline Node *
 alloc_instruction(struct gl_context *ctx, OpCode opcode, GLuint nparams)
 {
    return dlist_alloc(ctx, opcode, nparams * sizeof(Node));
@@ -1065,7 +1135,8 @@ save_Bitmap(GLsizei width, GLsizei height,
       n[4].f = yorig;
       n[5].f = xmove;
       n[6].f = ymove;
-      n[7].data = _mesa_unpack_bitmap(width, height, pixels, &ctx->Unpack);
+      n[7].data = unpack_image(ctx, 2, width, height, 1, GL_COLOR_INDEX,
+                               GL_BITMAP, pixels, &ctx->Unpack);
    }
    if (ctx->ExecuteFlag) {
       CALL_Bitmap(ctx->Exec, (width, height,
@@ -1229,6 +1300,83 @@ save_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA)
 }
 
 
+/* GL_ARB_draw_instanced. */
+static void GLAPIENTRY
+save_DrawArraysInstancedARB(GLenum mode,
+                           GLint first,
+                           GLsizei count,
+                           GLsizei primcount)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+              "glDrawArraysInstanced() during display list compile");
+}
+
+static void GLAPIENTRY
+save_DrawElementsInstancedARB(GLenum mode,
+                             GLsizei count,
+                             GLenum type,
+                             const GLvoid *indices,
+                             GLsizei primcount)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+              "glDrawElementsInstanced() during display list compile");
+}
+
+static void GLAPIENTRY
+save_DrawElementsInstancedBaseVertexARB(GLenum mode,
+                                       GLsizei count,
+                                       GLenum type,
+                                       const GLvoid *indices,
+                                       GLsizei primcount,
+                                       GLint basevertex)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+              "glDrawElementsInstancedBaseVertex() during display list compile");
+}
+
+/* GL_ARB_base_instance. */
+static void GLAPIENTRY
+save_DrawArraysInstancedBaseInstance(GLenum mode,
+                                     GLint first,
+                                     GLsizei count,
+                                     GLsizei primcount,
+                                     GLuint baseinstance)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+              "glDrawArraysInstancedBaseInstance() during display list compile");
+}
+
+static void APIENTRY
+save_DrawElementsInstancedBaseInstance(GLenum mode,
+                                       GLsizei count,
+                                       GLenum type,
+                                       const void *indices,
+                                       GLsizei primcount,
+                                       GLuint baseinstance)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+              "glDrawElementsInstancedBaseInstance() during display list compile");
+}
+
+static void APIENTRY
+save_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode,
+                                                 GLsizei count,
+                                                 GLenum type,
+                                                 const void *indices,
+                                                 GLsizei primcount,
+                                                 GLint basevertex,
+                                                 GLuint baseinstance)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+              "glDrawElementsInstancedBaseVertexBaseInstance() during display list compile");
+}
+
 static void invalidate_saved_current_state( struct gl_context *ctx )
 {
    GLint i;
@@ -1352,7 +1500,7 @@ save_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
       }
    }
    if (ctx->ExecuteFlag) {
-      /*CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value));*/
+      CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value));
    }
 }
 
@@ -1380,7 +1528,7 @@ save_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
       }
    }
    if (ctx->ExecuteFlag) {
-      /*CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));*/
+      CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));
    }
 }
 
@@ -1408,7 +1556,7 @@ save_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
       }
    }
    if (ctx->ExecuteFlag) {
-      /*CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));*/
+      CALL_ClearBufferfv(ctx->Exec, (buffer, drawbuffer, value));
    }
 }
 
@@ -1428,7 +1576,7 @@ save_ClearBufferfi(GLenum buffer, GLint drawbuffer,
       n[4].i = stencil;
    }
    if (ctx->ExecuteFlag) {
-      /*CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil));*/
+      CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil));
    }
 }
 
@@ -4453,6 +4601,24 @@ save_MultTransposeMatrixfARB(const GLfloat m[16])
    save_MultMatrixf(tm);
 }
 
+static GLvoid *copy_data(const GLvoid *data, GLsizei size, const char *func)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLvoid *image;
+
+   if (!data)
+      return NULL;
+
+   image = malloc(size);
+   if (!image) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
+      return NULL;
+   }
+   memcpy(image, data, size);
+
+   return image;
+}
+
 
 /* GL_ARB_texture_compression */
 static void GLAPIENTRY
@@ -4470,15 +4636,8 @@ save_CompressedTexImage1DARB(GLenum target, GLint level,
    }
    else {
       Node *n;
-      GLvoid *image;
       ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-      /* make copy of image */
-      image = malloc(imageSize);
-      if (!image) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1DARB");
-         return;
-      }
-      memcpy(image, data, imageSize);
+
       n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D, 7);
       if (n) {
          n[1].e = target;
@@ -4487,10 +4646,7 @@ save_CompressedTexImage1DARB(GLenum target, GLint level,
          n[4].i = (GLint) width;
          n[5].i = border;
          n[6].i = imageSize;
-         n[7].data = image;
-      }
-      else if (image) {
-         free(image);
+         n[7].data = copy_data(data, imageSize, "glCompressedTexImage1DARB");
       }
       if (ctx->ExecuteFlag) {
          CALL_CompressedTexImage1DARB(ctx->Exec,
@@ -4516,15 +4672,8 @@ save_CompressedTexImage2DARB(GLenum target, GLint level,
    }
    else {
       Node *n;
-      GLvoid *image;
       ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-      /* make copy of image */
-      image = malloc(imageSize);
-      if (!image) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
-         return;
-      }
-      memcpy(image, data, imageSize);
+
       n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D, 8);
       if (n) {
          n[1].e = target;
@@ -4534,10 +4683,7 @@ save_CompressedTexImage2DARB(GLenum target, GLint level,
          n[5].i = (GLint) height;
          n[6].i = border;
          n[7].i = imageSize;
-         n[8].data = image;
-      }
-      else if (image) {
-         free(image);
+         n[8].data = copy_data(data, imageSize, "glCompressedTexImage2DARB");
       }
       if (ctx->ExecuteFlag) {
          CALL_CompressedTexImage2DARB(ctx->Exec,
@@ -4563,15 +4709,8 @@ save_CompressedTexImage3DARB(GLenum target, GLint level,
    }
    else {
       Node *n;
-      GLvoid *image;
       ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-      /* make copy of image */
-      image = malloc(imageSize);
-      if (!image) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3DARB");
-         return;
-      }
-      memcpy(image, data, imageSize);
+
       n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D, 9);
       if (n) {
          n[1].e = target;
@@ -4582,10 +4721,7 @@ save_CompressedTexImage3DARB(GLenum target, GLint level,
          n[6].i = (GLint) depth;
          n[7].i = border;
          n[8].i = imageSize;
-         n[9].data = image;
-      }
-      else if (image) {
-         free(image);
+         n[9].data = copy_data(data, imageSize, "glCompressedTexImage3DARB");
       }
       if (ctx->ExecuteFlag) {
          CALL_CompressedTexImage3DARB(ctx->Exec,
@@ -4603,18 +4739,9 @@ save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
                                 GLsizei imageSize, const GLvoid * data)
 {
    Node *n;
-   GLvoid *image;
-
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
 
-   /* make copy of image */
-   image = malloc(imageSize);
-   if (!image) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage1DARB");
-      return;
-   }
-   memcpy(image, data, imageSize);
    n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, 7);
    if (n) {
       n[1].e = target;
@@ -4623,10 +4750,7 @@ save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
       n[4].i = (GLint) width;
       n[5].e = format;
       n[6].i = imageSize;
-      n[7].data = image;
-   }
-   else if (image) {
-      free(image);
+      n[7].data = copy_data(data, imageSize, "glCompressedTexSubImage1DARB");
    }
    if (ctx->ExecuteFlag) {
       CALL_CompressedTexSubImage1DARB(ctx->Exec, (target, level, xoffset,
@@ -4643,18 +4767,9 @@ save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
                                 const GLvoid * data)
 {
    Node *n;
-   GLvoid *image;
-
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
 
-   /* make copy of image */
-   image = malloc(imageSize);
-   if (!image) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2DARB");
-      return;
-   }
-   memcpy(image, data, imageSize);
    n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, 9);
    if (n) {
       n[1].e = target;
@@ -4665,10 +4780,7 @@ save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
       n[6].i = (GLint) height;
       n[7].e = format;
       n[8].i = imageSize;
-      n[9].data = image;
-   }
-   else if (image) {
-      free(image);
+      n[9].data = copy_data(data, imageSize, "glCompressedTexSubImage2DARB");
    }
    if (ctx->ExecuteFlag) {
       CALL_CompressedTexSubImage2DARB(ctx->Exec,
@@ -4685,18 +4797,9 @@ save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
                                 GLsizei imageSize, const GLvoid * data)
 {
    Node *n;
-   GLvoid *image;
-
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
 
-   /* make copy of image */
-   image = malloc(imageSize);
-   if (!image) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage3DARB");
-      return;
-   }
-   memcpy(image, data, imageSize);
    n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, 11);
    if (n) {
       n[1].e = target;
@@ -4709,10 +4812,7 @@ save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
       n[8].i = (GLint) depth;
       n[9].e = format;
       n[10].i = imageSize;
-      n[11].data = image;
-   }
-   else if (image) {
-      free(image);
+      n[11].data = copy_data(data, imageSize, "glCompressedTexSubImage3DARB");
    }
    if (ctx->ExecuteFlag) {
       CALL_CompressedTexSubImage3DARB(ctx->Exec,
@@ -5341,7 +5441,7 @@ save_SetFragmentShaderConstantATI(GLuint dst, const GLfloat *value)
 }
 #endif
 
-static void
+static void GLAPIENTRY
 save_Attr1fNV(GLenum attr, GLfloat x)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -5362,7 +5462,7 @@ save_Attr1fNV(GLenum attr, GLfloat x)
    }
 }
 
-static void
+static void GLAPIENTRY
 save_Attr2fNV(GLenum attr, GLfloat x, GLfloat y)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -5384,7 +5484,7 @@ save_Attr2fNV(GLenum attr, GLfloat x, GLfloat y)
    }
 }
 
-static void
+static void GLAPIENTRY
 save_Attr3fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -5407,7 +5507,7 @@ save_Attr3fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z)
    }
 }
 
-static void
+static void GLAPIENTRY
 save_Attr4fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -5432,7 +5532,7 @@ save_Attr4fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
 }
 
 
-static void
+static void GLAPIENTRY
 save_Attr1fARB(GLenum attr, GLfloat x)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -5453,7 +5553,7 @@ save_Attr1fARB(GLenum attr, GLfloat x)
    }
 }
 
-static void
+static void GLAPIENTRY
 save_Attr2fARB(GLenum attr, GLfloat x, GLfloat y)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -5475,7 +5575,7 @@ save_Attr2fARB(GLenum attr, GLfloat x, GLfloat y)
    }
 }
 
-static void
+static void GLAPIENTRY
 save_Attr3fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -5498,7 +5598,7 @@ save_Attr3fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z)
    }
 }
 
-static void
+static void GLAPIENTRY
 save_Attr4fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -5613,17 +5713,25 @@ save_Indexfv(const GLfloat * v)
 static void GLAPIENTRY
 save_EdgeFlag(GLboolean x)
 {
-   save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? (GLfloat)1.0 : (GLfloat)0.0);
+   save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? 1.0f : 0.0f);
 }
 
-static INLINE GLboolean compare4fv( const GLfloat *a,
-                                    const GLfloat *b,
-                                    GLuint count )
+
+/**
+ * Compare 'count' elements of vectors 'a' and 'b'.
+ * \return GL_TRUE if equal, GL_FALSE if different.
+ */
+static inline GLboolean
+compare_vec(const GLfloat *a, const GLfloat *b, GLuint count)
 {
    return memcmp( a, b, count * sizeof(GLfloat) ) == 0;
 }
-                              
 
+
+/**
+ * This glMaterial function is used for glMaterial calls that are outside
+ * a glBegin/End pair.  For glMaterial inside glBegin/End, see the VBO code.
+ */
 static void GLAPIENTRY
 save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
 {
@@ -5638,7 +5746,7 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
    case GL_FRONT_AND_BACK:
       break;
    default:
-      _mesa_compile_error(ctx, GL_INVALID_ENUM, "material(face)");
+      _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(face)");
       return;
    }
 
@@ -5657,7 +5765,7 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
       args = 3;
       break;
    default:
-      _mesa_compile_error(ctx, GL_INVALID_ENUM, "material(pname)");
+      _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(pname)");
       return;
    }
    
@@ -5674,7 +5782,8 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
    for (i = 0; i < MAT_ATTRIB_MAX; i++) {
       if (bitmask & (1 << i)) {
          if (ctx->ListState.ActiveMaterialSize[i] == args &&
-             compare4fv(ctx->ListState.CurrentMaterial[i], param, args)) {
+             compare_vec(ctx->ListState.CurrentMaterial[i], param, args)) {
+            /* no change in material value */
             bitmask &= ~(1 << i);
          }
          else {
@@ -5684,8 +5793,7 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
       }
    }
 
-   /* If this call has effect, return early:
-    */
+   /* If this call has no effect, return early */
    if (bitmask == 0)
       return;
 
@@ -5707,10 +5815,16 @@ save_Begin(GLenum mode)
    Node *n;
    GLboolean error = GL_FALSE;
 
-   if ( /*mode < GL_POINTS || */ mode > GL_POLYGON) {
-      _mesa_compile_error(ctx, GL_INVALID_ENUM, "Begin (mode)");
+   if (mode > GL_POLYGON) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glBegin(mode=%x)", mode);
       error = GL_TRUE;
    }
+   if (ctx->ExecuteFlag) {
+      if (!_mesa_valid_prim_mode(ctx, mode, "glBegin")) {
+        error = GL_TRUE;
+      }
+   }
+
    else if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN) {
       /* Typically the first begin.  This may raise an error on
        * playback, depending on whether CallList is issued from inside
@@ -6253,6 +6367,60 @@ save_EndTransformFeedback(void)
    }
 }
 
+static void GLAPIENTRY
+save_BindTransformFeedback(GLenum target, GLuint name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_BIND_TRANSFORM_FEEDBACK, 2);
+   if (n) {
+      n[1].e = target;
+      n[2].ui = name;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_BindTransformFeedback(ctx->Exec, (target, name));
+   }
+}
+
+static void GLAPIENTRY
+save_PauseTransformFeedback(void)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   (void) alloc_instruction(ctx, OPCODE_PAUSE_TRANSFORM_FEEDBACK, 0);
+   if (ctx->ExecuteFlag) {
+      CALL_PauseTransformFeedback(ctx->Exec, ());
+   }
+}
+
+static void GLAPIENTRY
+save_ResumeTransformFeedback(void)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   (void) alloc_instruction(ctx, OPCODE_RESUME_TRANSFORM_FEEDBACK, 0);
+   if (ctx->ExecuteFlag) {
+      CALL_ResumeTransformFeedback(ctx->Exec, ());
+   }
+}
+
+static void GLAPIENTRY
+save_DrawTransformFeedback(GLenum mode, GLuint name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_DRAW_TRANSFORM_FEEDBACK, 2);
+   if (n) {
+      n[1].e = mode;
+      n[2].ui = name;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_DrawTransformFeedback(ctx->Exec, (mode, name));
+   }
+}
+
 
 /* aka UseProgram() */
 static void GLAPIENTRY
@@ -6883,6 +7051,22 @@ save_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
    }
 }
 
+static void GLAPIENTRY
+save_ClampColorARB(GLenum target, GLenum clamp)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_CLAMP_COLOR, 2);
+   if (n) {
+      n[1].e = target;
+      n[2].e = clamp;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ClampColorARB(ctx->Exec, (target, clamp));
+   }
+}
+
 static void GLAPIENTRY
 save_UseShaderProgramEXT(GLenum type, GLuint program)
 {
@@ -7014,7 +7198,7 @@ exec_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
 
 
 /* GL_ARB_instanced_arrays */
-static void
+static void GLAPIENTRY
 save_VertexAttribDivisor(GLuint index, GLuint divisor)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -7031,6 +7215,257 @@ save_VertexAttribDivisor(GLuint index, GLuint divisor)
 }
 
 
+/* GL_NV_texture_barrier */
+static void GLAPIENTRY
+save_TextureBarrierNV(void)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   alloc_instruction(ctx, OPCODE_TEXTURE_BARRIER_NV, 0);
+   if (ctx->ExecuteFlag) {
+      CALL_TextureBarrierNV(ctx->Exec, ());
+   }
+}
+
+
+/* GL_ARB_sampler_objects */
+static void GLAPIENTRY
+save_BindSampler(GLuint unit, GLuint sampler)
+{
+   Node *n;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_BIND_SAMPLER, 2);
+   if (n) {
+      n[1].ui = unit;
+      n[2].ui = sampler;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_BindSampler(ctx->Exec, (unit, sampler));
+   }
+}
+
+static void GLAPIENTRY
+save_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params)
+{
+   Node *n;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_SAMPLER_PARAMETERIV, 6);
+   if (n) {
+      n[1].ui = sampler;
+      n[2].e = pname;
+      n[3].i = params[0];
+      if (pname == GL_TEXTURE_BORDER_COLOR) {
+         n[4].i = params[1];
+         n[5].i = params[2];
+         n[6].i = params[3];
+      }
+      else {
+         n[4].i = n[5].i = n[6].i = 0;
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_SamplerParameteriv(ctx->Exec, (sampler, pname, params));
+   }
+}
+
+static void GLAPIENTRY
+save_SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
+{
+   save_SamplerParameteriv(sampler, pname, &param);
+}
+
+static void GLAPIENTRY
+save_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params)
+{
+   Node *n;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_SAMPLER_PARAMETERFV, 6);
+   if (n) {
+      n[1].ui = sampler;
+      n[2].e = pname;
+      n[3].f = params[0];
+      if (pname == GL_TEXTURE_BORDER_COLOR) {
+         n[4].f = params[1];
+         n[5].f = params[2];
+         n[6].f = params[3];
+      }
+      else {
+         n[4].f = n[5].f = n[6].f = 0.0F;
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_SamplerParameterfv(ctx->Exec, (sampler, pname, params));
+   }
+}
+
+static void GLAPIENTRY
+save_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
+{
+   save_SamplerParameterfv(sampler, pname, &param);
+}
+
+static void GLAPIENTRY
+save_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params)
+{
+   Node *n;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_SAMPLER_PARAMETERIIV, 6);
+   if (n) {
+      n[1].ui = sampler;
+      n[2].e = pname;
+      n[3].i = params[0];
+      if (pname == GL_TEXTURE_BORDER_COLOR) {
+         n[4].i = params[1];
+         n[5].i = params[2];
+         n[6].i = params[3];
+      }
+      else {
+         n[4].i = n[5].i = n[6].i = 0;
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_SamplerParameterIiv(ctx->Exec, (sampler, pname, params));
+   }
+}
+
+static void GLAPIENTRY
+save_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params)
+{
+   Node *n;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_SAMPLER_PARAMETERUIV, 6);
+   if (n) {
+      n[1].ui = sampler;
+      n[2].e = pname;
+      n[3].ui = params[0];
+      if (pname == GL_TEXTURE_BORDER_COLOR) {
+         n[4].ui = params[1];
+         n[5].ui = params[2];
+         n[6].ui = params[3];
+      }
+      else {
+         n[4].ui = n[5].ui = n[6].ui = 0;
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_SamplerParameterIuiv(ctx->Exec, (sampler, pname, params));
+   }
+}
+
+/* GL_ARB_geometry_shader4 */
+static void GLAPIENTRY
+save_ProgramParameteri(GLuint program, GLenum pname, GLint value)
+{
+   Node *n;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_PARAMETERI, 3);
+   if (n) {
+      n[1].ui = program;
+      n[2].e = pname;
+      n[3].i = value;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramParameteriARB(ctx->Exec, (program, pname, value));
+   }
+}
+
+static void GLAPIENTRY
+save_FramebufferTexture(GLenum target, GLenum attachment,
+                        GLuint texture, GLint level)
+{
+   Node *n;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_FRAMEBUFFER_TEXTURE, 4);
+   if (n) {
+      n[1].e = target;
+      n[2].e = attachment;
+      n[3].ui = texture;
+      n[4].i = level;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_FramebufferTextureARB(ctx->Exec, (target, attachment, texture, level));
+   }
+}
+
+static void GLAPIENTRY
+save_FramebufferTextureFace(GLenum target, GLenum attachment,
+                            GLuint texture, GLint level, GLenum face)
+{
+   Node *n;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_FRAMEBUFFER_TEXTURE_FACE, 5);
+   if (n) {
+      n[1].e = target;
+      n[2].e = attachment;
+      n[3].ui = texture;
+      n[4].i = level;
+      n[5].e = face;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_FramebufferTextureFaceARB(ctx->Exec, (target, attachment, texture,
+                                                 level, face));
+   }
+}
+
+
+
+static void GLAPIENTRY
+save_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+   Node *n;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_WAIT_SYNC, 4);
+   if (n) {
+      union uint64_pair p;
+      p.uint64 = timeout;
+      n[1].data = sync;
+      n[2].e = flags;
+      n[3].ui = p.uint32[0];
+      n[4].ui = p.uint32[1];
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_WaitSync(ctx->Exec, (sync, flags, timeout));
+   }
+}
+
+
+/** GL_NV_conditional_render */
+static void GLAPIENTRY
+save_BeginConditionalRender(GLuint queryId, GLenum mode)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_BEGIN_CONDITIONAL_RENDER, 2);
+   if (n) {
+      n[1].i = queryId;
+      n[2].e = mode;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_BeginConditionalRenderNV(ctx->Exec, (queryId, mode));
+   }
+}
+
+static void GLAPIENTRY
+save_EndConditionalRender(void)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   alloc_instruction(ctx, OPCODE_END_CONDITIONAL_RENDER, 0);
+   if (ctx->ExecuteFlag) {
+      CALL_EndConditionalRenderNV(ctx->Exec, ());
+   }
+}
+
 
 /**
  * Save an error-generating command into display list.
@@ -7207,7 +7642,7 @@ execute_list(struct gl_context *ctx, GLuint list)
                value[1] = n[4].i;
                value[2] = n[5].i;
                value[3] = n[6].i;
-               /*CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/
+               CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));
             }
             break;
          case OPCODE_CLEAR_BUFFER_UIV:
@@ -7217,7 +7652,7 @@ execute_list(struct gl_context *ctx, GLuint list)
                value[1] = n[4].ui;
                value[2] = n[5].ui;
                value[3] = n[6].ui;
-               /*CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/
+               CALL_ClearBufferuiv(ctx->Exec, (n[1].e, n[2].i, value));
             }
             break;
          case OPCODE_CLEAR_BUFFER_FV:
@@ -7227,11 +7662,11 @@ execute_list(struct gl_context *ctx, GLuint list)
                value[1] = n[4].f;
                value[2] = n[5].f;
                value[3] = n[6].f;
-               /*CALL_ClearBufferfv(ctx->Exec, (n[1].e, n[2].i, value));*/
+               CALL_ClearBufferfv(ctx->Exec, (n[1].e, n[2].i, value));
             }
             break;
          case OPCODE_CLEAR_BUFFER_FI:
-            /*CALL_ClearBufferfi(ctx->Exec, (n[1].e, n[2].i, n[3].f, n[4].i));*/
+            CALL_ClearBufferfi(ctx->Exec, (n[1].e, n[2].i, n[3].f, n[4].i));
             break;
          case OPCODE_CLEAR_COLOR:
             CALL_ClearColor(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
@@ -7659,12 +8094,6 @@ execute_list(struct gl_context *ctx, GLuint list)
          case OPCODE_PROVOKING_VERTEX:
             CALL_ProvokingVertexEXT(ctx->Exec, (n[1].e));
             break;
-         case OPCODE_BEGIN_TRANSFORM_FEEDBACK:
-            CALL_BeginTransformFeedbackEXT(ctx->Exec, (n[1].e));
-            break;
-         case OPCODE_END_TRANSFORM_FEEDBACK:
-            CALL_EndTransformFeedbackEXT(ctx->Exec, ());
-            break;
          case OPCODE_STENCIL_FUNC:
             CALL_StencilFunc(ctx->Exec, (n[1].e, n[2].i, n[3].ui));
             break;
@@ -8056,6 +8485,10 @@ execute_list(struct gl_context *ctx, GLuint list)
                                     (n[1].i, n[2].i, n[3].b, n[4].data));
            break;
 
+         case OPCODE_CLAMP_COLOR:
+            CALL_ClampColorARB(ctx->Exec, (n[1].e, n[2].e));
+            break;
+
          case OPCODE_TEX_BUMP_PARAMETER_ATI:
             {
                GLfloat values[4];
@@ -8207,6 +8640,106 @@ execute_list(struct gl_context *ctx, GLuint list)
             CALL_VertexAttribDivisorARB(ctx->Exec, (n[1].ui, n[2].ui));
             break;
 
+         case OPCODE_TEXTURE_BARRIER_NV:
+            CALL_TextureBarrierNV(ctx->Exec, ());
+            break;
+
+         /* GL_EXT/ARB_transform_feedback */
+         case OPCODE_BEGIN_TRANSFORM_FEEDBACK:
+            CALL_BeginTransformFeedbackEXT(ctx->Exec, (n[1].e));
+            break;
+         case OPCODE_END_TRANSFORM_FEEDBACK:
+            CALL_EndTransformFeedbackEXT(ctx->Exec, ());
+            break;
+         case OPCODE_BIND_TRANSFORM_FEEDBACK:
+            CALL_BindTransformFeedback(ctx->Exec, (n[1].e, n[2].ui));
+            break;
+         case OPCODE_PAUSE_TRANSFORM_FEEDBACK:
+            CALL_PauseTransformFeedback(ctx->Exec, ());
+            break;
+         case OPCODE_RESUME_TRANSFORM_FEEDBACK:
+            CALL_ResumeTransformFeedback(ctx->Exec, ());
+            break;
+         case OPCODE_DRAW_TRANSFORM_FEEDBACK:
+            CALL_DrawTransformFeedback(ctx->Exec, (n[1].e, n[2].ui));
+            break;
+
+
+         case OPCODE_BIND_SAMPLER:
+            CALL_BindSampler(ctx->Exec, (n[1].ui, n[2].ui));
+            break;
+         case OPCODE_SAMPLER_PARAMETERIV:
+            {
+               GLint params[4];
+               params[0] = n[3].i;
+               params[1] = n[4].i;
+               params[2] = n[5].i;
+               params[3] = n[6].i;
+               CALL_SamplerParameteriv(ctx->Exec, (n[1].ui, n[2].e, params));
+            }
+            break;
+         case OPCODE_SAMPLER_PARAMETERFV:
+            {
+               GLfloat params[4];
+               params[0] = n[3].f;
+               params[1] = n[4].f;
+               params[2] = n[5].f;
+               params[3] = n[6].f;
+               CALL_SamplerParameterfv(ctx->Exec, (n[1].ui, n[2].e, params));
+            }
+            break;
+         case OPCODE_SAMPLER_PARAMETERIIV:
+            {
+               GLint params[4];
+               params[0] = n[3].i;
+               params[1] = n[4].i;
+               params[2] = n[5].i;
+               params[3] = n[6].i;
+               CALL_SamplerParameterIiv(ctx->Exec, (n[1].ui, n[2].e, params));
+            }
+            break;
+         case OPCODE_SAMPLER_PARAMETERUIV:
+            {
+               GLuint params[4];
+               params[0] = n[3].ui;
+               params[1] = n[4].ui;
+               params[2] = n[5].ui;
+               params[3] = n[6].ui;
+               CALL_SamplerParameterIuiv(ctx->Exec, (n[1].ui, n[2].e, params));
+            }
+            break;
+
+         /* GL_ARB_geometry_shader4 */
+         case OPCODE_PROGRAM_PARAMETERI:
+            CALL_ProgramParameteriARB(ctx->Exec, (n[1].ui, n[2].e, n[3].i));
+            break;
+         case OPCODE_FRAMEBUFFER_TEXTURE:
+            CALL_FramebufferTextureARB(ctx->Exec, (n[1].e, n[2].e,
+                                                   n[3].ui, n[4].i));
+            break;
+         case OPCODE_FRAMEBUFFER_TEXTURE_FACE:
+            CALL_FramebufferTextureFaceARB(ctx->Exec, (n[1].e, n[2].e,
+                                                       n[3].ui, n[4].i, n[5].e));
+            break;
+
+         /* GL_ARB_sync */
+         case OPCODE_WAIT_SYNC:
+            {
+               union uint64_pair p;
+               p.uint32[0] = n[3].ui;
+               p.uint32[1] = n[4].ui;
+               CALL_WaitSync(ctx->Exec, (n[1].data, n[2].bf, p.uint64));
+            }
+            break;
+
+         /* GL_NV_conditional_render */
+         case OPCODE_BEGIN_CONDITIONAL_RENDER:
+            CALL_BeginConditionalRenderNV(ctx->Exec, (n[1].i, n[2].e));
+            break;
+         case OPCODE_END_CONDITIONAL_RENDER:
+            CALL_EndConditionalRenderNV(ctx->Exec, ());
+            break;
+
          case OPCODE_CONTINUE:
             n = (Node *) n[1].next;
             break;
@@ -9230,8 +9763,6 @@ exec_MultiModeDrawElementsIBM(const GLenum * mode,
                                   modestride));
 }
 
-
-
 /**
  * Setup the given dispatch table to point to Mesa's display list
  * building functions.
@@ -9673,6 +10204,28 @@ _mesa_create_save_table(void)
    SET_GenVertexArraysAPPLE(table, _mesa_GenVertexArraysAPPLE);
    SET_IsVertexArrayAPPLE(table, _mesa_IsVertexArrayAPPLE);
 
+   /* 310. GL_EXT_framebuffer_object */
+   SET_GenFramebuffersEXT(table, _mesa_GenFramebuffersEXT);
+   SET_BindFramebufferEXT(table, _mesa_BindFramebufferEXT);
+   SET_DeleteFramebuffersEXT(table, _mesa_DeleteFramebuffersEXT);
+   SET_CheckFramebufferStatusEXT(table, _mesa_CheckFramebufferStatusEXT);
+   SET_GenRenderbuffersEXT(table, _mesa_GenRenderbuffersEXT);
+   SET_BindRenderbufferEXT(table, _mesa_BindRenderbufferEXT);
+   SET_DeleteRenderbuffersEXT(table, _mesa_DeleteRenderbuffersEXT);
+   SET_RenderbufferStorageEXT(table, _mesa_RenderbufferStorageEXT);
+   SET_FramebufferTexture1DEXT(table, _mesa_FramebufferTexture1DEXT);
+   SET_FramebufferTexture2DEXT(table, _mesa_FramebufferTexture2DEXT);
+   SET_FramebufferTexture3DEXT(table, _mesa_FramebufferTexture3DEXT);
+   SET_FramebufferRenderbufferEXT(table, _mesa_FramebufferRenderbufferEXT);
+   SET_GenerateMipmapEXT(table, _mesa_GenerateMipmapEXT);
+
+   /* 317. GL_EXT_framebuffer_multisample */
+   SET_RenderbufferStorageMultisample(table, _mesa_RenderbufferStorageMultisample);
+
+   /* GL_ARB_vertex_array_object */
+   SET_BindVertexArray(table, _mesa_BindVertexArray);
+   SET_GenVertexArrays(table, _mesa_GenVertexArrays);
+
    /* ???. GL_EXT_depth_bounds_test */
    SET_DepthBoundsEXT(table, save_DepthBoundsEXT);
 
@@ -9716,9 +10269,9 @@ _mesa_create_save_table(void)
    SET_DeleteProgramsNV(table, _mesa_DeletePrograms);
    SET_GenProgramsNV(table, _mesa_GenPrograms);
    SET_IsProgramNV(table, _mesa_IsProgramARB);
-   SET_GetVertexAttribdvNV(table, _mesa_GetVertexAttribdvNV);
-   SET_GetVertexAttribfvNV(table, _mesa_GetVertexAttribfvNV);
-   SET_GetVertexAttribivNV(table, _mesa_GetVertexAttribivNV);
+   SET_GetVertexAttribdvARB(table, _mesa_GetVertexAttribdvARB);
+   SET_GetVertexAttribfvARB(table, _mesa_GetVertexAttribfvARB);
+   SET_GetVertexAttribivARB(table, _mesa_GetVertexAttribivARB);
    SET_GetVertexAttribPointervNV(table, _mesa_GetVertexAttribPointervNV);
    SET_ProgramEnvParameter4dARB(table, save_ProgramEnvParameter4dARB);
    SET_ProgramEnvParameter4dvARB(table, save_ProgramEnvParameter4dvARB);
@@ -9739,7 +10292,6 @@ _mesa_create_save_table(void)
 #endif
 
    /* ARB 28. GL_ARB_vertex_buffer_object */
-#if FEATURE_ARB_vertex_buffer_object
    /* None of the extension's functions get compiled */
    SET_BindBufferARB(table, _mesa_BindBufferARB);
    SET_BufferDataARB(table, _mesa_BufferDataARB);
@@ -9752,18 +10304,13 @@ _mesa_create_save_table(void)
    SET_IsBufferARB(table, _mesa_IsBufferARB);
    SET_MapBufferARB(table, _mesa_MapBufferARB);
    SET_UnmapBufferARB(table, _mesa_UnmapBufferARB);
-#endif
 
 #if FEATURE_queryobj
+   _mesa_init_queryobj_dispatch(table); /* glGetQuery, etc */
    SET_BeginQueryARB(table, save_BeginQueryARB);
    SET_EndQueryARB(table, save_EndQueryARB);
-   SET_GenQueriesARB(table, _mesa_GenQueriesARB);
-   SET_DeleteQueriesARB(table, _mesa_DeleteQueriesARB);
-   SET_IsQueryARB(table, _mesa_IsQueryARB);
-   SET_GetQueryivARB(table, _mesa_GetQueryivARB);
-   SET_GetQueryObjectivARB(table, _mesa_GetQueryObjectivARB);
-   SET_GetQueryObjectuivARB(table, _mesa_GetQueryObjectuivARB);
 #endif
+
    SET_DrawBuffersARB(table, save_DrawBuffersARB);
 
 #if FEATURE_EXT_framebuffer_blit
@@ -9771,6 +10318,7 @@ _mesa_create_save_table(void)
 #endif
 
    /* GL_ARB_shader_objects */
+   _mesa_init_shader_dispatch(table); /* Plug in glCreate/Delete/Get, etc */
    SET_UseProgramObjectARB(table, save_UseProgramObjectARB);
    SET_Uniform1fARB(table, save_Uniform1fARB);
    SET_Uniform2fARB(table, save_Uniform2fARB);
@@ -9819,15 +10367,12 @@ _mesa_create_save_table(void)
    SET_FlushMappedBufferRange(table, _mesa_FlushMappedBufferRange); /* no dl */
 #endif
 
+   /* ARB 51. GL_ARB_texture_buffer_object */
+   SET_TexBufferARB(table, _mesa_TexBuffer); /* no dlist save */
+
    /* ARB 59. GL_ARB_copy_buffer */
    SET_CopyBufferSubData(table, _mesa_CopyBufferSubData); /* no dlist save */
 
-   /* 352. GL_EXT_transform_feedback */
-#if FEATURE_EXT_transform_feedback
-   SET_BeginTransformFeedbackEXT(table, save_BeginTransformFeedback);
-   SET_EndTransformFeedbackEXT(table, save_EndTransformFeedback);
-#endif
-
    /* 364. GL_EXT_provoking_vertex */
    SET_ProvokingVertexEXT(table, save_ProvokingVertexEXT);
 
@@ -9835,6 +10380,7 @@ _mesa_create_save_table(void)
 #if FEATURE_APPLE_object_purgeable
    SET_ObjectPurgeableAPPLE(table, _mesa_ObjectPurgeableAPPLE);
    SET_ObjectUnpurgeableAPPLE(table, _mesa_ObjectUnpurgeableAPPLE);
+   SET_GetObjectParameterivAPPLE(table, _mesa_GetObjectParameterivAPPLE);
 #endif
 
    /* GL_EXT_texture_integer */
@@ -9849,12 +10395,16 @@ _mesa_create_save_table(void)
    SET_UseShaderProgramEXT(table, save_UseShaderProgramEXT);
    SET_ActiveProgramEXT(table, save_ActiveProgramEXT);
 
+   /* GL_ARB_color_buffer_float */
+   SET_ClampColorARB(table, save_ClampColorARB);
+   SET_ClampColor(table, save_ClampColorARB);
+
    /* GL 3.0 */
-#if 0
    SET_ClearBufferiv(table, save_ClearBufferiv);
    SET_ClearBufferuiv(table, save_ClearBufferuiv);
    SET_ClearBufferfv(table, save_ClearBufferfv);
    SET_ClearBufferfi(table, save_ClearBufferfi);
+#if 0
    SET_Uniform1ui(table, save_Uniform1ui);
    SET_Uniform2ui(table, save_Uniform2ui);
    SET_Uniform3ui(table, save_Uniform3ui);
@@ -9864,10 +10414,6 @@ _mesa_create_save_table(void)
    SET_Uniform3uiv(table, save_Uniform3uiv);
    SET_Uniform4uiv(table, save_Uniform4uiv);
 #else
-   (void) save_ClearBufferiv;
-   (void) save_ClearBufferuiv;
-   (void) save_ClearBufferfv;
-   (void) save_ClearBufferfi;
    (void) save_Uniform1ui;
    (void) save_Uniform2ui;
    (void) save_Uniform3ui;
@@ -9878,15 +10424,70 @@ _mesa_create_save_table(void)
    (void) save_Uniform4uiv;
 #endif
 
+#if FEATURE_EXT_transform_feedback
+   /* These are not compiled into display lists: */
+   SET_BindBufferBaseEXT(table, _mesa_BindBufferBase);
+   SET_BindBufferOffsetEXT(table, _mesa_BindBufferOffsetEXT);
+   SET_BindBufferRangeEXT(table, _mesa_BindBufferRange);
+   SET_TransformFeedbackVaryingsEXT(table, _mesa_TransformFeedbackVaryings);
+   /* These are: */
+   SET_BeginTransformFeedbackEXT(table, save_BeginTransformFeedback);
+   SET_EndTransformFeedbackEXT(table, save_EndTransformFeedback);
+   SET_BindTransformFeedback(table, save_BindTransformFeedback);
+   SET_PauseTransformFeedback(table, save_PauseTransformFeedback);
+   SET_ResumeTransformFeedback(table, save_ResumeTransformFeedback);
+   SET_DrawTransformFeedback(table, save_DrawTransformFeedback);
+#endif
+
    /* GL_ARB_instanced_arrays */
    SET_VertexAttribDivisorARB(table, save_VertexAttribDivisor);
 
+   /* GL_NV_texture_barrier */
+   SET_TextureBarrierNV(table, save_TextureBarrierNV);
+
+   /* GL_ARB_sampler_objects */
+   _mesa_init_sampler_object_dispatch(table); /* plug in Gen/Get/etc functions */
+   SET_BindSampler(table, save_BindSampler);
+   SET_SamplerParameteri(table, save_SamplerParameteri);
+   SET_SamplerParameterf(table, save_SamplerParameterf);
+   SET_SamplerParameteriv(table, save_SamplerParameteriv);
+   SET_SamplerParameterfv(table, save_SamplerParameterfv);
+   SET_SamplerParameterIiv(table, save_SamplerParameterIiv);
+   SET_SamplerParameterIuiv(table, save_SamplerParameterIuiv);
+
    /* GL_ARB_draw_buffer_blend */
    SET_BlendFunciARB(table, save_BlendFunci);
    SET_BlendFuncSeparateiARB(table, save_BlendFuncSeparatei);
    SET_BlendEquationiARB(table, save_BlendEquationi);
    SET_BlendEquationSeparateiARB(table, save_BlendEquationSeparatei);
 
+   /* GL_ARB_geometry_shader4 */
+   SET_ProgramParameteriARB(table, save_ProgramParameteri);
+   SET_FramebufferTextureARB(table, save_FramebufferTexture);
+   SET_FramebufferTextureFaceARB(table, save_FramebufferTextureFace);
+
+   /* GL_NV_conditional_render */
+   SET_BeginConditionalRenderNV(table, save_BeginConditionalRender);
+   SET_EndConditionalRenderNV(table, save_EndConditionalRender);
+
+   /* GL_ARB_sync */
+   _mesa_init_sync_dispatch(table);
+   SET_WaitSync(table, save_WaitSync);
+
+   /* GL_ARB_texture_storage (no dlist support) */
+   SET_TexStorage1D(table, _mesa_TexStorage1D);
+   SET_TexStorage2D(table, _mesa_TexStorage2D);
+   SET_TexStorage3D(table, _mesa_TexStorage3D);
+   SET_TextureStorage1DEXT(table, _mesa_TextureStorage1DEXT);
+   SET_TextureStorage2DEXT(table, _mesa_TextureStorage2DEXT);
+   SET_TextureStorage3DEXT(table, _mesa_TextureStorage3DEXT);
+
+   /* GL_ARB_debug_output (no dlist support) */
+   _mesa_init_errors_dispatch(table);
+
+   /* GL_NV_primitive_restart */
+   SET_PrimitiveRestartIndexNV(table, _mesa_PrimitiveRestartIndex);
+
    return table;
 }
 
@@ -10248,6 +10849,18 @@ _mesa_save_vtxfmt_init(GLvertexformat * vfmt)
 
    vfmt->Rectf = save_Rectf;
 
+   /* GL_ARB_draw_instanced */
+   vfmt->DrawArraysInstanced = save_DrawArraysInstancedARB;
+   vfmt->DrawElementsInstanced = save_DrawElementsInstancedARB;
+
+   /* GL_ARB_draw_elements_base_vertex */
+   vfmt->DrawElementsInstancedBaseVertex = save_DrawElementsInstancedBaseVertexARB;
+
+   /* GL_ARB_base_instance */
+   vfmt->DrawArraysInstancedBaseInstance = save_DrawArraysInstancedBaseInstance;
+   vfmt->DrawElementsInstancedBaseInstance = save_DrawElementsInstancedBaseInstance;
+   vfmt->DrawElementsInstancedBaseVertexBaseInstance = save_DrawElementsInstancedBaseVertexBaseInstance;
+
    /* The driver is required to implement these as
     * 1) They can probably do a better job.
     * 2) A lot of new mechanisms would have to be added to this module