dri_util: Update internal_format to GL_RGB8 for MESA_FORMAT_B8G8R8X8_UNORM
[mesa.git] / src / mesa / main / dlist.c
index cd8e3b6a2f20f438006ab16325fefb3219a8c12e..a780100e456535519875ce591a06badd1002aceb 100644 (file)
 
 #include "c99_math.h"
 #include "glheader.h"
-#include "imports.h"
+
 #include "api_arrayelt.h"
 #include "api_exec.h"
 #include "api_loopback.h"
-#include "api_validate.h"
+#include "draw_validate.h"
 #include "atifragshader.h"
 #include "config.h"
 #include "bufferobj.h"
 #include "main/dispatch.h"
 
 #include "vbo/vbo.h"
+#include "vbo/vbo_util.h"
+#include "util/format_r11g11b10f.h"
+
+#include "util/u_memory.h"
+
+#define USE_BITMAP_ATLAS 1
 
 
 
@@ -107,67 +113,66 @@ struct gl_list_extensions
  * Checks if dd_function_table::SaveNeedFlush is marked to flush
  * stored (save) vertices, and calls vbo_save_SaveFlushVertices if so.
  */
-#define SAVE_FLUSH_VERTICES(ctx)               \
-do {                                           \
-   if (ctx->Driver.SaveNeedFlush)              \
-      vbo_save_SaveFlushVertices(ctx);               \
-} while (0)
+#define SAVE_FLUSH_VERTICES(ctx)                     \
+   do {                                              \
+      if (ctx->Driver.SaveNeedFlush)                 \
+         vbo_save_SaveFlushVertices(ctx);            \
+   } while (0)
 
 
 /**
  * Macro to assert that the API call was made outside the
  * glBegin()/glEnd() pair, with return value.
- * 
+ *
  * \param ctx GL context.
  * \param retval value to return value in case the assertion fails.
  */
-#define ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval)         \
-do {                                                                   \
-   if (ctx->Driver.CurrentSavePrimitive <= PRIM_MAX) {                 \
-      _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glBegin/End" ); \
-      return retval;                                                   \
-   }                                                                   \
-} while (0)
+#define ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval)          \
+   do {                                                                 \
+      if (ctx->Driver.CurrentSavePrimitive <= PRIM_MAX) {               \
+         _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glBegin/End" ); \
+         return retval;                                                 \
+      }                                                                 \
+   } while (0)
 
 /**
  * Macro to assert that the API call was made outside the
  * glBegin()/glEnd() pair.
- * 
+ *
  * \param ctx GL context.
  */
-#define ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx)                             \
-do {                                                                   \
-   if (ctx->Driver.CurrentSavePrimitive <= PRIM_MAX) {                 \
-      _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glBegin/End" ); \
-      return;                                                          \
-   }                                                                   \
-} while (0)
+#define ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx)                              \
+   do {                                                                 \
+      if (ctx->Driver.CurrentSavePrimitive <= PRIM_MAX) {               \
+         _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glBegin/End" ); \
+         return;                                                        \
+      }                                                                 \
+   } while (0)
 
 /**
  * Macro to assert that the API call was made outside the
  * glBegin()/glEnd() pair and flush the vertices.
- * 
+ *
  * \param ctx GL context.
  */
-#define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx)                   \
-do {                                                                   \
-   ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx);                                 \
-   SAVE_FLUSH_VERTICES(ctx);                                           \
-} while (0)
+#define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx)                    \
+   do {                                                                 \
+      ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx);                               \
+      SAVE_FLUSH_VERTICES(ctx);                                         \
+   } while (0)
 
 /**
  * Macro to assert that the API call was made outside the
  * glBegin()/glEnd() pair and flush the vertices, with return value.
- * 
+ *
  * \param ctx GL context.
  * \param retval value to return value in case the assertion fails.
  */
-#define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, retval)\
-do {                                                                   \
-   ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval);             \
-   SAVE_FLUSH_VERTICES(ctx);                                           \
-} while (0)
-
+#define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, retval) \
+   do {                                                                 \
+      ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval);           \
+      SAVE_FLUSH_VERTICES(ctx);                                         \
+   } while (0)
 
 
 /**
@@ -194,7 +199,7 @@ typedef enum
    OPCODE_BLEND_FUNC_SEPARATE_I,
 
    OPCODE_CALL_LIST,
-   OPCODE_CALL_LIST_OFFSET,
+   OPCODE_CALL_LISTS,
    OPCODE_CLEAR,
    OPCODE_CLEAR_ACCUM,
    OPCODE_CLEAR_COLOR,
@@ -288,6 +293,15 @@ typedef enum
    OPCODE_TRANSLATE,
    OPCODE_VIEWPORT,
    OPCODE_WINDOW_POS,
+   /* ARB_viewport_array */
+   OPCODE_VIEWPORT_ARRAY_V,
+   OPCODE_VIEWPORT_INDEXED_F,
+   OPCODE_VIEWPORT_INDEXED_FV,
+   OPCODE_SCISSOR_ARRAY_V,
+   OPCODE_SCISSOR_INDEXED,
+   OPCODE_SCISSOR_INDEXED_V,
+   OPCODE_DEPTH_ARRAY_V,
+   OPCODE_DEPTH_INDEXED,
    /* GL_ARB_multitexture */
    OPCODE_ACTIVE_TEXTURE,
    /* GL_ARB_texture_compression */
@@ -301,8 +315,8 @@ typedef enum
    OPCODE_SAMPLE_COVERAGE,
    /* GL_ARB_window_pos */
    OPCODE_WINDOW_POS_ARB,
-   /* GL_NV_fragment_program */
-   OPCODE_BIND_PROGRAM_NV,
+   /* GL_ARB_vertex_program */
+   OPCODE_BIND_PROGRAM_ARB,
    OPCODE_PROGRAM_LOCAL_PARAMETER_ARB,
    /* GL_EXT_stencil_two_side */
    OPCODE_ACTIVE_STENCIL_FACE_EXT,
@@ -323,7 +337,8 @@ typedef enum
    OPCODE_STENCIL_FUNC_SEPARATE,
    OPCODE_STENCIL_OP_SEPARATE,
    OPCODE_STENCIL_MASK_SEPARATE,
-
+   /* GL_NV_primitive_restart */
+   OPCODE_PRIMITIVE_RESTART_NV,
    /* GL_ARB_shader_objects */
    OPCODE_USE_PROGRAM,
    OPCODE_UNIFORM_1F,
@@ -362,6 +377,64 @@ typedef enum
    OPCODE_UNIFORM_3UIV,
    OPCODE_UNIFORM_4UIV,
 
+   /* GL_ARB_gpu_shader_fp64 */
+   OPCODE_UNIFORM_1D,
+   OPCODE_UNIFORM_2D,
+   OPCODE_UNIFORM_3D,
+   OPCODE_UNIFORM_4D,
+   OPCODE_UNIFORM_1DV,
+   OPCODE_UNIFORM_2DV,
+   OPCODE_UNIFORM_3DV,
+   OPCODE_UNIFORM_4DV,
+   OPCODE_UNIFORM_MATRIX22D,
+   OPCODE_UNIFORM_MATRIX33D,
+   OPCODE_UNIFORM_MATRIX44D,
+   OPCODE_UNIFORM_MATRIX23D,
+   OPCODE_UNIFORM_MATRIX32D,
+   OPCODE_UNIFORM_MATRIX24D,
+   OPCODE_UNIFORM_MATRIX42D,
+   OPCODE_UNIFORM_MATRIX34D,
+   OPCODE_UNIFORM_MATRIX43D,
+
+   /* GL_ARB_gpu_shader_int64 */
+   OPCODE_UNIFORM_1I64,
+   OPCODE_UNIFORM_2I64,
+   OPCODE_UNIFORM_3I64,
+   OPCODE_UNIFORM_4I64,
+   OPCODE_UNIFORM_1I64V,
+   OPCODE_UNIFORM_2I64V,
+   OPCODE_UNIFORM_3I64V,
+   OPCODE_UNIFORM_4I64V,
+   OPCODE_UNIFORM_1UI64,
+   OPCODE_UNIFORM_2UI64,
+   OPCODE_UNIFORM_3UI64,
+   OPCODE_UNIFORM_4UI64,
+   OPCODE_UNIFORM_1UI64V,
+   OPCODE_UNIFORM_2UI64V,
+   OPCODE_UNIFORM_3UI64V,
+   OPCODE_UNIFORM_4UI64V,
+   OPCODE_PROGRAM_UNIFORM_1I64,
+   OPCODE_PROGRAM_UNIFORM_2I64,
+   OPCODE_PROGRAM_UNIFORM_3I64,
+   OPCODE_PROGRAM_UNIFORM_4I64,
+   OPCODE_PROGRAM_UNIFORM_1I64V,
+   OPCODE_PROGRAM_UNIFORM_2I64V,
+   OPCODE_PROGRAM_UNIFORM_3I64V,
+   OPCODE_PROGRAM_UNIFORM_4I64V,
+   OPCODE_PROGRAM_UNIFORM_1UI64,
+   OPCODE_PROGRAM_UNIFORM_2UI64,
+   OPCODE_PROGRAM_UNIFORM_3UI64,
+   OPCODE_PROGRAM_UNIFORM_4UI64,
+   OPCODE_PROGRAM_UNIFORM_1UI64V,
+   OPCODE_PROGRAM_UNIFORM_2UI64V,
+   OPCODE_PROGRAM_UNIFORM_3UI64V,
+   OPCODE_PROGRAM_UNIFORM_4UI64V,
+
+   /* OpenGL 4.0 / GL_ARB_tessellation_shader */
+   OPCODE_PATCH_PARAMETER_I,
+   OPCODE_PATCH_PARAMETER_FV_INNER,
+   OPCODE_PATCH_PARAMETER_FV_OUTER,
+
    /* OpenGL 4.2 / GL_ARB_separate_shader_objects */
    OPCODE_USE_PROGRAM_STAGES,
    OPCODE_PROGRAM_UNIFORM_1F,
@@ -372,6 +445,14 @@ typedef enum
    OPCODE_PROGRAM_UNIFORM_2FV,
    OPCODE_PROGRAM_UNIFORM_3FV,
    OPCODE_PROGRAM_UNIFORM_4FV,
+   OPCODE_PROGRAM_UNIFORM_1D,
+   OPCODE_PROGRAM_UNIFORM_2D,
+   OPCODE_PROGRAM_UNIFORM_3D,
+   OPCODE_PROGRAM_UNIFORM_4D,
+   OPCODE_PROGRAM_UNIFORM_1DV,
+   OPCODE_PROGRAM_UNIFORM_2DV,
+   OPCODE_PROGRAM_UNIFORM_3DV,
+   OPCODE_PROGRAM_UNIFORM_4DV,
    OPCODE_PROGRAM_UNIFORM_1I,
    OPCODE_PROGRAM_UNIFORM_2I,
    OPCODE_PROGRAM_UNIFORM_3I,
@@ -397,6 +478,15 @@ typedef enum
    OPCODE_PROGRAM_UNIFORM_MATRIX42F,
    OPCODE_PROGRAM_UNIFORM_MATRIX34F,
    OPCODE_PROGRAM_UNIFORM_MATRIX43F,
+   OPCODE_PROGRAM_UNIFORM_MATRIX22D,
+   OPCODE_PROGRAM_UNIFORM_MATRIX33D,
+   OPCODE_PROGRAM_UNIFORM_MATRIX44D,
+   OPCODE_PROGRAM_UNIFORM_MATRIX23D,
+   OPCODE_PROGRAM_UNIFORM_MATRIX32D,
+   OPCODE_PROGRAM_UNIFORM_MATRIX24D,
+   OPCODE_PROGRAM_UNIFORM_MATRIX42D,
+   OPCODE_PROGRAM_UNIFORM_MATRIX34D,
+   OPCODE_PROGRAM_UNIFORM_MATRIX43D,
 
    /* GL_ARB_clip_control */
    OPCODE_CLIP_CONTROL,
@@ -418,6 +508,15 @@ typedef enum
    OPCODE_ATTR_2F_ARB,
    OPCODE_ATTR_3F_ARB,
    OPCODE_ATTR_4F_ARB,
+   OPCODE_ATTR_1I,
+   OPCODE_ATTR_2I,
+   OPCODE_ATTR_3I,
+   OPCODE_ATTR_4I,
+   OPCODE_ATTR_1D,
+   OPCODE_ATTR_2D,
+   OPCODE_ATTR_3D,
+   OPCODE_ATTR_4D,
+   OPCODE_ATTR_1UI64,
    OPCODE_MATERIAL,
    OPCODE_BEGIN,
    OPCODE_END,
@@ -457,6 +556,9 @@ typedef enum
    OPCODE_SAMPLER_PARAMETERIIV,
    OPCODE_SAMPLER_PARAMETERUIV,
 
+   /* ARB_compute_shader */
+   OPCODE_DISPATCH_COMPUTE,
+
    /* GL_ARB_sync */
    OPCODE_WAIT_SYNC,
 
@@ -479,9 +581,82 @@ typedef enum
    /* ARB_uniform_buffer_object */
    OPCODE_UNIFORM_BLOCK_BINDING,
 
+   /* ARB_shader_subroutines */
+   OPCODE_UNIFORM_SUBROUTINES,
+
    /* EXT_polygon_offset_clamp */
    OPCODE_POLYGON_OFFSET_CLAMP,
 
+   /* EXT_window_rectangles */
+   OPCODE_WINDOW_RECTANGLES,
+
+   /* NV_conservative_raster */
+   OPCODE_SUBPIXEL_PRECISION_BIAS,
+
+   /* NV_conservative_raster_dilate */
+   OPCODE_CONSERVATIVE_RASTER_PARAMETER_F,
+
+   /* NV_conservative_raster_pre_snap_triangles */
+   OPCODE_CONSERVATIVE_RASTER_PARAMETER_I,
+
+   /* EXT_direct_state_access */
+   OPCODE_MATRIX_LOAD,
+   OPCODE_MATRIX_MULT,
+   OPCODE_MATRIX_ROTATE,
+   OPCODE_MATRIX_SCALE,
+   OPCODE_MATRIX_TRANSLATE,
+   OPCODE_MATRIX_LOAD_IDENTITY,
+   OPCODE_MATRIX_ORTHO,
+   OPCODE_MATRIX_FRUSTUM,
+   OPCODE_MATRIX_PUSH,
+   OPCODE_MATRIX_POP,
+   OPCODE_TEXTUREPARAMETER_F,
+   OPCODE_TEXTUREPARAMETER_I,
+   OPCODE_TEXTUREPARAMETER_II,
+   OPCODE_TEXTUREPARAMETER_IUI,
+   OPCODE_TEXTURE_IMAGE1D,
+   OPCODE_TEXTURE_IMAGE2D,
+   OPCODE_TEXTURE_IMAGE3D,
+   OPCODE_TEXTURE_SUB_IMAGE1D,
+   OPCODE_TEXTURE_SUB_IMAGE2D,
+   OPCODE_TEXTURE_SUB_IMAGE3D,
+   OPCODE_COPY_TEXTURE_IMAGE1D,
+   OPCODE_COPY_TEXTURE_IMAGE2D,
+   OPCODE_COPY_TEXTURE_SUB_IMAGE1D,
+   OPCODE_COPY_TEXTURE_SUB_IMAGE2D,
+   OPCODE_COPY_TEXTURE_SUB_IMAGE3D,
+   OPCODE_BIND_MULTITEXTURE,
+   OPCODE_MULTITEXPARAMETER_F,
+   OPCODE_MULTITEXPARAMETER_I,
+   OPCODE_MULTITEXPARAMETER_II,
+   OPCODE_MULTITEXPARAMETER_IUI,
+   OPCODE_MULTITEX_IMAGE1D,
+   OPCODE_MULTITEX_IMAGE2D,
+   OPCODE_MULTITEX_IMAGE3D,
+   OPCODE_MULTITEX_SUB_IMAGE1D,
+   OPCODE_MULTITEX_SUB_IMAGE2D,
+   OPCODE_MULTITEX_SUB_IMAGE3D,
+   OPCODE_COPY_MULTITEX_IMAGE1D,
+   OPCODE_COPY_MULTITEX_IMAGE2D,
+   OPCODE_COPY_MULTITEX_SUB_IMAGE1D,
+   OPCODE_COPY_MULTITEX_SUB_IMAGE2D,
+   OPCODE_COPY_MULTITEX_SUB_IMAGE3D,
+   OPCODE_MULTITEXENV,
+   OPCODE_COMPRESSED_TEXTURE_IMAGE_1D,
+   OPCODE_COMPRESSED_TEXTURE_IMAGE_2D,
+   OPCODE_COMPRESSED_TEXTURE_IMAGE_3D,
+   OPCODE_COMPRESSED_TEXTURE_SUB_IMAGE_1D,
+   OPCODE_COMPRESSED_TEXTURE_SUB_IMAGE_2D,
+   OPCODE_COMPRESSED_TEXTURE_SUB_IMAGE_3D,
+   OPCODE_COMPRESSED_MULTITEX_IMAGE_1D,
+   OPCODE_COMPRESSED_MULTITEX_IMAGE_2D,
+   OPCODE_COMPRESSED_MULTITEX_IMAGE_3D,
+   OPCODE_COMPRESSED_MULTITEX_SUB_IMAGE_1D,
+   OPCODE_COMPRESSED_MULTITEX_SUB_IMAGE_2D,
+   OPCODE_COMPRESSED_MULTITEX_SUB_IMAGE_3D,
+   OPCODE_NAMED_PROGRAM_STRING,
+   OPCODE_NAMED_PROGRAM_LOCAL_PARAMETER,
+
    /* The following three are meta instructions */
    OPCODE_ERROR,                /* raise compiled-in error */
    OPCODE_CONTINUE,
@@ -586,6 +761,42 @@ union uint64_pair
 };
 
 
+union float64_pair
+{
+   GLdouble d;
+   GLuint uint32[2];
+};
+
+union int64_pair
+{
+   GLint64 int64;
+   GLint int32[2];
+};
+
+#define ASSIGN_DOUBLE_TO_NODES(n, idx, value)                              \
+   do {                                                                    \
+      union float64_pair tmp;                                              \
+      tmp.d = value;                                                       \
+      n[idx].ui = tmp.uint32[0];                                           \
+      n[idx+1].ui = tmp.uint32[1];                                         \
+   } while (0)
+
+#define ASSIGN_UINT64_TO_NODES(n, idx, value)                              \
+   do {                                                                    \
+      union uint64_pair tmp;                                               \
+      tmp.uint64 = value;                                                  \
+      n[idx].ui = tmp.uint32[0];                                           \
+      n[idx+1].ui = tmp.uint32[1];                                         \
+   } while (0)
+
+#define ASSIGN_INT64_TO_NODES(n, idx, value)                               \
+   do {                                                                    \
+      union int64_pair tmp;                                                \
+      tmp.int64 = value;                                                   \
+      n[idx].i = tmp.int32[0];                                             \
+      n[idx+1].i = tmp.int32[1];                                           \
+   } while (0)
+
 /**
  * How many nodes to allocate at a time.  Note that bulk vertex data
  * from glBegin/glVertex/glEnd primitives will typically wind up in
@@ -605,9 +816,270 @@ static GLuint InstSize[OPCODE_END_OF_LIST + 1];
 void mesa_print_display_list(GLuint list);
 
 
+/**
+ * Does the given display list only contain a single glBitmap call?
+ */
+static bool
+is_bitmap_list(const struct gl_display_list *dlist)
+{
+   const Node *n = dlist->Head;
+   if (n[0].opcode == OPCODE_BITMAP) {
+      n += InstSize[OPCODE_BITMAP];
+      if (n[0].opcode == OPCODE_END_OF_LIST)
+         return true;
+   }
+   return false;
+}
+
+
+/**
+ * Is the given display list an empty list?
+ */
+static bool
+is_empty_list(const struct gl_display_list *dlist)
+{
+   const Node *n = dlist->Head;
+   return n[0].opcode == OPCODE_END_OF_LIST;
+}
+
+
+/**
+ * Delete/free a gl_bitmap_atlas.  Called during context tear-down.
+ */
+void
+_mesa_delete_bitmap_atlas(struct gl_context *ctx, struct gl_bitmap_atlas *atlas)
+{
+   if (atlas->texObj) {
+      ctx->Driver.DeleteTexture(ctx, atlas->texObj);
+   }
+   free(atlas->glyphs);
+   free(atlas);
+}
+
+
+/**
+ * Lookup a gl_bitmap_atlas by listBase ID.
+ */
+static struct gl_bitmap_atlas *
+lookup_bitmap_atlas(struct gl_context *ctx, GLuint listBase)
+{
+   struct gl_bitmap_atlas *atlas;
+
+   assert(listBase > 0);
+   atlas = _mesa_HashLookup(ctx->Shared->BitmapAtlas, listBase);
+   return atlas;
+}
+
+
+/**
+ * Create new bitmap atlas and insert into hash table.
+ */
+static struct gl_bitmap_atlas *
+alloc_bitmap_atlas(struct gl_context *ctx, GLuint listBase)
+{
+   struct gl_bitmap_atlas *atlas;
+
+   assert(listBase > 0);
+   assert(_mesa_HashLookup(ctx->Shared->BitmapAtlas, listBase) == NULL);
+
+   atlas = calloc(1, sizeof(*atlas));
+   if (atlas) {
+      _mesa_HashInsert(ctx->Shared->BitmapAtlas, listBase, atlas);
+   }
+
+   return atlas;
+}
+
+
+/**
+ * Try to build a bitmap atlas.  This involves examining a sequence of
+ * display lists which contain glBitmap commands and putting the bitmap
+ * images into a texture map (the atlas).
+ * If we succeed, gl_bitmap_atlas::complete will be set to true.
+ * If we fail, gl_bitmap_atlas::incomplete will be set to true.
+ */
+static void
+build_bitmap_atlas(struct gl_context *ctx, struct gl_bitmap_atlas *atlas,
+                   GLuint listBase)
+{
+   unsigned i, row_height = 0, xpos = 0, ypos = 0;
+   GLubyte *map;
+   GLint map_stride;
+
+   assert(atlas);
+   assert(!atlas->complete);
+   assert(atlas->numBitmaps > 0);
+
+   /* We use a rectangle texture (non-normalized coords) for the atlas */
+   assert(ctx->Extensions.NV_texture_rectangle);
+   assert(ctx->Const.MaxTextureRectSize >= 1024);
+
+   atlas->texWidth = 1024;
+   atlas->texHeight = 0;  /* determined below */
+
+   atlas->glyphs = malloc(atlas->numBitmaps * sizeof(atlas->glyphs[0]));
+   if (!atlas->glyphs) {
+      /* give up */
+      atlas->incomplete = true;
+      return;
+   }
+
+   /* Loop over the display lists.  They should all contain a single glBitmap
+    * call.  If not, bail out.  Also, compute the position and sizes of each
+    * bitmap in the atlas to determine the texture atlas size.
+    */
+   for (i = 0; i < atlas->numBitmaps; i++) {
+      const struct gl_display_list *list = _mesa_lookup_list(ctx, listBase + i);
+      const Node *n;
+      struct gl_bitmap_glyph *g = &atlas->glyphs[i];
+      unsigned bitmap_width, bitmap_height;
+      float bitmap_xmove, bitmap_ymove, bitmap_xorig, bitmap_yorig;
+
+      if (!list || is_empty_list(list)) {
+         /* stop here */
+         atlas->numBitmaps = i;
+         break;
+      }
+
+      if (!is_bitmap_list(list)) {
+         /* This list does not contain exactly one glBitmap command. Give up. */
+         atlas->incomplete = true;
+         return;
+      }
+
+      /* get bitmap info from the display list command */
+      n = list->Head;
+      assert(n[0].opcode == OPCODE_BITMAP);
+      bitmap_width = n[1].i;
+      bitmap_height = n[2].i;
+      bitmap_xorig = n[3].f;
+      bitmap_yorig = n[4].f;
+      bitmap_xmove = n[5].f;
+      bitmap_ymove = n[6].f;
+
+      if (xpos + bitmap_width > atlas->texWidth) {
+         /* advance to the next row of the texture */
+         xpos = 0;
+         ypos += row_height;
+         row_height = 0;
+      }
+
+      /* save the bitmap's position in the atlas */
+      g->x = xpos;
+      g->y = ypos;
+      g->w = bitmap_width;
+      g->h = bitmap_height;
+      g->xorig = bitmap_xorig;
+      g->yorig = bitmap_yorig;
+      g->xmove = bitmap_xmove;
+      g->ymove = bitmap_ymove;
+
+      xpos += bitmap_width;
+
+      /* keep track of tallest bitmap in the row */
+      row_height = MAX2(row_height, bitmap_height);
+   }
+
+   /* Now we know the texture height */
+   atlas->texHeight = ypos + row_height;
+
+   if (atlas->texHeight == 0) {
+      /* no glyphs found, give up */
+      goto fail;
+   }
+   else if (atlas->texHeight > ctx->Const.MaxTextureRectSize) {
+      /* too large, give up */
+      goto fail;
+   }
+
+   /* Create atlas texture (texture ID is irrelevant) */
+   atlas->texObj = ctx->Driver.NewTextureObject(ctx, 999, GL_TEXTURE_RECTANGLE);
+   if (!atlas->texObj) {
+      goto out_of_memory;
+   }
+
+   atlas->texObj->Sampler.MinFilter = GL_NEAREST;
+   atlas->texObj->Sampler.MagFilter = GL_NEAREST;
+   atlas->texObj->MaxLevel = 0;
+   atlas->texObj->Immutable = GL_TRUE;
+
+   atlas->texImage = _mesa_get_tex_image(ctx, atlas->texObj,
+                                         GL_TEXTURE_RECTANGLE, 0);
+   if (!atlas->texImage) {
+      goto out_of_memory;
+   }
+
+   if (ctx->Const.BitmapUsesRed)
+      _mesa_init_teximage_fields(ctx, atlas->texImage,
+                                 atlas->texWidth, atlas->texHeight, 1, 0,
+                                 GL_RED, MESA_FORMAT_R_UNORM8);
+   else
+      _mesa_init_teximage_fields(ctx, atlas->texImage,
+                                 atlas->texWidth, atlas->texHeight, 1, 0,
+                                 GL_ALPHA, MESA_FORMAT_A_UNORM8);
+
+   /* alloc image storage */
+   if (!ctx->Driver.AllocTextureImageBuffer(ctx, atlas->texImage)) {
+      goto out_of_memory;
+   }
+
+   /* map teximage, load with bitmap glyphs */
+   ctx->Driver.MapTextureImage(ctx, atlas->texImage, 0,
+                               0, 0, atlas->texWidth, atlas->texHeight,
+                               GL_MAP_WRITE_BIT, &map, &map_stride);
+   if (!map) {
+      goto out_of_memory;
+   }
+
+   /* Background/clear pixels are 0xff, foreground/set pixels are 0x0 */
+   memset(map, 0xff, map_stride * atlas->texHeight);
+
+   for (i = 0; i < atlas->numBitmaps; i++) {
+      const struct gl_display_list *list = _mesa_lookup_list(ctx, listBase + i);
+      const Node *n = list->Head;
+
+      assert(n[0].opcode == OPCODE_BITMAP ||
+             n[0].opcode == OPCODE_END_OF_LIST);
+
+      if (n[0].opcode == OPCODE_BITMAP) {
+         unsigned bitmap_width = n[1].i;
+         unsigned bitmap_height = n[2].i;
+         unsigned xpos = atlas->glyphs[i].x;
+         unsigned ypos = atlas->glyphs[i].y;
+         const void *bitmap_image = get_pointer(&n[7]);
+
+         assert(atlas->glyphs[i].w == bitmap_width);
+         assert(atlas->glyphs[i].h == bitmap_height);
+
+         /* put the bitmap image into the texture image */
+         _mesa_expand_bitmap(bitmap_width, bitmap_height,
+                             &ctx->DefaultPacking, bitmap_image,
+                             map + map_stride * ypos + xpos, /* dest addr */
+                             map_stride, 0x0);
+      }
+   }
+
+   ctx->Driver.UnmapTextureImage(ctx, atlas->texImage, 0);
+
+   atlas->complete = true;
+
+   return;
+
+out_of_memory:
+   _mesa_error(ctx, GL_OUT_OF_MEMORY, "Display list bitmap atlas");
+fail:
+   if (atlas->texObj) {
+      ctx->Driver.DeleteTexture(ctx, atlas->texObj);
+   }
+   free(atlas->glyphs);
+   atlas->glyphs = NULL;
+   atlas->incomplete = true;
+}
+
+
 /**
  * Allocate a gl_display_list object with an initial block of storage.
- * \param count  how many display list nodes/tokes to allocate
+ * \param count  how many display list nodes/tokens to allocate
  */
 static struct gl_display_list *
 make_list(GLuint name, GLuint count)
@@ -616,6 +1088,8 @@ make_list(GLuint name, GLuint count)
    dlist->Name = name;
    dlist->Head = malloc(sizeof(Node) * count);
    dlist->Head[0].opcode = OPCODE_END_OF_LIST;
+   /* All InstSize[] entries must be non-zero */
+   InstSize[OPCODE_END_OF_LIST] = 1;
    return dlist;
 }
 
@@ -700,80 +1174,69 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
             /* for some commands, we need to free malloc'd memory */
          case OPCODE_MAP1:
             free(get_pointer(&n[6]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_MAP2:
             free(get_pointer(&n[10]));
-            n += InstSize[n[0].opcode];
+            break;
+         case OPCODE_CALL_LISTS:
+            free(get_pointer(&n[3]));
             break;
          case OPCODE_DRAW_PIXELS:
             free(get_pointer(&n[5]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_BITMAP:
             free(get_pointer(&n[7]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_POLYGON_STIPPLE:
             free(get_pointer(&n[1]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_TEX_IMAGE1D:
             free(get_pointer(&n[8]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_TEX_IMAGE2D:
             free(get_pointer(&n[9]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_TEX_IMAGE3D:
             free(get_pointer(&n[10]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_TEX_SUB_IMAGE1D:
             free(get_pointer(&n[7]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_TEX_SUB_IMAGE2D:
             free(get_pointer(&n[9]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_TEX_SUB_IMAGE3D:
             free(get_pointer(&n[11]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_COMPRESSED_TEX_IMAGE_1D:
             free(get_pointer(&n[7]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_COMPRESSED_TEX_IMAGE_2D:
             free(get_pointer(&n[8]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_COMPRESSED_TEX_IMAGE_3D:
             free(get_pointer(&n[9]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D:
             free(get_pointer(&n[7]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D:
             free(get_pointer(&n[9]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D:
             free(get_pointer(&n[11]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_PROGRAM_STRING_ARB:
             free(get_pointer(&n[4]));      /* program string */
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_UNIFORM_1FV:
          case OPCODE_UNIFORM_2FV:
          case OPCODE_UNIFORM_3FV:
          case OPCODE_UNIFORM_4FV:
+         case OPCODE_UNIFORM_1DV:
+         case OPCODE_UNIFORM_2DV:
+         case OPCODE_UNIFORM_3DV:
+         case OPCODE_UNIFORM_4DV:
          case OPCODE_UNIFORM_1IV:
          case OPCODE_UNIFORM_2IV:
          case OPCODE_UNIFORM_3IV:
@@ -782,8 +1245,15 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
          case OPCODE_UNIFORM_2UIV:
          case OPCODE_UNIFORM_3UIV:
          case OPCODE_UNIFORM_4UIV:
+         case OPCODE_UNIFORM_1I64V:
+         case OPCODE_UNIFORM_2I64V:
+         case OPCODE_UNIFORM_3I64V:
+         case OPCODE_UNIFORM_4I64V:
+         case OPCODE_UNIFORM_1UI64V:
+         case OPCODE_UNIFORM_2UI64V:
+         case OPCODE_UNIFORM_3UI64V:
+         case OPCODE_UNIFORM_4UI64V:
             free(get_pointer(&n[3]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_UNIFORM_MATRIX22:
          case OPCODE_UNIFORM_MATRIX33:
@@ -794,13 +1264,25 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
          case OPCODE_UNIFORM_MATRIX32:
          case OPCODE_UNIFORM_MATRIX34:
          case OPCODE_UNIFORM_MATRIX43:
+         case OPCODE_UNIFORM_MATRIX22D:
+         case OPCODE_UNIFORM_MATRIX33D:
+         case OPCODE_UNIFORM_MATRIX44D:
+         case OPCODE_UNIFORM_MATRIX24D:
+         case OPCODE_UNIFORM_MATRIX42D:
+         case OPCODE_UNIFORM_MATRIX23D:
+         case OPCODE_UNIFORM_MATRIX32D:
+         case OPCODE_UNIFORM_MATRIX34D:
+         case OPCODE_UNIFORM_MATRIX43D:
             free(get_pointer(&n[4]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_PROGRAM_UNIFORM_1FV:
          case OPCODE_PROGRAM_UNIFORM_2FV:
          case OPCODE_PROGRAM_UNIFORM_3FV:
          case OPCODE_PROGRAM_UNIFORM_4FV:
+         case OPCODE_PROGRAM_UNIFORM_1DV:
+         case OPCODE_PROGRAM_UNIFORM_2DV:
+         case OPCODE_PROGRAM_UNIFORM_3DV:
+         case OPCODE_PROGRAM_UNIFORM_4DV:
          case OPCODE_PROGRAM_UNIFORM_1IV:
          case OPCODE_PROGRAM_UNIFORM_2IV:
          case OPCODE_PROGRAM_UNIFORM_3IV:
@@ -809,8 +1291,15 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
          case OPCODE_PROGRAM_UNIFORM_2UIV:
          case OPCODE_PROGRAM_UNIFORM_3UIV:
          case OPCODE_PROGRAM_UNIFORM_4UIV:
+         case OPCODE_PROGRAM_UNIFORM_1I64V:
+         case OPCODE_PROGRAM_UNIFORM_2I64V:
+         case OPCODE_PROGRAM_UNIFORM_3I64V:
+         case OPCODE_PROGRAM_UNIFORM_4I64V:
+         case OPCODE_PROGRAM_UNIFORM_1UI64V:
+         case OPCODE_PROGRAM_UNIFORM_2UI64V:
+         case OPCODE_PROGRAM_UNIFORM_3UI64V:
+         case OPCODE_PROGRAM_UNIFORM_4UI64V:
             free(get_pointer(&n[4]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_PROGRAM_UNIFORM_MATRIX22F:
          case OPCODE_PROGRAM_UNIFORM_MATRIX33F:
@@ -821,14 +1310,72 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
          case OPCODE_PROGRAM_UNIFORM_MATRIX32F:
          case OPCODE_PROGRAM_UNIFORM_MATRIX34F:
          case OPCODE_PROGRAM_UNIFORM_MATRIX43F:
+         case OPCODE_PROGRAM_UNIFORM_MATRIX22D:
+         case OPCODE_PROGRAM_UNIFORM_MATRIX33D:
+         case OPCODE_PROGRAM_UNIFORM_MATRIX44D:
+         case OPCODE_PROGRAM_UNIFORM_MATRIX24D:
+         case OPCODE_PROGRAM_UNIFORM_MATRIX42D:
+         case OPCODE_PROGRAM_UNIFORM_MATRIX23D:
+         case OPCODE_PROGRAM_UNIFORM_MATRIX32D:
+         case OPCODE_PROGRAM_UNIFORM_MATRIX34D:
+         case OPCODE_PROGRAM_UNIFORM_MATRIX43D:
             free(get_pointer(&n[5]));
-            n += InstSize[n[0].opcode];
             break;
          case OPCODE_PIXEL_MAP:
             free(get_pointer(&n[3]));
-            n += InstSize[n[0].opcode];
             break;
-
+         case OPCODE_VIEWPORT_ARRAY_V:
+         case OPCODE_SCISSOR_ARRAY_V:
+         case OPCODE_DEPTH_ARRAY_V:
+         case OPCODE_UNIFORM_SUBROUTINES:
+         case OPCODE_WINDOW_RECTANGLES:
+            free(get_pointer(&n[3]));
+            break;
+         case OPCODE_TEXTURE_IMAGE1D:
+         case OPCODE_MULTITEX_IMAGE1D:
+            free(get_pointer(&n[9]));
+            break;
+         case OPCODE_TEXTURE_IMAGE2D:
+         case OPCODE_MULTITEX_IMAGE2D:
+            free(get_pointer(&n[10]));
+            break;
+         case OPCODE_TEXTURE_IMAGE3D:
+         case OPCODE_MULTITEX_IMAGE3D:
+            free(get_pointer(&n[11]));
+            break;
+         case OPCODE_TEXTURE_SUB_IMAGE1D:
+         case OPCODE_MULTITEX_SUB_IMAGE1D:
+         case OPCODE_COMPRESSED_TEXTURE_SUB_IMAGE_1D:
+         case OPCODE_COMPRESSED_MULTITEX_SUB_IMAGE_1D:
+            free(get_pointer(&n[8]));
+            break;
+         case OPCODE_TEXTURE_SUB_IMAGE2D:
+         case OPCODE_MULTITEX_SUB_IMAGE2D:
+         case OPCODE_COMPRESSED_TEXTURE_SUB_IMAGE_2D:
+         case OPCODE_COMPRESSED_MULTITEX_SUB_IMAGE_2D:
+            free(get_pointer(&n[10]));
+            break;
+         case OPCODE_TEXTURE_SUB_IMAGE3D:
+         case OPCODE_MULTITEX_SUB_IMAGE3D:
+         case OPCODE_COMPRESSED_TEXTURE_SUB_IMAGE_3D:
+         case OPCODE_COMPRESSED_MULTITEX_SUB_IMAGE_3D:
+            free(get_pointer(&n[12]));
+            break;
+         case OPCODE_COMPRESSED_TEXTURE_IMAGE_1D:
+         case OPCODE_COMPRESSED_MULTITEX_IMAGE_1D:
+            free(get_pointer(&n[8]));
+            break;
+         case OPCODE_COMPRESSED_TEXTURE_IMAGE_2D:
+         case OPCODE_COMPRESSED_MULTITEX_IMAGE_2D:
+            free(get_pointer(&n[9]));
+            break;
+         case OPCODE_COMPRESSED_TEXTURE_IMAGE_3D:
+         case OPCODE_COMPRESSED_MULTITEX_IMAGE_3D:
+            free(get_pointer(&n[10]));
+            break;
+         case OPCODE_NAMED_PROGRAM_STRING:
+            free(get_pointer(&n[5]));
+            break;
          case OPCODE_CONTINUE:
             n = (Node *) get_pointer(&n[1]);
             free(block);
@@ -839,9 +1386,13 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
             done = GL_TRUE;
             break;
          default:
-            /* Most frequent case */
-            n += InstSize[n[0].opcode];
-            break;
+            /* just increment 'n' pointer, below */
+            ;
+         }
+
+         if (opcode != OPCODE_CONTINUE) {
+            assert(InstSize[opcode] > 0);
+            n += InstSize[opcode];
          }
       }
    }
@@ -851,6 +1402,30 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
 }
 
 
+/**
+ * Called by _mesa_HashWalk() to check if a display list which is being
+ * deleted belongs to a bitmap texture atlas.
+ */
+static void
+check_atlas_for_deleted_list(GLuint atlas_id, void *data, void *userData)
+{
+   struct gl_bitmap_atlas *atlas = (struct gl_bitmap_atlas *) data;
+   GLuint list_id = *((GLuint *) userData);  /* the list being deleted */
+
+   /* See if the list_id falls in the range contained in this texture atlas */
+   if (atlas->complete &&
+       list_id >= atlas_id &&
+       list_id < atlas_id + atlas->numBitmaps) {
+      /* Mark the atlas as incomplete so it doesn't get used.  But don't
+       * delete it yet since we don't want to try to recreate it in the next
+       * glCallLists.
+       */
+      atlas->complete = false;
+      atlas->incomplete = true;
+   }
+}
+
+
 /**
  * Destroy a display list and remove from hash table.
  * \param list - display list number
@@ -867,6 +1442,16 @@ destroy_list(struct gl_context *ctx, GLuint list)
    if (!dlist)
       return;
 
+   if (is_bitmap_list(dlist)) {
+      /* If we're destroying a simple glBitmap display list, there's a
+       * chance that we're destroying a bitmap image that's in a texture
+       * atlas.  Examine all atlases to see if that's the case.  There's
+       * usually few (if any) atlases so this isn't expensive.
+       */
+      _mesa_HashWalk(ctx->Shared->BitmapAtlas,
+                     check_atlas_for_deleted_list, &list);
+   }
+
    _mesa_delete_list(ctx, dlist);
    _mesa_HashRemove(ctx->Shared->DisplayList, list);
 }
@@ -952,7 +1537,7 @@ unpack_image(struct gl_context *ctx, GLuint dimensions,
       return NULL;
    }
 
-   if (!_mesa_is_bufferobj(unpack->BufferObj)) {
+   if (!unpack->BufferObj) {
       /* no PBO */
       GLvoid *image;
 
@@ -970,7 +1555,7 @@ unpack_image(struct gl_context *ctx, GLuint dimensions,
 
       map = (GLubyte *)
          ctx->Driver.MapBufferRange(ctx, 0, unpack->BufferObj->Size,
-                                   GL_MAP_READ_BIT, unpack->BufferObj,
+                                    GL_MAP_READ_BIT, unpack->BufferObj,
                                     MAP_INTERNAL);
       if (!map) {
          /* unable to map src buffer! */
@@ -1023,6 +1608,8 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes, bool align8)
    GLuint nopNode;
    Node *n;
 
+   assert(bytes <= BLOCK_SIZE * sizeof(Node));
+
    if (opcode < OPCODE_EXT_0) {
       if (InstSize[opcode] == 0) {
          /* save instruction size now */
@@ -1444,81 +2031,122 @@ 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)
+save_DrawArraysInstancedARB(UNUSED GLenum mode,
+                            UNUSED GLint first,
+                            UNUSED GLsizei count,
+                            UNUSED GLsizei primcount)
 {
    GET_CURRENT_CONTEXT(ctx);
    _mesa_error(ctx, GL_INVALID_OPERATION,
-              "glDrawArraysInstanced() during display list compile");
+               "glDrawArraysInstanced() during display list compile");
 }
 
 static void GLAPIENTRY
-save_DrawElementsInstancedARB(GLenum mode,
-                             GLsizei count,
-                             GLenum type,
-                             const GLvoid *indices,
-                             GLsizei primcount)
+save_DrawElementsInstancedARB(UNUSED GLenum mode,
+                              UNUSED GLsizei count,
+                              UNUSED GLenum type,
+                              UNUSED const GLvoid *indices,
+                              UNUSED GLsizei primcount)
 {
    GET_CURRENT_CONTEXT(ctx);
    _mesa_error(ctx, GL_INVALID_OPERATION,
-              "glDrawElementsInstanced() during display list compile");
+               "glDrawElementsInstanced() during display list compile");
 }
 
 static void GLAPIENTRY
-save_DrawElementsInstancedBaseVertexARB(GLenum mode,
-                                       GLsizei count,
-                                       GLenum type,
-                                       const GLvoid *indices,
-                                       GLsizei primcount,
-                                       GLint basevertex)
+save_DrawElementsInstancedBaseVertexARB(UNUSED GLenum mode,
+                                        UNUSED GLsizei count,
+                                        UNUSED GLenum type,
+                                        UNUSED const GLvoid *indices,
+                                        UNUSED GLsizei primcount,
+                                        UNUSED GLint basevertex)
 {
    GET_CURRENT_CONTEXT(ctx);
    _mesa_error(ctx, GL_INVALID_OPERATION,
-              "glDrawElementsInstancedBaseVertex() during display list compile");
+               "glDrawElementsInstancedBaseVertex() during display list compile");
 }
 
 /* GL_ARB_base_instance. */
 static void GLAPIENTRY
-save_DrawArraysInstancedBaseInstance(GLenum mode,
-                                     GLint first,
-                                     GLsizei count,
-                                     GLsizei primcount,
-                                     GLuint baseinstance)
+save_DrawArraysInstancedBaseInstance(UNUSED GLenum mode,
+                                     UNUSED GLint first,
+                                     UNUSED GLsizei count,
+                                     UNUSED GLsizei primcount,
+                                     UNUSED GLuint baseinstance)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+               "glDrawArraysInstancedBaseInstance() during display list compile");
+}
+
+static void APIENTRY
+save_DrawElementsInstancedBaseInstance(UNUSED GLenum mode,
+                                       UNUSED GLsizei count,
+                                       UNUSED GLenum type,
+                                       UNUSED const void *indices,
+                                       UNUSED GLsizei primcount,
+                                       UNUSED GLuint baseinstance)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+               "glDrawElementsInstancedBaseInstance() during display list compile");
+}
+
+static void APIENTRY
+save_DrawElementsInstancedBaseVertexBaseInstance(UNUSED GLenum mode,
+                                                 UNUSED GLsizei count,
+                                                 UNUSED GLenum type,
+                                                 UNUSED const void *indices,
+                                                 UNUSED GLsizei primcount,
+                                                 UNUSED GLint basevertex,
+                                                 UNUSED GLuint baseinstance)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+               "glDrawElementsInstancedBaseVertexBaseInstance() during display list compile");
+}
+
+static void APIENTRY
+save_DrawArraysIndirect(UNUSED GLenum mode,
+                        UNUSED const void *indirect)
 {
    GET_CURRENT_CONTEXT(ctx);
    _mesa_error(ctx, GL_INVALID_OPERATION,
-              "glDrawArraysInstancedBaseInstance() during display list compile");
+               "glDrawArraysIndirect() during display list compile");
 }
 
 static void APIENTRY
-save_DrawElementsInstancedBaseInstance(GLenum mode,
-                                       GLsizei count,
-                                       GLenum type,
-                                       const void *indices,
-                                       GLsizei primcount,
-                                       GLuint baseinstance)
+save_DrawElementsIndirect(UNUSED GLenum mode,
+                          UNUSED GLenum type,
+                          UNUSED const void *indirect)
 {
    GET_CURRENT_CONTEXT(ctx);
    _mesa_error(ctx, GL_INVALID_OPERATION,
-              "glDrawElementsInstancedBaseInstance() during display list compile");
+               "glDrawElementsIndirect() during display list compile");
 }
 
 static void APIENTRY
-save_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode,
-                                                 GLsizei count,
-                                                 GLenum type,
-                                                 const void *indices,
-                                                 GLsizei primcount,
-                                                 GLint basevertex,
-                                                 GLuint baseinstance)
+save_MultiDrawArraysIndirect(UNUSED GLenum mode,
+                             UNUSED const void *indirect,
+                             UNUSED GLsizei primcount,
+                             UNUSED GLsizei stride)
 {
    GET_CURRENT_CONTEXT(ctx);
    _mesa_error(ctx, GL_INVALID_OPERATION,
-              "glDrawElementsInstancedBaseVertexBaseInstance() during display list compile");
+               "glMultiDrawArraysIndirect() during display list compile");
 }
 
+static void APIENTRY
+save_MultiDrawElementsIndirect(UNUSED GLenum mode,
+                               UNUSED GLenum type,
+                               UNUSED const void *indirect,
+                               UNUSED GLsizei primcount,
+                               UNUSED GLsizei stride)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+               "glMultiDrawElementsIndirect() during display list compile");
+}
 
 /**
  * While building a display list we cache some OpenGL state.
@@ -1569,35 +2197,47 @@ static void GLAPIENTRY
 save_CallLists(GLsizei num, GLenum type, const GLvoid * lists)
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLint i;
-   GLboolean typeErrorFlag;
+   unsigned type_size;
+   Node *n;
+   void *lists_copy;
 
    SAVE_FLUSH_VERTICES(ctx);
 
    switch (type) {
    case GL_BYTE:
    case GL_UNSIGNED_BYTE:
+      type_size = 1;
+      break;
    case GL_SHORT:
    case GL_UNSIGNED_SHORT:
+   case GL_2_BYTES:
+      type_size = 2;
+      break;
+   case GL_3_BYTES:
+      type_size = 3;
+      break;
    case GL_INT:
    case GL_UNSIGNED_INT:
    case GL_FLOAT:
-   case GL_2_BYTES:
-   case GL_3_BYTES:
    case GL_4_BYTES:
-      typeErrorFlag = GL_FALSE;
+      type_size = 4;
       break;
    default:
-      typeErrorFlag = GL_TRUE;
+      type_size = 0;
    }
 
-   for (i = 0; i < num; i++) {
-      GLint list = translate_id(i, type, lists);
-      Node *n = alloc_instruction(ctx, OPCODE_CALL_LIST_OFFSET, 2);
-      if (n) {
-         n[1].i = list;
-         n[2].b = typeErrorFlag;
-      }
+   if (num > 0 && type_size > 0) {
+      /* create a copy of the array of list IDs to save in the display list */
+      lists_copy = memdup(lists, num * type_size);
+   } else {
+      lists_copy = NULL;
+   }
+
+   n = alloc_instruction(ctx, OPCODE_CALL_LISTS, 2 + POINTER_DWORDS);
+   if (n) {
+      n[1].i = num;
+      n[2].e = type;
+      save_pointer(&n[3], lists_copy);
    }
 
    /* After this, we don't know what state we're in.  Invalidate all
@@ -2302,6 +2942,7 @@ save_Fogiv(GLenum pname, const GLint *params)
    case GL_FOG_START:
    case GL_FOG_END:
    case GL_FOG_INDEX:
+   case GL_FOG_COORDINATE_SOURCE:
       p[0] = (GLfloat) *params;
       p[1] = 0.0f;
       p[2] = 0.0f;
@@ -2967,6 +3608,54 @@ save_Ortho(GLdouble left, GLdouble right,
 }
 
 
+static void GLAPIENTRY
+save_PatchParameteri(GLenum pname, const GLint value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PATCH_PARAMETER_I, 2);
+   if (n) {
+      n[1].e = pname;
+      n[2].i = value;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_PatchParameteri(ctx->Exec, (pname, value));
+   }
+}
+
+
+static void GLAPIENTRY
+save_PatchParameterfv(GLenum pname, const GLfloat *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+   if (pname == GL_PATCH_DEFAULT_OUTER_LEVEL) {
+      n = alloc_instruction(ctx, OPCODE_PATCH_PARAMETER_FV_OUTER, 5);
+   } else {
+      assert(pname == GL_PATCH_DEFAULT_INNER_LEVEL);
+      n = alloc_instruction(ctx, OPCODE_PATCH_PARAMETER_FV_INNER, 3);
+   }
+   if (n) {
+      n[1].e = pname;
+      if (pname == GL_PATCH_DEFAULT_OUTER_LEVEL) {
+         n[2].f = params[0];
+         n[3].f = params[1];
+         n[4].f = params[2];
+         n[5].f = params[3];
+      } else {
+         n[2].f = params[0];
+         n[3].f = params[1];
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_PatchParameterfv(ctx->Exec, (pname, params));
+   }
+}
+
+
 static void GLAPIENTRY
 save_PixelMapfv(GLenum map, GLint mapsize, const GLfloat *values)
 {
@@ -3181,14 +3870,6 @@ save_PolygonOffset(GLfloat factor, GLfloat units)
 }
 
 
-static void GLAPIENTRY
-save_PolygonOffsetEXT(GLfloat factor, GLfloat bias)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   /* XXX mult by DepthMaxF here??? */
-   save_PolygonOffset(factor, ctx->DrawBuffer->_DepthMaxF * bias);
-}
-
 static void GLAPIENTRY
 save_PolygonOffsetClampEXT(GLfloat factor, GLfloat units, GLfloat clamp)
 {
@@ -4181,37 +4862,185 @@ save_Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
    }
 }
 
-
 static void GLAPIENTRY
-save_WindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+save_ViewportIndexedf(GLuint index, GLfloat x, GLfloat y, GLfloat width,
+                      GLfloat height)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_WINDOW_POS, 4);
+   n = alloc_instruction(ctx, OPCODE_VIEWPORT_INDEXED_F, 5);
    if (n) {
-      n[1].f = x;
-      n[2].f = y;
-      n[3].f = z;
-      n[4].f = w;
+      n[1].ui = index;
+      n[2].f = x;
+      n[3].f = y;
+      n[4].f = width;
+      n[5].f = height;
    }
    if (ctx->ExecuteFlag) {
-      CALL_WindowPos4fMESA(ctx->Exec, (x, y, z, w));
+      CALL_ViewportIndexedf(ctx->Exec, (index, x, y, width, height));
    }
 }
 
 static void GLAPIENTRY
-save_WindowPos2dMESA(GLdouble x, GLdouble y)
+save_ViewportIndexedfv(GLuint index, const GLfloat *v)
 {
-   save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_VIEWPORT_INDEXED_FV, 5);
+   if (n) {
+      n[1].ui = index;
+      n[2].f = v[0];
+      n[3].f = v[1];
+      n[4].f = v[2];
+      n[5].f = v[3];
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ViewportIndexedfv(ctx->Exec, (index, v));
+   }
 }
 
 static void GLAPIENTRY
-save_WindowPos2fMESA(GLfloat x, GLfloat y)
+save_ViewportArrayv(GLuint first, GLsizei count, const GLfloat *v)
 {
-   save_WindowPos4fMESA(x, y, 0.0F, 1.0F);
-}
-
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_VIEWPORT_ARRAY_V, 2 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = first;
+      n[2].si = count;
+      save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLfloat)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ViewportArrayv(ctx->Exec, (first, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ScissorIndexed(GLuint index, GLint left, GLint bottom, GLsizei width,
+                    GLsizei height)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_SCISSOR_INDEXED, 5);
+   if (n) {
+      n[1].ui = index;
+      n[2].i = left;
+      n[3].i = bottom;
+      n[4].si = width;
+      n[5].si = height;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ScissorIndexed(ctx->Exec, (index, left, bottom, width, height));
+   }
+}
+
+static void GLAPIENTRY
+save_ScissorIndexedv(GLuint index, const GLint *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_SCISSOR_INDEXED_V, 5);
+   if (n) {
+      n[1].ui = index;
+      n[2].i = v[0];
+      n[3].i = v[1];
+      n[4].si = v[2];
+      n[5].si = v[3];
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ScissorIndexedv(ctx->Exec, (index, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ScissorArrayv(GLuint first, GLsizei count, const GLint *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_SCISSOR_ARRAY_V, 2 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = first;
+      n[2].si = count;
+      save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLint)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ScissorArrayv(ctx->Exec, (first, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_DepthRangeIndexed(GLuint index, GLclampd n, GLclampd f)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *node;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   node = alloc_instruction(ctx, OPCODE_DEPTH_INDEXED, 3);
+   if (node) {
+      node[1].ui = index;
+      /* Mesa stores these as floats internally so we deliberately convert
+       * them to a float here.
+       */
+      node[2].f = n;
+      node[3].f = f;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_DepthRangeIndexed(ctx->Exec, (index, n, f));
+   }
+}
+
+static void GLAPIENTRY
+save_DepthRangeArrayv(GLuint first, GLsizei count, const GLclampd *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_DEPTH_ARRAY_V, 2 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = first;
+      n[2].si = count;
+      save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLclampd)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_DepthRangeArrayv(ctx->Exec, (first, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_WindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_WINDOW_POS, 4);
+   if (n) {
+      n[1].f = x;
+      n[2].f = y;
+      n[3].f = z;
+      n[4].f = w;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_WindowPos4fMESA(ctx->Exec, (x, y, z, w));
+   }
+}
+
+static void GLAPIENTRY
+save_WindowPos2dMESA(GLdouble x, GLdouble y)
+{
+   save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
+}
+
+static void GLAPIENTRY
+save_WindowPos2fMESA(GLfloat x, GLfloat y)
+{
+   save_WindowPos4fMESA(x, y, 0.0F, 1.0F);
+}
+
 static void GLAPIENTRY
 save_WindowPos2iMESA(GLint x, GLint y)
 {
@@ -4649,15 +5478,15 @@ save_SampleCoverageARB(GLclampf value, GLboolean invert)
 
 
 /*
- * GL_NV_fragment_program
+ * GL_ARB_vertex_program
  */
 static void GLAPIENTRY
-save_BindProgramNV(GLenum target, GLuint id)
+save_BindProgramARB(GLenum target, GLuint id)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_BIND_PROGRAM_NV, 2);
+   n = alloc_instruction(ctx, OPCODE_BIND_PROGRAM_ARB, 2);
    if (n) {
       n[1].e = target;
       n[2].ui = id;
@@ -4700,7 +5529,7 @@ save_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
 
 static void GLAPIENTRY
 save_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
-                               const GLfloat * params)
+                                const GLfloat * params)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
@@ -4711,16 +5540,16 @@ save_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
       const GLfloat * p = params;
 
       for (i = 0 ; i < count ; i++) {
-        n = alloc_instruction(ctx, OPCODE_PROGRAM_ENV_PARAMETER_ARB, 6);
-        if (n) {
-           n[1].e = target;
-           n[2].ui = index;
-           n[3].f = p[0];
-           n[4].f = p[1];
-           n[5].f = p[2];
-           n[6].f = p[3];
-           p += 4;
-        }
+         n = alloc_instruction(ctx, OPCODE_PROGRAM_ENV_PARAMETER_ARB, 6);
+         if (n) {
+            n[1].e = target;
+            n[2].ui = index;
+            n[3].f = p[0];
+            n[4].f = p[1];
+            n[5].f = p[2];
+            n[6].f = p[3];
+            p += 4;
+         }
       }
    }
 
@@ -4797,7 +5626,7 @@ save_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
 
 static void GLAPIENTRY
 save_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
-                                 const GLfloat *params)
+                                  const GLfloat *params)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
@@ -4808,16 +5637,16 @@ save_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
       const GLfloat * p = params;
 
       for (i = 0 ; i < count ; i++) {
-        n = alloc_instruction(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6);
-        if (n) {
-           n[1].e = target;
-           n[2].ui = index;
-           n[3].f = p[0];
-           n[4].f = p[1];
-           n[5].f = p[2];
-           n[6].f = p[3];
-           p += 4;
-        }
+         n = alloc_instruction(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6);
+         if (n) {
+            n[1].e = target;
+            n[2].ui = index;
+            n[3].f = p[0];
+            n[4].f = p[1];
+            n[5].f = p[2];
+            n[6].f = p[3];
+            p += 4;
+         }
       }
    }
 
@@ -5072,188 +5901,6 @@ save_SetFragmentShaderConstantATI(GLuint dst, const GLfloat *value)
    }
 }
 
-static void GLAPIENTRY
-save_Attr1fNV(GLenum attr, GLfloat x)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   Node *n;
-   SAVE_FLUSH_VERTICES(ctx);
-   n = alloc_instruction(ctx, OPCODE_ATTR_1F_NV, 2);
-   if (n) {
-      n[1].e = attr;
-      n[2].f = x;
-   }
-
-   assert(attr < MAX_VERTEX_GENERIC_ATTRIBS);
-   ctx->ListState.ActiveAttribSize[attr] = 1;
-   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, 0, 0, 1);
-
-   if (ctx->ExecuteFlag) {
-      CALL_VertexAttrib1fNV(ctx->Exec, (attr, x));
-   }
-}
-
-static void GLAPIENTRY
-save_Attr2fNV(GLenum attr, GLfloat x, GLfloat y)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   Node *n;
-   SAVE_FLUSH_VERTICES(ctx);
-   n = alloc_instruction(ctx, OPCODE_ATTR_2F_NV, 3);
-   if (n) {
-      n[1].e = attr;
-      n[2].f = x;
-      n[3].f = y;
-   }
-
-   assert(attr < MAX_VERTEX_GENERIC_ATTRIBS);
-   ctx->ListState.ActiveAttribSize[attr] = 2;
-   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, 0, 1);
-
-   if (ctx->ExecuteFlag) {
-      CALL_VertexAttrib2fNV(ctx->Exec, (attr, x, y));
-   }
-}
-
-static void GLAPIENTRY
-save_Attr3fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   Node *n;
-   SAVE_FLUSH_VERTICES(ctx);
-   n = alloc_instruction(ctx, OPCODE_ATTR_3F_NV, 4);
-   if (n) {
-      n[1].e = attr;
-      n[2].f = x;
-      n[3].f = y;
-      n[4].f = z;
-   }
-
-   assert(attr < MAX_VERTEX_GENERIC_ATTRIBS);
-   ctx->ListState.ActiveAttribSize[attr] = 3;
-   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, 1);
-
-   if (ctx->ExecuteFlag) {
-      CALL_VertexAttrib3fNV(ctx->Exec, (attr, x, y, z));
-   }
-}
-
-static void GLAPIENTRY
-save_Attr4fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   Node *n;
-   SAVE_FLUSH_VERTICES(ctx);
-   n = alloc_instruction(ctx, OPCODE_ATTR_4F_NV, 5);
-   if (n) {
-      n[1].e = attr;
-      n[2].f = x;
-      n[3].f = y;
-      n[4].f = z;
-      n[5].f = w;
-   }
-
-   assert(attr < MAX_VERTEX_GENERIC_ATTRIBS);
-   ctx->ListState.ActiveAttribSize[attr] = 4;
-   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, w);
-
-   if (ctx->ExecuteFlag) {
-      CALL_VertexAttrib4fNV(ctx->Exec, (attr, x, y, z, w));
-   }
-}
-
-
-static void GLAPIENTRY
-save_Attr1fARB(GLenum attr, GLfloat x)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   Node *n;
-   SAVE_FLUSH_VERTICES(ctx);
-   n = alloc_instruction(ctx, OPCODE_ATTR_1F_ARB, 2);
-   if (n) {
-      n[1].e = attr;
-      n[2].f = x;
-   }
-
-   assert(attr < MAX_VERTEX_GENERIC_ATTRIBS);
-   ctx->ListState.ActiveAttribSize[attr] = 1;
-   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, 0, 0, 1);
-
-   if (ctx->ExecuteFlag) {
-      CALL_VertexAttrib1fARB(ctx->Exec, (attr, x));
-   }
-}
-
-static void GLAPIENTRY
-save_Attr2fARB(GLenum attr, GLfloat x, GLfloat y)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   Node *n;
-   SAVE_FLUSH_VERTICES(ctx);
-   n = alloc_instruction(ctx, OPCODE_ATTR_2F_ARB, 3);
-   if (n) {
-      n[1].e = attr;
-      n[2].f = x;
-      n[3].f = y;
-   }
-
-   assert(attr < MAX_VERTEX_GENERIC_ATTRIBS);
-   ctx->ListState.ActiveAttribSize[attr] = 2;
-   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, 0, 1);
-
-   if (ctx->ExecuteFlag) {
-      CALL_VertexAttrib2fARB(ctx->Exec, (attr, x, y));
-   }
-}
-
-static void GLAPIENTRY
-save_Attr3fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   Node *n;
-   SAVE_FLUSH_VERTICES(ctx);
-   n = alloc_instruction(ctx, OPCODE_ATTR_3F_ARB, 4);
-   if (n) {
-      n[1].e = attr;
-      n[2].f = x;
-      n[3].f = y;
-      n[4].f = z;
-   }
-
-   assert(attr < MAX_VERTEX_GENERIC_ATTRIBS);
-   ctx->ListState.ActiveAttribSize[attr] = 3;
-   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, 1);
-
-   if (ctx->ExecuteFlag) {
-      CALL_VertexAttrib3fARB(ctx->Exec, (attr, x, y, z));
-   }
-}
-
-static void GLAPIENTRY
-save_Attr4fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   Node *n;
-   SAVE_FLUSH_VERTICES(ctx);
-   n = alloc_instruction(ctx, OPCODE_ATTR_4F_ARB, 5);
-   if (n) {
-      n[1].e = attr;
-      n[2].f = x;
-      n[3].f = y;
-      n[4].f = z;
-      n[5].f = w;
-   }
-
-   assert(attr < MAX_VERTEX_GENERIC_ATTRIBS);
-   ctx->ListState.ActiveAttribSize[attr] = 4;
-   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, w);
-
-   if (ctx->ExecuteFlag) {
-      CALL_VertexAttrib4fARB(ctx->Exec, (attr, x, y, z, w));
-   }
-}
-
-
 static void GLAPIENTRY
 save_EvalCoord1f(GLfloat x)
 {
@@ -5329,24 +5976,6 @@ save_EvalPoint2(GLint x, GLint y)
    }
 }
 
-static void GLAPIENTRY
-save_Indexf(GLfloat x)
-{
-   save_Attr1fNV(VERT_ATTRIB_COLOR_INDEX, x);
-}
-
-static void GLAPIENTRY
-save_Indexfv(const GLfloat * v)
-{
-   save_Attr1fNV(VERT_ATTRIB_COLOR_INDEX, v[0]);
-}
-
-static void GLAPIENTRY
-save_EdgeFlag(GLboolean x)
-{
-   save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? 1.0f : 0.0f);
-}
-
 
 /**
  * Compare 'count' elements of vectors 'a' and 'b'.
@@ -5399,7 +6028,7 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
       _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(pname)");
       return;
    }
-   
+
    if (ctx->ExecuteFlag) {
       CALL_Materialfv(ctx->Exec, (face, pname, param));
    }
@@ -5453,25 +6082,9 @@ save_Begin(GLenum mode)
       _mesa_compile_error(ctx, GL_INVALID_OPERATION, "recursive glBegin");
    }
    else {
-      Node *n;
-
       ctx->Driver.CurrentSavePrimitive = mode;
 
-      /* Give the driver an opportunity to hook in an optimized
-       * display list compiler.
-       */
-      if (vbo_save_NotifyBegin(ctx, mode))
-         return;
-
-      SAVE_FLUSH_VERTICES(ctx);
-      n = alloc_instruction(ctx, OPCODE_BEGIN, 1);
-      if (n) {
-         n[1].e = mode;
-      }
-
-      if (ctx->ExecuteFlag) {
-         CALL_Begin(ctx->Exec, (mode));
-      }
+      vbo_save_NotifyBegin(ctx, mode, false);
    }
 }
 
@@ -5505,297 +6118,18 @@ save_Rectf(GLfloat a, GLfloat b, GLfloat c, GLfloat d)
    }
 }
 
-
 static void GLAPIENTRY
-save_Vertex2f(GLfloat x, GLfloat y)
+save_PrimitiveRestartNV(void)
 {
-   save_Attr2fNV(VERT_ATTRIB_POS, x, y);
+   /* Note: this is used when outside a glBegin/End pair in a display list */
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   (void) alloc_instruction(ctx, OPCODE_PRIMITIVE_RESTART_NV, 0);
+   if (ctx->ExecuteFlag) {
+      CALL_PrimitiveRestartNV(ctx->Exec, ());
+   }
 }
 
-static void GLAPIENTRY
-save_Vertex2fv(const GLfloat * v)
-{
-   save_Attr2fNV(VERT_ATTRIB_POS, v[0], v[1]);
-}
-
-static void GLAPIENTRY
-save_Vertex3f(GLfloat x, GLfloat y, GLfloat z)
-{
-   save_Attr3fNV(VERT_ATTRIB_POS, x, y, z);
-}
-
-static void GLAPIENTRY
-save_Vertex3fv(const GLfloat * v)
-{
-   save_Attr3fNV(VERT_ATTRIB_POS, v[0], v[1], v[2]);
-}
-
-static void GLAPIENTRY
-save_Vertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-   save_Attr4fNV(VERT_ATTRIB_POS, x, y, z, w);
-}
-
-static void GLAPIENTRY
-save_Vertex4fv(const GLfloat * v)
-{
-   save_Attr4fNV(VERT_ATTRIB_POS, v[0], v[1], v[2], v[3]);
-}
-
-static void GLAPIENTRY
-save_TexCoord1f(GLfloat x)
-{
-   save_Attr1fNV(VERT_ATTRIB_TEX0, x);
-}
-
-static void GLAPIENTRY
-save_TexCoord1fv(const GLfloat * v)
-{
-   save_Attr1fNV(VERT_ATTRIB_TEX0, v[0]);
-}
-
-static void GLAPIENTRY
-save_TexCoord2f(GLfloat x, GLfloat y)
-{
-   save_Attr2fNV(VERT_ATTRIB_TEX0, x, y);
-}
-
-static void GLAPIENTRY
-save_TexCoord2fv(const GLfloat * v)
-{
-   save_Attr2fNV(VERT_ATTRIB_TEX0, v[0], v[1]);
-}
-
-static void GLAPIENTRY
-save_TexCoord3f(GLfloat x, GLfloat y, GLfloat z)
-{
-   save_Attr3fNV(VERT_ATTRIB_TEX0, x, y, z);
-}
-
-static void GLAPIENTRY
-save_TexCoord3fv(const GLfloat * v)
-{
-   save_Attr3fNV(VERT_ATTRIB_TEX0, v[0], v[1], v[2]);
-}
-
-static void GLAPIENTRY
-save_TexCoord4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-   save_Attr4fNV(VERT_ATTRIB_TEX0, x, y, z, w);
-}
-
-static void GLAPIENTRY
-save_TexCoord4fv(const GLfloat * v)
-{
-   save_Attr4fNV(VERT_ATTRIB_TEX0, v[0], v[1], v[2], v[3]);
-}
-
-static void GLAPIENTRY
-save_Normal3f(GLfloat x, GLfloat y, GLfloat z)
-{
-   save_Attr3fNV(VERT_ATTRIB_NORMAL, x, y, z);
-}
-
-static void GLAPIENTRY
-save_Normal3fv(const GLfloat * v)
-{
-   save_Attr3fNV(VERT_ATTRIB_NORMAL, v[0], v[1], v[2]);
-}
-
-static void GLAPIENTRY
-save_FogCoordfEXT(GLfloat x)
-{
-   save_Attr1fNV(VERT_ATTRIB_FOG, x);
-}
-
-static void GLAPIENTRY
-save_FogCoordfvEXT(const GLfloat * v)
-{
-   save_Attr1fNV(VERT_ATTRIB_FOG, v[0]);
-}
-
-static void GLAPIENTRY
-save_Color3f(GLfloat x, GLfloat y, GLfloat z)
-{
-   save_Attr3fNV(VERT_ATTRIB_COLOR0, x, y, z);
-}
-
-static void GLAPIENTRY
-save_Color3fv(const GLfloat * v)
-{
-   save_Attr3fNV(VERT_ATTRIB_COLOR0, v[0], v[1], v[2]);
-}
-
-static void GLAPIENTRY
-save_Color4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-   save_Attr4fNV(VERT_ATTRIB_COLOR0, x, y, z, w);
-}
-
-static void GLAPIENTRY
-save_Color4fv(const GLfloat * v)
-{
-   save_Attr4fNV(VERT_ATTRIB_COLOR0, v[0], v[1], v[2], v[3]);
-}
-
-static void GLAPIENTRY
-save_SecondaryColor3fEXT(GLfloat x, GLfloat y, GLfloat z)
-{
-   save_Attr3fNV(VERT_ATTRIB_COLOR1, x, y, z);
-}
-
-static void GLAPIENTRY
-save_SecondaryColor3fvEXT(const GLfloat * v)
-{
-   save_Attr3fNV(VERT_ATTRIB_COLOR1, v[0], v[1], v[2]);
-}
-
-
-/* Just call the respective ATTR for texcoord
- */
-static void GLAPIENTRY
-save_MultiTexCoord1f(GLenum target, GLfloat x)
-{
-   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
-   save_Attr1fNV(attr, x);
-}
-
-static void GLAPIENTRY
-save_MultiTexCoord1fv(GLenum target, const GLfloat * v)
-{
-   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
-   save_Attr1fNV(attr, v[0]);
-}
-
-static void GLAPIENTRY
-save_MultiTexCoord2f(GLenum target, GLfloat x, GLfloat y)
-{
-   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
-   save_Attr2fNV(attr, x, y);
-}
-
-static void GLAPIENTRY
-save_MultiTexCoord2fv(GLenum target, const GLfloat * v)
-{
-   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
-   save_Attr2fNV(attr, v[0], v[1]);
-}
-
-static void GLAPIENTRY
-save_MultiTexCoord3f(GLenum target, GLfloat x, GLfloat y, GLfloat z)
-{
-   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
-   save_Attr3fNV(attr, x, y, z);
-}
-
-static void GLAPIENTRY
-save_MultiTexCoord3fv(GLenum target, const GLfloat * v)
-{
-   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
-   save_Attr3fNV(attr, v[0], v[1], v[2]);
-}
-
-static void GLAPIENTRY
-save_MultiTexCoord4f(GLenum target, GLfloat x, GLfloat y,
-                     GLfloat z, GLfloat w)
-{
-   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
-   save_Attr4fNV(attr, x, y, z, w);
-}
-
-static void GLAPIENTRY
-save_MultiTexCoord4fv(GLenum target, const GLfloat * v)
-{
-   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
-   save_Attr4fNV(attr, v[0], v[1], v[2], v[3]);
-}
-
-
-/**
- * Record a GL_INVALID_VALUE error when a invalid vertex attribute
- * index is found.
- */
-static void
-index_error(void)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   _mesa_error(ctx, GL_INVALID_VALUE, "VertexAttribf(index)");
-}
-
-
-
-static void GLAPIENTRY
-save_VertexAttrib1fARB(GLuint index, GLfloat x)
-{
-   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
-      save_Attr1fARB(index, x);
-   else
-      index_error();
-}
-
-static void GLAPIENTRY
-save_VertexAttrib1fvARB(GLuint index, const GLfloat * v)
-{
-   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
-      save_Attr1fARB(index, v[0]);
-   else
-      index_error();
-}
-
-static void GLAPIENTRY
-save_VertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y)
-{
-   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
-      save_Attr2fARB(index, x, y);
-   else
-      index_error();
-}
-
-static void GLAPIENTRY
-save_VertexAttrib2fvARB(GLuint index, const GLfloat * v)
-{
-   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
-      save_Attr2fARB(index, v[0], v[1]);
-   else
-      index_error();
-}
-
-static void GLAPIENTRY
-save_VertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z)
-{
-   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
-      save_Attr3fARB(index, x, y, z);
-   else
-      index_error();
-}
-
-static void GLAPIENTRY
-save_VertexAttrib3fvARB(GLuint index, const GLfloat * v)
-{
-   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
-      save_Attr3fARB(index, v[0], v[1], v[2]);
-   else
-      index_error();
-}
-
-static void GLAPIENTRY
-save_VertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z,
-                       GLfloat w)
-{
-   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
-      save_Attr4fARB(index, x, y, z, w);
-   else
-      index_error();
-}
-
-static void GLAPIENTRY
-save_VertexAttrib4fvARB(GLuint index, const GLfloat * v)
-{
-   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
-      save_Attr4fARB(index, v[0], v[1], v[2], v[3]);
-   else
-      index_error();
-}
 
 static void GLAPIENTRY
 save_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
@@ -5982,6 +6316,198 @@ save_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name,
    }
 }
 
+static void GLAPIENTRY
+save_DispatchCompute(GLuint num_groups_x, GLuint num_groups_y,
+                     GLuint num_groups_z)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_DISPATCH_COMPUTE, 3);
+   if (n) {
+      n[1].ui = num_groups_x;
+      n[2].ui = num_groups_y;
+      n[3].ui = num_groups_z;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_DispatchCompute(ctx->Exec, (num_groups_x, num_groups_y,
+                                       num_groups_z));
+   }
+}
+
+static void GLAPIENTRY
+save_DispatchComputeIndirect(GLintptr indirect)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+               "glDispatchComputeIndirect() during display list compile");
+}
+
+static void ALWAYS_INLINE
+save_Attr32bit(struct gl_context *ctx, unsigned attr, unsigned size,
+               GLenum type, uint32_t x, uint32_t y, uint32_t z, uint32_t w)
+{
+   Node *n;
+   SAVE_FLUSH_VERTICES(ctx);
+   unsigned base_op;
+   unsigned index = attr;
+
+   /* We don't care about GL_INT vs GL_UNSIGNED_INT. The idea is to get W=1
+    * right for 3 or lower number of components, so only distinguish between
+    * FLOAT and INT.
+    */
+   if (type == GL_FLOAT) {
+      if (attr >= VERT_ATTRIB_GENERIC0) {
+         base_op = OPCODE_ATTR_1F_ARB;
+         attr -= VERT_ATTRIB_GENERIC0;
+      } else {
+         base_op = OPCODE_ATTR_1F_NV;
+      }
+   } else {
+      base_op = OPCODE_ATTR_1I;
+      attr -= VERT_ATTRIB_GENERIC0;
+   }
+
+   n = alloc_instruction(ctx, base_op + size - 1, 1 + size);
+   if (n) {
+      n[1].ui = attr;
+      n[2].ui = x;
+      if (size >= 2) n[3].ui = y;
+      if (size >= 3) n[4].ui = z;
+      if (size >= 4) n[5].ui = w;
+   }
+
+   ctx->ListState.ActiveAttribSize[index] = size;
+   ASSIGN_4V(ctx->ListState.CurrentAttrib[index], x, y, z, w);
+
+   if (ctx->ExecuteFlag) {
+      if (type == GL_FLOAT) {
+         if (base_op == OPCODE_ATTR_1F_NV) {
+            if (size == 4)
+               CALL_VertexAttrib4fNV(ctx->Exec, (attr, uif(x), uif(y), uif(z), uif(w)));
+            else if (size == 3)
+               CALL_VertexAttrib3fNV(ctx->Exec, (attr, uif(x), uif(y), uif(z)));
+            else if (size == 2)
+               CALL_VertexAttrib2fNV(ctx->Exec, (attr, uif(x), uif(y)));
+            else
+               CALL_VertexAttrib1fNV(ctx->Exec, (attr, uif(x)));
+         } else {
+            if (size == 4)
+               CALL_VertexAttrib4fARB(ctx->Exec, (attr, uif(x), uif(y), uif(z), uif(w)));
+            else if (size == 3)
+               CALL_VertexAttrib3fARB(ctx->Exec, (attr, uif(x), uif(y), uif(z)));
+            else if (size == 2)
+               CALL_VertexAttrib2fARB(ctx->Exec, (attr, uif(x), uif(y)));
+            else
+               CALL_VertexAttrib1fARB(ctx->Exec, (attr, uif(x)));
+         }
+      } else {
+         if (size == 4)
+            CALL_VertexAttribI4iEXT(ctx->Exec, (attr, x, y, z, w));
+         else if (size == 3)
+            CALL_VertexAttribI3iEXT(ctx->Exec, (attr, x, y, z));
+         else if (size == 2)
+            CALL_VertexAttribI2iEXT(ctx->Exec, (attr, x, y));
+         else
+            CALL_VertexAttribI1iEXT(ctx->Exec, (attr, x));
+      }
+   }
+}
+
+static void ALWAYS_INLINE
+save_Attr64bit(struct gl_context *ctx, unsigned attr, unsigned size,
+               GLenum type, uint64_t x, uint64_t y, uint64_t z, uint64_t w)
+{
+   Node *n;
+   SAVE_FLUSH_VERTICES(ctx);
+   unsigned base_op;
+   unsigned index = attr;
+
+   if (type == GL_DOUBLE) {
+      base_op = OPCODE_ATTR_1D;
+   } else {
+      base_op = OPCODE_ATTR_1UI64;
+      assert(size == 1);
+   }
+
+   attr -= VERT_ATTRIB_GENERIC0;
+   n = alloc_instruction(ctx, base_op + size - 1, 1 + size * 2);
+   if (n) {
+      n[1].ui = attr;
+      ASSIGN_UINT64_TO_NODES(n, 2, x);
+      if (size >= 2) ASSIGN_UINT64_TO_NODES(n, 4, y);
+      if (size >= 3) ASSIGN_UINT64_TO_NODES(n, 6, z);
+      if (size >= 4) ASSIGN_UINT64_TO_NODES(n, 8, w);
+   }
+
+   ctx->ListState.ActiveAttribSize[index] = size;
+   memcpy(ctx->ListState.CurrentAttrib[index], &n[2], size * sizeof(uint64_t));
+
+   if (ctx->ExecuteFlag) {
+      uint64_t v[] = {x, y, z, w};
+      if (type == GL_DOUBLE) {
+         if (size == 4)
+            CALL_VertexAttribL4dv(ctx->Exec, (attr, (GLdouble*)v));
+         else if (size == 3)
+            CALL_VertexAttribL3dv(ctx->Exec, (attr, (GLdouble*)v));
+         else if (size == 2)
+            CALL_VertexAttribL2dv(ctx->Exec, (attr, (GLdouble*)v));
+         else
+            CALL_VertexAttribL1d(ctx->Exec, (attr, UINT64_AS_DOUBLE(x)));
+      } else {
+         CALL_VertexAttribL1ui64ARB(ctx->Exec, (attr, x));
+      }
+   }
+}
+
+/**
+ * If index=0, does glVertexAttrib*() alias glVertex() to emit a vertex?
+ * It depends on a few things, including whether we're inside or outside
+ * of glBegin/glEnd.
+ */
+static inline bool
+is_vertex_position(const struct gl_context *ctx, GLuint index)
+{
+   return (index == 0 &&
+           _mesa_attr_zero_aliases_vertex(ctx) &&
+           _mesa_inside_dlist_begin_end(ctx));
+}
+
+/**
+ * This macro is used to implement all the glVertex, glColor, glTexCoord,
+ * glVertexAttrib, etc functions.
+ * \param A  VBO_ATTRIB_x attribute index
+ * \param N  attribute size (1..4)
+ * \param T  type (GL_FLOAT, GL_DOUBLE, GL_INT, GL_UNSIGNED_INT)
+ * \param C  cast type (uint32_t or uint64_t)
+ * \param V0, V1, v2, V3  attribute value
+ */
+#define ATTR_UNION(A, N, T, C, V0, V1, V2, V3)                          \
+do {                                                                    \
+   if (sizeof(C) == 4) {                                                \
+      save_Attr32bit(ctx, A, N, T, V0, V1, V2, V3);                     \
+   } else {                                                             \
+      save_Attr64bit(ctx, A, N, T, V0, V1, V2, V3);                     \
+   }                                                                    \
+} while (0)
+
+#undef ERROR
+#define ERROR(err) _mesa_error(ctx, err, __func__)
+#define TAG(x) save_##x
+
+#define VBO_ATTRIB_POS           VERT_ATTRIB_POS
+#define VBO_ATTRIB_NORMAL        VERT_ATTRIB_NORMAL
+#define VBO_ATTRIB_COLOR0        VERT_ATTRIB_COLOR0
+#define VBO_ATTRIB_COLOR1        VERT_ATTRIB_COLOR1
+#define VBO_ATTRIB_FOG           VERT_ATTRIB_FOG
+#define VBO_ATTRIB_COLOR_INDEX   VERT_ATTRIB_COLOR_INDEX
+#define VBO_ATTRIB_EDGEFLAG      VERT_ATTRIB_EDGEFLAG
+#define VBO_ATTRIB_TEX0          VERT_ATTRIB_TEX0
+#define VBO_ATTRIB_GENERIC0      VERT_ATTRIB_GENERIC0
+#define VBO_ATTRIB_MAX           VERT_ATTRIB_MAX
+
+#include "vbo/vbo_attrib_tmp.h"
+
 static void GLAPIENTRY
 save_UseProgram(GLuint program)
 {
@@ -6142,118 +6668,264 @@ save_Uniform4fvARB(GLint location, GLsizei count, const GLfloat *v)
 
 
 static void GLAPIENTRY
-save_Uniform1iARB(GLint location, GLint x)
+save_Uniform1d(GLint location, GLdouble x)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_UNIFORM_1I, 2);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_1D, 3);
    if (n) {
       n[1].i = location;
-      n[2].i = x;
+      ASSIGN_DOUBLE_TO_NODES(n, 2, x);
    }
    if (ctx->ExecuteFlag) {
-      CALL_Uniform1i(ctx->Exec, (location, x));
+      CALL_Uniform1d(ctx->Exec, (location, x));
    }
 }
 
+
 static void GLAPIENTRY
-save_Uniform2iARB(GLint location, GLint x, GLint y)
+save_Uniform2d(GLint location, GLdouble x, GLdouble y)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_UNIFORM_2I, 3);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_2D, 5);
    if (n) {
       n[1].i = location;
-      n[2].i = x;
-      n[3].i = y;
+      ASSIGN_DOUBLE_TO_NODES(n, 2, x);
+      ASSIGN_DOUBLE_TO_NODES(n, 4, y);
    }
    if (ctx->ExecuteFlag) {
-      CALL_Uniform2i(ctx->Exec, (location, x, y));
+      CALL_Uniform2d(ctx->Exec, (location, x, y));
    }
 }
 
+
 static void GLAPIENTRY
-save_Uniform3iARB(GLint location, GLint x, GLint y, GLint z)
+save_Uniform3d(GLint location, GLdouble x, GLdouble y, GLdouble z)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_UNIFORM_3I, 4);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_3D, 7);
    if (n) {
       n[1].i = location;
-      n[2].i = x;
-      n[3].i = y;
-      n[4].i = z;
+      ASSIGN_DOUBLE_TO_NODES(n, 2, x);
+      ASSIGN_DOUBLE_TO_NODES(n, 4, y);
+      ASSIGN_DOUBLE_TO_NODES(n, 6, z);
    }
    if (ctx->ExecuteFlag) {
-      CALL_Uniform3i(ctx->Exec, (location, x, y, z));
+      CALL_Uniform3d(ctx->Exec, (location, x, y, z));
    }
 }
 
+
 static void GLAPIENTRY
-save_Uniform4iARB(GLint location, GLint x, GLint y, GLint z, GLint w)
+save_Uniform4d(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_UNIFORM_4I, 5);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_4D, 9);
    if (n) {
       n[1].i = location;
-      n[2].i = x;
-      n[3].i = y;
-      n[4].i = z;
-      n[5].i = w;
+      ASSIGN_DOUBLE_TO_NODES(n, 2, x);
+      ASSIGN_DOUBLE_TO_NODES(n, 4, y);
+      ASSIGN_DOUBLE_TO_NODES(n, 6, z);
+      ASSIGN_DOUBLE_TO_NODES(n, 8, w);
    }
    if (ctx->ExecuteFlag) {
-      CALL_Uniform4i(ctx->Exec, (location, x, y, z, w));
+      CALL_Uniform4d(ctx->Exec, (location, x, y, z, w));
    }
 }
 
 
-
 static void GLAPIENTRY
-save_Uniform1ivARB(GLint location, GLsizei count, const GLint *v)
+save_Uniform1dv(GLint location, GLsizei count, const GLdouble *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_UNIFORM_1IV, 2 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_1DV, 2 + POINTER_DWORDS);
    if (n) {
       n[1].i = location;
       n[2].i = count;
-      save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLint)));
+      save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLdouble)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_Uniform1iv(ctx->Exec, (location, count, v));
+      CALL_Uniform1dv(ctx->Exec, (location, count, v));
    }
 }
 
+
 static void GLAPIENTRY
-save_Uniform2ivARB(GLint location, GLsizei count, const GLint *v)
+save_Uniform2dv(GLint location, GLsizei count, const GLdouble *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_UNIFORM_2IV, 2 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_2DV, 2 + POINTER_DWORDS);
    if (n) {
       n[1].i = location;
       n[2].i = count;
-      save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLint)));
+      save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLdouble)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_Uniform2iv(ctx->Exec, (location, count, v));
+      CALL_Uniform2dv(ctx->Exec, (location, count, v));
    }
 }
 
+
 static void GLAPIENTRY
-save_Uniform3ivARB(GLint location, GLsizei count, const GLint *v)
+save_Uniform3dv(GLint location, GLsizei count, const GLdouble *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_UNIFORM_3IV, 2 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_3DV, 2 + POINTER_DWORDS);
+   if (n) {
+      n[1].i = location;
+      n[2].i = count;
+      save_pointer(&n[3], memdup(v, count * 3 * sizeof(GLdouble)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_Uniform3dv(ctx->Exec, (location, count, v));
+   }
+}
+
+
+static void GLAPIENTRY
+save_Uniform4dv(GLint location, GLsizei count, const GLdouble *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_4DV, 2 + POINTER_DWORDS);
+   if (n) {
+      n[1].i = location;
+      n[2].i = count;
+      save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLdouble)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_Uniform4dv(ctx->Exec, (location, count, v));
+   }
+}
+
+
+static void GLAPIENTRY
+save_Uniform1iARB(GLint location, GLint x)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_1I, 2);
+   if (n) {
+      n[1].i = location;
+      n[2].i = x;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_Uniform1i(ctx->Exec, (location, x));
+   }
+}
+
+static void GLAPIENTRY
+save_Uniform2iARB(GLint location, GLint x, GLint y)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_2I, 3);
+   if (n) {
+      n[1].i = location;
+      n[2].i = x;
+      n[3].i = y;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_Uniform2i(ctx->Exec, (location, x, y));
+   }
+}
+
+static void GLAPIENTRY
+save_Uniform3iARB(GLint location, GLint x, GLint y, GLint z)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_3I, 4);
+   if (n) {
+      n[1].i = location;
+      n[2].i = x;
+      n[3].i = y;
+      n[4].i = z;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_Uniform3i(ctx->Exec, (location, x, y, z));
+   }
+}
+
+static void GLAPIENTRY
+save_Uniform4iARB(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_4I, 5);
+   if (n) {
+      n[1].i = location;
+      n[2].i = x;
+      n[3].i = y;
+      n[4].i = z;
+      n[5].i = w;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_Uniform4i(ctx->Exec, (location, x, y, z, w));
+   }
+}
+
+
+
+static void GLAPIENTRY
+save_Uniform1ivARB(GLint location, GLsizei count, const GLint *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_1IV, 2 + POINTER_DWORDS);
+   if (n) {
+      n[1].i = location;
+      n[2].i = count;
+      save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLint)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_Uniform1iv(ctx->Exec, (location, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_Uniform2ivARB(GLint location, GLsizei count, const GLint *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_2IV, 2 + POINTER_DWORDS);
+   if (n) {
+      n[1].i = location;
+      n[2].i = count;
+      save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLint)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_Uniform2iv(ctx->Exec, (location, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_Uniform3ivARB(GLint location, GLsizei count, const GLint *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_3IV, 2 + POINTER_DWORDS);
    if (n) {
       n[1].i = location;
       n[2].i = count;
@@ -6295,7 +6967,7 @@ save_Uniform1ui(GLint location, GLuint x)
       n[2].i = x;
    }
    if (ctx->ExecuteFlag) {
-      /*CALL_Uniform1ui(ctx->Exec, (location, x));*/
+      CALL_Uniform1ui(ctx->Exec, (location, x));
    }
 }
 
@@ -6312,7 +6984,7 @@ save_Uniform2ui(GLint location, GLuint x, GLuint y)
       n[3].i = y;
    }
    if (ctx->ExecuteFlag) {
-      /*CALL_Uniform2ui(ctx->Exec, (location, x, y));*/
+      CALL_Uniform2ui(ctx->Exec, (location, x, y));
    }
 }
 
@@ -6330,7 +7002,7 @@ save_Uniform3ui(GLint location, GLuint x, GLuint y, GLuint z)
       n[4].i = z;
    }
    if (ctx->ExecuteFlag) {
-      /*CALL_Uniform3ui(ctx->Exec, (location, x, y, z));*/
+      CALL_Uniform3ui(ctx->Exec, (location, x, y, z));
    }
 }
 
@@ -6349,7 +7021,7 @@ save_Uniform4ui(GLint location, GLuint x, GLuint y, GLuint z, GLuint w)
       n[5].i = w;
    }
    if (ctx->ExecuteFlag) {
-      /*CALL_Uniform4ui(ctx->Exec, (location, x, y, z, w));*/
+      CALL_Uniform4ui(ctx->Exec, (location, x, y, z, w));
    }
 }
 
@@ -6368,7 +7040,7 @@ save_Uniform1uiv(GLint location, GLsizei count, const GLuint *v)
       save_pointer(&n[3], memdup(v, count * 1 * sizeof(*v)));
    }
    if (ctx->ExecuteFlag) {
-      /*CALL_Uniform1uiv(ctx->Exec, (location, count, v));*/
+      CALL_Uniform1uiv(ctx->Exec, (location, count, v));
    }
 }
 
@@ -6385,7 +7057,7 @@ save_Uniform2uiv(GLint location, GLsizei count, const GLuint *v)
       save_pointer(&n[3], memdup(v, count * 2 * sizeof(*v)));
    }
    if (ctx->ExecuteFlag) {
-      /*CALL_Uniform2uiv(ctx->Exec, (location, count, v));*/
+      CALL_Uniform2uiv(ctx->Exec, (location, count, v));
    }
 }
 
@@ -6402,7 +7074,7 @@ save_Uniform3uiv(GLint location, GLsizei count, const GLuint *v)
       save_pointer(&n[3], memdup(v, count * 3 * sizeof(*v)));
    }
    if (ctx->ExecuteFlag) {
-      /*CALL_Uniform3uiv(ctx->Exec, (location, count, v));*/
+      CALL_Uniform3uiv(ctx->Exec, (location, count, v));
    }
 }
 
@@ -6419,7 +7091,7 @@ save_Uniform4uiv(GLint location, GLsizei count, const GLuint *v)
       save_pointer(&n[3], memdup(v, count * 4 * sizeof(*v)));
    }
    if (ctx->ExecuteFlag) {
-      /*CALL_Uniform4uiv(ctx->Exec, (location, count, v));*/
+      CALL_Uniform4uiv(ctx->Exec, (location, count, v));
    }
 }
 
@@ -6599,1019 +7271,4002 @@ save_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
    }
 }
 
+
 static void GLAPIENTRY
-save_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
+save_UniformMatrix2dv(GLint location, GLsizei count, GLboolean transpose,
+                      const GLdouble *m)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_USE_PROGRAM_STAGES, 3);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX22D, 3 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = pipeline;
-      n[2].ui = stages;
-      n[3].ui = program;
+      n[1].i = location;
+      n[2].i = count;
+      n[3].b = transpose;
+      save_pointer(&n[4], memdup(m, count * 2 * 2 * sizeof(GLdouble)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_UseProgramStages(ctx->Exec, (pipeline, stages, program));
+      CALL_UniformMatrix2dv(ctx->Exec, (location, count, transpose, m));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform1f(GLuint program, GLint location, GLfloat x)
+save_UniformMatrix3dv(GLint location, GLsizei count, GLboolean transpose,
+                      const GLdouble *m)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1F, 3);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX33D, 3 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].f = x;
+      n[1].i = location;
+      n[2].i = count;
+      n[3].b = transpose;
+      save_pointer(&n[4], memdup(m, count * 3 * 3 * sizeof(GLdouble)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform1f(ctx->Exec, (program, location, x));
+      CALL_UniformMatrix3dv(ctx->Exec, (location, count, transpose, m));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform2f(GLuint program, GLint location, GLfloat x, GLfloat y)
+save_UniformMatrix4dv(GLint location, GLsizei count, GLboolean transpose,
+                      const GLdouble *m)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2F, 4);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX44D, 3 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].f = x;
-      n[4].f = y;
+      n[1].i = location;
+      n[2].i = count;
+      n[3].b = transpose;
+      save_pointer(&n[4], memdup(m, count * 4 * 4 * sizeof(GLdouble)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform2f(ctx->Exec, (program, location, x, y));
+      CALL_UniformMatrix4dv(ctx->Exec, (location, count, transpose, m));
    }
 }
 
+
 static void GLAPIENTRY
-save_ProgramUniform3f(GLuint program, GLint location,
-                      GLfloat x, GLfloat y, GLfloat z)
+save_UniformMatrix2x3dv(GLint location, GLsizei count, GLboolean transpose,
+                        const GLdouble *m)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3F, 5);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX23D, 3 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].f = x;
-      n[4].f = y;
-      n[5].f = z;
+      n[1].i = location;
+      n[2].i = count;
+      n[3].b = transpose;
+      save_pointer(&n[4], memdup(m, count * 2 * 3 * sizeof(GLdouble)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform3f(ctx->Exec, (program, location, x, y, z));
+      CALL_UniformMatrix2x3dv(ctx->Exec, (location, count, transpose, m));
    }
 }
 
+
 static void GLAPIENTRY
-save_ProgramUniform4f(GLuint program, GLint location,
-                      GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+save_UniformMatrix3x2dv(GLint location, GLsizei count, GLboolean transpose,
+                        const GLdouble *m)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4F, 6);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX32D, 3 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].f = x;
-      n[4].f = y;
-      n[5].f = z;
-      n[6].f = w;
+      n[1].i = location;
+      n[2].i = count;
+      n[3].b = transpose;
+      save_pointer(&n[4], memdup(m, count * 3 * 2 * sizeof(GLdouble)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform4f(ctx->Exec, (program, location, x, y, z, w));
+      CALL_UniformMatrix3x2dv(ctx->Exec, (location, count, transpose, m));
    }
 }
 
+
 static void GLAPIENTRY
-save_ProgramUniform1fv(GLuint program, GLint location, GLsizei count,
-                       const GLfloat *v)
+save_UniformMatrix2x4dv(GLint location, GLsizei count, GLboolean transpose,
+                        const GLdouble *m)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1FV, 3 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX24D, 3 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = count;
-      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLfloat)));
+      n[1].i = location;
+      n[2].i = count;
+      n[3].b = transpose;
+      save_pointer(&n[4], memdup(m, count * 2 * 4 * sizeof(GLdouble)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform1fv(ctx->Exec, (program, location, count, v));
+      CALL_UniformMatrix2x4dv(ctx->Exec, (location, count, transpose, m));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform2fv(GLuint program, GLint location, GLsizei count,
-                       const GLfloat *v)
+save_UniformMatrix4x2dv(GLint location, GLsizei count, GLboolean transpose,
+                        const GLdouble *m)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2FV, 3 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX42D, 3 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = count;
-      save_pointer(&n[4], memdup(v, count * 2 * sizeof(GLfloat)));
+      n[1].i = location;
+      n[2].i = count;
+      n[3].b = transpose;
+      save_pointer(&n[4], memdup(m, count * 4 * 2 * sizeof(GLdouble)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform2fv(ctx->Exec, (program, location, count, v));
+      CALL_UniformMatrix4x2dv(ctx->Exec, (location, count, transpose, m));
    }
 }
 
+
 static void GLAPIENTRY
-save_ProgramUniform3fv(GLuint program, GLint location, GLsizei count,
-                       const GLfloat *v)
+save_UniformMatrix3x4dv(GLint location, GLsizei count, GLboolean transpose,
+                        const GLdouble *m)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3FV, 3 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX34D, 3 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = count;
-      save_pointer(&n[4], memdup(v, count * 3 * sizeof(GLfloat)));
+      n[1].i = location;
+      n[2].i = count;
+      n[3].b = transpose;
+      save_pointer(&n[4], memdup(m, count * 3 * 4 * sizeof(GLdouble)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform3fv(ctx->Exec, (program, location, count, v));
+      CALL_UniformMatrix3x4dv(ctx->Exec, (location, count, transpose, m));
    }
 }
 
+
 static void GLAPIENTRY
-save_ProgramUniform4fv(GLuint program, GLint location, GLsizei count,
-                       const GLfloat *v)
+save_UniformMatrix4x3dv(GLint location, GLsizei count, GLboolean transpose,
+                        const GLdouble *m)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4FV, 3 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX43D, 3 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = count;
-      save_pointer(&n[4], memdup(v, count * 4 * sizeof(GLfloat)));
+      n[1].i = location;
+      n[2].i = count;
+      n[3].b = transpose;
+      save_pointer(&n[4], memdup(m, count * 4 * 3 * sizeof(GLdouble)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform4fv(ctx->Exec, (program, location, count, v));
+      CALL_UniformMatrix4x3dv(ctx->Exec, (location, count, transpose, m));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform1i(GLuint program, GLint location, GLint x)
+save_Uniform1i64ARB(GLint location, GLint64 x)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1I, 3);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_1I64, 3);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = x;
+      n[1].i = location;
+      ASSIGN_INT64_TO_NODES(n, 2, x);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform1i(ctx->Exec, (program, location, x));
+      CALL_Uniform1i64ARB(ctx->Exec, (location, x));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform2i(GLuint program, GLint location, GLint x, GLint y)
+save_Uniform2i64ARB(GLint location, GLint64 x, GLint64 y)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2I, 4);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_2I64, 5);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = x;
-      n[4].i = y;
+      n[1].i = location;
+      ASSIGN_INT64_TO_NODES(n, 2, x);
+      ASSIGN_INT64_TO_NODES(n, 4, y);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform2i(ctx->Exec, (program, location, x, y));
+      CALL_Uniform2i64ARB(ctx->Exec, (location, x, y));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform3i(GLuint program, GLint location,
-                      GLint x, GLint y, GLint z)
+save_Uniform3i64ARB(GLint location, GLint64 x, GLint64 y, GLint64 z)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3I, 5);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_3I64, 7);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = x;
-      n[4].i = y;
-      n[5].i = z;
+      n[1].i = location;
+      ASSIGN_INT64_TO_NODES(n, 2, x);
+      ASSIGN_INT64_TO_NODES(n, 4, y);
+      ASSIGN_INT64_TO_NODES(n, 6, z);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform3i(ctx->Exec, (program, location, x, y, z));
+      CALL_Uniform3i64ARB(ctx->Exec, (location, x, y, z));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform4i(GLuint program, GLint location,
-                      GLint x, GLint y, GLint z, GLint w)
+save_Uniform4i64ARB(GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4I, 6);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_4I64, 9);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = x;
-      n[4].i = y;
-      n[5].i = z;
-      n[6].i = w;
+      n[1].i = location;
+      ASSIGN_INT64_TO_NODES(n, 2, x);
+      ASSIGN_INT64_TO_NODES(n, 4, y);
+      ASSIGN_INT64_TO_NODES(n, 6, z);
+      ASSIGN_INT64_TO_NODES(n, 8, w);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform4i(ctx->Exec, (program, location, x, y, z, w));
+      CALL_Uniform4i64ARB(ctx->Exec, (location, x, y, z, w));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform1iv(GLuint program, GLint location, GLsizei count,
-                       const GLint *v)
+save_Uniform1i64vARB(GLint location, GLsizei count, const GLint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1IV, 3 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_1I64V, 2 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = count;
-      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLint)));
+     n[1].i = location;
+     n[2].i = count;
+     save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform1iv(ctx->Exec, (program, location, count, v));
+      CALL_Uniform1i64vARB(ctx->Exec, (location, count, v));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform2iv(GLuint program, GLint location, GLsizei count,
-                       const GLint *v)
+save_Uniform2i64vARB(GLint location, GLsizei count, const GLint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2IV, 3 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_2I64V, 2 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = count;
-      save_pointer(&n[4], memdup(v, count * 2 * sizeof(GLint)));
+     n[1].i = location;
+     n[2].i = count;
+     save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform2iv(ctx->Exec, (program, location, count, v));
+      CALL_Uniform2i64vARB(ctx->Exec, (location, count, v));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform3iv(GLuint program, GLint location, GLsizei count,
-                       const GLint *v)
+save_Uniform3i64vARB(GLint location, GLsizei count, const GLint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3IV, 3 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_3I64V, 2 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = count;
-      save_pointer(&n[4], memdup(v, count * 3 * sizeof(GLint)));
+     n[1].i = location;
+     n[2].i = count;
+     save_pointer(&n[3], memdup(v, count * 3 * sizeof(GLint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform3iv(ctx->Exec, (program, location, count, v));
+      CALL_Uniform3i64vARB(ctx->Exec, (location, count, v));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform4iv(GLuint program, GLint location, GLsizei count,
-                       const GLint *v)
+save_Uniform4i64vARB(GLint location, GLsizei count, const GLint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4IV, 3 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_4I64V, 2 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = count;
-      save_pointer(&n[4], memdup(v, count * 4 * sizeof(GLint)));
+     n[1].i = location;
+     n[2].i = count;
+     save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform4iv(ctx->Exec, (program, location, count, v));
+      CALL_Uniform4i64vARB(ctx->Exec, (location, count, v));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform1ui(GLuint program, GLint location, GLuint x)
+save_Uniform1ui64ARB(GLint location, GLuint64 x)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1UI, 3);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_1UI64, 3);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].ui = x;
+      n[1].i = location;
+      ASSIGN_UINT64_TO_NODES(n, 2, x);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform1ui(ctx->Exec, (program, location, x));
+      CALL_Uniform1ui64ARB(ctx->Exec, (location, x));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform2ui(GLuint program, GLint location, GLuint x, GLuint y)
+save_Uniform2ui64ARB(GLint location, GLuint64 x, GLuint64 y)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2UI, 4);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_2UI64, 5);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].ui = x;
-      n[4].ui = y;
+      n[1].i = location;
+      ASSIGN_UINT64_TO_NODES(n, 2, x);
+      ASSIGN_UINT64_TO_NODES(n, 4, y);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform2ui(ctx->Exec, (program, location, x, y));
+      CALL_Uniform2ui64ARB(ctx->Exec, (location, x, y));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform3ui(GLuint program, GLint location,
-                       GLuint x, GLuint y, GLuint z)
+save_Uniform3ui64ARB(GLint location, GLuint64 x, GLuint64 y, GLuint64 z)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3UI, 5);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_3UI64, 7);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].ui = x;
-      n[4].ui = y;
-      n[5].ui = z;
+      n[1].i = location;
+      ASSIGN_UINT64_TO_NODES(n, 2, x);
+      ASSIGN_UINT64_TO_NODES(n, 4, y);
+      ASSIGN_UINT64_TO_NODES(n, 6, z);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform3ui(ctx->Exec, (program, location, x, y, z));
+      CALL_Uniform3ui64ARB(ctx->Exec, (location, x, y, z));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform4ui(GLuint program, GLint location,
-                       GLuint x, GLuint y, GLuint z, GLuint w)
+save_Uniform4ui64ARB(GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4UI, 6);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_4UI64, 9);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].ui = x;
-      n[4].ui = y;
-      n[5].ui = z;
-      n[6].ui = w;
+      n[1].i = location;
+      ASSIGN_UINT64_TO_NODES(n, 2, x);
+      ASSIGN_UINT64_TO_NODES(n, 4, y);
+      ASSIGN_UINT64_TO_NODES(n, 6, z);
+      ASSIGN_UINT64_TO_NODES(n, 8, w);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform4ui(ctx->Exec, (program, location, x, y, z, w));
+      CALL_Uniform4ui64ARB(ctx->Exec, (location, x, y, z, w));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform1uiv(GLuint program, GLint location, GLsizei count,
-                        const GLuint *v)
+save_Uniform1ui64vARB(GLint location, GLsizei count, const GLuint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1UIV, 3 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_1UI64V, 2 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = count;
-      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLuint)));
+     n[1].i = location;
+     n[2].i = count;
+     save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLuint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform1uiv(ctx->Exec, (program, location, count, v));
+      CALL_Uniform1ui64vARB(ctx->Exec, (location, count, v));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform2uiv(GLuint program, GLint location, GLsizei count,
-                        const GLuint *v)
+save_Uniform2ui64vARB(GLint location, GLsizei count, const GLuint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2UIV, 3 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_2UI64V, 2 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = count;
-      save_pointer(&n[4], memdup(v, count * 2 * sizeof(GLuint)));
+     n[1].i = location;
+     n[2].i = count;
+     save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLuint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform2uiv(ctx->Exec, (program, location, count, v));
+      CALL_Uniform2ui64vARB(ctx->Exec, (location, count, v));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform3uiv(GLuint program, GLint location, GLsizei count,
-                        const GLuint *v)
+save_Uniform3ui64vARB(GLint location, GLsizei count, const GLuint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3UIV, 3 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_3UI64V, 2 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = count;
-      save_pointer(&n[4], memdup(v, count * 3 * sizeof(GLuint)));
+     n[1].i = location;
+     n[2].i = count;
+     save_pointer(&n[3], memdup(v, count * 3 * sizeof(GLuint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform3uiv(ctx->Exec, (program, location, count, v));
+      CALL_Uniform3ui64vARB(ctx->Exec, (location, count, v));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniform4uiv(GLuint program, GLint location, GLsizei count,
-                        const GLuint *v)
+save_Uniform4ui64vARB(GLint location, GLsizei count, const GLuint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4UIV, 3 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_4UI64V, 2 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = program;
-      n[2].i = location;
-      n[3].i = count;
-      save_pointer(&n[4], memdup(v, count * 4 * sizeof(GLuint)));
+     n[1].i = location;
+     n[2].i = count;
+     save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLuint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniform4uiv(ctx->Exec, (program, location, count, v));
+      CALL_Uniform4ui64vARB(ctx->Exec, (location, count, v));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count,
-                             GLboolean transpose, const GLfloat *v)
+save_ProgramUniform1i64ARB(GLuint program, GLint location, GLint64 x)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX22F,
-                         4 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1I64, 4);
    if (n) {
       n[1].ui = program;
       n[2].i = location;
-      n[3].i = count;
-      n[4].b = transpose;
-      save_pointer(&n[5], memdup(v, count * 2 * 2 * sizeof(GLfloat)));
+      ASSIGN_INT64_TO_NODES(n, 3, x);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniformMatrix2fv(ctx->Exec,
-                                   (program, location, count, transpose, v));
+      CALL_ProgramUniform1i64ARB(ctx->Exec, (program, location, x));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count,
-                               GLboolean transpose, const GLfloat *v)
+save_ProgramUniform2i64ARB(GLuint program, GLint location, GLint64 x,
+                           GLint64 y)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX23F,
-                         4 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2I64, 6);
    if (n) {
       n[1].ui = program;
       n[2].i = location;
-      n[3].i = count;
-      n[4].b = transpose;
-      save_pointer(&n[5], memdup(v, count * 2 * 3 * sizeof(GLfloat)));
+      ASSIGN_INT64_TO_NODES(n, 3, x);
+      ASSIGN_INT64_TO_NODES(n, 5, y);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniformMatrix2x3fv(ctx->Exec,
-                                     (program, location, count, transpose, v));
+      CALL_ProgramUniform2i64ARB(ctx->Exec, (program, location, x, y));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count,
-                               GLboolean transpose, const GLfloat *v)
+save_ProgramUniform3i64ARB(GLuint program, GLint location, GLint64 x,
+                           GLint64 y, GLint64 z)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX24F,
-                         4 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3I64, 8);
    if (n) {
       n[1].ui = program;
       n[2].i = location;
-      n[3].i = count;
-      n[4].b = transpose;
-      save_pointer(&n[5], memdup(v, count * 2 * 4 * sizeof(GLfloat)));
+      ASSIGN_INT64_TO_NODES(n, 3, x);
+      ASSIGN_INT64_TO_NODES(n, 5, y);
+      ASSIGN_INT64_TO_NODES(n, 7, z);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniformMatrix2x4fv(ctx->Exec,
-                                     (program, location, count, transpose, v));
+      CALL_ProgramUniform3i64ARB(ctx->Exec, (program, location, x, y, z));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count,
-                               GLboolean transpose, const GLfloat *v)
+save_ProgramUniform4i64ARB(GLuint program, GLint location, GLint64 x,
+                           GLint64 y, GLint64 z, GLint64 w)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX32F,
-                         4 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4I64, 10);
    if (n) {
       n[1].ui = program;
       n[2].i = location;
-      n[3].i = count;
-      n[4].b = transpose;
-      save_pointer(&n[5], memdup(v, count * 3 * 2 * sizeof(GLfloat)));
+      ASSIGN_INT64_TO_NODES(n, 3, x);
+      ASSIGN_INT64_TO_NODES(n, 5, y);
+      ASSIGN_INT64_TO_NODES(n, 7, z);
+      ASSIGN_INT64_TO_NODES(n, 9, w);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniformMatrix3x2fv(ctx->Exec,
-                                     (program, location, count, transpose, v));
+      CALL_ProgramUniform4i64ARB(ctx->Exec, (program, location, x, y, z, w));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count,
-                             GLboolean transpose, const GLfloat *v)
+save_ProgramUniform1i64vARB(GLuint program, GLint location, GLsizei count,
+                            const GLint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX33F,
-                         4 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1I64V, 3 + POINTER_DWORDS);
    if (n) {
       n[1].ui = program;
       n[2].i = location;
       n[3].i = count;
-      n[4].b = transpose;
-      save_pointer(&n[5], memdup(v, count * 3 * 3 * sizeof(GLfloat)));
+      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniformMatrix3fv(ctx->Exec,
-                                   (program, location, count, transpose, v));
+      CALL_ProgramUniform1i64vARB(ctx->Exec, (program, location, count, v));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count,
-                               GLboolean transpose, const GLfloat *v)
+save_ProgramUniform2i64vARB(GLuint program, GLint location, GLsizei count,
+                            const GLint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX34F,
-                         4 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2I64V, 3 + POINTER_DWORDS);
    if (n) {
       n[1].ui = program;
       n[2].i = location;
       n[3].i = count;
-      n[4].b = transpose;
-      save_pointer(&n[5], memdup(v, count * 3 * 4 * sizeof(GLfloat)));
+      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniformMatrix3x4fv(ctx->Exec,
-                                     (program, location, count, transpose, v));
+      CALL_ProgramUniform2i64vARB(ctx->Exec, (program, location, count, v));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count,
-                               GLboolean transpose, const GLfloat *v)
+save_ProgramUniform3i64vARB(GLuint program, GLint location, GLsizei count,
+                            const GLint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX42F,
-                         4 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3I64V, 3 + POINTER_DWORDS);
    if (n) {
       n[1].ui = program;
       n[2].i = location;
       n[3].i = count;
-      n[4].b = transpose;
-      save_pointer(&n[5], memdup(v, count * 4 * 2 * sizeof(GLfloat)));
+      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniformMatrix4x2fv(ctx->Exec,
-                                     (program, location, count, transpose, v));
+      CALL_ProgramUniform3i64vARB(ctx->Exec, (program, location, count, v));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count,
-                               GLboolean transpose, const GLfloat *v)
+save_ProgramUniform4i64vARB(GLuint program, GLint location, GLsizei count,
+                            const GLint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX43F,
-                         4 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4I64V, 3 + POINTER_DWORDS);
    if (n) {
       n[1].ui = program;
       n[2].i = location;
       n[3].i = count;
-      n[4].b = transpose;
-      save_pointer(&n[5], memdup(v, count * 4 * 3 * sizeof(GLfloat)));
+      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniformMatrix4x3fv(ctx->Exec,
-                                     (program, location, count, transpose, v));
+      CALL_ProgramUniform4i64vARB(ctx->Exec, (program, location, count, v));
    }
 }
 
 static void GLAPIENTRY
-save_ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count,
-                             GLboolean transpose, const GLfloat *v)
+save_ProgramUniform1ui64ARB(GLuint program, GLint location, GLuint64 x)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX44F,
-                         4 + POINTER_DWORDS);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1UI64, 4);
    if (n) {
       n[1].ui = program;
       n[2].i = location;
-      n[3].i = count;
-      n[4].b = transpose;
-      save_pointer(&n[5], memdup(v, count * 4 * 4 * sizeof(GLfloat)));
+      ASSIGN_UINT64_TO_NODES(n, 3, x);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ProgramUniformMatrix4fv(ctx->Exec,
-                                   (program, location, count, transpose, v));
+      CALL_ProgramUniform1ui64ARB(ctx->Exec, (program, location, x));
    }
 }
 
 static void GLAPIENTRY
-save_ClipControl(GLenum origin, GLenum depth)
+save_ProgramUniform2ui64ARB(GLuint program, GLint location, GLuint64 x,
+                            GLuint64 y)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_CLIP_CONTROL, 2);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2UI64, 6);
    if (n) {
-      n[1].e = origin;
-      n[2].e = depth;
+      n[1].ui = program;
+      n[2].i = location;
+      ASSIGN_UINT64_TO_NODES(n, 3, x);
+      ASSIGN_UINT64_TO_NODES(n, 5, y);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ClipControl(ctx->Exec, (origin, depth));
+      CALL_ProgramUniform2ui64ARB(ctx->Exec, (program, location, x, y));
    }
 }
 
 static void GLAPIENTRY
-save_ClampColorARB(GLenum target, GLenum clamp)
+save_ProgramUniform3ui64ARB(GLuint program, GLint location, GLuint64 x,
+                            GLuint64 y, GLuint64 z)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_CLAMP_COLOR, 2);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3UI64, 8);
    if (n) {
-      n[1].e = target;
-      n[2].e = clamp;
+      n[1].ui = program;
+      n[2].i = location;
+      ASSIGN_UINT64_TO_NODES(n, 3, x);
+      ASSIGN_UINT64_TO_NODES(n, 5, y);
+      ASSIGN_UINT64_TO_NODES(n, 7, z);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ClampColor(ctx->Exec, (target, clamp));
+      CALL_ProgramUniform3ui64ARB(ctx->Exec, (program, location, x, y, z));
    }
 }
 
-/** GL_EXT_texture_integer */
 static void GLAPIENTRY
-save_ClearColorIi(GLint red, GLint green, GLint blue, GLint alpha)
+save_ProgramUniform4ui64ARB(GLuint program, GLint location, GLuint64 x,
+                            GLuint64 y, GLuint64 z, GLuint64 w)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_CLEARCOLOR_I, 4);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4UI64, 10);
    if (n) {
-      n[1].i = red;
-      n[2].i = green;
-      n[3].i = blue;
-      n[4].i = alpha;
+      n[1].ui = program;
+      n[2].i = location;
+      ASSIGN_UINT64_TO_NODES(n, 3, x);
+      ASSIGN_UINT64_TO_NODES(n, 5, y);
+      ASSIGN_UINT64_TO_NODES(n, 7, z);
+      ASSIGN_UINT64_TO_NODES(n, 9, w);
    }
    if (ctx->ExecuteFlag) {
-      CALL_ClearColorIiEXT(ctx->Exec, (red, green, blue, alpha));
+      CALL_ProgramUniform4i64ARB(ctx->Exec, (program, location, x, y, z, w));
    }
 }
 
-/** GL_EXT_texture_integer */
 static void GLAPIENTRY
-save_ClearColorIui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
+save_ProgramUniform1ui64vARB(GLuint program, GLint location, GLsizei count,
+                             const GLuint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_CLEARCOLOR_UI, 4);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1UI64V,
+                         3 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = red;
-      n[2].ui = green;
-      n[3].ui = blue;
-      n[4].ui = alpha;
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLuint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_ClearColorIuiEXT(ctx->Exec, (red, green, blue, alpha));
+      CALL_ProgramUniform1ui64vARB(ctx->Exec, (program, location, count, v));
    }
 }
 
-/** GL_EXT_texture_integer */
 static void GLAPIENTRY
-save_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
+save_ProgramUniform2ui64vARB(GLuint program, GLint location, GLsizei count,
+                            const GLuint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_TEXPARAMETER_I, 6);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2UI64V,
+                         3 + POINTER_DWORDS);
    if (n) {
-      n[1].e = target;
-      n[2].e = pname;
-      n[3].i = params[0];
-      n[4].i = params[1];
-      n[5].i = params[2];
-      n[6].i = params[3];
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLuint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_TexParameterIiv(ctx->Exec, (target, pname, params));
+      CALL_ProgramUniform2ui64vARB(ctx->Exec, (program, location, count, v));
    }
 }
 
-/** GL_EXT_texture_integer */
 static void GLAPIENTRY
-save_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
+save_ProgramUniform3ui64vARB(GLuint program, GLint location, GLsizei count,
+                             const GLuint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_TEXPARAMETER_UI, 6);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3UI64V,
+                         3 + POINTER_DWORDS);
    if (n) {
-      n[1].e = target;
-      n[2].e = pname;
-      n[3].ui = params[0];
-      n[4].ui = params[1];
-      n[5].ui = params[2];
-      n[6].ui = params[3];
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLuint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_TexParameterIuiv(ctx->Exec, (target, pname, params));
+      CALL_ProgramUniform3ui64vARB(ctx->Exec, (program, location, count, v));
    }
 }
 
-/* GL_ARB_instanced_arrays */
 static void GLAPIENTRY
-save_VertexAttribDivisor(GLuint index, GLuint divisor)
+save_ProgramUniform4ui64vARB(GLuint program, GLint location, GLsizei count,
+                             const GLuint64 *v)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_VERTEX_ATTRIB_DIVISOR, 2);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4UI64V,
+                         3 + POINTER_DWORDS);
    if (n) {
-      n[1].ui = index;
-      n[2].ui = divisor;
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLuint64)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_VertexAttribDivisor(ctx->Exec, (index, divisor));
+      CALL_ProgramUniform4ui64vARB(ctx->Exec, (program, location, count, v));
    }
 }
 
 
-/* GL_NV_texture_barrier */
 static void GLAPIENTRY
-save_TextureBarrierNV(void)
+save_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
 {
    GET_CURRENT_CONTEXT(ctx);
+   Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   alloc_instruction(ctx, OPCODE_TEXTURE_BARRIER_NV, 0);
+   n = alloc_instruction(ctx, OPCODE_USE_PROGRAM_STAGES, 3);
+   if (n) {
+      n[1].ui = pipeline;
+      n[2].ui = stages;
+      n[3].ui = program;
+   }
    if (ctx->ExecuteFlag) {
-      CALL_TextureBarrierNV(ctx->Exec, ());
+      CALL_UseProgramStages(ctx->Exec, (pipeline, stages, program));
    }
 }
 
-
-/* GL_ARB_sampler_objects */
 static void GLAPIENTRY
-save_BindSampler(GLuint unit, GLuint sampler)
+save_ProgramUniform1f(GLuint program, GLint location, GLfloat x)
 {
-   Node *n;
    GET_CURRENT_CONTEXT(ctx);
+   Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_BIND_SAMPLER, 2);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1F, 3);
    if (n) {
-      n[1].ui = unit;
-      n[2].ui = sampler;
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].f = x;
    }
    if (ctx->ExecuteFlag) {
-      CALL_BindSampler(ctx->Exec, (unit, sampler));
+      CALL_ProgramUniform1f(ctx->Exec, (program, location, x));
    }
 }
 
 static void GLAPIENTRY
-save_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params)
+save_ProgramUniform2f(GLuint program, GLint location, GLfloat x, GLfloat y)
 {
-   Node *n;
    GET_CURRENT_CONTEXT(ctx);
+   Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_SAMPLER_PARAMETERIV, 6);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2F, 4);
    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;
-      }
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].f = x;
+      n[4].f = y;
    }
    if (ctx->ExecuteFlag) {
-      CALL_SamplerParameteriv(ctx->Exec, (sampler, pname, params));
+      CALL_ProgramUniform2f(ctx->Exec, (program, location, x, y));
    }
 }
 
 static void GLAPIENTRY
-save_SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
+save_ProgramUniform3f(GLuint program, GLint location,
+                      GLfloat x, GLfloat y, GLfloat z)
 {
-   GLint parray[4];
-   parray[0] = param;
-   parray[1] = parray[2] = parray[3] = 0;
-   save_SamplerParameteriv(sampler, pname, parray);
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3F, 5);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].f = x;
+      n[4].f = y;
+      n[5].f = z;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform3f(ctx->Exec, (program, location, x, y, z));
+   }
 }
 
 static void GLAPIENTRY
-save_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params)
+save_ProgramUniform4f(GLuint program, GLint location,
+                      GLfloat x, GLfloat y, GLfloat z, GLfloat w)
 {
+   GET_CURRENT_CONTEXT(ctx);
    Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4F, 6);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].f = x;
+      n[4].f = y;
+      n[5].f = z;
+      n[6].f = w;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform4f(ctx->Exec, (program, location, x, y, z, w));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform1fv(GLuint program, GLint location, GLsizei count,
+                       const GLfloat *v)
+{
    GET_CURRENT_CONTEXT(ctx);
+   Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_SAMPLER_PARAMETERFV, 6);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1FV, 3 + POINTER_DWORDS);
    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;
-      }
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLfloat)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_SamplerParameterfv(ctx->Exec, (sampler, pname, params));
+      CALL_ProgramUniform1fv(ctx->Exec, (program, location, count, v));
    }
 }
 
 static void GLAPIENTRY
-save_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
+save_ProgramUniform2fv(GLuint program, GLint location, GLsizei count,
+                       const GLfloat *v)
 {
-   GLfloat parray[4];
-   parray[0] = param;
-   parray[1] = parray[2] = parray[3] = 0.0F;
-   save_SamplerParameterfv(sampler, pname, parray);
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2FV, 3 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 2 * sizeof(GLfloat)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform2fv(ctx->Exec, (program, location, count, v));
+   }
 }
 
 static void GLAPIENTRY
-save_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params)
+save_ProgramUniform3fv(GLuint program, GLint location, GLsizei count,
+                       const GLfloat *v)
 {
+   GET_CURRENT_CONTEXT(ctx);
    Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3FV, 3 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 3 * sizeof(GLfloat)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform3fv(ctx->Exec, (program, location, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform4fv(GLuint program, GLint location, GLsizei count,
+                       const GLfloat *v)
+{
    GET_CURRENT_CONTEXT(ctx);
+   Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_SAMPLER_PARAMETERIIV, 6);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4FV, 3 + POINTER_DWORDS);
    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;
-      }
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 4 * sizeof(GLfloat)));
    }
    if (ctx->ExecuteFlag) {
-      CALL_SamplerParameterIiv(ctx->Exec, (sampler, pname, params));
+      CALL_ProgramUniform4fv(ctx->Exec, (program, location, count, v));
    }
 }
 
 static void GLAPIENTRY
-save_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params)
+save_ProgramUniform1d(GLuint program, GLint location, GLdouble x)
 {
+   GET_CURRENT_CONTEXT(ctx);
    Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1D, 4);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      ASSIGN_DOUBLE_TO_NODES(n, 3, x);
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform1d(ctx->Exec, (program, location, x));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform2d(GLuint program, GLint location, GLdouble x, GLdouble y)
+{
    GET_CURRENT_CONTEXT(ctx);
+   Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_SAMPLER_PARAMETERUIV, 6);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2D, 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;
-      }
+      n[1].ui = program;
+      n[2].i = location;
+      ASSIGN_DOUBLE_TO_NODES(n, 3, x);
+      ASSIGN_DOUBLE_TO_NODES(n, 5, y);
    }
    if (ctx->ExecuteFlag) {
-      CALL_SamplerParameterIuiv(ctx->Exec, (sampler, pname, params));
+      CALL_ProgramUniform2d(ctx->Exec, (program, location, x, y));
    }
 }
 
 static void GLAPIENTRY
-save_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+save_ProgramUniform3d(GLuint program, GLint location,
+                      GLdouble x, GLdouble y, GLdouble z)
 {
+   GET_CURRENT_CONTEXT(ctx);
    Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3D, 8);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      ASSIGN_DOUBLE_TO_NODES(n, 3, x);
+      ASSIGN_DOUBLE_TO_NODES(n, 5, y);
+      ASSIGN_DOUBLE_TO_NODES(n, 7, z);
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform3d(ctx->Exec, (program, location, x, y, z));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform4d(GLuint program, GLint location,
+                      GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
    GET_CURRENT_CONTEXT(ctx);
+   Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_WAIT_SYNC, 4);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4D, 10);
    if (n) {
-      union uint64_pair p;
-      p.uint64 = timeout;
-      n[1].bf = flags;
-      n[2].ui = p.uint32[0];
-      n[3].ui = p.uint32[1];
-      save_pointer(&n[4], sync);
+      n[1].ui = program;
+      n[2].i = location;
+      ASSIGN_DOUBLE_TO_NODES(n, 3, x);
+      ASSIGN_DOUBLE_TO_NODES(n, 5, y);
+      ASSIGN_DOUBLE_TO_NODES(n, 7, z);
+      ASSIGN_DOUBLE_TO_NODES(n, 9, w);
    }
    if (ctx->ExecuteFlag) {
-      CALL_WaitSync(ctx->Exec, (sync, flags, timeout));
+      CALL_ProgramUniform4d(ctx->Exec, (program, location, x, y, z, w));
    }
 }
 
+static void GLAPIENTRY
+save_ProgramUniform1dv(GLuint program, GLint location, GLsizei count,
+                       const GLdouble *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1DV, 3 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLdouble)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform1dv(ctx->Exec, (program, location, count, v));
+   }
+}
 
-/** GL_NV_conditional_render */
 static void GLAPIENTRY
-save_BeginConditionalRender(GLuint queryId, GLenum mode)
+save_ProgramUniform2dv(GLuint program, GLint location, GLsizei count,
+                       const GLdouble *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2DV, 3 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 2 * sizeof(GLdouble)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform2dv(ctx->Exec, (program, location, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform3dv(GLuint program, GLint location, GLsizei count,
+                       const GLdouble *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3DV, 3 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 3 * sizeof(GLdouble)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform3dv(ctx->Exec, (program, location, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform4dv(GLuint program, GLint location, GLsizei count,
+                       const GLdouble *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4DV, 3 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 4 * sizeof(GLdouble)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform4dv(ctx->Exec, (program, location, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform1i(GLuint program, GLint location, GLint x)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1I, 3);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = x;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform1i(ctx->Exec, (program, location, x));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform2i(GLuint program, GLint location, GLint x, GLint y)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2I, 4);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = x;
+      n[4].i = y;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform2i(ctx->Exec, (program, location, x, y));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform3i(GLuint program, GLint location,
+                      GLint x, GLint y, GLint z)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3I, 5);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = x;
+      n[4].i = y;
+      n[5].i = z;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform3i(ctx->Exec, (program, location, x, y, z));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform4i(GLuint program, GLint location,
+                      GLint x, GLint y, GLint z, GLint w)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4I, 6);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = x;
+      n[4].i = y;
+      n[5].i = z;
+      n[6].i = w;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform4i(ctx->Exec, (program, location, x, y, z, w));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform1iv(GLuint program, GLint location, GLsizei count,
+                       const GLint *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1IV, 3 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLint)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform1iv(ctx->Exec, (program, location, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform2iv(GLuint program, GLint location, GLsizei count,
+                       const GLint *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2IV, 3 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 2 * sizeof(GLint)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform2iv(ctx->Exec, (program, location, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform3iv(GLuint program, GLint location, GLsizei count,
+                       const GLint *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3IV, 3 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 3 * sizeof(GLint)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform3iv(ctx->Exec, (program, location, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform4iv(GLuint program, GLint location, GLsizei count,
+                       const GLint *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4IV, 3 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 4 * sizeof(GLint)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform4iv(ctx->Exec, (program, location, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform1ui(GLuint program, GLint location, GLuint x)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1UI, 3);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].ui = x;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform1ui(ctx->Exec, (program, location, x));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform2ui(GLuint program, GLint location, GLuint x, GLuint y)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2UI, 4);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].ui = x;
+      n[4].ui = y;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform2ui(ctx->Exec, (program, location, x, y));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform3ui(GLuint program, GLint location,
+                       GLuint x, GLuint y, GLuint z)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3UI, 5);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].ui = x;
+      n[4].ui = y;
+      n[5].ui = z;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform3ui(ctx->Exec, (program, location, x, y, z));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform4ui(GLuint program, GLint location,
+                       GLuint x, GLuint y, GLuint z, GLuint w)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4UI, 6);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].ui = x;
+      n[4].ui = y;
+      n[5].ui = z;
+      n[6].ui = w;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform4ui(ctx->Exec, (program, location, x, y, z, w));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform1uiv(GLuint program, GLint location, GLsizei count,
+                        const GLuint *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1UIV, 3 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLuint)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform1uiv(ctx->Exec, (program, location, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform2uiv(GLuint program, GLint location, GLsizei count,
+                        const GLuint *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2UIV, 3 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 2 * sizeof(GLuint)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform2uiv(ctx->Exec, (program, location, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform3uiv(GLuint program, GLint location, GLsizei count,
+                        const GLuint *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3UIV, 3 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 3 * sizeof(GLuint)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform3uiv(ctx->Exec, (program, location, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniform4uiv(GLuint program, GLint location, GLsizei count,
+                        const GLuint *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4UIV, 3 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      save_pointer(&n[4], memdup(v, count * 4 * sizeof(GLuint)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniform4uiv(ctx->Exec, (program, location, count, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count,
+                             GLboolean transpose, const GLfloat *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX22F,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 2 * 2 * sizeof(GLfloat)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix2fv(ctx->Exec,
+                                   (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count,
+                               GLboolean transpose, const GLfloat *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX23F,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 2 * 3 * sizeof(GLfloat)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix2x3fv(ctx->Exec,
+                                     (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count,
+                               GLboolean transpose, const GLfloat *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX24F,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 2 * 4 * sizeof(GLfloat)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix2x4fv(ctx->Exec,
+                                     (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count,
+                               GLboolean transpose, const GLfloat *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX32F,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 3 * 2 * sizeof(GLfloat)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix3x2fv(ctx->Exec,
+                                     (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count,
+                             GLboolean transpose, const GLfloat *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX33F,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 3 * 3 * sizeof(GLfloat)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix3fv(ctx->Exec,
+                                   (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count,
+                               GLboolean transpose, const GLfloat *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX34F,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 3 * 4 * sizeof(GLfloat)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix3x4fv(ctx->Exec,
+                                     (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count,
+                               GLboolean transpose, const GLfloat *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX42F,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 4 * 2 * sizeof(GLfloat)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix4x2fv(ctx->Exec,
+                                     (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count,
+                               GLboolean transpose, const GLfloat *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX43F,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 4 * 3 * sizeof(GLfloat)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix4x3fv(ctx->Exec,
+                                     (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count,
+                             GLboolean transpose, const GLfloat *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX44F,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 4 * 4 * sizeof(GLfloat)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix4fv(ctx->Exec,
+                                   (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix2dv(GLuint program, GLint location, GLsizei count,
+                             GLboolean transpose, const GLdouble *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX22D,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 2 * 2 * sizeof(GLdouble)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix2dv(ctx->Exec,
+                                   (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix2x3dv(GLuint program, GLint location, GLsizei count,
+                               GLboolean transpose, const GLdouble *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX23D,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 2 * 3 * sizeof(GLdouble)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix2x3dv(ctx->Exec,
+                                     (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix2x4dv(GLuint program, GLint location, GLsizei count,
+                               GLboolean transpose, const GLdouble *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX24D,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 2 * 4 * sizeof(GLdouble)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix2x4dv(ctx->Exec,
+                                     (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix3x2dv(GLuint program, GLint location, GLsizei count,
+                               GLboolean transpose, const GLdouble *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX32D,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 3 * 2 * sizeof(GLdouble)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix3x2dv(ctx->Exec,
+                                     (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix3dv(GLuint program, GLint location, GLsizei count,
+                             GLboolean transpose, const GLdouble *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX33D,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 3 * 3 * sizeof(GLdouble)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix3dv(ctx->Exec,
+                                   (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix3x4dv(GLuint program, GLint location, GLsizei count,
+                               GLboolean transpose, const GLdouble *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX34D,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 3 * 4 * sizeof(GLdouble)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix3x4dv(ctx->Exec,
+                                     (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix4x2dv(GLuint program, GLint location, GLsizei count,
+                               GLboolean transpose, const GLdouble *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX42D,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 4 * 2 * sizeof(GLdouble)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix4x2dv(ctx->Exec,
+                                     (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix4x3dv(GLuint program, GLint location, GLsizei count,
+                               GLboolean transpose, const GLdouble *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX43D,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 4 * 3 * sizeof(GLdouble)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix4x3dv(ctx->Exec,
+                                     (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ProgramUniformMatrix4dv(GLuint program, GLint location, GLsizei count,
+                             GLboolean transpose, const GLdouble *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX44D,
+                         4 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = program;
+      n[2].i = location;
+      n[3].i = count;
+      n[4].b = transpose;
+      save_pointer(&n[5], memdup(v, count * 4 * 4 * sizeof(GLdouble)));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ProgramUniformMatrix4dv(ctx->Exec,
+                                   (program, location, count, transpose, v));
+   }
+}
+
+static void GLAPIENTRY
+save_ClipControl(GLenum origin, GLenum depth)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_CLIP_CONTROL, 2);
+   if (n) {
+      n[1].e = origin;
+      n[2].e = depth;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ClipControl(ctx->Exec, (origin, depth));
+   }
+}
+
+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_ClampColor(ctx->Exec, (target, clamp));
+   }
+}
+
+/** GL_EXT_texture_integer */
+static void GLAPIENTRY
+save_ClearColorIi(GLint red, GLint green, GLint blue, GLint alpha)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_CLEARCOLOR_I, 4);
+   if (n) {
+      n[1].i = red;
+      n[2].i = green;
+      n[3].i = blue;
+      n[4].i = alpha;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ClearColorIiEXT(ctx->Exec, (red, green, blue, alpha));
+   }
+}
+
+/** GL_EXT_texture_integer */
+static void GLAPIENTRY
+save_ClearColorIui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_CLEARCOLOR_UI, 4);
+   if (n) {
+      n[1].ui = red;
+      n[2].ui = green;
+      n[3].ui = blue;
+      n[4].ui = alpha;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ClearColorIuiEXT(ctx->Exec, (red, green, blue, alpha));
+   }
+}
+
+/** GL_EXT_texture_integer */
+static void GLAPIENTRY
+save_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_TEXPARAMETER_I, 6);
+   if (n) {
+      n[1].e = target;
+      n[2].e = pname;
+      n[3].i = params[0];
+      n[4].i = params[1];
+      n[5].i = params[2];
+      n[6].i = params[3];
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_TexParameterIiv(ctx->Exec, (target, pname, params));
+   }
+}
+
+/** GL_EXT_texture_integer */
+static void GLAPIENTRY
+save_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_TEXPARAMETER_UI, 6);
+   if (n) {
+      n[1].e = target;
+      n[2].e = pname;
+      n[3].ui = params[0];
+      n[4].ui = params[1];
+      n[5].ui = params[2];
+      n[6].ui = params[3];
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_TexParameterIuiv(ctx->Exec, (target, pname, params));
+   }
+}
+
+/* GL_ARB_instanced_arrays */
+static void GLAPIENTRY
+save_VertexAttribDivisor(GLuint index, GLuint divisor)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_VERTEX_ATTRIB_DIVISOR, 2);
+   if (n) {
+      n[1].ui = index;
+      n[2].ui = divisor;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_VertexAttribDivisor(ctx->Exec, (index, 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)
+{
+   GLint parray[4];
+   parray[0] = param;
+   parray[1] = parray[2] = parray[3] = 0;
+   save_SamplerParameteriv(sampler, pname, parray);
+}
+
+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)
+{
+   GLfloat parray[4];
+   parray[0] = param;
+   parray[1] = parray[2] = parray[3] = 0.0F;
+   save_SamplerParameterfv(sampler, pname, parray);
+}
+
+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));
+   }
+}
+
+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].bf = flags;
+      n[2].ui = p.uint32[0];
+      n[3].ui = p.uint32[1];
+      save_pointer(&n[4], sync);
+   }
+   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_BeginConditionalRender(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_EndConditionalRender(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));
+   }
+}
+
+static void GLAPIENTRY
+save_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
+                           const GLuint *indices)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_UNIFORM_SUBROUTINES, 2 + POINTER_DWORDS);
+   if (n) {
+      GLint *indices_copy = NULL;
+
+      if (count > 0)
+         indices_copy = memdup(indices, sizeof(GLuint) * 4 * count);
+      n[1].e = shadertype;
+      n[2].si = count;
+      save_pointer(&n[3], indices_copy);
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_UniformSubroutinesuiv(ctx->Exec, (shadertype, count, indices));
+   }
+}
+
+/** GL_EXT_window_rectangles */
+static void GLAPIENTRY
+save_WindowRectanglesEXT(GLenum mode, GLsizei count, const GLint *box)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_WINDOW_RECTANGLES, 2 + POINTER_DWORDS);
+   if (n) {
+      GLint *box_copy = NULL;
+
+      if (count > 0)
+         box_copy = memdup(box, sizeof(GLint) * 4 * count);
+      n[1].e = mode;
+      n[2].si = count;
+      save_pointer(&n[3], box_copy);
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_WindowRectanglesEXT(ctx->Exec, (mode, count, box));
+   }
+}
+
+
+/** GL_NV_conservative_raster */
+static void GLAPIENTRY
+save_SubpixelPrecisionBiasNV(GLuint xbits, GLuint ybits)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_SUBPIXEL_PRECISION_BIAS, 2);
+   if (n) {
+      n[1].ui = xbits;
+      n[2].ui = ybits;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_SubpixelPrecisionBiasNV(ctx->Exec, (xbits, ybits));
+   }
+}
+
+/** GL_NV_conservative_raster_dilate */
+static void GLAPIENTRY
+save_ConservativeRasterParameterfNV(GLenum pname, GLfloat param)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_CONSERVATIVE_RASTER_PARAMETER_F, 2);
+   if (n) {
+      n[1].e = pname;
+      n[2].f = param;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ConservativeRasterParameterfNV(ctx->Exec, (pname, param));
+   }
+}
+
+/** GL_NV_conservative_raster_pre_snap_triangles */
+static void GLAPIENTRY
+save_ConservativeRasterParameteriNV(GLenum pname, GLint param)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_CONSERVATIVE_RASTER_PARAMETER_I, 2);
+   if (n) {
+      n[1].e = pname;
+      n[2].i = param;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ConservativeRasterParameteriNV(ctx->Exec, (pname, param));
+   }
+}
+
+/** GL_EXT_direct_state_access */
+
+static void GLAPIENTRY
+save_MatrixLoadfEXT(GLenum matrixMode, const GLfloat *m)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_MATRIX_LOAD, 17);
+   if (n) {
+      n[1].e = matrixMode;
+      for (unsigned i = 0; i < 16; i++) {
+         n[2 + i].f = m[i];
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MatrixLoadfEXT(ctx->Exec, (matrixMode, m));
+   }
+}
+
+static void GLAPIENTRY
+save_MatrixLoaddEXT(GLenum matrixMode, const GLdouble *m)
+{
+   GLfloat f[16];
+   for (unsigned i = 0; i < 16; i++) {
+      f[i] = (GLfloat) m[i];
+   }
+   save_MatrixLoadfEXT(matrixMode, f);
+}
+
+static void GLAPIENTRY
+save_MatrixMultfEXT(GLenum matrixMode, const GLfloat * m)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_MATRIX_MULT, 17);
+   if (n) {
+      n[1].e = matrixMode;
+      for (unsigned i = 0; i < 16; i++) {
+         n[2 + i].f = m[i];
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MatrixMultfEXT(ctx->Exec, (matrixMode, m));
+   }
+}
+
+static void GLAPIENTRY
+save_MatrixMultdEXT(GLenum matrixMode, const GLdouble * m)
+{
+   GLfloat f[16];
+   for (unsigned i = 0; i < 16; i++) {
+      f[i] = (GLfloat) m[i];
+   }
+   save_MatrixMultfEXT(matrixMode, f);
+}
+
+static void GLAPIENTRY
+save_MatrixRotatefEXT(GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_MATRIX_ROTATE, 5);
+   if (n) {
+      n[1].e = matrixMode;
+      n[2].f = angle;
+      n[3].f = x;
+      n[4].f = y;
+      n[5].f = z;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MatrixRotatefEXT(ctx->Exec, (matrixMode, angle, x, y, z));
+   }
+}
+
+static void GLAPIENTRY
+save_MatrixRotatedEXT(GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
+{
+   save_MatrixRotatefEXT(matrixMode, (GLfloat) angle, (GLfloat) x, (GLfloat) y, (GLfloat) z);
+}
+
+static void GLAPIENTRY
+save_MatrixScalefEXT(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_MATRIX_SCALE, 4);
+   if (n) {
+      n[1].e = matrixMode;
+      n[2].f = x;
+      n[3].f = y;
+      n[4].f = z;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MatrixScalefEXT(ctx->Exec, (matrixMode, x, y, z));
+   }
+}
+
+static void GLAPIENTRY
+save_MatrixScaledEXT(GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z)
+{
+   save_MatrixScalefEXT(matrixMode, (GLfloat) x, (GLfloat) y, (GLfloat) z);
+}
+
+static void GLAPIENTRY
+save_MatrixTranslatefEXT(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_MATRIX_TRANSLATE, 4);
+   if (n) {
+      n[1].e = matrixMode;
+      n[2].f = x;
+      n[3].f = y;
+      n[4].f = z;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MatrixTranslatefEXT(ctx->Exec, (matrixMode, x, y, z));
+   }
+}
+
+static void GLAPIENTRY
+save_MatrixTranslatedEXT(GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z)
+{
+   save_MatrixTranslatefEXT(matrixMode, (GLfloat) x, (GLfloat) y, (GLfloat) z);
+}
+
+static void GLAPIENTRY
+save_MatrixLoadIdentityEXT(GLenum matrixMode)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_MATRIX_LOAD_IDENTITY, 1);
+   if (n) {
+      n[1].e = matrixMode;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MatrixLoadIdentityEXT(ctx->Exec, (matrixMode));
+   }
+}
+
+static void GLAPIENTRY
+save_MatrixOrthoEXT(GLenum matrixMode, GLdouble left, GLdouble right,
+                    GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_MATRIX_ORTHO, 7);
+   if (n) {
+      n[1].e = matrixMode;
+      n[2].f = (GLfloat) left;
+      n[3].f = (GLfloat) right;
+      n[4].f = (GLfloat) bottom;
+      n[5].f = (GLfloat) top;
+      n[6].f = (GLfloat) nearval;
+      n[7].f = (GLfloat) farval;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MatrixOrthoEXT(ctx->Exec, (matrixMode, left, right, bottom, top, nearval, farval));
+   }
+}
+
+
+static void GLAPIENTRY
+save_MatrixFrustumEXT(GLenum matrixMode, GLdouble left, GLdouble right,
+                      GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_MATRIX_FRUSTUM, 7);
+   if (n) {
+      n[1].e = matrixMode;
+      n[2].f = (GLfloat) left;
+      n[3].f = (GLfloat) right;
+      n[4].f = (GLfloat) bottom;
+      n[5].f = (GLfloat) top;
+      n[6].f = (GLfloat) nearval;
+      n[7].f = (GLfloat) farval;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MatrixFrustumEXT(ctx->Exec, (matrixMode, left, right, bottom, top, nearval, farval));
+   }
+}
+
+static void GLAPIENTRY
+save_MatrixPushEXT(GLenum matrixMode)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node* n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_MATRIX_PUSH, 1);
+   if (n) {
+      n[1].e = matrixMode;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MatrixPushEXT(ctx->Exec, (matrixMode));
+   }
+}
+
+static void GLAPIENTRY
+save_MatrixPopEXT(GLenum matrixMode)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node* n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_MATRIX_POP, 1);
+   if (n) {
+      n[1].e = matrixMode;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MatrixPopEXT(ctx->Exec, (matrixMode));
+   }
+}
+
+static void GLAPIENTRY
+save_MatrixLoadTransposefEXT(GLenum matrixMode, const GLfloat m[16])
+{
+   GLfloat tm[16];
+   _math_transposef(tm, m);
+   save_MatrixLoadfEXT(matrixMode, tm);
+}
+
+static void GLAPIENTRY
+save_MatrixLoadTransposedEXT(GLenum matrixMode, const GLdouble m[16])
+{
+   GLfloat tm[16];
+   _math_transposefd(tm, m);
+   save_MatrixLoadfEXT(matrixMode, tm);
+}
+
+static void GLAPIENTRY
+save_MatrixMultTransposefEXT(GLenum matrixMode, const GLfloat m[16])
+{
+   GLfloat tm[16];
+   _math_transposef(tm, m);
+   save_MatrixMultfEXT(matrixMode, tm);
+}
+
+static void GLAPIENTRY
+save_MatrixMultTransposedEXT(GLenum matrixMode, const GLdouble m[16])
+{
+   GLfloat tm[16];
+   _math_transposefd(tm, m);
+   save_MatrixMultfEXT(matrixMode, tm);
+}
+
+static void GLAPIENTRY
+save_TextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname,
+                           const GLfloat *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_TEXTUREPARAMETER_F, 7);
+   if (n) {
+      n[1].ui = texture;
+      n[2].e = target;
+      n[3].e = pname;
+      n[4].f = params[0];
+      n[5].f = params[1];
+      n[6].f = params[2];
+      n[7].f = params[3];
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_TextureParameterfvEXT(ctx->Exec, (texture, target, pname, params));
+   }
+}
+
+
+static void GLAPIENTRY
+save_TextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param)
+{
+   GLfloat parray[4];
+   parray[0] = param;
+   parray[1] = parray[2] = parray[3] = 0.0F;
+   save_TextureParameterfvEXT(texture, target, pname, parray);
+}
+
+static void GLAPIENTRY
+save_TextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, const GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_TEXTUREPARAMETER_I, 7);
+   if (n) {
+      n[1].ui = texture;
+      n[2].e = target;
+      n[3].e = pname;
+      n[4].i = params[0];
+      n[5].i = params[1];
+      n[6].i = params[2];
+      n[7].i = params[3];
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_TextureParameterivEXT(ctx->Exec, (texture, target, pname, params));
+   }
+}
+
+static void GLAPIENTRY
+save_TextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param)
+{
+   GLint fparam[4];
+   fparam[0] = param;
+   fparam[1] = fparam[2] = fparam[3] = 0;
+   save_TextureParameterivEXT(texture, target, pname, fparam);
+}
+
+static void GLAPIENTRY
+save_TextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, const GLint* params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_TEXTUREPARAMETER_II, 7);
+   if (n) {
+      n[1].ui = texture;
+      n[2].e = target;
+      n[3].e = pname;
+      n[4].i = params[0];
+      n[5].i = params[1];
+      n[6].i = params[2];
+      n[7].i = params[3];
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_TextureParameterIivEXT(ctx->Exec, (texture, target, pname, params));
+   }
+}
+
+static void GLAPIENTRY
+save_TextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, const GLuint* params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_TEXTUREPARAMETER_IUI, 7);
+   if (n) {
+      n[1].ui = texture;
+      n[2].e = target;
+      n[3].e = pname;
+      n[4].ui = params[0];
+      n[5].ui = params[1];
+      n[6].ui = params[2];
+      n[7].ui = params[3];
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_TextureParameterIuivEXT(ctx->Exec, (texture, target, pname, params));
+   }
+}
+
+
+static void GLAPIENTRY
+save_TextureImage1DEXT(GLuint texture, GLenum target,
+                       GLint level, GLint components,
+                       GLsizei width, GLint border,
+                       GLenum format, GLenum type, const GLvoid * pixels)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   if (target == GL_PROXY_TEXTURE_1D) {
+      /* don't compile, execute immediately */
+      CALL_TextureImage1DEXT(ctx->Exec, (texture, target, level, components, width,
+                                         border, format, type, pixels));
+   }
+   else {
+      Node *n;
+      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+      n = alloc_instruction(ctx, OPCODE_TEXTURE_IMAGE1D, 8 + POINTER_DWORDS);
+      if (n) {
+         n[1].ui = texture;
+         n[2].e = target;
+         n[3].i = level;
+         n[4].i = components;
+         n[5].i = (GLint) width;
+         n[6].i = border;
+         n[7].e = format;
+         n[8].e = type;
+         save_pointer(&n[9],
+                      unpack_image(ctx, 1, width, 1, 1, format, type,
+                                   pixels, &ctx->Unpack));
+      }
+      if (ctx->ExecuteFlag) {
+         CALL_TextureImage1DEXT(ctx->Exec, (texture, target, level, components, width,
+                                            border, format, type, pixels));
+      }
+   }
+}
+
+
+static void GLAPIENTRY
+save_TextureImage2DEXT(GLuint texture, GLenum target,
+                       GLint level, GLint components,
+                       GLsizei width, GLsizei height, GLint border,
+                       GLenum format, GLenum type, const GLvoid * pixels)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   if (target == GL_PROXY_TEXTURE_2D) {
+      /* don't compile, execute immediately */
+      CALL_TextureImage2DEXT(ctx->Exec, (texture, target, level, components, width,
+                                         height, border, format, type, pixels));
+   }
+   else {
+      Node *n;
+      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+      n = alloc_instruction(ctx, OPCODE_TEXTURE_IMAGE2D, 9 + POINTER_DWORDS);
+      if (n) {
+         n[1].ui = texture;
+         n[2].e = target;
+         n[3].i = level;
+         n[4].i = components;
+         n[5].i = (GLint) width;
+         n[6].i = (GLint) height;
+         n[7].i = border;
+         n[8].e = format;
+         n[9].e = type;
+         save_pointer(&n[10],
+                      unpack_image(ctx, 2, width, height, 1, format, type,
+                                   pixels, &ctx->Unpack));
+      }
+      if (ctx->ExecuteFlag) {
+         CALL_TextureImage2DEXT(ctx->Exec, (texture, target, level, components, width,
+                                            height, border, format, type, pixels));
+      }
+   }
+}
+
+
+static void GLAPIENTRY
+save_TextureImage3DEXT(GLuint texture, GLenum target,
+                       GLint level, GLint internalFormat,
+                       GLsizei width, GLsizei height, GLsizei depth,
+                       GLint border,
+                       GLenum format, GLenum type, const GLvoid * pixels)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   if (target == GL_PROXY_TEXTURE_3D) {
+      /* don't compile, execute immediately */
+      CALL_TextureImage3DEXT(ctx->Exec, (texture, target, level, internalFormat, width,
+                                         height, depth, border, format, type,
+                                         pixels));
+   }
+   else {
+      Node *n;
+      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+      n = alloc_instruction(ctx, OPCODE_TEXTURE_IMAGE3D, 10 + POINTER_DWORDS);
+      if (n) {
+         n[1].ui = texture;
+         n[2].e = target;
+         n[3].i = level;
+         n[4].i = (GLint) internalFormat;
+         n[5].i = (GLint) width;
+         n[6].i = (GLint) height;
+         n[7].i = (GLint) depth;
+         n[8].i = border;
+         n[9].e = format;
+         n[10].e = type;
+         save_pointer(&n[11],
+                      unpack_image(ctx, 3, width, height, depth, format, type,
+                                   pixels, &ctx->Unpack));
+      }
+      if (ctx->ExecuteFlag) {
+         CALL_TextureImage3DEXT(ctx->Exec, (texture, target, level, internalFormat,
+                                            width, height, depth, border, format,
+                                            type, pixels));
+      }
+   }
+}
+
+
+static void GLAPIENTRY
+save_TextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset,
+                   GLsizei width, GLenum format, GLenum type,
+                   const GLvoid * pixels)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+   n = alloc_instruction(ctx, OPCODE_TEXTURE_SUB_IMAGE1D, 7 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = texture;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = (GLint) width;
+      n[6].e = format;
+      n[7].e = type;
+      save_pointer(&n[8],
+                   unpack_image(ctx, 1, width, 1, 1, format, type,
+                                pixels, &ctx->Unpack));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_TextureSubImage1DEXT(ctx->Exec, (texture, target, level, xoffset, width,
+                                            format, type, pixels));
+   }
+}
+
+
+static void GLAPIENTRY
+save_TextureSubImage2DEXT(GLuint texture, GLenum target, GLint level,
+                          GLint xoffset, GLint yoffset,
+                          GLsizei width, GLsizei height,
+                          GLenum format, GLenum type, const GLvoid * pixels)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+   n = alloc_instruction(ctx, OPCODE_TEXTURE_SUB_IMAGE2D, 9 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = texture;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = yoffset;
+      n[6].i = (GLint) width;
+      n[7].i = (GLint) height;
+      n[8].e = format;
+      n[9].e = type;
+      save_pointer(&n[10],
+                   unpack_image(ctx, 2, width, height, 1, format, type,
+                                pixels, &ctx->Unpack));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_TextureSubImage2DEXT(ctx->Exec, (texture, target, level, xoffset, yoffset,
+                                            width, height, format, type, pixels));
+   }
+}
+
+
+static void GLAPIENTRY
+save_TextureSubImage3DEXT(GLuint texture, GLenum target, GLint level,
+                          GLint xoffset, GLint yoffset, GLint zoffset,
+                          GLsizei width, GLsizei height, GLsizei depth,
+                          GLenum format, GLenum type, const GLvoid * pixels)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+   n = alloc_instruction(ctx, OPCODE_TEXTURE_SUB_IMAGE3D, 11 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = texture;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = yoffset;
+      n[6].i = zoffset;
+      n[7].i = (GLint) width;
+      n[8].i = (GLint) height;
+      n[9].i = (GLint) depth;
+      n[10].e = format;
+      n[11].e = type;
+      save_pointer(&n[12],
+                   unpack_image(ctx, 3, width, height, depth, format, type,
+                                pixels, &ctx->Unpack));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_TextureSubImage3DEXT(ctx->Exec, (texture, target, level,
+                                            xoffset, yoffset, zoffset,
+                                            width, height, depth, format, type,
+                                            pixels));
+   }
+}
+
+static void GLAPIENTRY
+save_CopyTextureImage1DEXT(GLuint texture, GLenum target, GLint level,
+                           GLenum internalformat, GLint x, GLint y,
+                           GLsizei width, GLint border)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_COPY_TEXTURE_IMAGE1D, 8);
+   if (n) {
+      n[1].ui = texture;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].e = internalformat;
+      n[5].i = x;
+      n[6].i = y;
+      n[7].i = width;
+      n[8].i = border;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CopyTextureImage1DEXT(ctx->Exec, (texture, target, level,
+                                             internalformat, x, y,
+                                             width, border));
+   }
+}
+
+static void GLAPIENTRY
+save_CopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level,
+                           GLenum internalformat,
+                           GLint x, GLint y, GLsizei width,
+                           GLsizei height, GLint border)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_COPY_TEXTURE_IMAGE2D, 9);
+   if (n) {
+      n[1].ui = texture;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].e = internalformat;
+      n[5].i = x;
+      n[6].i = y;
+      n[7].i = width;
+      n[8].i = height;
+      n[9].i = border;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CopyTextureImage2DEXT(ctx->Exec, (texture, target, level,
+                                             internalformat, x, y,
+                                             width, height, border));
+   }
+}
+
+static void GLAPIENTRY
+save_CopyTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level,
+                              GLint xoffset, GLint x, GLint y, GLsizei width)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_COPY_TEXTURE_SUB_IMAGE1D, 7);
+   if (n) {
+      n[1].ui = texture;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = x;
+      n[6].i = y;
+      n[7].i = width;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CopyTextureSubImage1DEXT(ctx->Exec,
+                             (texture, target, level, xoffset, x, y, width));
+   }
+}
+
+static void GLAPIENTRY
+save_CopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level,
+                              GLint xoffset, GLint yoffset,
+                              GLint x, GLint y, GLsizei width, GLint height)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_COPY_TEXTURE_SUB_IMAGE2D, 9);
+   if (n) {
+      n[1].ui = texture;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = yoffset;
+      n[6].i = x;
+      n[7].i = y;
+      n[8].i = width;
+      n[9].i = height;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CopyTextureSubImage2DEXT(ctx->Exec, (texture, target, level,
+                                                xoffset, yoffset,
+                                                x, y, width, height));
+   }
+}
+
+
+static void GLAPIENTRY
+save_CopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level,
+                              GLint xoffset, GLint yoffset, GLint zoffset,
+                              GLint x, GLint y, GLsizei width, GLint height)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_COPY_TEXTURE_SUB_IMAGE3D, 10);
+   if (n) {
+      n[1].ui = texture;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = yoffset;
+      n[6].i = zoffset;
+      n[7].i = x;
+      n[8].i = y;
+      n[9].i = width;
+      n[10].i = height;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CopyTextureSubImage3DEXT(ctx->Exec, (texture, target, level,
+                                                xoffset, yoffset, zoffset,
+                                                x, y, width, height));
+   }
+}
+
+
+static void GLAPIENTRY
+save_BindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_BIND_MULTITEXTURE, 3);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].ui = texture;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_BindMultiTextureEXT(ctx->Exec, (texunit, target, texture));
+   }
+}
+
+
+static void GLAPIENTRY
+save_MultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname,
+                           const GLfloat *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_MULTITEXPARAMETER_F, 7);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].e = pname;
+      n[4].f = params[0];
+      n[5].f = params[1];
+      n[6].f = params[2];
+      n[7].f = params[3];
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MultiTexParameterfvEXT(ctx->Exec, (texunit, target, pname, params));
+   }
+}
+
+
+static void GLAPIENTRY
+save_MultiTexParameterfEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat param)
+{
+   GLfloat parray[4];
+   parray[0] = param;
+   parray[1] = parray[2] = parray[3] = 0.0F;
+   save_MultiTexParameterfvEXT(texunit, target, pname, parray);
+}
+
+static void GLAPIENTRY
+save_MultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_MULTITEXPARAMETER_I, 7);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].e = pname;
+      n[4].i = params[0];
+      n[5].i = params[1];
+      n[6].i = params[2];
+      n[7].i = params[3];
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MultiTexParameterivEXT(ctx->Exec, (texunit, target, pname, params));
+   }
+}
+
+static void GLAPIENTRY
+save_MultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_MULTITEXPARAMETER_II, 7);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].e = pname;
+      n[4].i = params[0];
+      n[5].i = params[1];
+      n[6].i = params[2];
+      n[7].i = params[3];
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MultiTexParameterIivEXT(ctx->Exec, (texunit, target, pname, params));
+   }
+}
+
+static void GLAPIENTRY
+save_MultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, const GLuint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_MULTITEXPARAMETER_IUI, 7);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].e = pname;
+      n[4].ui = params[0];
+      n[5].ui = params[1];
+      n[6].ui = params[2];
+      n[7].ui = params[3];
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MultiTexParameterIuivEXT(ctx->Exec, (texunit, target, pname, params));
+   }
+}
+
+static void GLAPIENTRY
+save_MultiTexParameteriEXT(GLenum texunit, GLenum target, GLenum pname, GLint param)
+{
+   GLint fparam[4];
+   fparam[0] = param;
+   fparam[1] = fparam[2] = fparam[3] = 0;
+   save_MultiTexParameterivEXT(texunit, target, pname, fparam);
+}
+
+
+static void GLAPIENTRY
+save_MultiTexImage1DEXT(GLenum texunit, GLenum target,
+                        GLint level, GLint components,
+                        GLsizei width, GLint border,
+                        GLenum format, GLenum type, const GLvoid * pixels)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   if (target == GL_PROXY_TEXTURE_1D) {
+      /* don't compile, execute immediately */
+      CALL_MultiTexImage1DEXT(ctx->Exec, (texunit, target, level, components, width,
+                                         border, format, type, pixels));
+   }
+   else {
+      Node *n;
+      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+      n = alloc_instruction(ctx, OPCODE_MULTITEX_IMAGE1D, 8 + POINTER_DWORDS);
+      if (n) {
+         n[1].e = texunit;
+         n[2].e = target;
+         n[3].i = level;
+         n[4].i = components;
+         n[5].i = (GLint) width;
+         n[6].i = border;
+         n[7].e = format;
+         n[8].e = type;
+         save_pointer(&n[9],
+                      unpack_image(ctx, 1, width, 1, 1, format, type,
+                                   pixels, &ctx->Unpack));
+      }
+      if (ctx->ExecuteFlag) {
+         CALL_MultiTexImage1DEXT(ctx->Exec, (texunit, target, level, components, width,
+                                            border, format, type, pixels));
+      }
+   }
+}
+
+
+static void GLAPIENTRY
+save_MultiTexImage2DEXT(GLenum texunit, GLenum target,
+                       GLint level, GLint components,
+                       GLsizei width, GLsizei height, GLint border,
+                       GLenum format, GLenum type, const GLvoid * pixels)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   if (target == GL_PROXY_TEXTURE_2D) {
+      /* don't compile, execute immediately */
+      CALL_MultiTexImage2DEXT(ctx->Exec, (texunit, target, level, components, width,
+                                         height, border, format, type, pixels));
+   }
+   else {
+      Node *n;
+      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+      n = alloc_instruction(ctx, OPCODE_MULTITEX_IMAGE2D, 9 + POINTER_DWORDS);
+      if (n) {
+         n[1].e = texunit;
+         n[2].e = target;
+         n[3].i = level;
+         n[4].i = components;
+         n[5].i = (GLint) width;
+         n[6].i = (GLint) height;
+         n[7].i = border;
+         n[8].e = format;
+         n[9].e = type;
+         save_pointer(&n[10],
+                      unpack_image(ctx, 2, width, height, 1, format, type,
+                                   pixels, &ctx->Unpack));
+      }
+      if (ctx->ExecuteFlag) {
+         CALL_MultiTexImage2DEXT(ctx->Exec, (texunit, target, level, components, width,
+                                            height, border, format, type, pixels));
+      }
+   }
+}
+
+
+static void GLAPIENTRY
+save_MultiTexImage3DEXT(GLenum texunit, GLenum target,
+                       GLint level, GLint internalFormat,
+                       GLsizei width, GLsizei height, GLsizei depth,
+                       GLint border,
+                       GLenum format, GLenum type, const GLvoid * pixels)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   if (target == GL_PROXY_TEXTURE_3D) {
+      /* don't compile, execute immediately */
+      CALL_MultiTexImage3DEXT(ctx->Exec, (texunit, target, level, internalFormat, width,
+                                         height, depth, border, format, type,
+                                         pixels));
+   }
+   else {
+      Node *n;
+      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+      n = alloc_instruction(ctx, OPCODE_MULTITEX_IMAGE3D, 10 + POINTER_DWORDS);
+      if (n) {
+         n[1].e = texunit;
+         n[2].e = target;
+         n[3].i = level;
+         n[4].i = (GLint) internalFormat;
+         n[5].i = (GLint) width;
+         n[6].i = (GLint) height;
+         n[7].i = (GLint) depth;
+         n[8].i = border;
+         n[9].e = format;
+         n[10].e = type;
+         save_pointer(&n[11],
+                      unpack_image(ctx, 3, width, height, depth, format, type,
+                                   pixels, &ctx->Unpack));
+      }
+      if (ctx->ExecuteFlag) {
+         CALL_MultiTexImage3DEXT(ctx->Exec, (texunit, target, level, internalFormat,
+                                            width, height, depth, border, format,
+                                            type, pixels));
+      }
+   }
+}
+
+
+static void GLAPIENTRY
+save_MultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset,
+                   GLsizei width, GLenum format, GLenum type,
+                   const GLvoid * pixels)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+   n = alloc_instruction(ctx, OPCODE_MULTITEX_SUB_IMAGE1D, 7 + POINTER_DWORDS);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = (GLint) width;
+      n[6].e = format;
+      n[7].e = type;
+      save_pointer(&n[8],
+                   unpack_image(ctx, 1, width, 1, 1, format, type,
+                                pixels, &ctx->Unpack));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MultiTexSubImage1DEXT(ctx->Exec, (texunit, target, level, xoffset, width,
+                                            format, type, pixels));
+   }
+}
+
+
+static void GLAPIENTRY
+save_MultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level,
+                          GLint xoffset, GLint yoffset,
+                          GLsizei width, GLsizei height,
+                          GLenum format, GLenum type, const GLvoid * pixels)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+   n = alloc_instruction(ctx, OPCODE_MULTITEX_SUB_IMAGE2D, 9 + POINTER_DWORDS);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = yoffset;
+      n[6].i = (GLint) width;
+      n[7].i = (GLint) height;
+      n[8].e = format;
+      n[9].e = type;
+      save_pointer(&n[10],
+                   unpack_image(ctx, 2, width, height, 1, format, type,
+                                pixels, &ctx->Unpack));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MultiTexSubImage2DEXT(ctx->Exec, (texunit, target, level, xoffset, yoffset,
+                                            width, height, format, type, pixels));
+   }
+}
+
+
+static void GLAPIENTRY
+save_MultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level,
+                          GLint xoffset, GLint yoffset, GLint zoffset,
+                          GLsizei width, GLsizei height, GLsizei depth,
+                          GLenum format, GLenum type, const GLvoid * pixels)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+   n = alloc_instruction(ctx, OPCODE_MULTITEX_SUB_IMAGE3D, 11 + POINTER_DWORDS);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = yoffset;
+      n[6].i = zoffset;
+      n[7].i = (GLint) width;
+      n[8].i = (GLint) height;
+      n[9].i = (GLint) depth;
+      n[10].e = format;
+      n[11].e = type;
+      save_pointer(&n[12],
+                   unpack_image(ctx, 3, width, height, depth, format, type,
+                                pixels, &ctx->Unpack));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MultiTexSubImage3DEXT(ctx->Exec, (texunit, target, level,
+                                            xoffset, yoffset, zoffset,
+                                            width, height, depth, format, type,
+                                            pixels));
+   }
+}
+
+
+static void GLAPIENTRY
+save_CopyMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level,
+                           GLenum internalformat, GLint x, GLint y,
+                           GLsizei width, GLint border)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_COPY_MULTITEX_IMAGE1D, 8);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].e = internalformat;
+      n[5].i = x;
+      n[6].i = y;
+      n[7].i = width;
+      n[8].i = border;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CopyMultiTexImage1DEXT(ctx->Exec, (texunit, target, level,
+                                             internalformat, x, y,
+                                             width, border));
+   }
+}
+
+
+static void GLAPIENTRY
+save_CopyMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level,
+                           GLenum internalformat,
+                           GLint x, GLint y, GLsizei width,
+                           GLsizei height, GLint border)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_COPY_MULTITEX_IMAGE2D, 9);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].e = internalformat;
+      n[5].i = x;
+      n[6].i = y;
+      n[7].i = width;
+      n[8].i = height;
+      n[9].i = border;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CopyMultiTexImage2DEXT(ctx->Exec, (texunit, target, level,
+                                             internalformat, x, y,
+                                             width, height, border));
+   }
+}
+
+
+static void GLAPIENTRY
+save_CopyMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level,
+                              GLint xoffset, GLint x, GLint y, GLsizei width)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_COPY_MULTITEX_SUB_IMAGE1D, 7);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = x;
+      n[6].i = y;
+      n[7].i = width;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CopyMultiTexSubImage1DEXT(ctx->Exec,
+                             (texunit, target, level, xoffset, x, y, width));
+   }
+}
+
+
+static void GLAPIENTRY
+save_CopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level,
+                              GLint xoffset, GLint yoffset,
+                              GLint x, GLint y, GLsizei width, GLint height)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_COPY_MULTITEX_SUB_IMAGE2D, 9);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = yoffset;
+      n[6].i = x;
+      n[7].i = y;
+      n[8].i = width;
+      n[9].i = height;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CopyMultiTexSubImage2DEXT(ctx->Exec, (texunit, target, level,
+                                                xoffset, yoffset,
+                                                x, y, width, height));
+   }
+}
+
+
+static void GLAPIENTRY
+save_CopyMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level,
+                              GLint xoffset, GLint yoffset, GLint zoffset,
+                              GLint x, GLint y, GLsizei width, GLint height)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_COPY_MULTITEX_SUB_IMAGE3D, 10);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = yoffset;
+      n[6].i = zoffset;
+      n[7].i = x;
+      n[8].i = y;
+      n[9].i = width;
+      n[10].i = height;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CopyMultiTexSubImage3DEXT(ctx->Exec, (texunit, target, level,
+                                                xoffset, yoffset, zoffset,
+                                                x, y, width, height));
+   }
+}
+
+
+static void GLAPIENTRY
+save_MultiTexEnvfvEXT(GLenum texunit, GLenum target, GLenum pname, const GLfloat *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_MULTITEXENV, 7);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].e = pname;
+      if (pname == GL_TEXTURE_ENV_COLOR) {
+         n[4].f = params[0];
+         n[5].f = params[1];
+         n[6].f = params[2];
+         n[7].f = params[3];
+      }
+      else {
+         n[4].f = params[0];
+         n[5].f = n[6].f = n[7].f = 0.0F;
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_MultiTexEnvfvEXT(ctx->Exec, (texunit, target, pname, params));
+   }
+}
+
+
+static void GLAPIENTRY
+save_MultiTexEnvfEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat param)
+{
+   GLfloat parray[4];
+   parray[0] = (GLfloat) param;
+   parray[1] = parray[2] = parray[3] = 0.0F;
+   save_MultiTexEnvfvEXT(texunit, target, pname, parray);
+}
+
+
+static void GLAPIENTRY
+save_MultiTexEnviEXT(GLenum texunit, GLenum target, GLenum pname, GLint param)
+{
+   GLfloat p[4];
+   p[0] = (GLfloat) param;
+   p[1] = p[2] = p[3] = 0.0F;
+   save_MultiTexEnvfvEXT(texunit, target, pname, p);
+}
+
+
+static void GLAPIENTRY
+save_MultiTexEnvivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint * param)
+{
+   GLfloat p[4];
+   if (pname == GL_TEXTURE_ENV_COLOR) {
+      p[0] = INT_TO_FLOAT(param[0]);
+      p[1] = INT_TO_FLOAT(param[1]);
+      p[2] = INT_TO_FLOAT(param[2]);
+      p[3] = INT_TO_FLOAT(param[3]);
+   }
+   else {
+      p[0] = (GLfloat) param[0];
+      p[1] = p[2] = p[3] = 0.0F;
+   }
+   save_MultiTexEnvfvEXT(texunit, target, pname, p);
+}
+
+
+static void GLAPIENTRY
+save_CompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level,
+                                 GLenum internalFormat, GLsizei width,
+                                 GLint border, GLsizei imageSize,
+                                 const GLvoid * data)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   if (target == GL_PROXY_TEXTURE_1D) {
+      /* don't compile, execute immediately */
+      CALL_CompressedTextureImage1DEXT(ctx->Exec, (texture, target, level,
+                                                   internalFormat, width,
+                                                   border, imageSize,
+                                                   data));
+   }
+   else {
+      Node *n;
+      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+      n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEXTURE_IMAGE_1D,
+                            7 + POINTER_DWORDS);
+      if (n) {
+         n[1].ui = texture;
+         n[2].e = target;
+         n[3].i = level;
+         n[4].e = internalFormat;
+         n[5].i = (GLint) width;
+         n[6].i = border;
+         n[7].i = imageSize;
+         save_pointer(&n[8],
+                      copy_data(data, imageSize, "glCompressedTextureImage1DEXT"));
+      }
+      if (ctx->ExecuteFlag) {
+         CALL_CompressedTextureImage1DEXT(ctx->Exec,
+                                          (texture, target, level, internalFormat,
+                                           width, border, imageSize, data));
+      }
+   }
+}
+
+
+static void GLAPIENTRY
+save_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level,
+                                 GLenum internalFormat, GLsizei width,
+                                 GLsizei height, GLint border, GLsizei imageSize,
+                                 const GLvoid * data)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   if (target == GL_PROXY_TEXTURE_2D) {
+      /* don't compile, execute immediately */
+      CALL_CompressedTextureImage2DEXT(ctx->Exec, (texture, target, level,
+                                                   internalFormat, width, height,
+                                                   border, imageSize, data));
+   }
+   else {
+      Node *n;
+      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+      n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEXTURE_IMAGE_2D,
+                            8 + POINTER_DWORDS);
+      if (n) {
+         n[1].ui = texture;
+         n[2].e = target;
+         n[3].i = level;
+         n[4].e = internalFormat;
+         n[5].i = (GLint) width;
+         n[6].i = (GLint) height;
+         n[7].i = border;
+         n[8].i = imageSize;
+         save_pointer(&n[9],
+                      copy_data(data, imageSize, "glCompressedTextureImage2DEXT"));
+      }
+      if (ctx->ExecuteFlag) {
+         CALL_CompressedTextureImage2DEXT(ctx->Exec,
+                                          (texture, target, level, internalFormat,
+                                           width, height, border, imageSize, data));
+      }
+   }
+}
+
+
+static void GLAPIENTRY
+save_CompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level,
+                                 GLenum internalFormat, GLsizei width,
+                                 GLsizei height, GLsizei depth, GLint border,
+                                 GLsizei imageSize, const GLvoid * data)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   if (target == GL_PROXY_TEXTURE_3D) {
+      /* don't compile, execute immediately */
+      CALL_CompressedTextureImage3DEXT(ctx->Exec, (texture, target, level,
+                                                   internalFormat, width,
+                                                   height, depth, border,
+                                                   imageSize, data));
+   }
+   else {
+      Node *n;
+      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+      n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEXTURE_IMAGE_3D,
+                            9 + POINTER_DWORDS);
+      if (n) {
+         n[1].ui = texture;
+         n[2].e = target;
+         n[3].i = level;
+         n[4].e = internalFormat;
+         n[5].i = (GLint) width;
+         n[6].i = (GLint) height;
+         n[7].i = (GLint) depth;
+         n[8].i = border;
+         n[9].i = imageSize;
+         save_pointer(&n[10],
+                      copy_data(data, imageSize, "glCompressedTextureImage3DEXT"));
+      }
+      if (ctx->ExecuteFlag) {
+         CALL_CompressedTextureImage3DEXT(ctx->Exec,
+                                          (texture, target, level, internalFormat,
+                                           width, height, depth, border, imageSize,
+                                           data));
+      }
+   }
+}
+
+
+static void GLAPIENTRY
+save_CompressedTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset,
+                                    GLsizei width, GLenum format,
+                                    GLsizei imageSize, const GLvoid * data)
+{
+   Node *n;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+   n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEXTURE_SUB_IMAGE_1D,
+                         7 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = texture;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = (GLint) width;
+      n[6].e = format;
+      n[7].i = imageSize;
+      save_pointer(&n[8],
+                   copy_data(data, imageSize, "glCompressedTextureSubImage1DEXT"));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CompressedTextureSubImage1DEXT(ctx->Exec, (texture, target, level, xoffset,
+                                                      width, format, imageSize, data));
+   }
+}
+
+
+static void GLAPIENTRY
+save_CompressedTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset,
+                                    GLint yoffset, GLsizei width, GLsizei height,
+                                    GLenum format, GLsizei imageSize,
+                                    const GLvoid * data)
+{
+   Node *n;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+   n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEXTURE_SUB_IMAGE_2D,
+                         9 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = texture;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = yoffset;
+      n[6].i = (GLint) width;
+      n[7].i = (GLint) height;
+      n[8].e = format;
+      n[9].i = imageSize;
+      save_pointer(&n[10],
+                   copy_data(data, imageSize, "glCompressedTextureSubImage2DEXT"));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CompressedTextureSubImage2DEXT(ctx->Exec,
+                                          (texture, target, level, xoffset, yoffset,
+                                           width, height, format, imageSize, data));
+   }
+}
+
+
+static void GLAPIENTRY
+save_CompressedTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset,
+                                    GLint yoffset, GLint zoffset, GLsizei width,
+                                    GLsizei height, GLsizei depth, GLenum format,
+                                    GLsizei imageSize, const GLvoid * data)
+{
+   Node *n;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+   n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEXTURE_SUB_IMAGE_3D,
+                         11 + POINTER_DWORDS);
+   if (n) {
+      n[1].ui = texture;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = yoffset;
+      n[6].i = zoffset;
+      n[7].i = (GLint) width;
+      n[8].i = (GLint) height;
+      n[9].i = (GLint) depth;
+      n[10].e = format;
+      n[11].i = imageSize;
+      save_pointer(&n[12],
+                   copy_data(data, imageSize, "glCompressedTextureSubImage3DEXT"));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CompressedTextureSubImage3DEXT(ctx->Exec,
+                                          (texture, target, level, xoffset, yoffset,
+                                           zoffset, width, height, depth, format,
+                                           imageSize, data));
+   }
+}
+
+
+static void GLAPIENTRY
+save_CompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level,
+                                  GLenum internalFormat, GLsizei width,
+                                  GLint border, GLsizei imageSize,
+                                  const GLvoid * data)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   if (target == GL_PROXY_TEXTURE_1D) {
+      /* don't compile, execute immediately */
+      CALL_CompressedMultiTexImage1DEXT(ctx->Exec, (texunit, target, level,
+                                                   internalFormat, width,
+                                                   border, imageSize,
+                                                   data));
+   }
+   else {
+      Node *n;
+      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+      n = alloc_instruction(ctx, OPCODE_COMPRESSED_MULTITEX_IMAGE_1D,
+                            7 + POINTER_DWORDS);
+      if (n) {
+         n[1].e = texunit;
+         n[2].e = target;
+         n[3].i = level;
+         n[4].e = internalFormat;
+         n[5].i = (GLint) width;
+         n[6].i = border;
+         n[7].i = imageSize;
+         save_pointer(&n[8],
+                      copy_data(data, imageSize, "glCompressedMultiTexImage1DEXT"));
+      }
+      if (ctx->ExecuteFlag) {
+         CALL_CompressedMultiTexImage1DEXT(ctx->Exec,
+                                           (texunit, target, level, internalFormat,
+                                            width, border, imageSize, data));
+      }
+   }
+}
+
+
+static void GLAPIENTRY
+save_CompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level,
+                                  GLenum internalFormat, GLsizei width,
+                                  GLsizei height, GLint border, GLsizei imageSize,
+                                  const GLvoid * data)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   if (target == GL_PROXY_TEXTURE_2D) {
+      /* don't compile, execute immediately */
+      CALL_CompressedMultiTexImage2DEXT(ctx->Exec, (texunit, target, level,
+                                                   internalFormat, width, height,
+                                                   border, imageSize, data));
+   }
+   else {
+      Node *n;
+      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+      n = alloc_instruction(ctx, OPCODE_COMPRESSED_MULTITEX_IMAGE_2D,
+                            8 + POINTER_DWORDS);
+      if (n) {
+         n[1].e = texunit;
+         n[2].e = target;
+         n[3].i = level;
+         n[4].e = internalFormat;
+         n[5].i = (GLint) width;
+         n[6].i = (GLint) height;
+         n[7].i = border;
+         n[8].i = imageSize;
+         save_pointer(&n[9],
+                      copy_data(data, imageSize, "glCompressedMultiTexImage2DEXT"));
+      }
+      if (ctx->ExecuteFlag) {
+         CALL_CompressedMultiTexImage2DEXT(ctx->Exec,
+                                           (texunit, target, level, internalFormat,
+                                            width, height, border, imageSize, data));
+      }
+   }
+}
+
+
+static void GLAPIENTRY
+save_CompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level,
+                                  GLenum internalFormat, GLsizei width,
+                                  GLsizei height, GLsizei depth, GLint border,
+                                  GLsizei imageSize, const GLvoid * data)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   if (target == GL_PROXY_TEXTURE_3D) {
+      /* don't compile, execute immediately */
+      CALL_CompressedMultiTexImage3DEXT(ctx->Exec, (texunit, target, level,
+                                                   internalFormat, width,
+                                                   height, depth, border,
+                                                   imageSize, data));
+   }
+   else {
+      Node *n;
+      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+      n = alloc_instruction(ctx, OPCODE_COMPRESSED_MULTITEX_IMAGE_3D,
+                            9 + POINTER_DWORDS);
+      if (n) {
+         n[1].e = texunit;
+         n[2].e = target;
+         n[3].i = level;
+         n[4].e = internalFormat;
+         n[5].i = (GLint) width;
+         n[6].i = (GLint) height;
+         n[7].i = (GLint) depth;
+         n[8].i = border;
+         n[9].i = imageSize;
+         save_pointer(&n[10],
+                      copy_data(data, imageSize, "glCompressedMultiTexImage3DEXT"));
+      }
+      if (ctx->ExecuteFlag) {
+         CALL_CompressedMultiTexImage3DEXT(ctx->Exec,
+                                           (texunit, target, level, internalFormat,
+                                            width, height, depth, border, imageSize,
+                                            data));
+      }
+   }
+}
+
+
+static void GLAPIENTRY
+save_CompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset,
+                                     GLsizei width, GLenum format,
+                                     GLsizei imageSize, const GLvoid * data)
+{
+   Node *n;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+   n = alloc_instruction(ctx, OPCODE_COMPRESSED_MULTITEX_SUB_IMAGE_1D,
+                         7 + POINTER_DWORDS);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = (GLint) width;
+      n[6].e = format;
+      n[7].i = imageSize;
+      save_pointer(&n[8],
+                   copy_data(data, imageSize, "glCompressedMultiTexSubImage1DEXT"));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CompressedMultiTexSubImage1DEXT(ctx->Exec, (texunit, target, level, xoffset,
+                                                       width, format, imageSize, data));
+   }
+}
+
+
+static void GLAPIENTRY
+save_CompressedMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset,
+                                     GLint yoffset, GLsizei width, GLsizei height,
+                                     GLenum format, GLsizei imageSize,
+                                     const GLvoid * data)
+{
+   Node *n;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+   n = alloc_instruction(ctx, OPCODE_COMPRESSED_MULTITEX_SUB_IMAGE_2D,
+                         9 + POINTER_DWORDS);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = yoffset;
+      n[6].i = (GLint) width;
+      n[7].i = (GLint) height;
+      n[8].e = format;
+      n[9].i = imageSize;
+      save_pointer(&n[10],
+                   copy_data(data, imageSize, "glCompressedMultiTexSubImage2DEXT"));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CompressedMultiTexSubImage2DEXT(ctx->Exec,
+                                           (texunit, target, level, xoffset, yoffset,
+                                            width, height, format, imageSize, data));
+   }
+}
+
+
+static void GLAPIENTRY
+save_CompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset,
+                                     GLint yoffset, GLint zoffset, GLsizei width,
+                                     GLsizei height, GLsizei depth, GLenum format,
+                                     GLsizei imageSize, const GLvoid * data)
+{
+   Node *n;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+   n = alloc_instruction(ctx, OPCODE_COMPRESSED_MULTITEX_SUB_IMAGE_3D,
+                         11 + POINTER_DWORDS);
+   if (n) {
+      n[1].e = texunit;
+      n[2].e = target;
+      n[3].i = level;
+      n[4].i = xoffset;
+      n[5].i = yoffset;
+      n[6].i = zoffset;
+      n[7].i = (GLint) width;
+      n[8].i = (GLint) height;
+      n[9].i = (GLint) depth;
+      n[10].e = format;
+      n[11].i = imageSize;
+      save_pointer(&n[12],
+                   copy_data(data, imageSize, "glCompressedMultiTexSubImage3DEXT"));
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_CompressedMultiTexSubImage3DEXT(ctx->Exec,
+                                           (texunit, target, level, xoffset, yoffset,
+                                            zoffset, width, height, depth, format,
+                                            imageSize, data));
+   }
+}
+
+
+static void GLAPIENTRY
+save_NamedProgramStringEXT(GLuint program, GLenum target, GLenum format, GLsizei len,
+                           const GLvoid * string)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
+   n = alloc_instruction(ctx, OPCODE_NAMED_PROGRAM_STRING, 4 + POINTER_DWORDS);
+   if (n) {
+      GLubyte *programCopy = malloc(len);
+      if (!programCopy) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glNamedProgramStringEXT");
+         return;
+      }
+      memcpy(programCopy, string, len);
+      n[1].ui = program;
+      n[2].e = target;
+      n[3].e = format;
+      n[4].i = len;
+      save_pointer(&n[5], programCopy);
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_NamedProgramStringEXT(ctx->Exec, (program, target, format, len, string));
+   }
+}
+
+
+static void GLAPIENTRY
+save_NamedProgramLocalParameter4fEXT(GLuint program, GLenum target, GLuint index,
+                                     GLfloat x, GLfloat y, GLfloat z, GLfloat w)
 {
    GET_CURRENT_CONTEXT(ctx);
    Node *n;
    ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   n = alloc_instruction(ctx, OPCODE_BEGIN_CONDITIONAL_RENDER, 2);
+   n = alloc_instruction(ctx, OPCODE_NAMED_PROGRAM_LOCAL_PARAMETER, 7);
    if (n) {
-      n[1].i = queryId;
-      n[2].e = mode;
+      n[1].ui = program;
+      n[2].e = target;
+      n[3].ui = index;
+      n[4].f = x;
+      n[5].f = y;
+      n[6].f = z;
+      n[7].f = w;
    }
    if (ctx->ExecuteFlag) {
-      CALL_BeginConditionalRender(ctx->Exec, (queryId, mode));
+      CALL_NamedProgramLocalParameter4fEXT(ctx->Exec, (program, target, index, x, y, z, w));
    }
 }
 
+
 static void GLAPIENTRY
-save_EndConditionalRender(void)
+save_NamedProgramLocalParameter4fvEXT(GLuint program, GLenum target, GLuint index,
+                                      const GLfloat *params)
 {
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-   alloc_instruction(ctx, OPCODE_END_CONDITIONAL_RENDER, 0);
-   if (ctx->ExecuteFlag) {
-      CALL_EndConditionalRender(ctx->Exec, ());
-   }
+   save_NamedProgramLocalParameter4fEXT(program, target, index, params[0],
+                                        params[1], params[2], params[3]);
 }
 
+
 static void GLAPIENTRY
-save_UniformBlockBinding(GLuint prog, GLuint index, GLuint binding)
+save_NamedProgramLocalParameter4dEXT(GLuint program, GLenum target, GLuint index,
+                                    GLdouble x, GLdouble y,
+                                    GLdouble z, GLdouble w)
 {
-   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_NamedProgramLocalParameter4fEXT(program, target, index, (GLfloat) x,
+                                           (GLfloat) y, (GLfloat) z, (GLfloat) w);
+}
+
+
+static void GLAPIENTRY
+save_NamedProgramLocalParameter4dvEXT(GLuint program, GLenum target, GLuint index,
+                                      const GLdouble *params)
+{
+   save_NamedProgramLocalParameter4fEXT(program, target, index, (GLfloat) params[0],
+                                        (GLfloat) params[1], (GLfloat) params[2],
+                                        (GLfloat) params[3]);
 }
 
 
@@ -7772,15 +11427,9 @@ execute_list(struct gl_context *ctx, GLuint list)
                execute_list(ctx, n[1].ui);
             }
             break;
-         case OPCODE_CALL_LIST_OFFSET:
-            /* Generated by glCallLists() so we must add ListBase */
-            if (n[2].b) {
-               /* user specified a bad data type at compile time */
-               _mesa_error(ctx, GL_INVALID_ENUM, "glCallLists(type)");
-            }
-            else if (ctx->ListState.CallDepth < MAX_LIST_NESTING) {
-               GLuint list = (GLuint) (ctx->List.ListBase + n[1].i);
-               execute_list(ctx, list);
+         case OPCODE_CALL_LISTS:
+            if (ctx->ListState.CallDepth < MAX_LIST_NESTING) {
+               CALL_CallLists(ctx->Exec, (n[1].i, n[2].e, get_pointer(&n[3])));
             }
             break;
          case OPCODE_CLEAR:
@@ -8040,6 +11689,27 @@ execute_list(struct gl_context *ctx, GLuint list)
          case OPCODE_PASSTHROUGH:
             CALL_PassThrough(ctx->Exec, (n[1].f));
             break;
+         case OPCODE_PATCH_PARAMETER_I:
+            CALL_PatchParameteri(ctx->Exec, (n[1].e, n[2].i));
+            break;
+         case OPCODE_PATCH_PARAMETER_FV_INNER:
+            {
+               GLfloat params[2];
+               params[0] = n[2].f;
+               params[1] = n[3].f;
+               CALL_PatchParameterfv(ctx->Exec, (n[1].e, params));
+            }
+            break;
+         case OPCODE_PATCH_PARAMETER_FV_OUTER:
+            {
+               GLfloat params[4];
+               params[0] = n[2].f;
+               params[1] = n[3].f;
+               params[2] = n[4].f;
+               params[3] = n[5].f;
+               CALL_PatchParameterfv(ctx->Exec, (n[1].e, params));
+            }
+            break;
          case OPCODE_PIXEL_MAP:
             CALL_PixelMapfv(ctx->Exec,
                             (n[1].e, n[2].i, get_pointer(&n[3])));
@@ -8261,6 +11931,47 @@ execute_list(struct gl_context *ctx, GLuint list)
          case OPCODE_WINDOW_POS:
             CALL_WindowPos4fMESA(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
             break;
+         case OPCODE_VIEWPORT_ARRAY_V:
+            CALL_ViewportArrayv(ctx->Exec, (n[1].ui, n[2].si,
+                                            get_pointer(&n[3])));
+            break;
+         case OPCODE_VIEWPORT_INDEXED_F:
+            CALL_ViewportIndexedf(ctx->Exec, (n[1].ui, n[2].f, n[3].f, n[4].f,
+                                              n[5].f));
+            break;
+         case OPCODE_VIEWPORT_INDEXED_FV: {
+            GLfloat v[4];
+            v[0] = n[2].f;
+            v[1] = n[3].f;
+            v[2] = n[4].f;
+            v[3] = n[5].f;
+            CALL_ViewportIndexedfv(ctx->Exec, (n[1].ui, v));
+            break;
+         }
+         case OPCODE_SCISSOR_ARRAY_V:
+            CALL_ScissorArrayv(ctx->Exec, (n[1].ui, n[2].si,
+                                           get_pointer(&n[3])));
+            break;
+         case OPCODE_SCISSOR_INDEXED:
+            CALL_ScissorIndexed(ctx->Exec, (n[1].ui, n[2].i, n[3].i, n[4].si,
+                                            n[5].si));
+            break;
+         case OPCODE_SCISSOR_INDEXED_V: {
+            GLint v[4];
+            v[0] = n[2].i;
+            v[1] = n[3].i;
+            v[2] = n[4].si;
+            v[3] = n[5].si;
+            CALL_ScissorIndexedv(ctx->Exec, (n[1].ui, v));
+            break;
+         }
+         case OPCODE_DEPTH_ARRAY_V:
+            CALL_DepthRangeArrayv(ctx->Exec, (n[1].ui, n[2].si,
+                                              get_pointer(&n[3])));
+            break;
+         case OPCODE_DEPTH_INDEXED:
+            CALL_DepthRangeIndexed(ctx->Exec, (n[1].ui, n[2].f, n[3].f));
+            break;
          case OPCODE_ACTIVE_TEXTURE:   /* GL_ARB_multitexture */
             CALL_ActiveTexture(ctx->Exec, (n[1].e));
             break;
@@ -8305,7 +12016,7 @@ execute_list(struct gl_context *ctx, GLuint list)
          case OPCODE_WINDOW_POS_ARB:   /* GL_ARB_window_pos */
             CALL_WindowPos3f(ctx->Exec, (n[1].f, n[2].f, n[3].f));
             break;
-         case OPCODE_BIND_PROGRAM_NV:  /* GL_ARB_vertex_program */
+         case OPCODE_BIND_PROGRAM_ARB:  /* GL_ARB_vertex_program */
             CALL_BindProgramARB(ctx->Exec, (n[1].e, n[2].ui));
             break;
          case OPCODE_PROGRAM_LOCAL_PARAMETER_ARB:
@@ -8353,134 +12064,523 @@ execute_list(struct gl_context *ctx, GLuint list)
                CALL_DrawBuffers(ctx->Exec, (n[1].i, buffers));
             }
             break;
-        case OPCODE_BLIT_FRAMEBUFFER:
-           CALL_BlitFramebuffer(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i,
+         case OPCODE_BLIT_FRAMEBUFFER:
+            CALL_BlitFramebuffer(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;
-        case OPCODE_USE_PROGRAM:
-           CALL_UseProgram(ctx->Exec, (n[1].ui));
-           break;
-        case OPCODE_UNIFORM_1F:
-           CALL_Uniform1f(ctx->Exec, (n[1].i, n[2].f));
-           break;
-        case OPCODE_UNIFORM_2F:
-           CALL_Uniform2f(ctx->Exec, (n[1].i, n[2].f, n[3].f));
-           break;
-        case OPCODE_UNIFORM_3F:
-           CALL_Uniform3f(ctx->Exec, (n[1].i, n[2].f, n[3].f, n[4].f));
-           break;
-        case OPCODE_UNIFORM_4F:
-           CALL_Uniform4f(ctx->Exec,
+            break;
+         case OPCODE_PRIMITIVE_RESTART_NV:
+            CALL_PrimitiveRestartNV(ctx->Exec, ());
+            break;
+
+         case OPCODE_USE_PROGRAM:
+            CALL_UseProgram(ctx->Exec, (n[1].ui));
+            break;
+         case OPCODE_UNIFORM_1F:
+            CALL_Uniform1f(ctx->Exec, (n[1].i, n[2].f));
+            break;
+         case OPCODE_UNIFORM_2F:
+            CALL_Uniform2f(ctx->Exec, (n[1].i, n[2].f, n[3].f));
+            break;
+         case OPCODE_UNIFORM_3F:
+            CALL_Uniform3f(ctx->Exec, (n[1].i, n[2].f, n[3].f, n[4].f));
+            break;
+         case OPCODE_UNIFORM_4F:
+            CALL_Uniform4f(ctx->Exec,
                               (n[1].i, n[2].f, n[3].f, n[4].f, n[5].f));
-           break;
-        case OPCODE_UNIFORM_1FV:
-           CALL_Uniform1fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
-           break;
-        case OPCODE_UNIFORM_2FV:
-           CALL_Uniform2fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
-           break;
-        case OPCODE_UNIFORM_3FV:
-           CALL_Uniform3fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
-           break;
-        case OPCODE_UNIFORM_4FV:
-           CALL_Uniform4fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
-           break;
-        case OPCODE_UNIFORM_1I:
-           CALL_Uniform1i(ctx->Exec, (n[1].i, n[2].i));
-           break;
-        case OPCODE_UNIFORM_2I:
-           CALL_Uniform2i(ctx->Exec, (n[1].i, n[2].i, n[3].i));
-           break;
-        case OPCODE_UNIFORM_3I:
-           CALL_Uniform3i(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i));
-           break;
-        case OPCODE_UNIFORM_4I:
-           CALL_Uniform4i(ctx->Exec,
-                              (n[1].i, n[2].i, n[3].i, n[4].i, n[5].i));
-           break;
-        case OPCODE_UNIFORM_1IV:
-           CALL_Uniform1iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
-           break;
-        case OPCODE_UNIFORM_2IV:
-           CALL_Uniform2iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
-           break;
-        case OPCODE_UNIFORM_3IV:
-           CALL_Uniform3iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
-           break;
-        case OPCODE_UNIFORM_4IV:
-           CALL_Uniform4iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
-           break;
-        case OPCODE_UNIFORM_1UI:
-           /*CALL_Uniform1uiARB(ctx->Exec, (n[1].i, n[2].i));*/
-           break;
-        case OPCODE_UNIFORM_2UI:
-           /*CALL_Uniform2uiARB(ctx->Exec, (n[1].i, n[2].i, n[3].i));*/
-           break;
-        case OPCODE_UNIFORM_3UI:
-           /*CALL_Uniform3uiARB(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i));*/
-           break;
-        case OPCODE_UNIFORM_4UI:
-           /*CALL_Uniform4uiARB(ctx->Exec,
+            break;
+         case OPCODE_UNIFORM_1FV:
+            CALL_Uniform1fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_2FV:
+            CALL_Uniform2fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_3FV:
+            CALL_Uniform3fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_4FV:
+            CALL_Uniform4fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_1D: {
+            union float64_pair x;
+
+            x.uint32[0] = n[2].ui;
+            x.uint32[1] = n[3].ui;
+
+            CALL_Uniform1d(ctx->Exec, (n[1].i, x.d));
+            break;
+         }
+         case OPCODE_UNIFORM_2D: {
+            union float64_pair x;
+            union float64_pair y;
+
+            x.uint32[0] = n[2].ui;
+            x.uint32[1] = n[3].ui;
+            y.uint32[0] = n[4].ui;
+            y.uint32[1] = n[5].ui;
+
+            CALL_Uniform2d(ctx->Exec, (n[1].i, x.d, y.d));
+            break;
+         }
+         case OPCODE_UNIFORM_3D: {
+            union float64_pair x;
+            union float64_pair y;
+            union float64_pair z;
+
+            x.uint32[0] = n[2].ui;
+            x.uint32[1] = n[3].ui;
+            y.uint32[0] = n[4].ui;
+            y.uint32[1] = n[5].ui;
+            z.uint32[0] = n[6].ui;
+            z.uint32[1] = n[7].ui;
+
+            CALL_Uniform3d(ctx->Exec, (n[1].i, x.d, y.d, z.d));
+            break;
+         }
+         case OPCODE_UNIFORM_4D: {
+            union float64_pair x;
+            union float64_pair y;
+            union float64_pair z;
+            union float64_pair w;
+
+            x.uint32[0] = n[2].ui;
+            x.uint32[1] = n[3].ui;
+            y.uint32[0] = n[4].ui;
+            y.uint32[1] = n[5].ui;
+            z.uint32[0] = n[6].ui;
+            z.uint32[1] = n[7].ui;
+            w.uint32[0] = n[8].ui;
+            w.uint32[1] = n[9].ui;
+
+            CALL_Uniform4d(ctx->Exec, (n[1].i, x.d, y.d, z.d, w.d));
+            break;
+         }
+         case OPCODE_UNIFORM_1DV:
+            CALL_Uniform1dv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_2DV:
+            CALL_Uniform2dv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_3DV:
+            CALL_Uniform3dv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_4DV:
+            CALL_Uniform4dv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_1I:
+            CALL_Uniform1i(ctx->Exec, (n[1].i, n[2].i));
+            break;
+         case OPCODE_UNIFORM_2I:
+            CALL_Uniform2i(ctx->Exec, (n[1].i, n[2].i, n[3].i));
+            break;
+         case OPCODE_UNIFORM_3I:
+            CALL_Uniform3i(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i));
+            break;
+         case OPCODE_UNIFORM_4I:
+            CALL_Uniform4i(ctx->Exec,
                               (n[1].i, n[2].i, n[3].i, n[4].i, n[5].i));
-            */
-           break;
-        case OPCODE_UNIFORM_1UIV:
-           /*CALL_Uniform1uivARB(ctx->Exec, (n[1].i, n[2].i,
-                                              get_pointer(&n[3])));*/
-           break;
-        case OPCODE_UNIFORM_2UIV:
-           /*CALL_Uniform2uivARB(ctx->Exec, (n[1].i, n[2].i,
-                                              get_pointer(&n[3])));*/
-           break;
-        case OPCODE_UNIFORM_3UIV:
-           /*CALL_Uniform3uivARB(ctx->Exec, (n[1].i, n[2].i,
-                                              get_pointer(&n[3])));*/
-           break;
-        case OPCODE_UNIFORM_4UIV:
-           /*CALL_Uniform4uivARB(ctx->Exec, (n[1].i, n[2].i,
-                                              get_pointer(&n[3])));*/
-           break;
-        case OPCODE_UNIFORM_MATRIX22:
-           CALL_UniformMatrix2fv(ctx->Exec,
+            break;
+         case OPCODE_UNIFORM_1IV:
+            CALL_Uniform1iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_2IV:
+            CALL_Uniform2iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_3IV:
+            CALL_Uniform3iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_4IV:
+            CALL_Uniform4iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_1UI:
+            CALL_Uniform1ui(ctx->Exec, (n[1].i, n[2].i));
+            break;
+         case OPCODE_UNIFORM_2UI:
+            CALL_Uniform2ui(ctx->Exec, (n[1].i, n[2].i, n[3].i));
+            break;
+         case OPCODE_UNIFORM_3UI:
+            CALL_Uniform3ui(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i));
+            break;
+         case OPCODE_UNIFORM_4UI:
+            CALL_Uniform4ui(ctx->Exec,
+                            (n[1].i, n[2].i, n[3].i, n[4].i, n[5].i));
+            break;
+         case OPCODE_UNIFORM_1UIV:
+            CALL_Uniform1uiv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_2UIV:
+            CALL_Uniform2uiv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_3UIV:
+            CALL_Uniform3uiv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_4UIV:
+            CALL_Uniform4uiv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_MATRIX22:
+            CALL_UniformMatrix2fv(ctx->Exec,
+                                  (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
+            break;
+         case OPCODE_UNIFORM_MATRIX33:
+            CALL_UniformMatrix3fv(ctx->Exec,
+                                  (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
+            break;
+         case OPCODE_UNIFORM_MATRIX44:
+            CALL_UniformMatrix4fv(ctx->Exec,
+                                  (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
+            break;
+         case OPCODE_UNIFORM_MATRIX23:
+            CALL_UniformMatrix2x3fv(ctx->Exec,
+                                    (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
+            break;
+         case OPCODE_UNIFORM_MATRIX32:
+            CALL_UniformMatrix3x2fv(ctx->Exec,
+                                    (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
+            break;
+         case OPCODE_UNIFORM_MATRIX24:
+            CALL_UniformMatrix2x4fv(ctx->Exec,
+                                    (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
+            break;
+         case OPCODE_UNIFORM_MATRIX42:
+            CALL_UniformMatrix4x2fv(ctx->Exec,
+                                    (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
+            break;
+         case OPCODE_UNIFORM_MATRIX34:
+            CALL_UniformMatrix3x4fv(ctx->Exec,
+                                    (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
+            break;
+         case OPCODE_UNIFORM_MATRIX43:
+            CALL_UniformMatrix4x3fv(ctx->Exec,
+                                    (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
+            break;
+         case OPCODE_UNIFORM_MATRIX22D:
+            CALL_UniformMatrix2dv(ctx->Exec,
                                   (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
-           break;
-        case OPCODE_UNIFORM_MATRIX33:
-           CALL_UniformMatrix3fv(ctx->Exec,
+            break;
+         case OPCODE_UNIFORM_MATRIX33D:
+            CALL_UniformMatrix3dv(ctx->Exec,
                                   (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
-           break;
-        case OPCODE_UNIFORM_MATRIX44:
-           CALL_UniformMatrix4fv(ctx->Exec,
+            break;
+         case OPCODE_UNIFORM_MATRIX44D:
+            CALL_UniformMatrix4dv(ctx->Exec,
                                   (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
-           break;
-        case OPCODE_UNIFORM_MATRIX23:
-           CALL_UniformMatrix2x3fv(ctx->Exec,
+            break;
+         case OPCODE_UNIFORM_MATRIX23D:
+            CALL_UniformMatrix2x3dv(ctx->Exec,
                                     (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
-           break;
-        case OPCODE_UNIFORM_MATRIX32:
-           CALL_UniformMatrix3x2fv(ctx->Exec,
+            break;
+         case OPCODE_UNIFORM_MATRIX32D:
+            CALL_UniformMatrix3x2dv(ctx->Exec,
                                     (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
-           break;
-        case OPCODE_UNIFORM_MATRIX24:
-           CALL_UniformMatrix2x4fv(ctx->Exec,
+            break;
+         case OPCODE_UNIFORM_MATRIX24D:
+            CALL_UniformMatrix2x4dv(ctx->Exec,
                                     (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
-           break;
-        case OPCODE_UNIFORM_MATRIX42:
-           CALL_UniformMatrix4x2fv(ctx->Exec,
+            break;
+         case OPCODE_UNIFORM_MATRIX42D:
+            CALL_UniformMatrix4x2dv(ctx->Exec,
                                     (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
-           break;
-        case OPCODE_UNIFORM_MATRIX34:
-           CALL_UniformMatrix3x4fv(ctx->Exec,
+            break;
+         case OPCODE_UNIFORM_MATRIX34D:
+            CALL_UniformMatrix3x4dv(ctx->Exec,
                                     (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
-           break;
-        case OPCODE_UNIFORM_MATRIX43:
-           CALL_UniformMatrix4x3fv(ctx->Exec,
+            break;
+         case OPCODE_UNIFORM_MATRIX43D:
+            CALL_UniformMatrix4x3dv(ctx->Exec,
                                     (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
-           break;
+            break;
+
+         case OPCODE_UNIFORM_1I64: {
+            union int64_pair x;
+
+            x.int32[0] = n[2].i;
+            x.int32[1] = n[3].i;
+
+            CALL_Uniform1i64ARB(ctx->Exec, (n[1].i, x.int64));
+            break;
+         }
+         case OPCODE_UNIFORM_2I64: {
+            union int64_pair x;
+            union int64_pair y;
+
+            x.int32[0] = n[2].i;
+            x.int32[1] = n[3].i;
+            y.int32[0] = n[4].i;
+            y.int32[1] = n[5].i;
+
+            CALL_Uniform2i64ARB(ctx->Exec, (n[1].i, x.int64, y.int64));
+            break;
+         }
+         case OPCODE_UNIFORM_3I64: {
+            union int64_pair x;
+            union int64_pair y;
+            union int64_pair z;
+
+            x.int32[0] = n[2].i;
+            x.int32[1] = n[3].i;
+            y.int32[0] = n[4].i;
+            y.int32[1] = n[5].i;
+            z.int32[0] = n[6].i;
+            z.int32[1] = n[7].i;
+
+
+            CALL_Uniform3i64ARB(ctx->Exec, (n[1].i, x.int64, y.int64, z.int64));
+            break;
+         }
+         case OPCODE_UNIFORM_4I64: {
+            union int64_pair x;
+            union int64_pair y;
+            union int64_pair z;
+            union int64_pair w;
+
+            x.int32[0] = n[2].i;
+            x.int32[1] = n[3].i;
+            y.int32[0] = n[4].i;
+            y.int32[1] = n[5].i;
+            z.int32[0] = n[6].i;
+            z.int32[1] = n[7].i;
+            w.int32[0] = n[8].i;
+            w.int32[1] = n[9].i;
+
+            CALL_Uniform4i64ARB(ctx->Exec, (n[1].i, x.int64, y.int64, z.int64, w.int64));
+            break;
+         }
+         case OPCODE_UNIFORM_1I64V:
+            CALL_Uniform1i64vARB(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_2I64V:
+            CALL_Uniform2i64vARB(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_3I64V:
+            CALL_Uniform3i64vARB(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_4I64V:
+            CALL_Uniform4i64vARB(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_1UI64: {
+            union uint64_pair x;
+
+            x.uint32[0] = n[2].ui;
+            x.uint32[1] = n[3].ui;
+
+            CALL_Uniform1ui64ARB(ctx->Exec, (n[1].i, x.uint64));
+            break;
+         }
+         case OPCODE_UNIFORM_2UI64: {
+            union uint64_pair x;
+            union uint64_pair y;
+
+            x.uint32[0] = n[2].ui;
+            x.uint32[1] = n[3].ui;
+            y.uint32[0] = n[4].ui;
+            y.uint32[1] = n[5].ui;
+
+            CALL_Uniform2ui64ARB(ctx->Exec, (n[1].i, x.uint64, y.uint64));
+            break;
+         }
+         case OPCODE_UNIFORM_3UI64: {
+            union uint64_pair x;
+            union uint64_pair y;
+            union uint64_pair z;
+
+            x.uint32[0] = n[2].ui;
+            x.uint32[1] = n[3].ui;
+            y.uint32[0] = n[4].ui;
+            y.uint32[1] = n[5].ui;
+            z.uint32[0] = n[6].ui;
+            z.uint32[1] = n[7].ui;
+
+
+            CALL_Uniform3ui64ARB(ctx->Exec, (n[1].i, x.uint64, y.uint64,
+                                 z.uint64));
+            break;
+         }
+         case OPCODE_UNIFORM_4UI64: {
+            union uint64_pair x;
+            union uint64_pair y;
+            union uint64_pair z;
+            union uint64_pair w;
+
+            x.uint32[0] = n[2].ui;
+            x.uint32[1] = n[3].ui;
+            y.uint32[0] = n[4].ui;
+            y.uint32[1] = n[5].ui;
+            z.uint32[0] = n[6].ui;
+            z.uint32[1] = n[7].ui;
+            w.uint32[0] = n[8].ui;
+            w.uint32[1] = n[9].ui;
+
+            CALL_Uniform4ui64ARB(ctx->Exec, (n[1].i, x.uint64, y.uint64,
+                                 z.uint64, w.uint64));
+            break;
+         }
+         case OPCODE_UNIFORM_1UI64V:
+            CALL_Uniform1ui64vARB(ctx->Exec, (n[1].i, n[2].i,
+                                  get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_2UI64V:
+            CALL_Uniform2ui64vARB(ctx->Exec, (n[1].i, n[2].i,
+                                  get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_3UI64V:
+            CALL_Uniform3ui64vARB(ctx->Exec, (n[1].i, n[2].i,
+                                  get_pointer(&n[3])));
+            break;
+         case OPCODE_UNIFORM_4UI64V:
+            CALL_Uniform4ui64vARB(ctx->Exec, (n[1].i, n[2].i,
+                                  get_pointer(&n[3])));
+            break;
+
+         case OPCODE_PROGRAM_UNIFORM_1I64: {
+            union int64_pair x;
+
+            x.int32[0] = n[3].i;
+            x.int32[1] = n[4].i;
 
-        case OPCODE_USE_PROGRAM_STAGES:
-           CALL_UseProgramStages(ctx->Exec, (n[1].ui, n[2].ui, n[3].ui));
-           break;
+            CALL_ProgramUniform1i64ARB(ctx->Exec, (n[1].ui, n[2].i, x.int64));
+            break;
+         }
+         case OPCODE_PROGRAM_UNIFORM_2I64: {
+            union int64_pair x;
+            union int64_pair y;
+
+            x.int32[0] = n[3].i;
+            x.int32[1] = n[4].i;
+            y.int32[0] = n[5].i;
+            y.int32[1] = n[6].i;
+
+            CALL_ProgramUniform2i64ARB(ctx->Exec, (n[1].ui, n[2].i, x.int64,
+                                       y.int64));
+            break;
+         }
+         case OPCODE_PROGRAM_UNIFORM_3I64: {
+            union int64_pair x;
+            union int64_pair y;
+            union int64_pair z;
+
+            x.int32[0] = n[3].i;
+            x.int32[1] = n[4].i;
+            y.int32[0] = n[5].i;
+            y.int32[1] = n[6].i;
+            z.int32[0] = n[7].i;
+            z.int32[1] = n[8].i;
+
+            CALL_ProgramUniform3i64ARB(ctx->Exec, (n[1].ui, n[2].i, x.int64,
+                                       y.int64, z.int64));
+            break;
+         }
+         case OPCODE_PROGRAM_UNIFORM_4I64: {
+            union int64_pair x;
+            union int64_pair y;
+            union int64_pair z;
+            union int64_pair w;
+
+            x.int32[0] = n[3].i;
+            x.int32[1] = n[4].i;
+            y.int32[0] = n[5].i;
+            y.int32[1] = n[6].i;
+            z.int32[0] = n[7].i;
+            z.int32[1] = n[8].i;
+            w.int32[0] = n[9].i;
+            w.int32[1] = n[10].i;
+
+            CALL_ProgramUniform4i64ARB(ctx->Exec, (n[1].ui, n[2].i, x.int64,
+                                       y.int64, z.int64, w.int64));
+            break;
+         }
+         case OPCODE_PROGRAM_UNIFORM_1I64V:
+            CALL_ProgramUniform1i64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
+                                        get_pointer(&n[4])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_2I64V:
+            CALL_ProgramUniform2i64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
+                                        get_pointer(&n[4])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_3I64V:
+            CALL_ProgramUniform3i64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
+                                        get_pointer(&n[4])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_4I64V:
+            CALL_ProgramUniform4i64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
+                                        get_pointer(&n[4])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_1UI64: {
+            union uint64_pair x;
+
+            x.uint32[0] = n[3].ui;
+            x.uint32[1] = n[4].ui;
+
+            CALL_ProgramUniform1i64ARB(ctx->Exec, (n[1].ui, n[2].i, x.uint64));
+            break;
+         }
+         case OPCODE_PROGRAM_UNIFORM_2UI64: {
+            union uint64_pair x;
+            union uint64_pair y;
+
+            x.uint32[0] = n[3].ui;
+            x.uint32[1] = n[4].ui;
+            y.uint32[0] = n[5].ui;
+            y.uint32[1] = n[6].ui;
+
+            CALL_ProgramUniform2ui64ARB(ctx->Exec, (n[1].ui, n[2].i, x.uint64,
+                                        y.uint64));
+            break;
+         }
+         case OPCODE_PROGRAM_UNIFORM_3UI64: {
+            union uint64_pair x;
+            union uint64_pair y;
+            union uint64_pair z;
+
+            x.uint32[0] = n[3].ui;
+            x.uint32[1] = n[4].ui;
+            y.uint32[0] = n[5].ui;
+            y.uint32[1] = n[6].ui;
+            z.uint32[0] = n[7].ui;
+            z.uint32[1] = n[8].ui;
+
+            CALL_ProgramUniform3ui64ARB(ctx->Exec, (n[1].ui, n[2].i, x.uint64,
+                                        y.uint64, z.uint64));
+            break;
+         }
+         case OPCODE_PROGRAM_UNIFORM_4UI64: {
+            union uint64_pair x;
+            union uint64_pair y;
+            union uint64_pair z;
+            union uint64_pair w;
+
+            x.uint32[0] = n[3].ui;
+            x.uint32[1] = n[4].ui;
+            y.uint32[0] = n[5].ui;
+            y.uint32[1] = n[6].ui;
+            z.uint32[0] = n[7].ui;
+            z.uint32[1] = n[8].ui;
+            w.uint32[0] = n[9].ui;
+            w.uint32[1] = n[10].ui;
+
+            CALL_ProgramUniform4ui64ARB(ctx->Exec, (n[1].ui, n[2].i, x.uint64,
+                                        y.uint64, z.uint64, w.uint64));
+            break;
+         }
+         case OPCODE_PROGRAM_UNIFORM_1UI64V:
+            CALL_ProgramUniform1ui64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
+                                         get_pointer(&n[4])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_2UI64V:
+            CALL_ProgramUniform2ui64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
+                                         get_pointer(&n[4])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_3UI64V:
+            CALL_ProgramUniform3ui64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
+                                         get_pointer(&n[4])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_4UI64V:
+            CALL_ProgramUniform4ui64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
+                                         get_pointer(&n[4])));
+            break;
+
+         case OPCODE_USE_PROGRAM_STAGES:
+            CALL_UseProgramStages(ctx->Exec, (n[1].ui, n[2].ui, n[3].ui));
+            break;
          case OPCODE_PROGRAM_UNIFORM_1F:
             CALL_ProgramUniform1f(ctx->Exec, (n[1].ui, n[2].i, n[3].f));
             break;
@@ -8499,16 +12599,88 @@ execute_list(struct gl_context *ctx, GLuint list)
             CALL_ProgramUniform1fv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
                                                get_pointer(&n[4])));
             break;
-         case OPCODE_PROGRAM_UNIFORM_2FV:
-            CALL_ProgramUniform2fv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
+         case OPCODE_PROGRAM_UNIFORM_2FV:
+            CALL_ProgramUniform2fv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
+                                               get_pointer(&n[4])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_3FV:
+            CALL_ProgramUniform3fv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
+                                               get_pointer(&n[4])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_4FV:
+            CALL_ProgramUniform4fv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
+                                               get_pointer(&n[4])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_1D: {
+            union float64_pair x;
+
+            x.uint32[0] = n[3].ui;
+            x.uint32[1] = n[4].ui;
+
+            CALL_ProgramUniform1d(ctx->Exec, (n[1].ui, n[2].i, x.d));
+            break;
+         }
+         case OPCODE_PROGRAM_UNIFORM_2D: {
+            union float64_pair x;
+            union float64_pair y;
+
+            x.uint32[0] = n[3].ui;
+            x.uint32[1] = n[4].ui;
+            y.uint32[0] = n[5].ui;
+            y.uint32[1] = n[6].ui;
+
+            CALL_ProgramUniform2d(ctx->Exec, (n[1].ui, n[2].i, x.d, y.d));
+            break;
+         }
+         case OPCODE_PROGRAM_UNIFORM_3D: {
+            union float64_pair x;
+            union float64_pair y;
+            union float64_pair z;
+
+            x.uint32[0] = n[3].ui;
+            x.uint32[1] = n[4].ui;
+            y.uint32[0] = n[5].ui;
+            y.uint32[1] = n[6].ui;
+            z.uint32[0] = n[7].ui;
+            z.uint32[1] = n[8].ui;
+
+            CALL_ProgramUniform3d(ctx->Exec, (n[1].ui, n[2].i,
+                                              x.d, y.d, z.d));
+            break;
+         }
+         case OPCODE_PROGRAM_UNIFORM_4D: {
+            union float64_pair x;
+            union float64_pair y;
+            union float64_pair z;
+            union float64_pair w;
+
+            x.uint32[0] = n[3].ui;
+            x.uint32[1] = n[4].ui;
+            y.uint32[0] = n[5].ui;
+            y.uint32[1] = n[6].ui;
+            z.uint32[0] = n[7].ui;
+            z.uint32[1] = n[8].ui;
+            w.uint32[0] = n[9].ui;
+            w.uint32[1] = n[10].ui;
+
+            CALL_ProgramUniform4d(ctx->Exec, (n[1].ui, n[2].i,
+                                              x.d, y.d, z.d, w.d));
+            break;
+         }
+         case OPCODE_PROGRAM_UNIFORM_1DV:
+            CALL_ProgramUniform1dv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
+                                               get_pointer(&n[4])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_2DV:
+            CALL_ProgramUniform2dv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
                                                get_pointer(&n[4])));
             break;
-         case OPCODE_PROGRAM_UNIFORM_3FV:
-            CALL_ProgramUniform3fv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
+         case OPCODE_PROGRAM_UNIFORM_3DV:
+            CALL_ProgramUniform3dv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
                                                get_pointer(&n[4])));
             break;
-         case OPCODE_PROGRAM_UNIFORM_4FV:
-            CALL_ProgramUniform4fv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
+         case OPCODE_PROGRAM_UNIFORM_4DV:
+            CALL_ProgramUniform4dv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
                                                get_pointer(&n[4])));
             break;
          case OPCODE_PROGRAM_UNIFORM_1I:
@@ -8618,6 +12790,51 @@ execute_list(struct gl_context *ctx, GLuint list)
                                          (n[1].ui, n[2].i, n[3].i, n[4].b,
                                           get_pointer(&n[5])));
             break;
+         case OPCODE_PROGRAM_UNIFORM_MATRIX22D:
+            CALL_ProgramUniformMatrix2dv(ctx->Exec,
+                                         (n[1].ui, n[2].i, n[3].i, n[4].b,
+                                          get_pointer(&n[5])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_MATRIX23D:
+            CALL_ProgramUniformMatrix2x3dv(ctx->Exec,
+                                           (n[1].ui, n[2].i, n[3].i, n[4].b,
+                                            get_pointer(&n[5])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_MATRIX24D:
+            CALL_ProgramUniformMatrix2x4dv(ctx->Exec,
+                                           (n[1].ui, n[2].i, n[3].i, n[4].b,
+                                            get_pointer(&n[5])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_MATRIX32D:
+            CALL_ProgramUniformMatrix3x2dv(ctx->Exec,
+                                           (n[1].ui, n[2].i, n[3].i, n[4].b,
+                                            get_pointer(&n[5])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_MATRIX33D:
+            CALL_ProgramUniformMatrix3dv(ctx->Exec,
+                                         (n[1].ui, n[2].i, n[3].i, n[4].b,
+                                          get_pointer(&n[5])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_MATRIX34D:
+            CALL_ProgramUniformMatrix3x4dv(ctx->Exec,
+                                           (n[1].ui, n[2].i, n[3].i, n[4].b,
+                                            get_pointer(&n[5])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_MATRIX42D:
+            CALL_ProgramUniformMatrix4x2dv(ctx->Exec,
+                                           (n[1].ui, n[2].i, n[3].i, n[4].b,
+                                            get_pointer(&n[5])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_MATRIX43D:
+            CALL_ProgramUniformMatrix4x3dv(ctx->Exec,
+                                           (n[1].ui, n[2].i, n[3].i, n[4].b,
+                                            get_pointer(&n[5])));
+            break;
+         case OPCODE_PROGRAM_UNIFORM_MATRIX44D:
+            CALL_ProgramUniformMatrix4dv(ctx->Exec,
+                                         (n[1].ui, n[2].i, n[3].i, n[4].b,
+                                          get_pointer(&n[5])));
+            break;
 
          case OPCODE_CLIP_CONTROL:
             CALL_ClipControl(ctx->Exec, (n[1].e, n[2].e));
@@ -8657,6 +12874,43 @@ execute_list(struct gl_context *ctx, GLuint list)
          case OPCODE_ATTR_4F_ARB:
             CALL_VertexAttrib4fvARB(ctx->Exec, (n[1].e, &n[2].f));
             break;
+         case OPCODE_ATTR_1I:
+            CALL_VertexAttribI1iEXT(ctx->Exec, (n[1].e, n[2].i));
+            break;
+         case OPCODE_ATTR_2I:
+            CALL_VertexAttribI2ivEXT(ctx->Exec, (n[1].e, &n[2].i));
+            break;
+         case OPCODE_ATTR_3I:
+            CALL_VertexAttribI3ivEXT(ctx->Exec, (n[1].e, &n[2].i));
+            break;
+         case OPCODE_ATTR_4I:
+            CALL_VertexAttribI4ivEXT(ctx->Exec, (n[1].e, &n[2].i));
+            break;
+         case OPCODE_ATTR_1D: {
+            GLdouble *d = (GLdouble *) &n[2];
+            CALL_VertexAttribL1d(ctx->Exec, (n[1].ui, *d));
+            break;
+         }
+         case OPCODE_ATTR_2D: {
+            GLdouble *d = (GLdouble *) &n[2];
+            CALL_VertexAttribL2dv(ctx->Exec, (n[1].ui, d));
+            break;
+         }
+         case OPCODE_ATTR_3D: {
+            GLdouble *d = (GLdouble *) &n[2];
+            CALL_VertexAttribL3dv(ctx->Exec, (n[1].ui, d));
+            break;
+         }
+         case OPCODE_ATTR_4D: {
+            GLdouble *d = (GLdouble *) &n[2];
+            CALL_VertexAttribL4dv(ctx->Exec, (n[1].ui, d));
+            break;
+         }
+         case OPCODE_ATTR_1UI64: {
+            uint64_t *ui64 = (uint64_t *) &n[2];
+            CALL_VertexAttribL1ui64ARB(ctx->Exec, (n[1].ui, *ui64));
+            break;
+         }
          case OPCODE_MATERIAL:
             CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, &n[3].f));
             break;
@@ -8797,6 +13051,11 @@ execute_list(struct gl_context *ctx, GLuint list)
             }
             break;
 
+         /* ARB_compute_shader */
+         case OPCODE_DISPATCH_COMPUTE:
+            CALL_DispatchCompute(ctx->Exec, (n[1].ui, n[2].ui, n[3].ui));
+            break;
+
          /* GL_ARB_sync */
          case OPCODE_WAIT_SYNC:
             {
@@ -8820,6 +13079,463 @@ execute_list(struct gl_context *ctx, GLuint list)
             CALL_UniformBlockBinding(ctx->Exec, (n[1].ui, n[2].ui, n[3].ui));
             break;
 
+         case OPCODE_UNIFORM_SUBROUTINES:
+            CALL_UniformSubroutinesuiv(ctx->Exec, (n[1].e, n[2].si,
+                                                   get_pointer(&n[3])));
+            break;
+
+         /* GL_EXT_window_rectangles */
+         case OPCODE_WINDOW_RECTANGLES:
+            CALL_WindowRectanglesEXT(
+                  ctx->Exec, (n[1].e, n[2].si, get_pointer(&n[3])));
+            break;
+
+         /* GL_NV_conservative_raster */
+         case OPCODE_SUBPIXEL_PRECISION_BIAS:
+            CALL_SubpixelPrecisionBiasNV(ctx->Exec, (n[1].ui, n[2].ui));
+            break;
+
+         /* GL_NV_conservative_raster_dilate */
+         case OPCODE_CONSERVATIVE_RASTER_PARAMETER_F:
+            CALL_ConservativeRasterParameterfNV(ctx->Exec, (n[1].e, n[2].f));
+            break;
+
+         /* GL_NV_conservative_raster_pre_snap_triangles */
+         case OPCODE_CONSERVATIVE_RASTER_PARAMETER_I:
+            CALL_ConservativeRasterParameteriNV(ctx->Exec, (n[1].e, n[2].i));
+            break;
+
+         /* GL_EXT_direct_state_access */
+         case OPCODE_MATRIX_LOAD:
+            CALL_MatrixLoadfEXT(ctx->Exec, (n[1].e, &n[2].f));
+            break;
+         case OPCODE_MATRIX_MULT:
+            CALL_MatrixMultfEXT(ctx->Exec, (n[1].e, &n[2].f));
+            break;
+         case OPCODE_MATRIX_ROTATE:
+            CALL_MatrixRotatefEXT(ctx->Exec, (n[1].e, n[2].f, n[3].f, n[4].f, n[5].f));
+            break;
+         case OPCODE_MATRIX_SCALE:
+            CALL_MatrixScalefEXT(ctx->Exec, (n[1].e, n[2].f, n[3].f, n[4].f));
+            break;
+         case OPCODE_MATRIX_TRANSLATE:
+            CALL_MatrixTranslatefEXT(ctx->Exec, (n[1].e, n[2].f, n[3].f, n[4].f));
+            break;
+         case OPCODE_MATRIX_LOAD_IDENTITY:
+            CALL_MatrixLoadIdentityEXT(ctx->Exec, (n[1].e));
+            break;
+         case OPCODE_MATRIX_ORTHO:
+            CALL_MatrixOrthoEXT(ctx->Exec, (n[1].e,
+                                            n[2].f, n[3].f, n[4].f,
+                                            n[5].f, n[6].f, n[7].f));
+            break;
+         case OPCODE_MATRIX_FRUSTUM:
+            CALL_MatrixFrustumEXT(ctx->Exec, (n[1].e,
+                                              n[2].f, n[3].f, n[4].f,
+                                              n[5].f, n[6].f, n[7].f));
+            break;
+         case OPCODE_MATRIX_PUSH:
+            CALL_MatrixPushEXT(ctx->Exec, (n[1].e));
+            break;
+         case OPCODE_MATRIX_POP:
+            CALL_MatrixPopEXT(ctx->Exec, (n[1].e));
+            break;
+         case OPCODE_TEXTUREPARAMETER_F:
+            {
+               GLfloat params[4];
+               params[0] = n[4].f;
+               params[1] = n[5].f;
+               params[2] = n[6].f;
+               params[3] = n[7].f;
+               CALL_TextureParameterfvEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].e, params));
+            }
+            break;
+         case OPCODE_TEXTUREPARAMETER_I:
+            {
+               GLint params[4];
+               params[0] = n[4].i;
+               params[1] = n[5].i;
+               params[2] = n[6].i;
+               params[3] = n[7].i;
+               CALL_TextureParameterivEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].e, params));
+            }
+            break;
+         case OPCODE_TEXTUREPARAMETER_II:
+            {
+               GLint params[4];
+               params[0] = n[4].i;
+               params[1] = n[5].i;
+               params[2] = n[6].i;
+               params[3] = n[7].i;
+               CALL_TextureParameterIivEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].e, params));
+            }
+            break;
+         case OPCODE_TEXTUREPARAMETER_IUI:
+            {
+               GLuint params[4];
+               params[0] = n[4].ui;
+               params[1] = n[5].ui;
+               params[2] = n[6].ui;
+               params[3] = n[7].ui;
+               CALL_TextureParameterIuivEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].e, params));
+            }
+            break;
+         case OPCODE_TEXTURE_IMAGE1D:
+            {
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
+               CALL_TextureImage1DEXT(ctx->Exec, (n[1].ui, /* texture */
+                                                  n[2].e,  /* target */
+                                                  n[3].i,  /* level */
+                                                  n[4].i,  /* components */
+                                                  n[5].i,  /* width */
+                                                  n[6].e,  /* border */
+                                                  n[7].e,  /* format */
+                                                  n[8].e,  /* type */
+                                                  get_pointer(&n[9])));
+               ctx->Unpack = save;      /* restore */
+            }
+            break;
+         case OPCODE_TEXTURE_IMAGE2D:
+            {
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
+               CALL_TextureImage2DEXT(ctx->Exec, (n[1].ui, /* texture */
+                                                  n[2].e,  /* target */
+                                                  n[3].i,  /* level */
+                                                  n[4].i,  /* components */
+                                                  n[5].i,  /* width */
+                                                  n[6].i,  /* height */
+                                                  n[7].e,  /* border */
+                                                  n[8].e,  /* format */
+                                                  n[9].e,  /* type */
+                                                  get_pointer(&n[10])));
+               ctx->Unpack = save;      /* restore */
+            }
+            break;
+         case OPCODE_TEXTURE_IMAGE3D:
+            {
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
+               CALL_TextureImage3DEXT(ctx->Exec, (n[1].ui, /* texture */
+                                                  n[2].e,  /* target */
+                                                  n[3].i,  /* level */
+                                                  n[4].i,  /* components */
+                                                  n[5].i,  /* width */
+                                                  n[6].i,  /* height */
+                                                  n[7].i,  /* depth  */
+                                                  n[8].e,  /* border */
+                                                  n[9].e,  /* format */
+                                                  n[10].e, /* type */
+                                                  get_pointer(&n[11])));
+               ctx->Unpack = save;      /* restore */
+            }
+            break;
+         case OPCODE_TEXTURE_SUB_IMAGE1D:
+            {
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
+               CALL_TextureSubImage1DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i,
+                                                     n[4].i, n[5].i, n[6].e,
+                                                     n[7].e, get_pointer(&n[8])));
+               ctx->Unpack = save;      /* restore */
+            }
+            break;
+         case OPCODE_TEXTURE_SUB_IMAGE2D:
+            {
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
+               CALL_TextureSubImage2DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i,
+                                                     n[4].i, n[5].i, n[6].e,
+                                                     n[7].i, n[8].e, n[9].e,
+                                                     get_pointer(&n[10])));
+               ctx->Unpack = save;
+            }
+            break;
+         case OPCODE_TEXTURE_SUB_IMAGE3D:
+            {
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
+               CALL_TextureSubImage3DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i,
+                                                     n[4].i, n[5].i, n[6].i,
+                                                     n[7].i, n[8].i, n[9].i,
+                                                     n[10].e, n[11].e,
+                                                     get_pointer(&n[12])));
+               ctx->Unpack = save;      /* restore */
+            }
+            break;
+         case OPCODE_COPY_TEXTURE_IMAGE1D:
+            CALL_CopyTextureImage1DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i,
+                                                   n[4].e, n[5].i, n[6].i,
+                                                   n[7].i, n[8].i));
+            break;
+         case OPCODE_COPY_TEXTURE_IMAGE2D:
+            CALL_CopyTextureImage2DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i,
+                                                   n[4].e, n[5].i, n[6].i,
+                                                   n[7].i, n[8].i, n[9].i));
+            break;
+         case OPCODE_COPY_TEXTURE_SUB_IMAGE1D:
+            CALL_CopyTextureSubImage1DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i,
+                                                      n[4].i, n[5].i, n[6].i,
+                                                      n[7].i));
+            break;
+         case OPCODE_COPY_TEXTURE_SUB_IMAGE2D:
+            CALL_CopyTextureSubImage2DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i,
+                                                      n[4].i, n[5].i, n[6].i,
+                                                      n[7].i, n[8].i, n[9].i));
+            break;
+         case OPCODE_COPY_TEXTURE_SUB_IMAGE3D:
+            CALL_CopyTextureSubImage3DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i,
+                                                      n[4].i, n[5].i, n[6].i,
+                                                      n[7].i, n[8].i, n[9].i,
+                                                      n[10].i));
+            break;
+         case OPCODE_BIND_MULTITEXTURE:
+            CALL_BindMultiTextureEXT(ctx->Exec, (n[1].e, n[2].e, n[3].ui));
+            break;
+         case OPCODE_MULTITEXPARAMETER_F:
+            {
+               GLfloat params[4];
+               params[0] = n[4].f;
+               params[1] = n[5].f;
+               params[2] = n[6].f;
+               params[3] = n[7].f;
+               CALL_MultiTexParameterfvEXT(ctx->Exec, (n[1].e, n[2].e, n[3].e, params));
+            }
+            break;
+         case OPCODE_MULTITEXPARAMETER_I:
+            {
+               GLint params[4];
+               params[0] = n[4].i;
+               params[1] = n[5].i;
+               params[2] = n[6].i;
+               params[3] = n[7].i;
+               CALL_MultiTexParameterivEXT(ctx->Exec, (n[1].e, n[2].e, n[3].e, params));
+            }
+            break;
+         case OPCODE_MULTITEXPARAMETER_II:
+            {
+               GLint params[4];
+               params[0] = n[4].i;
+               params[1] = n[5].i;
+               params[2] = n[6].i;
+               params[3] = n[7].i;
+               CALL_MultiTexParameterIivEXT(ctx->Exec, (n[1].e, n[2].e, n[3].e, params));
+            }
+            break;
+         case OPCODE_MULTITEXPARAMETER_IUI:
+            {
+               GLuint params[4];
+               params[0] = n[4].ui;
+               params[1] = n[5].ui;
+               params[2] = n[6].ui;
+               params[3] = n[7].ui;
+               CALL_MultiTexParameterIuivEXT(ctx->Exec, (n[1].e, n[2].e, n[3].e, params));
+            }
+            break;
+         case OPCODE_MULTITEX_IMAGE1D:
+            {
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
+               CALL_MultiTexImage1DEXT(ctx->Exec, (n[1].e, /* texture */
+                                                  n[2].e,  /* target */
+                                                  n[3].i,  /* level */
+                                                  n[4].i,  /* components */
+                                                  n[5].i,  /* width */
+                                                  n[6].e,  /* border */
+                                                  n[7].e,  /* format */
+                                                  n[8].e,  /* type */
+                                                  get_pointer(&n[9])));
+               ctx->Unpack = save;      /* restore */
+            }
+            break;
+         case OPCODE_MULTITEX_IMAGE2D:
+            {
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
+               CALL_MultiTexImage2DEXT(ctx->Exec, (n[1].e, /* texture */
+                                                  n[2].e,  /* target */
+                                                  n[3].i,  /* level */
+                                                  n[4].i,  /* components */
+                                                  n[5].i,  /* width */
+                                                  n[6].i,  /* height */
+                                                  n[7].e,  /* border */
+                                                  n[8].e,  /* format */
+                                                  n[9].e,  /* type */
+                                                  get_pointer(&n[10])));
+               ctx->Unpack = save;      /* restore */
+            }
+            break;
+         case OPCODE_MULTITEX_IMAGE3D:
+            {
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
+               CALL_MultiTexImage3DEXT(ctx->Exec, (n[1].e, /* texture */
+                                                  n[2].e,  /* target */
+                                                  n[3].i,  /* level */
+                                                  n[4].i,  /* components */
+                                                  n[5].i,  /* width */
+                                                  n[6].i,  /* height */
+                                                  n[7].i,  /* depth  */
+                                                  n[8].e,  /* border */
+                                                  n[9].e,  /* format */
+                                                  n[10].e, /* type */
+                                                  get_pointer(&n[11])));
+               ctx->Unpack = save;      /* restore */
+            }
+            break;
+         case OPCODE_MULTITEX_SUB_IMAGE1D:
+            {
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
+               CALL_MultiTexSubImage1DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i,
+                                                     n[4].i, n[5].i, n[6].e,
+                                                     n[7].e, get_pointer(&n[8])));
+               ctx->Unpack = save;      /* restore */
+            }
+            break;
+         case OPCODE_MULTITEX_SUB_IMAGE2D:
+            {
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
+               CALL_MultiTexSubImage2DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i,
+                                                     n[4].i, n[5].i, n[6].e,
+                                                     n[7].i, n[8].e, n[9].e,
+                                                     get_pointer(&n[10])));
+               ctx->Unpack = save;      /* restore */
+            }
+            break;
+         case OPCODE_MULTITEX_SUB_IMAGE3D:
+            {
+               const struct gl_pixelstore_attrib save = ctx->Unpack;
+               ctx->Unpack = ctx->DefaultPacking;
+               CALL_MultiTexSubImage3DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i,
+                                                     n[4].i, n[5].i, n[6].i,
+                                                     n[7].i, n[8].i, n[9].i,
+                                                     n[10].e, n[11].e,
+                                                     get_pointer(&n[12])));
+               ctx->Unpack = save;      /* restore */
+            }
+            break;
+         case OPCODE_COPY_MULTITEX_IMAGE1D:
+            CALL_CopyMultiTexImage1DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i,
+                                                   n[4].e, n[5].i, n[6].i,
+                                                   n[7].i, n[8].i));
+            break;
+         case OPCODE_COPY_MULTITEX_IMAGE2D:
+            CALL_CopyMultiTexImage2DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i,
+                                                   n[4].e, n[5].i, n[6].i,
+                                                   n[7].i, n[8].i, n[9].i));
+            break;
+         case OPCODE_COPY_MULTITEX_SUB_IMAGE1D:
+            CALL_CopyMultiTexSubImage1DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i,
+                                                      n[4].i, n[5].i, n[6].i,
+                                                      n[7].i));
+            break;
+         case OPCODE_COPY_MULTITEX_SUB_IMAGE2D:
+            CALL_CopyMultiTexSubImage2DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i,
+                                                      n[4].i, n[5].i, n[6].i,
+                                                      n[7].i, n[8].i, n[9].i));
+            break;
+         case OPCODE_COPY_MULTITEX_SUB_IMAGE3D:
+            CALL_CopyMultiTexSubImage3DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i,
+                                                      n[4].i, n[5].i, n[6].i,
+                                                      n[7].i, n[8].i, n[9].i,
+                                                      n[10].i));
+            break;
+         case OPCODE_MULTITEXENV:
+            {
+               GLfloat params[4];
+               params[0] = n[4].f;
+               params[1] = n[5].f;
+               params[2] = n[6].f;
+               params[3] = n[7].f;
+               CALL_MultiTexEnvfvEXT(ctx->Exec, (n[1].e, n[2].e, n[3].e, params));
+            }
+            break;
+         case OPCODE_COMPRESSED_TEXTURE_IMAGE_1D:
+            CALL_CompressedTextureImage1DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i,
+                                                         n[4].e, n[5].i, n[6].i,
+                                                         n[7].i, get_pointer(&n[8])));
+            break;
+         case OPCODE_COMPRESSED_TEXTURE_IMAGE_2D:
+            CALL_CompressedTextureImage2DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i,
+                                                         n[4].e, n[5].i, n[6].i,
+                                                         n[7].i, n[8].i,
+                                                         get_pointer(&n[9])));
+            break;
+         case OPCODE_COMPRESSED_TEXTURE_IMAGE_3D:
+            CALL_CompressedTextureImage3DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i,
+                                                         n[4].e, n[5].i, n[6].i,
+                                                         n[7].i, n[8].i, n[9].i,
+                                                         get_pointer(&n[10])));
+            break;
+         case OPCODE_COMPRESSED_TEXTURE_SUB_IMAGE_1D:
+            CALL_CompressedTextureSubImage1DEXT(ctx->Exec,
+                                                (n[1].ui, n[2].e, n[3].i, n[4].i,
+                                                 n[5].i, n[6].e, n[7].i,
+                                                 get_pointer(&n[8])));
+            break;
+         case OPCODE_COMPRESSED_TEXTURE_SUB_IMAGE_2D:
+            CALL_CompressedTextureSubImage2DEXT(ctx->Exec,
+                                                (n[1].ui, n[2].e, n[3].i, n[4].i,
+                                                 n[5].i, n[6].i, n[7].i, n[8].e,
+                                                 n[9].i, get_pointer(&n[10])));
+            break;
+         case OPCODE_COMPRESSED_TEXTURE_SUB_IMAGE_3D:
+            CALL_CompressedTextureSubImage3DEXT(ctx->Exec,
+                                                (n[1].ui, n[2].e, n[3].i, n[4].i,
+                                                 n[5].i, n[6].i, n[7].i, n[8].i,
+                                                 n[9].i, n[10].e, n[11].i,
+                                                 get_pointer(&n[12])));
+            break;
+         case OPCODE_COMPRESSED_MULTITEX_IMAGE_1D:
+            CALL_CompressedMultiTexImage1DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i,
+                                                         n[4].e, n[5].i, n[6].i,
+                                                         n[7].i, get_pointer(&n[8])));
+            break;
+         case OPCODE_COMPRESSED_MULTITEX_IMAGE_2D:
+            CALL_CompressedMultiTexImage2DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i,
+                                                         n[4].e, n[5].i, n[6].i,
+                                                         n[7].i, n[8].i,
+                                                         get_pointer(&n[9])));
+            break;
+         case OPCODE_COMPRESSED_MULTITEX_IMAGE_3D:
+            CALL_CompressedMultiTexImage3DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i,
+                                                         n[4].e, n[5].i, n[6].i,
+                                                         n[7].i, n[8].i, n[9].i,
+                                                         get_pointer(&n[10])));
+            break;
+         case OPCODE_COMPRESSED_MULTITEX_SUB_IMAGE_1D:
+            CALL_CompressedMultiTexSubImage1DEXT(ctx->Exec,
+                                                (n[1].e, n[2].e, n[3].i, n[4].i,
+                                                 n[5].i, n[6].e, n[7].i,
+                                                 get_pointer(&n[8])));
+            break;
+         case OPCODE_COMPRESSED_MULTITEX_SUB_IMAGE_2D:
+            CALL_CompressedMultiTexSubImage2DEXT(ctx->Exec,
+                                                (n[1].e, n[2].e, n[3].i, n[4].i,
+                                                 n[5].i, n[6].i, n[7].i, n[8].e,
+                                                 n[9].i, get_pointer(&n[10])));
+            break;
+         case OPCODE_COMPRESSED_MULTITEX_SUB_IMAGE_3D:
+            CALL_CompressedMultiTexSubImage3DEXT(ctx->Exec,
+                                                (n[1].e, n[2].e, n[3].i, n[4].i,
+                                                 n[5].i, n[6].i, n[7].i, n[8].i,
+                                                 n[9].i, n[10].e, n[11].i,
+                                                 get_pointer(&n[12])));
+            break;
+         case OPCODE_NAMED_PROGRAM_STRING:
+            CALL_NamedProgramStringEXT(ctx->Exec,
+                                  (n[1].ui, n[2].e, n[3].e, n[4].i,
+                                   get_pointer(&n[5])));
+            break;
+         case OPCODE_NAMED_PROGRAM_LOCAL_PARAMETER:
+            CALL_NamedProgramLocalParameter4fEXT(ctx->Exec,
+                                            (n[1].ui, n[2].e, n[3].ui, n[4].f,
+                                             n[5].f, n[6].f, n[7].f));
+            break;
+
          case OPCODE_CONTINUE:
             n = (Node *) get_pointer(&n[1]);
             break;
@@ -8832,7 +13548,7 @@ execute_list(struct gl_context *ctx, GLuint list)
          default:
             {
                char msg[1000];
-               _mesa_snprintf(msg, sizeof(msg), "Error in execute_list: opcode=%d",
+               snprintf(msg, sizeof(msg), "Error in execute_list: opcode=%d",
                              (int) opcode);
                _mesa_problem(ctx, "%s", msg);
             }
@@ -8841,6 +13557,7 @@ execute_list(struct gl_context *ctx, GLuint list)
 
          /* increment n to point to next compiled command */
          if (opcode != OPCODE_CONTINUE) {
+            assert(InstSize[opcode] > 0);
             n += InstSize[opcode];
          }
       }
@@ -8885,6 +13602,18 @@ _mesa_DeleteLists(GLuint list, GLsizei range)
       _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteLists");
       return;
    }
+
+   if (range > 1) {
+      /* We may be deleting a set of bitmap lists.  See if there's a
+       * bitmap atlas to free.
+       */
+      struct gl_bitmap_atlas *atlas = lookup_bitmap_atlas(ctx, list);
+      if (atlas) {
+         _mesa_delete_bitmap_atlas(ctx, atlas);
+         _mesa_HashRemove(ctx->Shared->BitmapAtlas, list);
+      }
+   }
+
    for (i = list; i < list + range; i++) {
       destroy_list(ctx, i);
    }
@@ -8914,19 +13643,37 @@ _mesa_GenLists(GLsizei range)
    /*
     * Make this an atomic operation
     */
-   mtx_lock(&ctx->Shared->Mutex);
+   _mesa_HashLockMutex(ctx->Shared->DisplayList);
 
    base = _mesa_HashFindFreeKeyBlock(ctx->Shared->DisplayList, range);
    if (base) {
       /* reserve the list IDs by with empty/dummy lists */
       GLint i;
       for (i = 0; i < range; i++) {
-         _mesa_HashInsert(ctx->Shared->DisplayList, base + i,
-                          make_list(base + i, 1));
+         _mesa_HashInsertLocked(ctx->Shared->DisplayList, base + i,
+                                make_list(base + i, 1));
+      }
+   }
+
+   if (USE_BITMAP_ATLAS &&
+       range > 16 &&
+       ctx->Driver.DrawAtlasBitmaps) {
+      /* "range > 16" is a rough heuristic to guess when glGenLists might be
+       * used to allocate display lists for glXUseXFont or wglUseFontBitmaps.
+       * Create the empty atlas now.
+       */
+      struct gl_bitmap_atlas *atlas = lookup_bitmap_atlas(ctx, base);
+      if (!atlas) {
+         atlas = alloc_bitmap_atlas(ctx, base);
+      }
+      if (atlas) {
+         /* Atlas _should_ be new/empty now, but clobbering is OK */
+         assert(atlas->numBitmaps == 0);
+         atlas->numBitmaps = range;
       }
    }
 
-   mtx_unlock(&ctx->Shared->Mutex);
+   _mesa_HashUnlockMutex(ctx->Shared->DisplayList);
 
    return base;
 }
@@ -8976,13 +13723,16 @@ _mesa_NewList(GLuint name, GLenum mode)
 
    vbo_save_NewList(ctx, name, mode);
 
-   ctx->CurrentDispatch = ctx->Save;
-   _glapi_set_dispatch(ctx->CurrentDispatch);
+   ctx->CurrentServerDispatch = ctx->Save;
+   _glapi_set_dispatch(ctx->CurrentServerDispatch);
+   if (ctx->MarshalExec == NULL) {
+      ctx->CurrentClientDispatch = ctx->CurrentServerDispatch;
+   }
 }
 
 
 /**
- * End definition of current display list. 
+ * End definition of current display list.
  */
 void GLAPIENTRY
 _mesa_EndList(void)
@@ -9004,7 +13754,7 @@ _mesa_EndList(void)
       _mesa_error(ctx, GL_INVALID_OPERATION, "glEndList");
       return;
    }
-   
+
    /* Call before emitting END_OF_LIST, in case the driver wants to
     * emit opcodes itself.
     */
@@ -9032,8 +13782,11 @@ _mesa_EndList(void)
    ctx->ExecuteFlag = GL_TRUE;
    ctx->CompileFlag = GL_FALSE;
 
-   ctx->CurrentDispatch = ctx->Exec;
-   _glapi_set_dispatch(ctx->CurrentDispatch);
+   ctx->CurrentServerDispatch = ctx->Exec;
+   _glapi_set_dispatch(ctx->CurrentServerDispatch);
+   if (ctx->MarshalExec == NULL) {
+      ctx->CurrentClientDispatch = ctx->CurrentServerDispatch;
+   }
 }
 
 
@@ -9068,9 +13821,71 @@ _mesa_CallList(GLuint list)
 
    /* also restore API function pointers to point to "save" versions */
    if (save_compile_flag) {
-      ctx->CurrentDispatch = ctx->Save;
-      _glapi_set_dispatch(ctx->CurrentDispatch);
+      ctx->CurrentServerDispatch = ctx->Save;
+       _glapi_set_dispatch(ctx->CurrentServerDispatch);
+      if (ctx->MarshalExec == NULL) {
+         ctx->CurrentClientDispatch = ctx->CurrentServerDispatch;
+      }
+   }
+}
+
+
+/**
+ * Try to execute a glCallLists() command where the display lists contain
+ * glBitmap commands with a texture atlas.
+ * \return true for success, false otherwise
+ */
+static bool
+render_bitmap_atlas(struct gl_context *ctx, GLsizei n, GLenum type,
+                    const void *lists)
+{
+   struct gl_bitmap_atlas *atlas;
+   int i;
+
+   if (!USE_BITMAP_ATLAS ||
+       !ctx->Current.RasterPosValid ||
+       ctx->List.ListBase == 0 ||
+       type != GL_UNSIGNED_BYTE ||
+       !ctx->Driver.DrawAtlasBitmaps) {
+      /* unsupported */
+      return false;
    }
+
+   atlas = lookup_bitmap_atlas(ctx, ctx->List.ListBase);
+
+   if (!atlas) {
+      /* Even if glGenLists wasn't called, we can still try to create
+       * the atlas now.
+       */
+      atlas = alloc_bitmap_atlas(ctx, ctx->List.ListBase);
+   }
+
+   if (atlas && !atlas->complete && !atlas->incomplete) {
+      /* Try to build the bitmap atlas now.
+       * If the atlas was created in glGenLists, we'll have recorded the
+       * number of lists (bitmaps).  Otherwise, take a guess at 256.
+       */
+      if (atlas->numBitmaps == 0)
+         atlas->numBitmaps = 256;
+      build_bitmap_atlas(ctx, atlas, ctx->List.ListBase);
+   }
+
+   if (!atlas || !atlas->complete) {
+      return false;
+   }
+
+   /* check that all display list IDs are in the atlas */
+   for (i = 0; i < n; i++) {
+      const GLubyte *ids = (const GLubyte *) lists;
+
+      if (ids[i] >= atlas->numBitmaps) {
+         return false;
+      }
+   }
+
+   ctx->Driver.DrawAtlasBitmaps(ctx, atlas, n, (const GLubyte *) lists);
+
+   return true;
 }
 
 
@@ -9105,6 +13920,18 @@ _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
       return;
    }
 
+   if (n < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glCallLists(n < 0)");
+      return;
+   } else if (n == 0 || lists == NULL) {
+      /* nothing to do */
+      return;
+   }
+
+   if (render_bitmap_atlas(ctx, n, type, lists)) {
+      return;
+   }
+
    /* Save the CompileFlag status, turn it off, execute display list,
     * and restore the CompileFlag.
     */
@@ -9120,8 +13947,11 @@ _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
 
    /* also restore API function pointers to point to "save" versions */
    if (save_compile_flag) {
-      ctx->CurrentDispatch = ctx->Save;
-      _glapi_set_dispatch(ctx->CurrentDispatch);
+      ctx->CurrentServerDispatch = ctx->Save;
+      _glapi_set_dispatch(ctx->CurrentServerDispatch);
+      if (ctx->MarshalExec == NULL) {
+         ctx->CurrentClientDispatch = ctx->CurrentServerDispatch;
+      }
    }
 }
 
@@ -9323,7 +14153,7 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
    SET_StencilMaskSeparate(table, save_StencilMaskSeparate);
    SET_StencilOpSeparate(table, save_StencilOpSeparate);
 
-   /* ATI_separate_stencil */ 
+   /* ATI_separate_stencil */
    SET_StencilFuncSeparateATI(table, save_StencilFuncSeparateATI);
 
    /* GL_ARB_imaging */
@@ -9336,9 +14166,6 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
    SET_BlendColorEXT(table, save_BlendColorEXT);
 #endif
 
-   /* 3. GL_EXT_polygon_offset */
-   SET_PolygonOffsetEXT(table, save_PolygonOffsetEXT);
-
    /* 6. GL_EXT_texture3d */
 #if 0
    SET_CopyTexSubImage3DEXT(table, save_CopyTexSubImage3D);
@@ -9355,6 +14182,24 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
    SET_PointParameterf(table, save_PointParameterfEXT);
    SET_PointParameterfv(table, save_PointParameterfvEXT);
 
+   /* 91. GL_ARB_tessellation_shader */
+   SET_PatchParameteri(table, save_PatchParameteri);
+   SET_PatchParameterfv(table, save_PatchParameterfv);
+
+   /* 100. ARB_viewport_array */
+   SET_ViewportArrayv(table, save_ViewportArrayv);
+   SET_ViewportIndexedf(table, save_ViewportIndexedf);
+   SET_ViewportIndexedfv(table, save_ViewportIndexedfv);
+   SET_ScissorArrayv(table, save_ScissorArrayv);
+   SET_ScissorIndexed(table, save_ScissorIndexed);
+   SET_ScissorIndexedv(table, save_ScissorIndexedv);
+   SET_DepthRangeArrayv(table, save_DepthRangeArrayv);
+   SET_DepthRangeIndexed(table, save_DepthRangeIndexed);
+
+   /* 122. ARB_compute_shader */
+   SET_DispatchCompute(table, save_DispatchCompute);
+   SET_DispatchComputeIndirect(table, save_DispatchComputeIndirect);
+
    /* 173. GL_EXT_blend_func_separate */
    SET_BlendFuncSeparate(table, save_BlendFuncSeparateEXT);
 
@@ -9384,13 +14229,6 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
    SET_WindowPos4sMESA(table, save_WindowPos4sMESA);
    SET_WindowPos4svMESA(table, save_WindowPos4svMESA);
 
-   /* 233. GL_NV_vertex_program */
-   /* The following commands DO NOT go into display lists:
-    * AreProgramsResidentNV, IsProgramNV, GenProgramsNV, DeleteProgramsNV,
-    * VertexAttribPointerNV, GetProgram*, GetVertexAttrib*
-    */
-   SET_BindProgramARB(table, save_BindProgramNV);
-
    /* 245. GL_ATI_fragment_shader */
    SET_BindFragmentShaderATI(table, save_BindFragmentShaderATI);
    SET_SetFragmentShaderConstantATI(table, save_SetFragmentShaderConstantATI);
@@ -9435,7 +14273,7 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
    /* ARB 27. GL_ARB_fragment_program */
    /* glVertexAttrib* functions alias the NV ones, handled elsewhere */
    SET_ProgramStringARB(table, save_ProgramStringARB);
-   SET_BindProgramARB(table, save_BindProgramNV);
+   SET_BindProgramARB(table, save_BindProgramARB);
    SET_ProgramEnvParameter4dARB(table, save_ProgramEnvParameter4dARB);
    SET_ProgramEnvParameter4dvARB(table, save_ProgramEnvParameter4dvARB);
    SET_ProgramEnvParameter4fARB(table, save_ProgramEnvParameter4fARB);
@@ -9507,7 +14345,6 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
    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);
@@ -9516,16 +14353,60 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
    SET_Uniform2uiv(table, save_Uniform2uiv);
    SET_Uniform3uiv(table, save_Uniform3uiv);
    SET_Uniform4uiv(table, save_Uniform4uiv);
-#else
-   (void) save_Uniform1ui;
-   (void) save_Uniform2ui;
-   (void) save_Uniform3ui;
-   (void) save_Uniform4ui;
-   (void) save_Uniform1uiv;
-   (void) save_Uniform2uiv;
-   (void) save_Uniform3uiv;
-   (void) save_Uniform4uiv;
-#endif
+
+   /* GL_ARB_gpu_shader_fp64 */
+   SET_Uniform1d(table, save_Uniform1d);
+   SET_Uniform2d(table, save_Uniform2d);
+   SET_Uniform3d(table, save_Uniform3d);
+   SET_Uniform4d(table, save_Uniform4d);
+   SET_Uniform1dv(table, save_Uniform1dv);
+   SET_Uniform2dv(table, save_Uniform2dv);
+   SET_Uniform3dv(table, save_Uniform3dv);
+   SET_Uniform4dv(table, save_Uniform4dv);
+   SET_UniformMatrix2dv(table, save_UniformMatrix2dv);
+   SET_UniformMatrix3dv(table, save_UniformMatrix3dv);
+   SET_UniformMatrix4dv(table, save_UniformMatrix4dv);
+   SET_UniformMatrix2x3dv(table, save_UniformMatrix2x3dv);
+   SET_UniformMatrix3x2dv(table, save_UniformMatrix3x2dv);
+   SET_UniformMatrix2x4dv(table, save_UniformMatrix2x4dv);
+   SET_UniformMatrix4x2dv(table, save_UniformMatrix4x2dv);
+   SET_UniformMatrix3x4dv(table, save_UniformMatrix3x4dv);
+   SET_UniformMatrix4x3dv(table, save_UniformMatrix4x3dv);
+
+   /* GL_ARB_gpu_shader_int64 */
+   SET_Uniform1i64ARB(table, save_Uniform1i64ARB);
+   SET_Uniform2i64ARB(table, save_Uniform2i64ARB);
+   SET_Uniform3i64ARB(table, save_Uniform3i64ARB);
+   SET_Uniform4i64ARB(table, save_Uniform4i64ARB);
+   SET_Uniform1i64vARB(table, save_Uniform1i64vARB);
+   SET_Uniform2i64vARB(table, save_Uniform2i64vARB);
+   SET_Uniform3i64vARB(table, save_Uniform3i64vARB);
+   SET_Uniform4i64vARB(table, save_Uniform4i64vARB);
+   SET_Uniform1ui64ARB(table, save_Uniform1ui64ARB);
+   SET_Uniform2ui64ARB(table, save_Uniform2ui64ARB);
+   SET_Uniform3ui64ARB(table, save_Uniform3ui64ARB);
+   SET_Uniform4ui64ARB(table, save_Uniform4ui64ARB);
+   SET_Uniform1ui64vARB(table, save_Uniform1ui64vARB);
+   SET_Uniform2ui64vARB(table, save_Uniform2ui64vARB);
+   SET_Uniform3ui64vARB(table, save_Uniform3ui64vARB);
+   SET_Uniform4ui64vARB(table, save_Uniform4ui64vARB);
+
+   SET_ProgramUniform1i64ARB(table, save_ProgramUniform1i64ARB);
+   SET_ProgramUniform2i64ARB(table, save_ProgramUniform2i64ARB);
+   SET_ProgramUniform3i64ARB(table, save_ProgramUniform3i64ARB);
+   SET_ProgramUniform4i64ARB(table, save_ProgramUniform4i64ARB);
+   SET_ProgramUniform1i64vARB(table, save_ProgramUniform1i64vARB);
+   SET_ProgramUniform2i64vARB(table, save_ProgramUniform2i64vARB);
+   SET_ProgramUniform3i64vARB(table, save_ProgramUniform3i64vARB);
+   SET_ProgramUniform4i64vARB(table, save_ProgramUniform4i64vARB);
+   SET_ProgramUniform1ui64ARB(table, save_ProgramUniform1ui64ARB);
+   SET_ProgramUniform2ui64ARB(table, save_ProgramUniform2ui64ARB);
+   SET_ProgramUniform3ui64ARB(table, save_ProgramUniform3ui64ARB);
+   SET_ProgramUniform4ui64ARB(table, save_ProgramUniform4ui64ARB);
+   SET_ProgramUniform1ui64vARB(table, save_ProgramUniform1ui64vARB);
+   SET_ProgramUniform2ui64vARB(table, save_ProgramUniform2ui64vARB);
+   SET_ProgramUniform3ui64vARB(table, save_ProgramUniform3ui64vARB);
+   SET_ProgramUniform4ui64vARB(table, save_ProgramUniform4ui64vARB);
 
    /* These are: */
    SET_BeginTransformFeedback(table, save_BeginTransformFeedback);
@@ -9572,6 +14453,9 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
    /* GL_ARB_uniform_buffer_object */
    SET_UniformBlockBinding(table, save_UniformBlockBinding);
 
+   /* GL_ARB_shader_subroutines */
+   SET_UniformSubroutinesuiv(table, save_UniformSubroutinesuiv);
+
    /* GL_ARB_draw_instanced */
    SET_DrawArraysInstancedARB(table, save_DrawArraysInstancedARB);
    SET_DrawElementsInstancedARB(table, save_DrawElementsInstancedARB);
@@ -9584,6 +14468,12 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
    SET_DrawElementsInstancedBaseInstance(table, save_DrawElementsInstancedBaseInstance);
    SET_DrawElementsInstancedBaseVertexBaseInstance(table, save_DrawElementsInstancedBaseVertexBaseInstance);
 
+   /* GL_ARB_draw_indirect / GL_ARB_multi_draw_indirect */
+   SET_DrawArraysIndirect(table, save_DrawArraysIndirect);
+   SET_DrawElementsIndirect(table, save_DrawElementsIndirect);
+   SET_MultiDrawArraysIndirect(table, save_MultiDrawArraysIndirect);
+   SET_MultiDrawElementsIndirect(table, save_MultiDrawElementsIndirect);
+
    /* OpenGL 4.2 / GL_ARB_separate_shader_objects */
    SET_UseProgramStages(table, save_UseProgramStages);
    SET_ProgramUniform1f(table, save_ProgramUniform1f);
@@ -9594,6 +14484,14 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
    SET_ProgramUniform2fv(table, save_ProgramUniform2fv);
    SET_ProgramUniform3fv(table, save_ProgramUniform3fv);
    SET_ProgramUniform4fv(table, save_ProgramUniform4fv);
+   SET_ProgramUniform1d(table, save_ProgramUniform1d);
+   SET_ProgramUniform2d(table, save_ProgramUniform2d);
+   SET_ProgramUniform3d(table, save_ProgramUniform3d);
+   SET_ProgramUniform4d(table, save_ProgramUniform4d);
+   SET_ProgramUniform1dv(table, save_ProgramUniform1dv);
+   SET_ProgramUniform2dv(table, save_ProgramUniform2dv);
+   SET_ProgramUniform3dv(table, save_ProgramUniform3dv);
+   SET_ProgramUniform4dv(table, save_ProgramUniform4dv);
    SET_ProgramUniform1i(table, save_ProgramUniform1i);
    SET_ProgramUniform2i(table, save_ProgramUniform2i);
    SET_ProgramUniform3i(table, save_ProgramUniform3i);
@@ -9619,9 +14517,107 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
    SET_ProgramUniformMatrix4x2fv(table, save_ProgramUniformMatrix4x2fv);
    SET_ProgramUniformMatrix3x4fv(table, save_ProgramUniformMatrix3x4fv);
    SET_ProgramUniformMatrix4x3fv(table, save_ProgramUniformMatrix4x3fv);
-
-   /* GL_EXT_polygon_offset_clamp */
+   SET_ProgramUniformMatrix2dv(table, save_ProgramUniformMatrix2dv);
+   SET_ProgramUniformMatrix3dv(table, save_ProgramUniformMatrix3dv);
+   SET_ProgramUniformMatrix4dv(table, save_ProgramUniformMatrix4dv);
+   SET_ProgramUniformMatrix2x3dv(table, save_ProgramUniformMatrix2x3dv);
+   SET_ProgramUniformMatrix3x2dv(table, save_ProgramUniformMatrix3x2dv);
+   SET_ProgramUniformMatrix2x4dv(table, save_ProgramUniformMatrix2x4dv);
+   SET_ProgramUniformMatrix4x2dv(table, save_ProgramUniformMatrix4x2dv);
+   SET_ProgramUniformMatrix3x4dv(table, save_ProgramUniformMatrix3x4dv);
+   SET_ProgramUniformMatrix4x3dv(table, save_ProgramUniformMatrix4x3dv);
+
+   /* GL_{ARB,EXT}_polygon_offset_clamp */
    SET_PolygonOffsetClampEXT(table, save_PolygonOffsetClampEXT);
+
+   /* GL_EXT_window_rectangles */
+   SET_WindowRectanglesEXT(table, save_WindowRectanglesEXT);
+
+   /* GL_NV_conservative_raster */
+   SET_SubpixelPrecisionBiasNV(table, save_SubpixelPrecisionBiasNV);
+
+   /* GL_NV_conservative_raster_dilate */
+   SET_ConservativeRasterParameterfNV(table, save_ConservativeRasterParameterfNV);
+
+   /* GL_NV_conservative_raster_pre_snap_triangles */
+   SET_ConservativeRasterParameteriNV(table, save_ConservativeRasterParameteriNV);
+
+   /* GL_EXT_direct_state_access */
+   SET_MatrixLoadfEXT(table, save_MatrixLoadfEXT);
+   SET_MatrixLoaddEXT(table, save_MatrixLoaddEXT);
+   SET_MatrixMultfEXT(table, save_MatrixMultfEXT);
+   SET_MatrixMultdEXT(table, save_MatrixMultdEXT);
+   SET_MatrixRotatefEXT(table, save_MatrixRotatefEXT);
+   SET_MatrixRotatedEXT(table, save_MatrixRotatedEXT);
+   SET_MatrixScalefEXT(table, save_MatrixScalefEXT);
+   SET_MatrixScaledEXT(table, save_MatrixScaledEXT);
+   SET_MatrixTranslatefEXT(table, save_MatrixTranslatefEXT);
+   SET_MatrixTranslatedEXT(table, save_MatrixTranslatedEXT);
+   SET_MatrixLoadIdentityEXT(table, save_MatrixLoadIdentityEXT);
+   SET_MatrixOrthoEXT(table, save_MatrixOrthoEXT);
+   SET_MatrixFrustumEXT(table, save_MatrixFrustumEXT);
+   SET_MatrixPushEXT(table, save_MatrixPushEXT);
+   SET_MatrixPopEXT(table, save_MatrixPopEXT);
+   SET_MatrixLoadTransposefEXT(table, save_MatrixLoadTransposefEXT);
+   SET_MatrixLoadTransposedEXT(table, save_MatrixLoadTransposedEXT);
+   SET_MatrixMultTransposefEXT(table, save_MatrixMultTransposefEXT);
+   SET_MatrixMultTransposedEXT(table, save_MatrixMultTransposedEXT);
+   SET_TextureParameteriEXT(table, save_TextureParameteriEXT);
+   SET_TextureParameterivEXT(table, save_TextureParameterivEXT);
+   SET_TextureParameterfEXT(table, save_TextureParameterfEXT);
+   SET_TextureParameterfvEXT(table, save_TextureParameterfvEXT);
+   SET_TextureParameterIivEXT(table, save_TextureParameterIivEXT);
+   SET_TextureParameterIuivEXT(table, save_TextureParameterIuivEXT);
+   SET_TextureImage1DEXT(table, save_TextureImage1DEXT);
+   SET_TextureImage2DEXT(table, save_TextureImage2DEXT);
+   SET_TextureImage3DEXT(table, save_TextureImage3DEXT);
+   SET_TextureSubImage1DEXT(table, save_TextureSubImage1DEXT);
+   SET_TextureSubImage2DEXT(table, save_TextureSubImage2DEXT);
+   SET_TextureSubImage3DEXT(table, save_TextureSubImage3DEXT);
+   SET_CopyTextureImage1DEXT(table, save_CopyTextureImage1DEXT);
+   SET_CopyTextureImage2DEXT(table, save_CopyTextureImage2DEXT);
+   SET_CopyTextureSubImage1DEXT(table, save_CopyTextureSubImage1DEXT);
+   SET_CopyTextureSubImage2DEXT(table, save_CopyTextureSubImage2DEXT);
+   SET_CopyTextureSubImage3DEXT(table, save_CopyTextureSubImage3DEXT);
+   SET_BindMultiTextureEXT(table, save_BindMultiTextureEXT);
+   SET_MultiTexParameteriEXT(table, save_MultiTexParameteriEXT);
+   SET_MultiTexParameterivEXT(table, save_MultiTexParameterivEXT);
+   SET_MultiTexParameterIivEXT(table, save_MultiTexParameterIivEXT);
+   SET_MultiTexParameterIuivEXT(table, save_MultiTexParameterIuivEXT);
+   SET_MultiTexParameterfEXT(table, save_MultiTexParameterfEXT);
+   SET_MultiTexParameterfvEXT(table, save_MultiTexParameterfvEXT);
+   SET_MultiTexImage1DEXT(table, save_MultiTexImage1DEXT);
+   SET_MultiTexImage2DEXT(table, save_MultiTexImage2DEXT);
+   SET_MultiTexImage3DEXT(table, save_MultiTexImage3DEXT);
+   SET_MultiTexSubImage1DEXT(table, save_MultiTexSubImage1DEXT);
+   SET_MultiTexSubImage2DEXT(table, save_MultiTexSubImage2DEXT);
+   SET_MultiTexSubImage3DEXT(table, save_MultiTexSubImage3DEXT);
+   SET_CopyMultiTexImage1DEXT(table, save_CopyMultiTexImage1DEXT);
+   SET_CopyMultiTexImage2DEXT(table, save_CopyMultiTexImage2DEXT);
+   SET_CopyMultiTexSubImage1DEXT(table, save_CopyMultiTexSubImage1DEXT);
+   SET_CopyMultiTexSubImage2DEXT(table, save_CopyMultiTexSubImage2DEXT);
+   SET_CopyMultiTexSubImage3DEXT(table, save_CopyMultiTexSubImage3DEXT);
+   SET_MultiTexEnvfEXT(table, save_MultiTexEnvfEXT);
+   SET_MultiTexEnvfvEXT(table, save_MultiTexEnvfvEXT);
+   SET_MultiTexEnviEXT(table, save_MultiTexEnviEXT);
+   SET_MultiTexEnvivEXT(table, save_MultiTexEnvivEXT);
+   SET_CompressedTextureImage1DEXT(table, save_CompressedTextureImage1DEXT);
+   SET_CompressedTextureImage2DEXT(table, save_CompressedTextureImage2DEXT);
+   SET_CompressedTextureImage3DEXT(table, save_CompressedTextureImage3DEXT);
+   SET_CompressedTextureSubImage1DEXT(table, save_CompressedTextureSubImage1DEXT);
+   SET_CompressedTextureSubImage2DEXT(table, save_CompressedTextureSubImage2DEXT);
+   SET_CompressedTextureSubImage3DEXT(table, save_CompressedTextureSubImage3DEXT);
+   SET_CompressedMultiTexImage1DEXT(table, save_CompressedMultiTexImage1DEXT);
+   SET_CompressedMultiTexImage2DEXT(table, save_CompressedMultiTexImage2DEXT);
+   SET_CompressedMultiTexImage3DEXT(table, save_CompressedMultiTexImage3DEXT);
+   SET_CompressedMultiTexSubImage1DEXT(table, save_CompressedMultiTexSubImage1DEXT);
+   SET_CompressedMultiTexSubImage2DEXT(table, save_CompressedMultiTexSubImage2DEXT);
+   SET_CompressedMultiTexSubImage3DEXT(table, save_CompressedMultiTexSubImage3DEXT);
+   SET_NamedProgramStringEXT(table, save_NamedProgramStringEXT);
+   SET_NamedProgramLocalParameter4dEXT(table, save_NamedProgramLocalParameter4dEXT);
+   SET_NamedProgramLocalParameter4dvEXT(table, save_NamedProgramLocalParameter4dvEXT);
+   SET_NamedProgramLocalParameter4fEXT(table, save_NamedProgramLocalParameter4fEXT);
+   SET_NamedProgramLocalParameter4fvEXT(table, save_NamedProgramLocalParameter4fvEXT);
 }
 
 
@@ -9654,12 +14650,13 @@ print_list(struct gl_context *ctx, GLuint list, const char *fname)
 
    if (!islist(ctx, list)) {
       fprintf(f, "%u is not a display list ID\n", list);
-      return;
+      goto out;
    }
 
    dlist = _mesa_lookup_list(ctx, list);
-   if (!dlist)
-      return;
+   if (!dlist) {
+      goto out;
+   }
 
    n = dlist->Head;
 
@@ -9728,9 +14725,8 @@ print_list(struct gl_context *ctx, GLuint list, const char *fname)
          case OPCODE_CALL_LIST:
             fprintf(f, "CallList %d\n", (int) n[1].ui);
             break;
-         case OPCODE_CALL_LIST_OFFSET:
-            fprintf(f, "CallList %d + offset %u = %u\n", (int) n[1].ui,
-                         ctx->List.ListBase, ctx->List.ListBase + n[1].ui);
+         case OPCODE_CALL_LISTS:
+            fprintf(f, "CallLists %d, %s\n", n[1].i, enum_string(n[1].e));
             break;
          case OPCODE_DISABLE:
             fprintf(f, "Disable %s\n", enum_string(n[1].e));
@@ -9931,7 +14927,7 @@ print_list(struct gl_context *ctx, GLuint list, const char *fname)
                printf
                   ("ERROR IN DISPLAY LIST: opcode = %d, address = %p\n",
                    opcode, (void *) n);
-               return;
+               goto out;
             }
             else {
                fprintf(f, "command %d, %u operands\n", opcode,
@@ -9940,11 +14936,13 @@ print_list(struct gl_context *ctx, GLuint list, const char *fname)
          }
          /* increment n to point to next compiled command */
          if (opcode != OPCODE_CONTINUE) {
+            assert(InstSize[opcode] > 0);
             n += InstSize[opcode];
          }
       }
    }
 
+ out:
    fflush(f);
    if (fname)
       fclose(f);
@@ -9969,72 +14967,6 @@ mesa_print_display_list(GLuint list)
 /*****                      Initialization                        *****/
 /**********************************************************************/
 
-static void
-save_vtxfmt_init(GLvertexformat * vfmt)
-{
-   vfmt->ArrayElement = _ae_ArrayElement;
-
-   vfmt->Begin = save_Begin;
-
-   vfmt->CallList = save_CallList;
-   vfmt->CallLists = save_CallLists;
-
-   vfmt->Color3f = save_Color3f;
-   vfmt->Color3fv = save_Color3fv;
-   vfmt->Color4f = save_Color4f;
-   vfmt->Color4fv = save_Color4fv;
-   vfmt->EdgeFlag = save_EdgeFlag;
-   vfmt->End = save_End;
-
-   vfmt->EvalCoord1f = save_EvalCoord1f;
-   vfmt->EvalCoord1fv = save_EvalCoord1fv;
-   vfmt->EvalCoord2f = save_EvalCoord2f;
-   vfmt->EvalCoord2fv = save_EvalCoord2fv;
-   vfmt->EvalPoint1 = save_EvalPoint1;
-   vfmt->EvalPoint2 = save_EvalPoint2;
-
-   vfmt->FogCoordfEXT = save_FogCoordfEXT;
-   vfmt->FogCoordfvEXT = save_FogCoordfvEXT;
-   vfmt->Indexf = save_Indexf;
-   vfmt->Indexfv = save_Indexfv;
-   vfmt->Materialfv = save_Materialfv;
-   vfmt->MultiTexCoord1fARB = save_MultiTexCoord1f;
-   vfmt->MultiTexCoord1fvARB = save_MultiTexCoord1fv;
-   vfmt->MultiTexCoord2fARB = save_MultiTexCoord2f;
-   vfmt->MultiTexCoord2fvARB = save_MultiTexCoord2fv;
-   vfmt->MultiTexCoord3fARB = save_MultiTexCoord3f;
-   vfmt->MultiTexCoord3fvARB = save_MultiTexCoord3fv;
-   vfmt->MultiTexCoord4fARB = save_MultiTexCoord4f;
-   vfmt->MultiTexCoord4fvARB = save_MultiTexCoord4fv;
-   vfmt->Normal3f = save_Normal3f;
-   vfmt->Normal3fv = save_Normal3fv;
-   vfmt->SecondaryColor3fEXT = save_SecondaryColor3fEXT;
-   vfmt->SecondaryColor3fvEXT = save_SecondaryColor3fvEXT;
-   vfmt->TexCoord1f = save_TexCoord1f;
-   vfmt->TexCoord1fv = save_TexCoord1fv;
-   vfmt->TexCoord2f = save_TexCoord2f;
-   vfmt->TexCoord2fv = save_TexCoord2fv;
-   vfmt->TexCoord3f = save_TexCoord3f;
-   vfmt->TexCoord3fv = save_TexCoord3fv;
-   vfmt->TexCoord4f = save_TexCoord4f;
-   vfmt->TexCoord4fv = save_TexCoord4fv;
-   vfmt->Vertex2f = save_Vertex2f;
-   vfmt->Vertex2fv = save_Vertex2fv;
-   vfmt->Vertex3f = save_Vertex3f;
-   vfmt->Vertex3fv = save_Vertex3fv;
-   vfmt->Vertex4f = save_Vertex4f;
-   vfmt->Vertex4fv = save_Vertex4fv;
-   vfmt->VertexAttrib1fARB = save_VertexAttrib1fARB;
-   vfmt->VertexAttrib1fvARB = save_VertexAttrib1fvARB;
-   vfmt->VertexAttrib2fARB = save_VertexAttrib2fARB;
-   vfmt->VertexAttrib2fvARB = save_VertexAttrib2fvARB;
-   vfmt->VertexAttrib3fARB = save_VertexAttrib3fARB;
-   vfmt->VertexAttrib3fvARB = save_VertexAttrib3fvARB;
-   vfmt->VertexAttrib4fARB = save_VertexAttrib4fARB;
-   vfmt->VertexAttrib4fvARB = save_VertexAttrib4fvARB;
-}
-
-
 void
 _mesa_install_dlist_vtxfmt(struct _glapi_table *disp,
                            const GLvertexformat *vfmt)
@@ -10051,6 +14983,7 @@ void
 _mesa_init_display_list(struct gl_context *ctx)
 {
    static GLboolean tableInitialized = GL_FALSE;
+   GLvertexformat *vfmt = &ctx->ListState.ListVtxfmt;
 
    /* zero-out the instruction size table, just once */
    if (!tableInitialized) {
@@ -10071,9 +15004,14 @@ _mesa_init_display_list(struct gl_context *ctx)
    /* Display List group */
    ctx->List.ListBase = 0;
 
-   save_vtxfmt_init(&ctx->ListState.ListVtxfmt);
-
    InstSize[OPCODE_NOP] = 1;
+
+#define NAME_AE(x) _ae_##x
+#define NAME_CALLLIST(x) save_##x
+#define NAME(x) save_##x
+#define NAME_ES(x) save_##x##ARB
+
+#include "vbo/vbo_init_tmp.h"
 }