mesa: minor whitespace fixes in teximage.c
[mesa.git] / src / mesa / main / dlist.c
index 226bb6837b0c88ec38d1dc4ae18960721fcb73ce..99519120a9f4aa8d7eb50d37f27701e7251644fb 100644 (file)
 #include "api_arrayelt.h"
 #include "api_exec.h"
 #include "api_loopback.h"
-#if FEATURE_ATI_fragment_shader
+#include "api_validate.h"
 #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"
+#include "fbobject.h"
 #include "framebuffer.h"
 #include "glapi/glapi.h"
-#include "glapidispatch.h"
+#include "glformats.h"
 #include "hash.h"
 #include "image.h"
 #include "light.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
 #include "arbprogram.h"
-#endif
-#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
 #include "nvprogram.h"
-#endif
+#include "transformfeedback.h"
 
 #include "math/m_matrix.h"
 
@@ -129,7 +125,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)
@@ -144,7 +140,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)
@@ -424,6 +420,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,
@@ -450,10 +450,31 @@ typedef enum
 
    /* 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,
+
+   /* ARB_timer_query */
+   OPCODE_QUERY_COUNTER,
+
+   /* ARB_transform_feedback3 */
+   OPCODE_BEGIN_QUERY_INDEXED,
+   OPCODE_END_QUERY_INDEXED,
+   OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM,
+
+   /* ARB_transform_feedback_instanced */
+   OPCODE_DRAW_TRANSFORM_FEEDBACK_INSTANCED,
+   OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM_INSTANCED,
+
+   /* ARB_uniform_buffer_object */
+   OPCODE_UNIFORM_BLOCK_BINDING,
+
    /* The following three are meta instructions */
    OPCODE_ERROR,                /* raise compiled-in error */
    OPCODE_CONTINUE,
@@ -486,6 +507,7 @@ union gl_dlist_node
    GLuint ui;
    GLenum e;
    GLfloat f;
+   GLsizei si;
    GLvoid *data;
    void *next;                  /* If prev node's opcode==OPCODE_CONTINUE */
 };
@@ -521,9 +543,6 @@ union uint64_pair
 static GLuint InstSize[OPCODE_END_OF_LIST + 1];
 
 
-#if FEATURE_dlist
-
-
 void mesa_print_display_list(GLuint list);
 
 
@@ -541,7 +560,7 @@ make_list(GLuint name, GLuint count)
 {
    struct gl_display_list *dlist = CALLOC_STRUCT(gl_display_list);
    dlist->Name = name;
-   dlist->Head = (Node *) malloc(sizeof(Node) * count);
+   dlist->Head = malloc(sizeof(Node) * count);
    dlist->Head[0].opcode = OPCODE_END_OF_LIST;
    return dlist;
 }
@@ -550,7 +569,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 *)
@@ -559,7 +578,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);
@@ -709,7 +728,6 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
             free(n[11].data);
             n += InstSize[n[0].opcode];
             break;
-#if FEATURE_NV_vertex_program
          case OPCODE_LOAD_PROGRAM_NV:
             free(n[4].data);      /* program string */
             n += InstSize[n[0].opcode];
@@ -718,19 +736,14 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
             free(n[2].data);      /* array of program ids */
             n += InstSize[n[0].opcode];
             break;
-#endif
-#if FEATURE_NV_fragment_program
          case OPCODE_PROGRAM_NAMED_PARAMETER_NV:
             free(n[3].data);      /* parameter name */
             n += InstSize[n[0].opcode];
             break;
-#endif
-#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
          case OPCODE_PROGRAM_STRING_ARB:
             free(n[4].data);      /* program string */
             n += InstSize[n[0].opcode];
             break;
-#endif
          case OPCODE_UNIFORM_1FV:
          case OPCODE_UNIFORM_2FV:
          case OPCODE_UNIFORM_3FV:
@@ -865,8 +878,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,
@@ -874,10 +891,24 @@ 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");
       }
@@ -889,8 +920,8 @@ unpack_image(struct gl_context *ctx, GLuint dimensions,
       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");
@@ -898,22 +929,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)
@@ -942,7 +976,7 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes)
       Node *newblock;
       n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos;
       n[0].opcode = OPCODE_CONTINUE;
-      newblock = (Node *) malloc(sizeof(Node) * BLOCK_SIZE);
+      newblock = malloc(sizeof(Node) * BLOCK_SIZE);
       if (!newblock) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "Building display list");
          return NULL;
@@ -1021,7 +1055,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));
@@ -1099,7 +1133,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,
@@ -1263,6 +1298,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;
@@ -1386,7 +1498,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));
    }
 }
 
@@ -1414,7 +1526,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));
    }
 }
 
@@ -1442,7 +1554,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));
    }
 }
 
@@ -1462,7 +1574,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));
    }
 }
 
@@ -3059,7 +3171,7 @@ save_PixelMapfv(GLenum map, GLint mapsize, const GLfloat *values)
    if (n) {
       n[1].e = map;
       n[2].i = mapsize;
-      n[3].data = (void *) malloc(mapsize * sizeof(GLfloat));
+      n[3].data = malloc(mapsize * sizeof(GLfloat));
       memcpy(n[3].data, (void *) values, mapsize * sizeof(GLfloat));
    }
    if (ctx->ExecuteFlag) {
@@ -4487,6 +4599,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
@@ -4504,15 +4634,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;
@@ -4521,10 +4644,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,
@@ -4550,15 +4670,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;
@@ -4568,10 +4681,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,
@@ -4597,15 +4707,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;
@@ -4616,10 +4719,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,
@@ -4637,18 +4737,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;
@@ -4657,10 +4748,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,
@@ -4677,18 +4765,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;
@@ -4699,10 +4778,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,
@@ -4719,18 +4795,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;
@@ -4743,10 +4810,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,
@@ -4778,7 +4842,6 @@ save_SampleCoverageARB(GLclampf value, GLboolean invert)
 /*
  * GL_NV_vertex_program
  */
-#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
 static void GLAPIENTRY
 save_BindProgramNV(GLenum target, GLuint id)
 {
@@ -4878,9 +4941,7 @@ save_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
                                  (GLfloat) params[2], (GLfloat) params[3]);
 }
 
-#endif /* FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program || FEATURE_NV_vertex_program */
 
-#if FEATURE_NV_vertex_program
 static void GLAPIENTRY
 save_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params)
 {
@@ -4935,7 +4996,7 @@ save_LoadProgramNV(GLenum target, GLuint id, GLsizei len,
 
    n = alloc_instruction(ctx, OPCODE_LOAD_PROGRAM_NV, 4);
    if (n) {
-      GLubyte *programCopy = (GLubyte *) malloc(len);
+      GLubyte *programCopy = malloc(len);
       if (!programCopy) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
          return;
@@ -4962,7 +5023,7 @@ save_RequestResidentProgramsNV(GLsizei num, const GLuint * ids)
 
    n = alloc_instruction(ctx, OPCODE_TRACK_MATRIX_NV, 2);
    if (n) {
-      GLuint *idCopy = (GLuint *) malloc(num * sizeof(GLuint));
+      GLuint *idCopy = malloc(num * sizeof(GLuint));
       if (!idCopy) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glRequestResidentProgramsNV");
          return;
@@ -4995,13 +5056,11 @@ save_TrackMatrixNV(GLenum target, GLuint address,
       CALL_TrackMatrixNV(ctx->Exec, (target, address, matrix, transform));
    }
 }
-#endif /* FEATURE_NV_vertex_program */
 
 
 /*
  * GL_NV_fragment_program
  */
-#if FEATURE_NV_fragment_program
 static void GLAPIENTRY
 save_ProgramLocalParameter4fARB(GLenum target, GLuint index,
                                 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
@@ -5133,7 +5192,7 @@ save_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte * name,
 
    n = alloc_instruction(ctx, OPCODE_PROGRAM_NAMED_PARAMETER_NV, 6);
    if (n) {
-      GLubyte *nameCopy = (GLubyte *) malloc(len);
+      GLubyte *nameCopy = malloc(len);
       if (!nameCopy) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramNamedParameter4fNV");
          return;
@@ -5179,9 +5238,6 @@ save_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte * name,
                                   (GLfloat) v[3]);
 }
 
-#endif /* FEATURE_NV_fragment_program */
-
-
 
 /* GL_EXT_stencil_two_side */
 static void GLAPIENTRY
@@ -5219,8 +5275,6 @@ save_DepthBoundsEXT(GLclampd zmin, GLclampd zmax)
 
 
 
-#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
-
 static void GLAPIENTRY
 save_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
                       const GLvoid * string)
@@ -5232,7 +5286,7 @@ save_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
 
    n = alloc_instruction(ctx, OPCODE_PROGRAM_STRING_ARB, 4);
    if (n) {
-      GLubyte *programCopy = (GLubyte *) malloc(len);
+      GLubyte *programCopy = malloc(len);
       if (!programCopy) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
          return;
@@ -5248,10 +5302,6 @@ save_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
    }
 }
 
-#endif /* FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program */
-
-
-#if FEATURE_queryobj
 
 static void GLAPIENTRY
 save_BeginQueryARB(GLenum target, GLuint id)
@@ -5269,7 +5319,6 @@ save_BeginQueryARB(GLenum target, GLuint id)
    }
 }
 
-
 static void GLAPIENTRY
 save_EndQueryARB(GLenum target)
 {
@@ -5285,7 +5334,54 @@ save_EndQueryARB(GLenum target)
    }
 }
 
-#endif /* FEATURE_queryobj */
+static void GLAPIENTRY
+save_QueryCounter(GLuint id, GLenum target)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_QUERY_COUNTER, 2);
+   if (n) {
+      n[1].ui = id;
+      n[2].e = target;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_QueryCounter(ctx->Exec, (id, target));
+   }
+}
+
+static void GLAPIENTRY
+save_BeginQueryIndexed(GLenum target, GLuint index, GLuint id)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_BEGIN_QUERY_INDEXED, 3);
+   if (n) {
+      n[1].e = target;
+      n[2].ui = index;
+      n[3].ui = id;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_BeginQueryIndexed(ctx->Exec, (target, index, id));
+   }
+}
+
+static void GLAPIENTRY
+save_EndQueryIndexed(GLenum target, GLuint index)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_END_QUERY_INDEXED, 2);
+   if (n) {
+      n[1].e = target;
+      n[2].ui = index;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_EndQueryIndexed(ctx->Exec, (target, index));
+   }
+}
 
 
 static void GLAPIENTRY
@@ -5339,7 +5435,6 @@ save_TexBumpParameterivATI(GLenum pname, const GLint *param)
    save_TexBumpParameterfvATI(pname, p);
 }
 
-#if FEATURE_ATI_fragment_shader
 static void GLAPIENTRY
 save_BindFragmentShaderATI(GLuint id)
 {
@@ -5373,7 +5468,6 @@ save_SetFragmentShaderConstantATI(GLuint dst, const GLfloat *value)
       CALL_SetFragmentShaderConstantATI(ctx->Exec, (dst, value));
    }
 }
-#endif
 
 static void GLAPIENTRY
 save_Attr1fNV(GLenum attr, GLfloat x)
@@ -5647,17 +5741,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)
 {
@@ -5672,7 +5774,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;
    }
 
@@ -5691,7 +5793,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;
    }
    
@@ -5708,7 +5810,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 {
@@ -5718,8 +5821,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;
 
@@ -5741,10 +5843,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
@@ -6209,7 +6317,6 @@ exec_GetUniformLocationARB(GLuint program, const GLchar *name)
 /* XXX more shader functions needed here */
 
 
-#if FEATURE_EXT_framebuffer_blit
 static void GLAPIENTRY
 save_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                         GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
@@ -6237,7 +6344,6 @@ save_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                                           mask, filter));
    }
 }
-#endif
 
 
 /** GL_EXT_provoking_vertex */
@@ -6287,6 +6393,114 @@ 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));
+   }
+}
+
+static void GLAPIENTRY
+save_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM, 3);
+   if (n) {
+      n[1].e = mode;
+      n[2].ui = name;
+      n[3].ui = stream;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_DrawTransformFeedbackStream(ctx->Exec, (mode, name, stream));
+   }
+}
+
+static void GLAPIENTRY
+save_DrawTransformFeedbackInstanced(GLenum mode, GLuint name,
+                                    GLsizei primcount)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_DRAW_TRANSFORM_FEEDBACK_INSTANCED, 3);
+   if (n) {
+      n[1].e = mode;
+      n[2].ui = name;
+      n[3].si = primcount;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_DrawTransformFeedbackInstanced(ctx->Exec, (mode, name, primcount));
+   }
+}
+
+static void GLAPIENTRY
+save_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name,
+                                          GLuint stream, GLsizei primcount)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM_INSTANCED, 4);
+   if (n) {
+      n[1].e = mode;
+      n[2].ui = name;
+      n[3].ui = stream;
+      n[4].si = primcount;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_DrawTransformFeedbackStreamInstanced(ctx->Exec, (mode, name, stream,
+                                                            primcount));
+   }
+}
 
 /* aka UseProgram() */
 static void GLAPIENTRY
@@ -7241,6 +7455,47 @@ save_ProgramParameteri(GLuint program, GLenum pname, GLint 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)
@@ -7263,6 +7518,52 @@ save_WaitSync(GLsync sync, GLbitfield flags, GLuint64 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, ());
+   }
+}
+
+static void GLAPIENTRY
+save_UniformBlockBinding(GLuint prog, GLuint index, GLuint binding)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_BLOCK_BINDING, 3);
+   if (n) {
+      n[1].ui = prog;
+      n[2].ui = index;
+      n[3].ui = binding;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_UniformBlockBinding(ctx->Exec, (prog, index, binding));
+   }
+}
+
+
 /**
  * Save an error-generating command into display list.
  *
@@ -7438,7 +7739,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:
@@ -7448,7 +7749,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:
@@ -7458,11 +7759,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));
@@ -7890,12 +8191,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;
@@ -8078,12 +8373,9 @@ execute_list(struct gl_context *ctx, GLuint list)
          case OPCODE_WINDOW_POS_ARB:   /* GL_ARB_window_pos */
             CALL_WindowPos3fMESA(ctx->Exec, (n[1].f, n[2].f, n[3].f));
             break;
-#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
          case OPCODE_BIND_PROGRAM_NV:  /* GL_NV_vertex_program */
             CALL_BindProgramNV(ctx->Exec, (n[1].e, n[2].ui));
             break;
-#endif
-#if FEATURE_NV_vertex_program
          case OPCODE_EXECUTE_PROGRAM_NV:
             {
                GLfloat v[4];
@@ -8105,9 +8397,6 @@ execute_list(struct gl_context *ctx, GLuint list)
          case OPCODE_TRACK_MATRIX_NV:
             CALL_TrackMatrixNV(ctx->Exec, (n[1].e, n[2].ui, n[3].e, n[4].e));
             break;
-#endif
-
-#if FEATURE_NV_fragment_program
          case OPCODE_PROGRAM_LOCAL_PARAMETER_ARB:
             CALL_ProgramLocalParameter4fARB(ctx->Exec,
                                             (n[1].e, n[2].ui, n[3].f, n[4].f,
@@ -8119,35 +8408,36 @@ execute_list(struct gl_context *ctx, GLuint list)
                                                        data, n[4].f, n[5].f,
                                                        n[6].f, n[7].f));
             break;
-#endif
-
          case OPCODE_ACTIVE_STENCIL_FACE_EXT:
             CALL_ActiveStencilFaceEXT(ctx->Exec, (n[1].e));
             break;
          case OPCODE_DEPTH_BOUNDS_EXT:
             CALL_DepthBoundsEXT(ctx->Exec, (n[1].f, n[2].f));
             break;
-#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
          case OPCODE_PROGRAM_STRING_ARB:
             CALL_ProgramStringARB(ctx->Exec,
                                   (n[1].e, n[2].e, n[3].i, n[4].data));
             break;
-#endif
-#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program || FEATURE_NV_vertex_program
          case OPCODE_PROGRAM_ENV_PARAMETER_ARB:
             CALL_ProgramEnvParameter4fARB(ctx->Exec, (n[1].e, n[2].ui, n[3].f,
                                                       n[4].f, n[5].f,
                                                       n[6].f));
             break;
-#endif
-#if FEATURE_queryobj
          case OPCODE_BEGIN_QUERY_ARB:
             CALL_BeginQueryARB(ctx->Exec, (n[1].e, n[2].ui));
             break;
          case OPCODE_END_QUERY_ARB:
             CALL_EndQueryARB(ctx->Exec, (n[1].e));
             break;
-#endif
+         case OPCODE_QUERY_COUNTER:
+            CALL_QueryCounter(ctx->Exec, (n[1].ui, n[2].e));
+            break;
+         case OPCODE_BEGIN_QUERY_INDEXED:
+            CALL_BeginQueryIndexed(ctx->Exec, (n[1].e, n[2].ui, n[3].ui));
+            break;
+         case OPCODE_END_QUERY_INDEXED:
+            CALL_EndQueryIndexed(ctx->Exec, (n[1].e, n[2].ui));
+            break;
          case OPCODE_DRAW_BUFFERS_ARB:
             {
                GLenum buffers[MAX_DRAW_BUFFERS];
@@ -8157,14 +8447,11 @@ execute_list(struct gl_context *ctx, GLuint list)
                CALL_DrawBuffersARB(ctx->Exec, (n[1].i, buffers));
             }
             break;
-#if FEATURE_EXT_framebuffer_blit
         case OPCODE_BLIT_FRAMEBUFFER:
            CALL_BlitFramebufferEXT(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i,
                                                 n[5].i, n[6].i, n[7].i, n[8].i,
                                                 n[9].i, n[10].e));
            break;
-#endif
-
         case OPCODE_USE_PROGRAM:
            CALL_UseProgramObjectARB(ctx->Exec, (n[1].ui));
            break;
@@ -8301,7 +8588,6 @@ execute_list(struct gl_context *ctx, GLuint list)
                CALL_TexBumpParameterfvATI(ctx->Exec, (pname, values));
             }
             break;
-#if FEATURE_ATI_fragment_shader
          case OPCODE_BIND_FRAGMENT_SHADER_ATI:
             CALL_BindFragmentShaderATI(ctx->Exec, (n[1].i));
             break;
@@ -8315,7 +8601,6 @@ execute_list(struct gl_context *ctx, GLuint list)
                CALL_SetFragmentShaderConstantATI(ctx->Exec, (dst, values));
             }
             break;
-#endif
          case OPCODE_ATTR_1F_NV:
             CALL_VertexAttrib1fNV(ctx->Exec, (n[1].e, n[2].f));
             break;
@@ -8446,6 +8731,39 @@ execute_list(struct gl_context *ctx, GLuint list)
             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_DRAW_TRANSFORM_FEEDBACK_STREAM:
+            CALL_DrawTransformFeedbackStream(ctx->Exec,
+                                             (n[1].e, n[2].ui, n[3].ui));
+            break;
+         case OPCODE_DRAW_TRANSFORM_FEEDBACK_INSTANCED:
+            CALL_DrawTransformFeedbackInstanced(ctx->Exec,
+                                                (n[1].e, n[2].ui, n[3].si));
+            break;
+         case OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM_INSTANCED:
+            CALL_DrawTransformFeedbackStreamInstanced(ctx->Exec,
+                                       (n[1].e, n[2].ui, n[3].ui, n[4].si));
+            break;
+
+
          case OPCODE_BIND_SAMPLER:
             CALL_BindSampler(ctx->Exec, (n[1].ui, n[2].ui));
             break;
@@ -8494,6 +8812,14 @@ execute_list(struct gl_context *ctx, GLuint list)
          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:
@@ -8505,6 +8831,18 @@ execute_list(struct gl_context *ctx, GLuint list)
             }
             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_UNIFORM_BLOCK_BINDING:
+            CALL_UniformBlockBinding(ctx->Exec, (n[1].ui, n[2].ui, n[3].ui));
+            break;
+
          case OPCODE_CONTINUE:
             n = (Node *) n[1].next;
             break;
@@ -9528,8 +9866,6 @@ exec_MultiModeDrawElementsIBM(const GLenum * mode,
                                   modestride));
 }
 
-
-
 /**
  * Setup the given dispatch table to point to Mesa's display list
  * building functions.
@@ -9539,7 +9875,7 @@ exec_MultiModeDrawElementsIBM(const GLenum * mode,
  * struct.
  */
 struct _glapi_table *
-_mesa_create_save_table(void)
+_mesa_create_save_table(const struct gl_context *ctx)
 {
    struct _glapi_table *table;
 
@@ -9547,7 +9883,7 @@ _mesa_create_save_table(void)
    if (table == NULL)
       return NULL;
 
-   _mesa_loopback_init_api_table(table);
+   _mesa_loopback_init_api_table(ctx, table);
 
    /* GL 1.0 */
    SET_Accum(table, save_Accum);
@@ -9895,7 +10231,6 @@ _mesa_create_save_table(void)
    SET_MultiModeDrawArraysIBM(table, exec_MultiModeDrawArraysIBM);
    SET_MultiModeDrawElementsIBM(table, exec_MultiModeDrawElementsIBM);
 
-#if FEATURE_NV_vertex_program
    /* 233. GL_NV_vertex_program */
    /* The following commands DO NOT go into display lists:
     * AreProgramsResidentNV, IsProgramNV, GenProgramsNV, DeleteProgramsNV,
@@ -9926,20 +10261,16 @@ _mesa_create_save_table(void)
    SET_ProgramParameters4fvNV(table, save_ProgramParameters4fvNV);
    SET_TrackMatrixNV(table, save_TrackMatrixNV);
    SET_VertexAttribPointerNV(table, _mesa_VertexAttribPointerNV);
-#endif
 
    /* 244. GL_ATI_envmap_bumpmap */
    SET_TexBumpParameterivATI(table, save_TexBumpParameterivATI);
    SET_TexBumpParameterfvATI(table, save_TexBumpParameterfvATI);
 
    /* 245. GL_ATI_fragment_shader */
-#if FEATURE_ATI_fragment_shader
    SET_BindFragmentShaderATI(table, save_BindFragmentShaderATI);
    SET_SetFragmentShaderConstantATI(table, save_SetFragmentShaderConstantATI);
-#endif
 
    /* 282. GL_NV_fragment_program */
-#if FEATURE_NV_fragment_program
    SET_ProgramNamedParameter4fNV(table, save_ProgramNamedParameter4fNV);
    SET_ProgramNamedParameter4dNV(table, save_ProgramNamedParameter4dNV);
    SET_ProgramNamedParameter4fvNV(table, save_ProgramNamedParameter4fvNV);
@@ -9956,7 +10287,6 @@ _mesa_create_save_table(void)
                                      _mesa_GetProgramLocalParameterdvARB);
    SET_GetProgramLocalParameterfvARB(table,
                                      _mesa_GetProgramLocalParameterfvARB);
-#endif
 
    /* 262. GL_NV_point_sprite */
    SET_PointParameteriNV(table, save_PointParameteriNV);
@@ -9971,6 +10301,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);
 
@@ -10004,7 +10356,6 @@ _mesa_create_save_table(void)
 
    /* ARB 26. GL_ARB_vertex_program */
    /* ARB 27. GL_ARB_fragment_program */
-#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
    /* glVertexAttrib* functions alias the NV ones, handled elsewhere */
    SET_VertexAttribPointerARB(table, _mesa_VertexAttribPointerARB);
    SET_EnableVertexAttribArrayARB(table, _mesa_EnableVertexAttribArrayARB);
@@ -10034,10 +10385,8 @@ _mesa_create_save_table(void)
                                      _mesa_GetProgramLocalParameterfvARB);
    SET_GetProgramivARB(table, _mesa_GetProgramivARB);
    SET_GetProgramStringARB(table, _mesa_GetProgramStringARB);
-#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);
@@ -10050,22 +10399,18 @@ _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);
-#endif
+   SET_QueryCounter(table, save_QueryCounter);
 
    SET_DrawBuffersARB(table, save_DrawBuffersARB);
 
-#if FEATURE_EXT_framebuffer_blit
    SET_BlitFramebufferEXT(table, save_BlitFramebufferEXT);
-#endif
 
    /* GL_ARB_shader_objects */
-   _mesa_init_shader_dispatch(table); /* Plug in glCreate/Delete/Get, etc */
+   _mesa_init_shader_dispatch(ctx, table); /* Plug in glCreate/Delete/Get, etc */
    SET_UseProgramObjectARB(table, save_UseProgramObjectARB);
    SET_Uniform1fARB(table, save_Uniform1fARB);
    SET_Uniform2fARB(table, save_Uniform2fARB);
@@ -10103,34 +10448,26 @@ _mesa_create_save_table(void)
    SET_BlendEquationSeparateEXT(table, save_BlendEquationSeparateEXT);
 
    /* GL_EXT_gpu_program_parameters */
-#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
    SET_ProgramEnvParameters4fvEXT(table, save_ProgramEnvParameters4fvEXT);
    SET_ProgramLocalParameters4fvEXT(table, save_ProgramLocalParameters4fvEXT);
-#endif
 
    /* ARB 50. GL_ARB_map_buffer_range */
-#if FEATURE_ARB_map_buffer_range
    SET_MapBufferRange(table, _mesa_MapBufferRange); /* no dlist save */
    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);
 
    /* 371. GL_APPLE_object_purgeable */
-#if FEATURE_APPLE_object_purgeable
    SET_ObjectPurgeableAPPLE(table, _mesa_ObjectPurgeableAPPLE);
    SET_ObjectUnpurgeableAPPLE(table, _mesa_ObjectUnpurgeableAPPLE);
-#endif
+   SET_GetObjectParameterivAPPLE(table, _mesa_GetObjectParameterivAPPLE);
 
    /* GL_EXT_texture_integer */
    SET_ClearColorIiEXT(table, save_ClearColorIi);
@@ -10173,6 +10510,26 @@ _mesa_create_save_table(void)
    (void) save_Uniform4uiv;
 #endif
 
+   /* 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);
+   SET_DrawTransformFeedbackStream(table, save_DrawTransformFeedbackStream);
+   SET_DrawTransformFeedbackInstanced(table,
+                                      save_DrawTransformFeedbackInstanced);
+   SET_DrawTransformFeedbackStreamInstanced(table,
+                                save_DrawTransformFeedbackStreamInstanced);
+   SET_BeginQueryIndexed(table, save_BeginQueryIndexed);
+   SET_EndQueryIndexed(table, save_EndQueryIndexed);
+
    /* GL_ARB_instanced_arrays */
    SET_VertexAttribDivisorARB(table, save_VertexAttribDivisor);
 
@@ -10197,11 +10554,34 @@ _mesa_create_save_table(void)
 
    /* 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_ARB_uniform_buffer_object */
+   SET_UniformBlockBinding(table, save_UniformBlockBinding);
+
+   /* GL_NV_primitive_restart */
+   SET_PrimitiveRestartIndexNV(table, _mesa_PrimitiveRestartIndex);
+
    return table;
 }
 
@@ -10563,6 +10943,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
@@ -10604,9 +10996,6 @@ void _mesa_init_dlist_dispatch(struct _glapi_table *disp)
 }
 
 
-#endif /* FEATURE_dlist */
-
-
 /**
  * Initialize display list state for given context.
  */
@@ -10634,9 +11023,7 @@ _mesa_init_display_list(struct gl_context *ctx)
    /* Display List group */
    ctx->List.ListBase = 0;
 
-#if FEATURE_dlist
    _mesa_save_vtxfmt_init(&ctx->ListState.ListVtxfmt);
-#endif
 }