dlist.c revision e4ae85df
1/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5 * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27/**
28 * \file dlist.c
29 * Display lists management functions.
30 */
31
32#include "glheader.h"
33#include "imports.h"
34#include "api_arrayelt.h"
35#include "api_exec.h"
36#include "api_loopback.h"
37#include "api_validate.h"
38#include "atifragshader.h"
39#include "config.h"
40#include "bufferobj.h"
41#include "arrayobj.h"
42#include "context.h"
43#include "dlist.h"
44#include "enums.h"
45#include "eval.h"
46#include "fbobject.h"
47#include "framebuffer.h"
48#include "glapi/glapi.h"
49#include "glformats.h"
50#include "hash.h"
51#include "image.h"
52#include "light.h"
53#include "macros.h"
54#include "pack.h"
55#include "pbo.h"
56#include "queryobj.h"
57#include "samplerobj.h"
58#include "shaderapi.h"
59#include "syncobj.h"
60#include "teximage.h"
61#include "texstorage.h"
62#include "mtypes.h"
63#include "varray.h"
64#include "arbprogram.h"
65#include "transformfeedback.h"
66
67#include "math/m_matrix.h"
68
69#include "main/dispatch.h"
70
71#include "vbo/vbo.h"
72
73
74
75/**
76 * Other parts of Mesa (such as the VBO module) can plug into the display
77 * list system.  This structure describes new display list instructions.
78 */
79struct gl_list_instruction
80{
81   GLuint Size;
82   void (*Execute)( struct gl_context *ctx, void *data );
83   void (*Destroy)( struct gl_context *ctx, void *data );
84   void (*Print)( struct gl_context *ctx, void *data );
85};
86
87
88#define MAX_DLIST_EXT_OPCODES 16
89
90/**
91 * Used by device drivers to hook new commands into display lists.
92 */
93struct gl_list_extensions
94{
95   struct gl_list_instruction Opcode[MAX_DLIST_EXT_OPCODES];
96   GLuint NumOpcodes;
97};
98
99
100
101/**
102 * Flush vertices.
103 *
104 * \param ctx GL context.
105 *
106 * Checks if dd_function_table::SaveNeedFlush is marked to flush
107 * stored (save) vertices, and calls
108 * dd_function_table::SaveFlushVertices if so.
109 */
110#define SAVE_FLUSH_VERTICES(ctx)		\
111do {						\
112   if (ctx->Driver.SaveNeedFlush)		\
113      ctx->Driver.SaveFlushVertices(ctx);	\
114} while (0)
115
116
117/**
118 * Macro to assert that the API call was made outside the
119 * glBegin()/glEnd() pair, with return value.
120 *
121 * \param ctx GL context.
122 * \param retval value to return value in case the assertion fails.
123 */
124#define ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval)		\
125do {									\
126   if (ctx->Driver.CurrentSavePrimitive <= PRIM_MAX) {			\
127      _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glBegin/End" );	\
128      return retval;							\
129   }									\
130} while (0)
131
132/**
133 * Macro to assert that the API call was made outside the
134 * glBegin()/glEnd() pair.
135 *
136 * \param ctx GL context.
137 */
138#define ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx)				\
139do {									\
140   if (ctx->Driver.CurrentSavePrimitive <= PRIM_MAX) {			\
141      _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glBegin/End" );	\
142      return;								\
143   }									\
144} while (0)
145
146/**
147 * Macro to assert that the API call was made outside the
148 * glBegin()/glEnd() pair and flush the vertices.
149 *
150 * \param ctx GL context.
151 */
152#define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx)			\
153do {									\
154   ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx);					\
155   SAVE_FLUSH_VERTICES(ctx);						\
156} while (0)
157
158/**
159 * Macro to assert that the API call was made outside the
160 * glBegin()/glEnd() pair and flush the vertices, with return value.
161 *
162 * \param ctx GL context.
163 * \param retval value to return value in case the assertion fails.
164 */
165#define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, retval)\
166do {									\
167   ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval);		\
168   SAVE_FLUSH_VERTICES(ctx);						\
169} while (0)
170
171
172
173/**
174 * Display list opcodes.
175 *
176 * The fact that these identifiers are assigned consecutive
177 * integer values starting at 0 is very important, see InstSize array usage)
178 */
179typedef enum
180{
181   OPCODE_INVALID = -1,         /* Force signed enum */
182   OPCODE_ACCUM,
183   OPCODE_ALPHA_FUNC,
184   OPCODE_BIND_TEXTURE,
185   OPCODE_BITMAP,
186   OPCODE_BLEND_COLOR,
187   OPCODE_BLEND_EQUATION,
188   OPCODE_BLEND_EQUATION_SEPARATE,
189   OPCODE_BLEND_FUNC_SEPARATE,
190
191   OPCODE_BLEND_EQUATION_I,
192   OPCODE_BLEND_EQUATION_SEPARATE_I,
193   OPCODE_BLEND_FUNC_I,
194   OPCODE_BLEND_FUNC_SEPARATE_I,
195
196   OPCODE_CALL_LIST,
197   OPCODE_CALL_LIST_OFFSET,
198   OPCODE_CLEAR,
199   OPCODE_CLEAR_ACCUM,
200   OPCODE_CLEAR_COLOR,
201   OPCODE_CLEAR_DEPTH,
202   OPCODE_CLEAR_INDEX,
203   OPCODE_CLEAR_STENCIL,
204   OPCODE_CLEAR_BUFFER_IV,
205   OPCODE_CLEAR_BUFFER_UIV,
206   OPCODE_CLEAR_BUFFER_FV,
207   OPCODE_CLEAR_BUFFER_FI,
208   OPCODE_CLIP_PLANE,
209   OPCODE_COLOR_MASK,
210   OPCODE_COLOR_MASK_INDEXED,
211   OPCODE_COLOR_MATERIAL,
212   OPCODE_COPY_PIXELS,
213   OPCODE_COPY_TEX_IMAGE1D,
214   OPCODE_COPY_TEX_IMAGE2D,
215   OPCODE_COPY_TEX_SUB_IMAGE1D,
216   OPCODE_COPY_TEX_SUB_IMAGE2D,
217   OPCODE_COPY_TEX_SUB_IMAGE3D,
218   OPCODE_CULL_FACE,
219   OPCODE_DEPTH_FUNC,
220   OPCODE_DEPTH_MASK,
221   OPCODE_DEPTH_RANGE,
222   OPCODE_DISABLE,
223   OPCODE_DISABLE_INDEXED,
224   OPCODE_DRAW_BUFFER,
225   OPCODE_DRAW_PIXELS,
226   OPCODE_ENABLE,
227   OPCODE_ENABLE_INDEXED,
228   OPCODE_EVALMESH1,
229   OPCODE_EVALMESH2,
230   OPCODE_FOG,
231   OPCODE_FRONT_FACE,
232   OPCODE_FRUSTUM,
233   OPCODE_HINT,
234   OPCODE_INDEX_MASK,
235   OPCODE_INIT_NAMES,
236   OPCODE_LIGHT,
237   OPCODE_LIGHT_MODEL,
238   OPCODE_LINE_STIPPLE,
239   OPCODE_LINE_WIDTH,
240   OPCODE_LIST_BASE,
241   OPCODE_LOAD_IDENTITY,
242   OPCODE_LOAD_MATRIX,
243   OPCODE_LOAD_NAME,
244   OPCODE_LOGIC_OP,
245   OPCODE_MAP1,
246   OPCODE_MAP2,
247   OPCODE_MAPGRID1,
248   OPCODE_MAPGRID2,
249   OPCODE_MATRIX_MODE,
250   OPCODE_MULT_MATRIX,
251   OPCODE_ORTHO,
252   OPCODE_PASSTHROUGH,
253   OPCODE_PIXEL_MAP,
254   OPCODE_PIXEL_TRANSFER,
255   OPCODE_PIXEL_ZOOM,
256   OPCODE_POINT_SIZE,
257   OPCODE_POINT_PARAMETERS,
258   OPCODE_POLYGON_MODE,
259   OPCODE_POLYGON_STIPPLE,
260   OPCODE_POLYGON_OFFSET,
261   OPCODE_POP_ATTRIB,
262   OPCODE_POP_MATRIX,
263   OPCODE_POP_NAME,
264   OPCODE_PRIORITIZE_TEXTURE,
265   OPCODE_PUSH_ATTRIB,
266   OPCODE_PUSH_MATRIX,
267   OPCODE_PUSH_NAME,
268   OPCODE_RASTER_POS,
269   OPCODE_READ_BUFFER,
270   OPCODE_ROTATE,
271   OPCODE_SCALE,
272   OPCODE_SCISSOR,
273   OPCODE_SELECT_TEXTURE_SGIS,
274   OPCODE_SELECT_TEXTURE_COORD_SET,
275   OPCODE_SHADE_MODEL,
276   OPCODE_STENCIL_FUNC,
277   OPCODE_STENCIL_MASK,
278   OPCODE_STENCIL_OP,
279   OPCODE_TEXENV,
280   OPCODE_TEXGEN,
281   OPCODE_TEXPARAMETER,
282   OPCODE_TEX_IMAGE1D,
283   OPCODE_TEX_IMAGE2D,
284   OPCODE_TEX_IMAGE3D,
285   OPCODE_TEX_SUB_IMAGE1D,
286   OPCODE_TEX_SUB_IMAGE2D,
287   OPCODE_TEX_SUB_IMAGE3D,
288   OPCODE_TRANSLATE,
289   OPCODE_VIEWPORT,
290   OPCODE_WINDOW_POS,
291   /* GL_ARB_multitexture */
292   OPCODE_ACTIVE_TEXTURE,
293   /* GL_ARB_texture_compression */
294   OPCODE_COMPRESSED_TEX_IMAGE_1D,
295   OPCODE_COMPRESSED_TEX_IMAGE_2D,
296   OPCODE_COMPRESSED_TEX_IMAGE_3D,
297   OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D,
298   OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D,
299   OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D,
300   /* GL_ARB_multisample */
301   OPCODE_SAMPLE_COVERAGE,
302   /* GL_ARB_window_pos */
303   OPCODE_WINDOW_POS_ARB,
304   /* GL_NV_fragment_program */
305   OPCODE_BIND_PROGRAM_NV,
306   OPCODE_PROGRAM_LOCAL_PARAMETER_ARB,
307   /* GL_EXT_stencil_two_side */
308   OPCODE_ACTIVE_STENCIL_FACE_EXT,
309   /* GL_EXT_depth_bounds_test */
310   OPCODE_DEPTH_BOUNDS_EXT,
311   /* GL_ARB_vertex/fragment_program */
312   OPCODE_PROGRAM_STRING_ARB,
313   OPCODE_PROGRAM_ENV_PARAMETER_ARB,
314   /* GL_ARB_occlusion_query */
315   OPCODE_BEGIN_QUERY_ARB,
316   OPCODE_END_QUERY_ARB,
317   /* GL_ARB_draw_buffers */
318   OPCODE_DRAW_BUFFERS_ARB,
319   /* GL_ATI_fragment_shader */
320   OPCODE_BIND_FRAGMENT_SHADER_ATI,
321   OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI,
322   /* OpenGL 2.0 */
323   OPCODE_STENCIL_FUNC_SEPARATE,
324   OPCODE_STENCIL_OP_SEPARATE,
325   OPCODE_STENCIL_MASK_SEPARATE,
326
327   /* GL_ARB_shader_objects */
328   OPCODE_USE_PROGRAM,
329   OPCODE_UNIFORM_1F,
330   OPCODE_UNIFORM_2F,
331   OPCODE_UNIFORM_3F,
332   OPCODE_UNIFORM_4F,
333   OPCODE_UNIFORM_1FV,
334   OPCODE_UNIFORM_2FV,
335   OPCODE_UNIFORM_3FV,
336   OPCODE_UNIFORM_4FV,
337   OPCODE_UNIFORM_1I,
338   OPCODE_UNIFORM_2I,
339   OPCODE_UNIFORM_3I,
340   OPCODE_UNIFORM_4I,
341   OPCODE_UNIFORM_1IV,
342   OPCODE_UNIFORM_2IV,
343   OPCODE_UNIFORM_3IV,
344   OPCODE_UNIFORM_4IV,
345   OPCODE_UNIFORM_MATRIX22,
346   OPCODE_UNIFORM_MATRIX33,
347   OPCODE_UNIFORM_MATRIX44,
348   OPCODE_UNIFORM_MATRIX23,
349   OPCODE_UNIFORM_MATRIX32,
350   OPCODE_UNIFORM_MATRIX24,
351   OPCODE_UNIFORM_MATRIX42,
352   OPCODE_UNIFORM_MATRIX34,
353   OPCODE_UNIFORM_MATRIX43,
354
355   /* OpenGL 3.0 */
356   OPCODE_UNIFORM_1UI,
357   OPCODE_UNIFORM_2UI,
358   OPCODE_UNIFORM_3UI,
359   OPCODE_UNIFORM_4UI,
360   OPCODE_UNIFORM_1UIV,
361   OPCODE_UNIFORM_2UIV,
362   OPCODE_UNIFORM_3UIV,
363   OPCODE_UNIFORM_4UIV,
364
365   /* OpenGL 4.2 / GL_ARB_separate_shader_objects */
366   OPCODE_USE_PROGRAM_STAGES,
367   OPCODE_PROGRAM_UNIFORM_1F,
368   OPCODE_PROGRAM_UNIFORM_2F,
369   OPCODE_PROGRAM_UNIFORM_3F,
370   OPCODE_PROGRAM_UNIFORM_4F,
371   OPCODE_PROGRAM_UNIFORM_1FV,
372   OPCODE_PROGRAM_UNIFORM_2FV,
373   OPCODE_PROGRAM_UNIFORM_3FV,
374   OPCODE_PROGRAM_UNIFORM_4FV,
375   OPCODE_PROGRAM_UNIFORM_1I,
376   OPCODE_PROGRAM_UNIFORM_2I,
377   OPCODE_PROGRAM_UNIFORM_3I,
378   OPCODE_PROGRAM_UNIFORM_4I,
379   OPCODE_PROGRAM_UNIFORM_1IV,
380   OPCODE_PROGRAM_UNIFORM_2IV,
381   OPCODE_PROGRAM_UNIFORM_3IV,
382   OPCODE_PROGRAM_UNIFORM_4IV,
383   OPCODE_PROGRAM_UNIFORM_1UI,
384   OPCODE_PROGRAM_UNIFORM_2UI,
385   OPCODE_PROGRAM_UNIFORM_3UI,
386   OPCODE_PROGRAM_UNIFORM_4UI,
387   OPCODE_PROGRAM_UNIFORM_1UIV,
388   OPCODE_PROGRAM_UNIFORM_2UIV,
389   OPCODE_PROGRAM_UNIFORM_3UIV,
390   OPCODE_PROGRAM_UNIFORM_4UIV,
391   OPCODE_PROGRAM_UNIFORM_MATRIX22F,
392   OPCODE_PROGRAM_UNIFORM_MATRIX33F,
393   OPCODE_PROGRAM_UNIFORM_MATRIX44F,
394   OPCODE_PROGRAM_UNIFORM_MATRIX23F,
395   OPCODE_PROGRAM_UNIFORM_MATRIX32F,
396   OPCODE_PROGRAM_UNIFORM_MATRIX24F,
397   OPCODE_PROGRAM_UNIFORM_MATRIX42F,
398   OPCODE_PROGRAM_UNIFORM_MATRIX34F,
399   OPCODE_PROGRAM_UNIFORM_MATRIX43F,
400
401   /* GL_ARB_color_buffer_float */
402   OPCODE_CLAMP_COLOR,
403
404   /* GL_EXT_framebuffer_blit */
405   OPCODE_BLIT_FRAMEBUFFER,
406
407   /* Vertex attributes -- fallback for when optimized display
408    * list build isn't active.
409    */
410   OPCODE_ATTR_1F_NV,
411   OPCODE_ATTR_2F_NV,
412   OPCODE_ATTR_3F_NV,
413   OPCODE_ATTR_4F_NV,
414   OPCODE_ATTR_1F_ARB,
415   OPCODE_ATTR_2F_ARB,
416   OPCODE_ATTR_3F_ARB,
417   OPCODE_ATTR_4F_ARB,
418   OPCODE_MATERIAL,
419   OPCODE_BEGIN,
420   OPCODE_END,
421   OPCODE_RECTF,
422   OPCODE_EVAL_C1,
423   OPCODE_EVAL_C2,
424   OPCODE_EVAL_P1,
425   OPCODE_EVAL_P2,
426
427   /* GL_EXT_provoking_vertex */
428   OPCODE_PROVOKING_VERTEX,
429
430   /* GL_EXT_transform_feedback */
431   OPCODE_BEGIN_TRANSFORM_FEEDBACK,
432   OPCODE_END_TRANSFORM_FEEDBACK,
433   OPCODE_BIND_TRANSFORM_FEEDBACK,
434   OPCODE_PAUSE_TRANSFORM_FEEDBACK,
435   OPCODE_RESUME_TRANSFORM_FEEDBACK,
436   OPCODE_DRAW_TRANSFORM_FEEDBACK,
437
438   /* GL_EXT_texture_integer */
439   OPCODE_CLEARCOLOR_I,
440   OPCODE_CLEARCOLOR_UI,
441   OPCODE_TEXPARAMETER_I,
442   OPCODE_TEXPARAMETER_UI,
443
444   /* GL_ARB_instanced_arrays */
445   OPCODE_VERTEX_ATTRIB_DIVISOR,
446
447   /* GL_NV_texture_barrier */
448   OPCODE_TEXTURE_BARRIER_NV,
449
450   /* GL_ARB_sampler_object */
451   OPCODE_BIND_SAMPLER,
452   OPCODE_SAMPLER_PARAMETERIV,
453   OPCODE_SAMPLER_PARAMETERFV,
454   OPCODE_SAMPLER_PARAMETERIIV,
455   OPCODE_SAMPLER_PARAMETERUIV,
456
457   /* GL_ARB_geometry_shader4 */
458   OPCODE_PROGRAM_PARAMETERI,
459   OPCODE_FRAMEBUFFER_TEXTURE,
460   OPCODE_FRAMEBUFFER_TEXTURE_FACE,
461
462   /* GL_ARB_sync */
463   OPCODE_WAIT_SYNC,
464
465   /* GL_NV_conditional_render */
466   OPCODE_BEGIN_CONDITIONAL_RENDER,
467   OPCODE_END_CONDITIONAL_RENDER,
468
469   /* ARB_timer_query */
470   OPCODE_QUERY_COUNTER,
471
472   /* ARB_transform_feedback3 */
473   OPCODE_BEGIN_QUERY_INDEXED,
474   OPCODE_END_QUERY_INDEXED,
475   OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM,
476
477   /* ARB_transform_feedback_instanced */
478   OPCODE_DRAW_TRANSFORM_FEEDBACK_INSTANCED,
479   OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM_INSTANCED,
480
481   /* ARB_uniform_buffer_object */
482   OPCODE_UNIFORM_BLOCK_BINDING,
483
484   /* The following three are meta instructions */
485   OPCODE_ERROR,                /* raise compiled-in error */
486   OPCODE_CONTINUE,
487   OPCODE_END_OF_LIST,
488   OPCODE_EXT_0
489} OpCode;
490
491
492
493/**
494 * Display list node.
495 *
496 * Display list instructions are stored as sequences of "nodes".  Nodes
497 * are allocated in blocks.  Each block has BLOCK_SIZE nodes.  Blocks
498 * are linked together with a pointer.
499 *
500 * Each instruction in the display list is stored as a sequence of
501 * contiguous nodes in memory.
502 * Each node is the union of a variety of data types.
503 *
504 * Note, all of these members should be 4 bytes in size or less for the
505 * sake of compact display lists.  We store 8-byte pointers in a pair of
506 * these nodes using the save/get_pointer() functions below.
507 */
508#if defined(__NetBSD__) && defined(_LP64) && !defined(__x86_64__)
509/*
510 * This pointer typ is returned with "node + 1", which ends up at an
511 * illegal offset for 64 bit values, such as pointers, which may be
512 * stored in the returned space.  As such, we have to force this
513 * structure to be 64-bit type aligned.  x86-64 is the only known
514 * platform that allows this.
515 */
516#define STRICT_DLIST_ALIGNMENT
517#endif
518union gl_dlist_node
519{
520   OpCode opcode;
521   GLboolean b;
522   GLbitfield bf;
523   GLubyte ub;
524   GLshort s;
525   GLushort us;
526   GLint i;
527   GLuint ui;
528   GLenum e;
529   GLfloat f;
530   GLsizei si;
531#ifdef STRICT_DLIST_ALIGNMENT
532   unsigned long long _dummy;
533#endif
534};
535
536
537typedef union gl_dlist_node Node;
538
539
540/** How many 4-byte dwords to store a pointer */
541#define POINTER_DWORDS (sizeof(void *) / 4)
542
543/* We want to keep sizeof(union gl_dlist_node) == 4 to minimize
544 * space for display lists.  The following types and functions are
545 * used to help store 4- and 8-byte pointers in 1 or 2 dlist_nodes.
546 */
547union pointer
548{
549   void *ptr;
550   GLuint dwords[POINTER_DWORDS];
551};
552
553
554/**
555 * Save a 4 or 8-byte pointer at dest (and dest+1).
556 */
557static inline void
558save_pointer(union gl_dlist_node *dest, void *src)
559{
560   union pointer p;
561   unsigned i;
562
563   STATIC_ASSERT(POINTER_DWORDS == 1 || POINTER_DWORDS == 2);
564#ifdef STRICT_DLIST_ALIGNMENT
565   STATIC_ASSERT(sizeof(union gl_dlist_node) == 4 ||
566                 sizeof(union gl_dlist_node) == 8);
567#else
568   STATIC_ASSERT(sizeof(union gl_dlist_node) == 4);
569#endif
570
571   p.ptr = src;
572
573   for (i = 0; i < POINTER_DWORDS; i++)
574      dest[i].ui = p.dwords[i];
575}
576
577
578/**
579 * Retrieve a 4 or 8-byte pointer from node (node+1).
580 */
581static inline void *
582get_pointer(const union gl_dlist_node *node)
583{
584   union pointer p;
585   unsigned i;
586
587   for (i = 0; i < POINTER_DWORDS; i++)
588      p.dwords[i] = node[i].ui;
589
590   return p.ptr;
591}
592
593
594/**
595 * Used to store a 64-bit uint in a pair of "Nodes" for the sake of 32-bit
596 * environment.  In 64-bit env, sizeof(Node)==8 anyway.
597 */
598union uint64_pair
599{
600   GLuint64 uint64;
601   GLuint uint32[2];
602};
603
604
605/**
606 * How many nodes to allocate at a time.  Note that bulk vertex data
607 * from glBegin/glVertex/glEnd primitives will typically wind up in
608 * a VBO, and not directly in the display list itself.
609 */
610#define BLOCK_SIZE 256
611
612
613
614/**
615 * Number of nodes of storage needed for each instruction.
616 * Sizes for dynamically allocated opcodes are stored in the context struct.
617 */
618static GLuint InstSize[OPCODE_END_OF_LIST + 1];
619
620
621void mesa_print_display_list(GLuint list);
622
623
624/**
625 * Allocate a gl_display_list object with an initial block of storage.
626 * \param count  how many display list nodes/tokes to allocate
627 */
628static struct gl_display_list *
629make_list(GLuint name, GLuint count)
630{
631   struct gl_display_list *dlist = CALLOC_STRUCT(gl_display_list);
632   dlist->Name = name;
633   dlist->Head = malloc(sizeof(Node) * count);
634   dlist->Head[0].opcode = OPCODE_END_OF_LIST;
635   return dlist;
636}
637
638
639/**
640 * Lookup function to just encapsulate casting.
641 */
642struct gl_display_list *
643_mesa_lookup_list(struct gl_context *ctx, GLuint list)
644{
645   return (struct gl_display_list *)
646      _mesa_HashLookup(ctx->Shared->DisplayList, list);
647}
648
649
650/** Is the given opcode an extension code? */
651static inline GLboolean
652is_ext_opcode(OpCode opcode)
653{
654   return (opcode >= OPCODE_EXT_0);
655}
656
657
658/** Destroy an extended opcode instruction */
659static GLint
660ext_opcode_destroy(struct gl_context *ctx, Node *node)
661{
662   const GLint i = node[0].opcode - OPCODE_EXT_0;
663   GLint step;
664   ctx->ListExt->Opcode[i].Destroy(ctx, &node[1]);
665   step = ctx->ListExt->Opcode[i].Size;
666   return step;
667}
668
669
670/** Execute an extended opcode instruction */
671static GLint
672ext_opcode_execute(struct gl_context *ctx, Node *node)
673{
674   const GLint i = node[0].opcode - OPCODE_EXT_0;
675   GLint step;
676   ctx->ListExt->Opcode[i].Execute(ctx, &node[1]);
677   step = ctx->ListExt->Opcode[i].Size;
678   return step;
679}
680
681
682/** Print an extended opcode instruction */
683static GLint
684ext_opcode_print(struct gl_context *ctx, Node *node)
685{
686   const GLint i = node[0].opcode - OPCODE_EXT_0;
687   GLint step;
688   ctx->ListExt->Opcode[i].Print(ctx, &node[1]);
689   step = ctx->ListExt->Opcode[i].Size;
690   return step;
691}
692
693
694/**
695 * Delete the named display list, but don't remove from hash table.
696 * \param dlist - display list pointer
697 */
698void
699_mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
700{
701   Node *n, *block;
702   GLboolean done;
703
704   n = block = dlist->Head;
705
706   done = block ? GL_FALSE : GL_TRUE;
707   while (!done) {
708      const OpCode opcode = n[0].opcode;
709
710      /* check for extension opcodes first */
711      if (is_ext_opcode(opcode)) {
712         n += ext_opcode_destroy(ctx, n);
713      }
714      else {
715         switch (opcode) {
716            /* for some commands, we need to free malloc'd memory */
717         case OPCODE_MAP1:
718            free(get_pointer(&n[6]));
719            n += InstSize[n[0].opcode];
720            break;
721         case OPCODE_MAP2:
722            free(get_pointer(&n[10]));
723            n += InstSize[n[0].opcode];
724            break;
725         case OPCODE_DRAW_PIXELS:
726            free(get_pointer(&n[5]));
727            n += InstSize[n[0].opcode];
728            break;
729         case OPCODE_BITMAP:
730            free(get_pointer(&n[7]));
731            n += InstSize[n[0].opcode];
732            break;
733         case OPCODE_POLYGON_STIPPLE:
734            free(get_pointer(&n[1]));
735            n += InstSize[n[0].opcode];
736            break;
737         case OPCODE_TEX_IMAGE1D:
738            free(get_pointer(&n[8]));
739            n += InstSize[n[0].opcode];
740            break;
741         case OPCODE_TEX_IMAGE2D:
742            free(get_pointer(&n[9]));
743            n += InstSize[n[0].opcode];
744            break;
745         case OPCODE_TEX_IMAGE3D:
746            free(get_pointer(&n[10]));
747            n += InstSize[n[0].opcode];
748            break;
749         case OPCODE_TEX_SUB_IMAGE1D:
750            free(get_pointer(&n[7]));
751            n += InstSize[n[0].opcode];
752            break;
753         case OPCODE_TEX_SUB_IMAGE2D:
754            free(get_pointer(&n[9]));
755            n += InstSize[n[0].opcode];
756            break;
757         case OPCODE_TEX_SUB_IMAGE3D:
758            free(get_pointer(&n[11]));
759            n += InstSize[n[0].opcode];
760            break;
761         case OPCODE_COMPRESSED_TEX_IMAGE_1D:
762            free(get_pointer(&n[7]));
763            n += InstSize[n[0].opcode];
764            break;
765         case OPCODE_COMPRESSED_TEX_IMAGE_2D:
766            free(get_pointer(&n[8]));
767            n += InstSize[n[0].opcode];
768            break;
769         case OPCODE_COMPRESSED_TEX_IMAGE_3D:
770            free(get_pointer(&n[9]));
771            n += InstSize[n[0].opcode];
772            break;
773         case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D:
774            free(get_pointer(&n[7]));
775            n += InstSize[n[0].opcode];
776            break;
777         case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D:
778            free(get_pointer(&n[9]));
779            n += InstSize[n[0].opcode];
780            break;
781         case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D:
782            free(get_pointer(&n[11]));
783            n += InstSize[n[0].opcode];
784            break;
785         case OPCODE_PROGRAM_STRING_ARB:
786            free(get_pointer(&n[4]));      /* program string */
787            n += InstSize[n[0].opcode];
788            break;
789         case OPCODE_UNIFORM_1FV:
790         case OPCODE_UNIFORM_2FV:
791         case OPCODE_UNIFORM_3FV:
792         case OPCODE_UNIFORM_4FV:
793         case OPCODE_UNIFORM_1IV:
794         case OPCODE_UNIFORM_2IV:
795         case OPCODE_UNIFORM_3IV:
796         case OPCODE_UNIFORM_4IV:
797         case OPCODE_UNIFORM_1UIV:
798         case OPCODE_UNIFORM_2UIV:
799         case OPCODE_UNIFORM_3UIV:
800         case OPCODE_UNIFORM_4UIV:
801            free(get_pointer(&n[3]));
802            n += InstSize[n[0].opcode];
803            break;
804         case OPCODE_UNIFORM_MATRIX22:
805         case OPCODE_UNIFORM_MATRIX33:
806         case OPCODE_UNIFORM_MATRIX44:
807         case OPCODE_UNIFORM_MATRIX24:
808         case OPCODE_UNIFORM_MATRIX42:
809         case OPCODE_UNIFORM_MATRIX23:
810         case OPCODE_UNIFORM_MATRIX32:
811         case OPCODE_UNIFORM_MATRIX34:
812         case OPCODE_UNIFORM_MATRIX43:
813            free(get_pointer(&n[4]));
814            n += InstSize[n[0].opcode];
815            break;
816         case OPCODE_PROGRAM_UNIFORM_1FV:
817         case OPCODE_PROGRAM_UNIFORM_2FV:
818         case OPCODE_PROGRAM_UNIFORM_3FV:
819         case OPCODE_PROGRAM_UNIFORM_4FV:
820         case OPCODE_PROGRAM_UNIFORM_1IV:
821         case OPCODE_PROGRAM_UNIFORM_2IV:
822         case OPCODE_PROGRAM_UNIFORM_3IV:
823         case OPCODE_PROGRAM_UNIFORM_4IV:
824         case OPCODE_PROGRAM_UNIFORM_1UIV:
825         case OPCODE_PROGRAM_UNIFORM_2UIV:
826         case OPCODE_PROGRAM_UNIFORM_3UIV:
827         case OPCODE_PROGRAM_UNIFORM_4UIV:
828            free(get_pointer(&n[4]));
829            n += InstSize[n[0].opcode];
830            break;
831         case OPCODE_PROGRAM_UNIFORM_MATRIX22F:
832         case OPCODE_PROGRAM_UNIFORM_MATRIX33F:
833         case OPCODE_PROGRAM_UNIFORM_MATRIX44F:
834         case OPCODE_PROGRAM_UNIFORM_MATRIX24F:
835         case OPCODE_PROGRAM_UNIFORM_MATRIX42F:
836         case OPCODE_PROGRAM_UNIFORM_MATRIX23F:
837         case OPCODE_PROGRAM_UNIFORM_MATRIX32F:
838         case OPCODE_PROGRAM_UNIFORM_MATRIX34F:
839         case OPCODE_PROGRAM_UNIFORM_MATRIX43F:
840            free(get_pointer(&n[5]));
841            n += InstSize[n[0].opcode];
842            break;
843         case OPCODE_PIXEL_MAP:
844            free(get_pointer(&n[3]));
845            n += InstSize[n[0].opcode];
846            break;
847
848         case OPCODE_CONTINUE:
849            n = (Node *) get_pointer(&n[1]);
850            free(block);
851            block = n;
852            break;
853         case OPCODE_END_OF_LIST:
854            free(block);
855            done = GL_TRUE;
856            break;
857         default:
858            /* Most frequent case */
859            n += InstSize[n[0].opcode];
860            break;
861         }
862      }
863   }
864
865   free(dlist->Label);
866   free(dlist);
867}
868
869
870/**
871 * Destroy a display list and remove from hash table.
872 * \param list - display list number
873 */
874static void
875destroy_list(struct gl_context *ctx, GLuint list)
876{
877   struct gl_display_list *dlist;
878
879   if (list == 0)
880      return;
881
882   dlist = _mesa_lookup_list(ctx, list);
883   if (!dlist)
884      return;
885
886   _mesa_delete_list(ctx, dlist);
887   _mesa_HashRemove(ctx->Shared->DisplayList, list);
888}
889
890
891/*
892 * Translate the nth element of list from <type> to GLint.
893 */
894static GLint
895translate_id(GLsizei n, GLenum type, const GLvoid * list)
896{
897   GLbyte *bptr;
898   GLubyte *ubptr;
899   GLshort *sptr;
900   GLushort *usptr;
901   GLint *iptr;
902   GLuint *uiptr;
903   GLfloat *fptr;
904
905   switch (type) {
906   case GL_BYTE:
907      bptr = (GLbyte *) list;
908      return (GLint) bptr[n];
909   case GL_UNSIGNED_BYTE:
910      ubptr = (GLubyte *) list;
911      return (GLint) ubptr[n];
912   case GL_SHORT:
913      sptr = (GLshort *) list;
914      return (GLint) sptr[n];
915   case GL_UNSIGNED_SHORT:
916      usptr = (GLushort *) list;
917      return (GLint) usptr[n];
918   case GL_INT:
919      iptr = (GLint *) list;
920      return iptr[n];
921   case GL_UNSIGNED_INT:
922      uiptr = (GLuint *) list;
923      return (GLint) uiptr[n];
924   case GL_FLOAT:
925      fptr = (GLfloat *) list;
926      return (GLint) FLOORF(fptr[n]);
927   case GL_2_BYTES:
928      ubptr = ((GLubyte *) list) + 2 * n;
929      return (GLint) ubptr[0] * 256
930           + (GLint) ubptr[1];
931   case GL_3_BYTES:
932      ubptr = ((GLubyte *) list) + 3 * n;
933      return (GLint) ubptr[0] * 65536
934           + (GLint) ubptr[1] * 256
935           + (GLint) ubptr[2];
936   case GL_4_BYTES:
937      ubptr = ((GLubyte *) list) + 4 * n;
938      return (GLint) ubptr[0] * 16777216
939           + (GLint) ubptr[1] * 65536
940           + (GLint) ubptr[2] * 256
941           + (GLint) ubptr[3];
942   default:
943      return 0;
944   }
945}
946
947
948/**
949 * Wrapper for _mesa_unpack_image/bitmap() that handles pixel buffer objects.
950 * If width < 0 or height < 0 or format or type are invalid we'll just
951 * return NULL.  We will not generate an error since OpenGL command
952 * arguments aren't error-checked until the command is actually executed
953 * (not when they're compiled).
954 * But if we run out of memory, GL_OUT_OF_MEMORY will be recorded.
955 */
956static GLvoid *
957unpack_image(struct gl_context *ctx, GLuint dimensions,
958             GLsizei width, GLsizei height, GLsizei depth,
959             GLenum format, GLenum type, const GLvoid * pixels,
960             const struct gl_pixelstore_attrib *unpack)
961{
962   if (width <= 0 || height <= 0) {
963      return NULL;
964   }
965
966   if (_mesa_bytes_per_pixel(format, type) < 0) {
967      /* bad format and/or type */
968      return NULL;
969   }
970
971   if (!_mesa_is_bufferobj(unpack->BufferObj)) {
972      /* no PBO */
973      GLvoid *image;
974
975      if (type == GL_BITMAP)
976         image = _mesa_unpack_bitmap(width, height, pixels, unpack);
977      else
978         image = _mesa_unpack_image(dimensions, width, height, depth,
979                                    format, type, pixels, unpack);
980      if (pixels && !image) {
981         _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
982      }
983      return image;
984   }
985   else if (_mesa_validate_pbo_access(dimensions, unpack, width, height,
986                                      depth, format, type, INT_MAX, pixels)) {
987      const GLubyte *map, *src;
988      GLvoid *image;
989
990      map = (GLubyte *)
991         ctx->Driver.MapBufferRange(ctx, 0, unpack->BufferObj->Size,
992				    GL_MAP_READ_BIT, unpack->BufferObj,
993                                    MAP_INTERNAL);
994      if (!map) {
995         /* unable to map src buffer! */
996         _mesa_error(ctx, GL_INVALID_OPERATION, "unable to map PBO");
997         return NULL;
998      }
999
1000      src = ADD_POINTERS(map, pixels);
1001      if (type == GL_BITMAP)
1002         image = _mesa_unpack_bitmap(width, height, src, unpack);
1003      else
1004         image = _mesa_unpack_image(dimensions, width, height, depth,
1005                                    format, type, src, unpack);
1006
1007      ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj, MAP_INTERNAL);
1008
1009      if (!image) {
1010         _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
1011      }
1012      return image;
1013   }
1014
1015   /* bad access! */
1016   _mesa_error(ctx, GL_INVALID_OPERATION, "invalid PBO access");
1017   return NULL;
1018}
1019
1020
1021/** Return copy of memory */
1022static void *
1023memdup(const void *src, GLsizei bytes)
1024{
1025   void *b = bytes >= 0 ? malloc(bytes) : NULL;
1026   if (b)
1027      memcpy(b, src, bytes);
1028   return b;
1029}
1030
1031
1032/**
1033 * Allocate space for a display list instruction (opcode + payload space).
1034 * \param opcode  the instruction opcode (OPCODE_* value)
1035 * \param bytes   instruction payload size (not counting opcode)
1036 * \return pointer to allocated memory (the opcode space)
1037 */
1038static Node *
1039dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes)
1040{
1041   const GLuint numNodes = 1 + (bytes + sizeof(Node) - 1) / sizeof(Node);
1042   const GLuint contNodes = 1 + POINTER_DWORDS;  /* size of continue info */
1043   Node *n;
1044
1045   if (opcode < (GLuint) OPCODE_EXT_0) {
1046      if (InstSize[opcode] == 0) {
1047         /* save instruction size now */
1048         InstSize[opcode] = numNodes;
1049      }
1050      else {
1051         /* make sure instruction size agrees */
1052         ASSERT(numNodes == InstSize[opcode]);
1053      }
1054   }
1055
1056   if (ctx->ListState.CurrentPos + numNodes + contNodes > BLOCK_SIZE) {
1057      /* This block is full.  Allocate a new block and chain to it */
1058      Node *newblock;
1059      n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos;
1060      n[0].opcode = OPCODE_CONTINUE;
1061      newblock = malloc(sizeof(Node) * BLOCK_SIZE);
1062      if (!newblock) {
1063         _mesa_error(ctx, GL_OUT_OF_MEMORY, "Building display list");
1064         return NULL;
1065      }
1066      save_pointer(&n[1], newblock);
1067      ctx->ListState.CurrentBlock = newblock;
1068      ctx->ListState.CurrentPos = 0;
1069   }
1070
1071   n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos;
1072   ctx->ListState.CurrentPos += numNodes;
1073
1074   n[0].opcode = opcode;
1075
1076   return n;
1077}
1078
1079
1080
1081/**
1082 * Allocate space for a display list instruction.  Used by callers outside
1083 * this file for things like VBO vertex data.
1084 *
1085 * \param opcode  the instruction opcode (OPCODE_* value)
1086 * \param bytes   instruction size in bytes, not counting opcode.
1087 * \return pointer to the usable data area (not including the internal
1088 *         opcode).
1089 */
1090void *
1091_mesa_dlist_alloc(struct gl_context *ctx, GLuint opcode, GLuint bytes)
1092{
1093   Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes);
1094   if (n)
1095      return n + 1;  /* return pointer to payload area, after opcode */
1096   else
1097      return NULL;
1098}
1099
1100
1101/**
1102 * This function allows modules and drivers to get their own opcodes
1103 * for extending display list functionality.
1104 * \param ctx  the rendering context
1105 * \param size  number of bytes for storing the new display list command
1106 * \param execute  function to execute the new display list command
1107 * \param destroy  function to destroy the new display list command
1108 * \param print  function to print the new display list command
1109 * \return  the new opcode number or -1 if error
1110 */
1111GLint
1112_mesa_dlist_alloc_opcode(struct gl_context *ctx,
1113                         GLuint size,
1114                         void (*execute) (struct gl_context *, void *),
1115                         void (*destroy) (struct gl_context *, void *),
1116                         void (*print) (struct gl_context *, void *))
1117{
1118   if (ctx->ListExt->NumOpcodes < MAX_DLIST_EXT_OPCODES) {
1119      const GLuint i = ctx->ListExt->NumOpcodes++;
1120      ctx->ListExt->Opcode[i].Size =
1121         1 + (size + sizeof(Node) - 1) / sizeof(Node);
1122      ctx->ListExt->Opcode[i].Execute = execute;
1123      ctx->ListExt->Opcode[i].Destroy = destroy;
1124      ctx->ListExt->Opcode[i].Print = print;
1125      return i + OPCODE_EXT_0;
1126   }
1127   return -1;
1128}
1129
1130
1131/**
1132 * Allocate space for a display list instruction.  The space is basically
1133 * an array of Nodes where node[0] holds the opcode, node[1] is the first
1134 * function parameter, node[2] is the second parameter, etc.
1135 *
1136 * \param opcode  one of OPCODE_x
1137 * \param nparams  number of function parameters
1138 * \return  pointer to start of instruction space
1139 */
1140static inline Node *
1141alloc_instruction(struct gl_context *ctx, OpCode opcode, GLuint nparams)
1142{
1143   return dlist_alloc(ctx, opcode, nparams * sizeof(Node));
1144}
1145
1146
1147/**
1148 * Called by EndList to try to reduce memory used for the list.
1149 */
1150static void
1151trim_list(struct gl_context *ctx)
1152{
1153   /* If the list we're ending only has one allocated block of nodes/tokens
1154    * and its size isn't a full block size, realloc the block to use less
1155    * memory.  This is important for apps that create many small display
1156    * lists and apps that use glXUseXFont (many lists each containing one
1157    * glBitmap call).
1158    * Note: we currently only trim display lists that allocated one block
1159    * of tokens.  That hits the short list case which is what we're mainly
1160    * concerned with.  Trimming longer lists would involve traversing the
1161    * linked list of blocks.
1162    */
1163   struct gl_dlist_state *list = &ctx->ListState;
1164
1165   if ((list->CurrentList->Head == list->CurrentBlock) &&
1166       (list->CurrentPos < BLOCK_SIZE)) {
1167      /* There's only one block and it's not full, so realloc */
1168      GLuint newSize = list->CurrentPos * sizeof(Node);
1169      list->CurrentList->Head =
1170      list->CurrentBlock = realloc(list->CurrentBlock, newSize);
1171      if (!list->CurrentBlock) {
1172         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEndList");
1173      }
1174   }
1175}
1176
1177
1178
1179/*
1180 * Display List compilation functions
1181 */
1182static void GLAPIENTRY
1183save_Accum(GLenum op, GLfloat value)
1184{
1185   GET_CURRENT_CONTEXT(ctx);
1186   Node *n;
1187   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1188   n = alloc_instruction(ctx, OPCODE_ACCUM, 2);
1189   if (n) {
1190      n[1].e = op;
1191      n[2].f = value;
1192   }
1193   if (ctx->ExecuteFlag) {
1194      CALL_Accum(ctx->Exec, (op, value));
1195   }
1196}
1197
1198
1199static void GLAPIENTRY
1200save_AlphaFunc(GLenum func, GLclampf ref)
1201{
1202   GET_CURRENT_CONTEXT(ctx);
1203   Node *n;
1204   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1205   n = alloc_instruction(ctx, OPCODE_ALPHA_FUNC, 2);
1206   if (n) {
1207      n[1].e = func;
1208      n[2].f = (GLfloat) ref;
1209   }
1210   if (ctx->ExecuteFlag) {
1211      CALL_AlphaFunc(ctx->Exec, (func, ref));
1212   }
1213}
1214
1215
1216static void GLAPIENTRY
1217save_BindTexture(GLenum target, GLuint texture)
1218{
1219   GET_CURRENT_CONTEXT(ctx);
1220   Node *n;
1221   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1222   n = alloc_instruction(ctx, OPCODE_BIND_TEXTURE, 2);
1223   if (n) {
1224      n[1].e = target;
1225      n[2].ui = texture;
1226   }
1227   if (ctx->ExecuteFlag) {
1228      CALL_BindTexture(ctx->Exec, (target, texture));
1229   }
1230}
1231
1232
1233static void GLAPIENTRY
1234save_Bitmap(GLsizei width, GLsizei height,
1235            GLfloat xorig, GLfloat yorig,
1236            GLfloat xmove, GLfloat ymove, const GLubyte * pixels)
1237{
1238   GET_CURRENT_CONTEXT(ctx);
1239   Node *n;
1240   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1241   n = alloc_instruction(ctx, OPCODE_BITMAP, 6 + POINTER_DWORDS);
1242   if (n) {
1243      n[1].i = (GLint) width;
1244      n[2].i = (GLint) height;
1245      n[3].f = xorig;
1246      n[4].f = yorig;
1247      n[5].f = xmove;
1248      n[6].f = ymove;
1249      save_pointer(&n[7],
1250                   unpack_image(ctx, 2, width, height, 1, GL_COLOR_INDEX,
1251                                GL_BITMAP, pixels, &ctx->Unpack));
1252   }
1253   if (ctx->ExecuteFlag) {
1254      CALL_Bitmap(ctx->Exec, (width, height,
1255                              xorig, yorig, xmove, ymove, pixels));
1256   }
1257}
1258
1259
1260static void GLAPIENTRY
1261save_BlendEquation(GLenum mode)
1262{
1263   GET_CURRENT_CONTEXT(ctx);
1264   Node *n;
1265   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1266   n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION, 1);
1267   if (n) {
1268      n[1].e = mode;
1269   }
1270   if (ctx->ExecuteFlag) {
1271      CALL_BlendEquation(ctx->Exec, (mode));
1272   }
1273}
1274
1275
1276static void GLAPIENTRY
1277save_BlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA)
1278{
1279   GET_CURRENT_CONTEXT(ctx);
1280   Node *n;
1281   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1282   n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION_SEPARATE, 2);
1283   if (n) {
1284      n[1].e = modeRGB;
1285      n[2].e = modeA;
1286   }
1287   if (ctx->ExecuteFlag) {
1288      CALL_BlendEquationSeparate(ctx->Exec, (modeRGB, modeA));
1289   }
1290}
1291
1292
1293static void GLAPIENTRY
1294save_BlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB,
1295                          GLenum sfactorA, GLenum dfactorA)
1296{
1297   GET_CURRENT_CONTEXT(ctx);
1298   Node *n;
1299   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1300   n = alloc_instruction(ctx, OPCODE_BLEND_FUNC_SEPARATE, 4);
1301   if (n) {
1302      n[1].e = sfactorRGB;
1303      n[2].e = dfactorRGB;
1304      n[3].e = sfactorA;
1305      n[4].e = dfactorA;
1306   }
1307   if (ctx->ExecuteFlag) {
1308      CALL_BlendFuncSeparate(ctx->Exec,
1309                                (sfactorRGB, dfactorRGB, sfactorA, dfactorA));
1310   }
1311}
1312
1313
1314static void GLAPIENTRY
1315save_BlendFunc(GLenum srcfactor, GLenum dstfactor)
1316{
1317   save_BlendFuncSeparateEXT(srcfactor, dstfactor, srcfactor, dstfactor);
1318}
1319
1320
1321static void GLAPIENTRY
1322save_BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
1323{
1324   GET_CURRENT_CONTEXT(ctx);
1325   Node *n;
1326   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1327   n = alloc_instruction(ctx, OPCODE_BLEND_COLOR, 4);
1328   if (n) {
1329      n[1].f = red;
1330      n[2].f = green;
1331      n[3].f = blue;
1332      n[4].f = alpha;
1333   }
1334   if (ctx->ExecuteFlag) {
1335      CALL_BlendColor(ctx->Exec, (red, green, blue, alpha));
1336   }
1337}
1338
1339/* GL_ARB_draw_buffers_blend */
1340static void GLAPIENTRY
1341save_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB,
1342                        GLenum sfactorA, GLenum dfactorA)
1343{
1344   GET_CURRENT_CONTEXT(ctx);
1345   Node *n;
1346   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1347   n = alloc_instruction(ctx, OPCODE_BLEND_FUNC_SEPARATE_I, 5);
1348   if (n) {
1349      n[1].ui = buf;
1350      n[2].e = sfactorRGB;
1351      n[3].e = dfactorRGB;
1352      n[4].e = sfactorA;
1353      n[5].e = dfactorA;
1354   }
1355   if (ctx->ExecuteFlag) {
1356      CALL_BlendFuncSeparateiARB(ctx->Exec, (buf, sfactorRGB, dfactorRGB,
1357                                             sfactorA, dfactorA));
1358   }
1359}
1360
1361/* GL_ARB_draw_buffers_blend */
1362static void GLAPIENTRY
1363save_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor)
1364{
1365   GET_CURRENT_CONTEXT(ctx);
1366   Node *n;
1367   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1368   n = alloc_instruction(ctx, OPCODE_BLEND_FUNC_SEPARATE_I, 3);
1369   if (n) {
1370      n[1].ui = buf;
1371      n[2].e = sfactor;
1372      n[3].e = dfactor;
1373   }
1374   if (ctx->ExecuteFlag) {
1375      CALL_BlendFunciARB(ctx->Exec, (buf, sfactor, dfactor));
1376   }
1377}
1378
1379/* GL_ARB_draw_buffers_blend */
1380static void GLAPIENTRY
1381save_BlendEquationi(GLuint buf, GLenum mode)
1382{
1383   GET_CURRENT_CONTEXT(ctx);
1384   Node *n;
1385   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1386   n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION_I, 2);
1387   if (n) {
1388      n[1].ui = buf;
1389      n[2].e = mode;
1390   }
1391   if (ctx->ExecuteFlag) {
1392      CALL_BlendEquationiARB(ctx->Exec, (buf, mode));
1393   }
1394}
1395
1396/* GL_ARB_draw_buffers_blend */
1397static void GLAPIENTRY
1398save_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA)
1399{
1400   GET_CURRENT_CONTEXT(ctx);
1401   Node *n;
1402   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1403   n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION_SEPARATE_I, 3);
1404   if (n) {
1405      n[1].ui = buf;
1406      n[2].e = modeRGB;
1407      n[3].e = modeA;
1408   }
1409   if (ctx->ExecuteFlag) {
1410      CALL_BlendEquationSeparateiARB(ctx->Exec, (buf, modeRGB, modeA));
1411   }
1412}
1413
1414
1415/* GL_ARB_draw_instanced. */
1416static void GLAPIENTRY
1417save_DrawArraysInstancedARB(GLenum mode,
1418			    GLint first,
1419			    GLsizei count,
1420			    GLsizei primcount)
1421{
1422   GET_CURRENT_CONTEXT(ctx);
1423   _mesa_error(ctx, GL_INVALID_OPERATION,
1424	       "glDrawArraysInstanced() during display list compile");
1425}
1426
1427static void GLAPIENTRY
1428save_DrawElementsInstancedARB(GLenum mode,
1429			      GLsizei count,
1430			      GLenum type,
1431			      const GLvoid *indices,
1432			      GLsizei primcount)
1433{
1434   GET_CURRENT_CONTEXT(ctx);
1435   _mesa_error(ctx, GL_INVALID_OPERATION,
1436	       "glDrawElementsInstanced() during display list compile");
1437}
1438
1439static void GLAPIENTRY
1440save_DrawElementsInstancedBaseVertexARB(GLenum mode,
1441					GLsizei count,
1442					GLenum type,
1443					const GLvoid *indices,
1444					GLsizei primcount,
1445					GLint basevertex)
1446{
1447   GET_CURRENT_CONTEXT(ctx);
1448   _mesa_error(ctx, GL_INVALID_OPERATION,
1449	       "glDrawElementsInstancedBaseVertex() during display list compile");
1450}
1451
1452/* GL_ARB_base_instance. */
1453static void GLAPIENTRY
1454save_DrawArraysInstancedBaseInstance(GLenum mode,
1455                                     GLint first,
1456                                     GLsizei count,
1457                                     GLsizei primcount,
1458                                     GLuint baseinstance)
1459{
1460   GET_CURRENT_CONTEXT(ctx);
1461   _mesa_error(ctx, GL_INVALID_OPERATION,
1462	       "glDrawArraysInstancedBaseInstance() during display list compile");
1463}
1464
1465static void APIENTRY
1466save_DrawElementsInstancedBaseInstance(GLenum mode,
1467                                       GLsizei count,
1468                                       GLenum type,
1469                                       const void *indices,
1470                                       GLsizei primcount,
1471                                       GLuint baseinstance)
1472{
1473   GET_CURRENT_CONTEXT(ctx);
1474   _mesa_error(ctx, GL_INVALID_OPERATION,
1475	       "glDrawElementsInstancedBaseInstance() during display list compile");
1476}
1477
1478static void APIENTRY
1479save_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode,
1480                                                 GLsizei count,
1481                                                 GLenum type,
1482                                                 const void *indices,
1483                                                 GLsizei primcount,
1484                                                 GLint basevertex,
1485                                                 GLuint baseinstance)
1486{
1487   GET_CURRENT_CONTEXT(ctx);
1488   _mesa_error(ctx, GL_INVALID_OPERATION,
1489	       "glDrawElementsInstancedBaseVertexBaseInstance() during display list compile");
1490}
1491
1492
1493/**
1494 * While building a display list we cache some OpenGL state.
1495 * Under some circumstances we need to invalidate that state (immediately
1496 * when we start compiling a list, or after glCallList(s)).
1497 */
1498static void
1499invalidate_saved_current_state(struct gl_context *ctx)
1500{
1501   GLint i;
1502
1503   for (i = 0; i < VERT_ATTRIB_MAX; i++)
1504      ctx->ListState.ActiveAttribSize[i] = 0;
1505
1506   for (i = 0; i < MAT_ATTRIB_MAX; i++)
1507      ctx->ListState.ActiveMaterialSize[i] = 0;
1508
1509   memset(&ctx->ListState.Current, 0, sizeof ctx->ListState.Current);
1510
1511   ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
1512}
1513
1514
1515static void GLAPIENTRY
1516save_CallList(GLuint list)
1517{
1518   GET_CURRENT_CONTEXT(ctx);
1519   Node *n;
1520   SAVE_FLUSH_VERTICES(ctx);
1521
1522   n = alloc_instruction(ctx, OPCODE_CALL_LIST, 1);
1523   if (n) {
1524      n[1].ui = list;
1525   }
1526
1527   /* After this, we don't know what state we're in.  Invalidate all
1528    * cached information previously gathered:
1529    */
1530   invalidate_saved_current_state( ctx );
1531
1532   if (ctx->ExecuteFlag) {
1533      _mesa_CallList(list);
1534   }
1535}
1536
1537
1538static void GLAPIENTRY
1539save_CallLists(GLsizei num, GLenum type, const GLvoid * lists)
1540{
1541   GET_CURRENT_CONTEXT(ctx);
1542   GLint i;
1543   GLboolean typeErrorFlag;
1544
1545   SAVE_FLUSH_VERTICES(ctx);
1546
1547   switch (type) {
1548   case GL_BYTE:
1549   case GL_UNSIGNED_BYTE:
1550   case GL_SHORT:
1551   case GL_UNSIGNED_SHORT:
1552   case GL_INT:
1553   case GL_UNSIGNED_INT:
1554   case GL_FLOAT:
1555   case GL_2_BYTES:
1556   case GL_3_BYTES:
1557   case GL_4_BYTES:
1558      typeErrorFlag = GL_FALSE;
1559      break;
1560   default:
1561      typeErrorFlag = GL_TRUE;
1562   }
1563
1564   for (i = 0; i < num; i++) {
1565      GLint list = translate_id(i, type, lists);
1566      Node *n = alloc_instruction(ctx, OPCODE_CALL_LIST_OFFSET, 2);
1567      if (n) {
1568         n[1].i = list;
1569         n[2].b = typeErrorFlag;
1570      }
1571   }
1572
1573   /* After this, we don't know what state we're in.  Invalidate all
1574    * cached information previously gathered:
1575    */
1576   invalidate_saved_current_state( ctx );
1577
1578   if (ctx->ExecuteFlag) {
1579      CALL_CallLists(ctx->Exec, (num, type, lists));
1580   }
1581}
1582
1583
1584static void GLAPIENTRY
1585save_Clear(GLbitfield mask)
1586{
1587   GET_CURRENT_CONTEXT(ctx);
1588   Node *n;
1589   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1590   n = alloc_instruction(ctx, OPCODE_CLEAR, 1);
1591   if (n) {
1592      n[1].bf = mask;
1593   }
1594   if (ctx->ExecuteFlag) {
1595      CALL_Clear(ctx->Exec, (mask));
1596   }
1597}
1598
1599
1600static void GLAPIENTRY
1601save_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
1602{
1603   GET_CURRENT_CONTEXT(ctx);
1604   Node *n;
1605   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1606   n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_IV, 6);
1607   if (n) {
1608      n[1].e = buffer;
1609      n[2].i = drawbuffer;
1610      n[3].i = value[0];
1611      if (buffer == GL_COLOR) {
1612         n[4].i = value[1];
1613         n[5].i = value[2];
1614         n[6].i = value[3];
1615      }
1616      else {
1617         n[4].i = 0;
1618         n[5].i = 0;
1619         n[6].i = 0;
1620      }
1621   }
1622   if (ctx->ExecuteFlag) {
1623      CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value));
1624   }
1625}
1626
1627
1628static void GLAPIENTRY
1629save_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
1630{
1631   GET_CURRENT_CONTEXT(ctx);
1632   Node *n;
1633   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1634   n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_UIV, 6);
1635   if (n) {
1636      n[1].e = buffer;
1637      n[2].i = drawbuffer;
1638      n[3].ui = value[0];
1639      if (buffer == GL_COLOR) {
1640         n[4].ui = value[1];
1641         n[5].ui = value[2];
1642         n[6].ui = value[3];
1643      }
1644      else {
1645         n[4].ui = 0;
1646         n[5].ui = 0;
1647         n[6].ui = 0;
1648      }
1649   }
1650   if (ctx->ExecuteFlag) {
1651      CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));
1652   }
1653}
1654
1655
1656static void GLAPIENTRY
1657save_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
1658{
1659   GET_CURRENT_CONTEXT(ctx);
1660   Node *n;
1661   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1662   n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_FV, 6);
1663   if (n) {
1664      n[1].e = buffer;
1665      n[2].i = drawbuffer;
1666      n[3].f = value[0];
1667      if (buffer == GL_COLOR) {
1668         n[4].f = value[1];
1669         n[5].f = value[2];
1670         n[6].f = value[3];
1671      }
1672      else {
1673         n[4].f = 0.0F;
1674         n[5].f = 0.0F;
1675         n[6].f = 0.0F;
1676      }
1677   }
1678   if (ctx->ExecuteFlag) {
1679      CALL_ClearBufferfv(ctx->Exec, (buffer, drawbuffer, value));
1680   }
1681}
1682
1683
1684static void GLAPIENTRY
1685save_ClearBufferfi(GLenum buffer, GLint drawbuffer,
1686                   GLfloat depth, GLint stencil)
1687{
1688   GET_CURRENT_CONTEXT(ctx);
1689   Node *n;
1690   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1691   n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_FI, 4);
1692   if (n) {
1693      n[1].e = buffer;
1694      n[2].i = drawbuffer;
1695      n[3].f = depth;
1696      n[4].i = stencil;
1697   }
1698   if (ctx->ExecuteFlag) {
1699      CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil));
1700   }
1701}
1702
1703
1704static void GLAPIENTRY
1705save_ClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
1706{
1707   GET_CURRENT_CONTEXT(ctx);
1708   Node *n;
1709   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1710   n = alloc_instruction(ctx, OPCODE_CLEAR_ACCUM, 4);
1711   if (n) {
1712      n[1].f = red;
1713      n[2].f = green;
1714      n[3].f = blue;
1715      n[4].f = alpha;
1716   }
1717   if (ctx->ExecuteFlag) {
1718      CALL_ClearAccum(ctx->Exec, (red, green, blue, alpha));
1719   }
1720}
1721
1722
1723static void GLAPIENTRY
1724save_ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
1725{
1726   GET_CURRENT_CONTEXT(ctx);
1727   Node *n;
1728   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1729   n = alloc_instruction(ctx, OPCODE_CLEAR_COLOR, 4);
1730   if (n) {
1731      n[1].f = red;
1732      n[2].f = green;
1733      n[3].f = blue;
1734      n[4].f = alpha;
1735   }
1736   if (ctx->ExecuteFlag) {
1737      CALL_ClearColor(ctx->Exec, (red, green, blue, alpha));
1738   }
1739}
1740
1741
1742static void GLAPIENTRY
1743save_ClearDepth(GLclampd depth)
1744{
1745   GET_CURRENT_CONTEXT(ctx);
1746   Node *n;
1747   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1748   n = alloc_instruction(ctx, OPCODE_CLEAR_DEPTH, 1);
1749   if (n) {
1750      n[1].f = (GLfloat) depth;
1751   }
1752   if (ctx->ExecuteFlag) {
1753      CALL_ClearDepth(ctx->Exec, (depth));
1754   }
1755}
1756
1757
1758static void GLAPIENTRY
1759save_ClearIndex(GLfloat c)
1760{
1761   GET_CURRENT_CONTEXT(ctx);
1762   Node *n;
1763   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1764   n = alloc_instruction(ctx, OPCODE_CLEAR_INDEX, 1);
1765   if (n) {
1766      n[1].f = c;
1767   }
1768   if (ctx->ExecuteFlag) {
1769      CALL_ClearIndex(ctx->Exec, (c));
1770   }
1771}
1772
1773
1774static void GLAPIENTRY
1775save_ClearStencil(GLint s)
1776{
1777   GET_CURRENT_CONTEXT(ctx);
1778   Node *n;
1779   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1780   n = alloc_instruction(ctx, OPCODE_CLEAR_STENCIL, 1);
1781   if (n) {
1782      n[1].i = s;
1783   }
1784   if (ctx->ExecuteFlag) {
1785      CALL_ClearStencil(ctx->Exec, (s));
1786   }
1787}
1788
1789
1790static void GLAPIENTRY
1791save_ClipPlane(GLenum plane, const GLdouble * equ)
1792{
1793   GET_CURRENT_CONTEXT(ctx);
1794   Node *n;
1795   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1796   n = alloc_instruction(ctx, OPCODE_CLIP_PLANE, 5);
1797   if (n) {
1798      n[1].e = plane;
1799      n[2].f = (GLfloat) equ[0];
1800      n[3].f = (GLfloat) equ[1];
1801      n[4].f = (GLfloat) equ[2];
1802      n[5].f = (GLfloat) equ[3];
1803   }
1804   if (ctx->ExecuteFlag) {
1805      CALL_ClipPlane(ctx->Exec, (plane, equ));
1806   }
1807}
1808
1809
1810
1811static void GLAPIENTRY
1812save_ColorMask(GLboolean red, GLboolean green,
1813               GLboolean blue, GLboolean alpha)
1814{
1815   GET_CURRENT_CONTEXT(ctx);
1816   Node *n;
1817   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1818   n = alloc_instruction(ctx, OPCODE_COLOR_MASK, 4);
1819   if (n) {
1820      n[1].b = red;
1821      n[2].b = green;
1822      n[3].b = blue;
1823      n[4].b = alpha;
1824   }
1825   if (ctx->ExecuteFlag) {
1826      CALL_ColorMask(ctx->Exec, (red, green, blue, alpha));
1827   }
1828}
1829
1830
1831static void GLAPIENTRY
1832save_ColorMaskIndexed(GLuint buf, GLboolean red, GLboolean green,
1833                      GLboolean blue, GLboolean alpha)
1834{
1835   GET_CURRENT_CONTEXT(ctx);
1836   Node *n;
1837   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1838   n = alloc_instruction(ctx, OPCODE_COLOR_MASK_INDEXED, 5);
1839   if (n) {
1840      n[1].ui = buf;
1841      n[2].b = red;
1842      n[3].b = green;
1843      n[4].b = blue;
1844      n[5].b = alpha;
1845   }
1846   if (ctx->ExecuteFlag) {
1847      /*CALL_ColorMaski(ctx->Exec, (buf, red, green, blue, alpha));*/
1848   }
1849}
1850
1851
1852static void GLAPIENTRY
1853save_ColorMaterial(GLenum face, GLenum mode)
1854{
1855   GET_CURRENT_CONTEXT(ctx);
1856   Node *n;
1857   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1858
1859   n = alloc_instruction(ctx, OPCODE_COLOR_MATERIAL, 2);
1860   if (n) {
1861      n[1].e = face;
1862      n[2].e = mode;
1863   }
1864   if (ctx->ExecuteFlag) {
1865      CALL_ColorMaterial(ctx->Exec, (face, mode));
1866   }
1867}
1868
1869
1870static void GLAPIENTRY
1871save_CopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
1872{
1873   GET_CURRENT_CONTEXT(ctx);
1874   Node *n;
1875   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1876   n = alloc_instruction(ctx, OPCODE_COPY_PIXELS, 5);
1877   if (n) {
1878      n[1].i = x;
1879      n[2].i = y;
1880      n[3].i = (GLint) width;
1881      n[4].i = (GLint) height;
1882      n[5].e = type;
1883   }
1884   if (ctx->ExecuteFlag) {
1885      CALL_CopyPixels(ctx->Exec, (x, y, width, height, type));
1886   }
1887}
1888
1889
1890
1891static void GLAPIENTRY
1892save_CopyTexImage1D(GLenum target, GLint level, GLenum internalformat,
1893                    GLint x, GLint y, GLsizei width, GLint border)
1894{
1895   GET_CURRENT_CONTEXT(ctx);
1896   Node *n;
1897   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1898   n = alloc_instruction(ctx, OPCODE_COPY_TEX_IMAGE1D, 7);
1899   if (n) {
1900      n[1].e = target;
1901      n[2].i = level;
1902      n[3].e = internalformat;
1903      n[4].i = x;
1904      n[5].i = y;
1905      n[6].i = width;
1906      n[7].i = border;
1907   }
1908   if (ctx->ExecuteFlag) {
1909      CALL_CopyTexImage1D(ctx->Exec, (target, level, internalformat,
1910                                      x, y, width, border));
1911   }
1912}
1913
1914
1915static void GLAPIENTRY
1916save_CopyTexImage2D(GLenum target, GLint level,
1917                    GLenum internalformat,
1918                    GLint x, GLint y, GLsizei width,
1919                    GLsizei height, GLint border)
1920{
1921   GET_CURRENT_CONTEXT(ctx);
1922   Node *n;
1923   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1924   n = alloc_instruction(ctx, OPCODE_COPY_TEX_IMAGE2D, 8);
1925   if (n) {
1926      n[1].e = target;
1927      n[2].i = level;
1928      n[3].e = internalformat;
1929      n[4].i = x;
1930      n[5].i = y;
1931      n[6].i = width;
1932      n[7].i = height;
1933      n[8].i = border;
1934   }
1935   if (ctx->ExecuteFlag) {
1936      CALL_CopyTexImage2D(ctx->Exec, (target, level, internalformat,
1937                                      x, y, width, height, border));
1938   }
1939}
1940
1941
1942
1943static void GLAPIENTRY
1944save_CopyTexSubImage1D(GLenum target, GLint level,
1945                       GLint xoffset, GLint x, GLint y, GLsizei width)
1946{
1947   GET_CURRENT_CONTEXT(ctx);
1948   Node *n;
1949   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1950   n = alloc_instruction(ctx, OPCODE_COPY_TEX_SUB_IMAGE1D, 6);
1951   if (n) {
1952      n[1].e = target;
1953      n[2].i = level;
1954      n[3].i = xoffset;
1955      n[4].i = x;
1956      n[5].i = y;
1957      n[6].i = width;
1958   }
1959   if (ctx->ExecuteFlag) {
1960      CALL_CopyTexSubImage1D(ctx->Exec,
1961                             (target, level, xoffset, x, y, width));
1962   }
1963}
1964
1965
1966static void GLAPIENTRY
1967save_CopyTexSubImage2D(GLenum target, GLint level,
1968                       GLint xoffset, GLint yoffset,
1969                       GLint x, GLint y, GLsizei width, GLint height)
1970{
1971   GET_CURRENT_CONTEXT(ctx);
1972   Node *n;
1973   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1974   n = alloc_instruction(ctx, OPCODE_COPY_TEX_SUB_IMAGE2D, 8);
1975   if (n) {
1976      n[1].e = target;
1977      n[2].i = level;
1978      n[3].i = xoffset;
1979      n[4].i = yoffset;
1980      n[5].i = x;
1981      n[6].i = y;
1982      n[7].i = width;
1983      n[8].i = height;
1984   }
1985   if (ctx->ExecuteFlag) {
1986      CALL_CopyTexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset,
1987                                         x, y, width, height));
1988   }
1989}
1990
1991
1992static void GLAPIENTRY
1993save_CopyTexSubImage3D(GLenum target, GLint level,
1994                       GLint xoffset, GLint yoffset, GLint zoffset,
1995                       GLint x, GLint y, GLsizei width, GLint height)
1996{
1997   GET_CURRENT_CONTEXT(ctx);
1998   Node *n;
1999   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2000   n = alloc_instruction(ctx, OPCODE_COPY_TEX_SUB_IMAGE3D, 9);
2001   if (n) {
2002      n[1].e = target;
2003      n[2].i = level;
2004      n[3].i = xoffset;
2005      n[4].i = yoffset;
2006      n[5].i = zoffset;
2007      n[6].i = x;
2008      n[7].i = y;
2009      n[8].i = width;
2010      n[9].i = height;
2011   }
2012   if (ctx->ExecuteFlag) {
2013      CALL_CopyTexSubImage3D(ctx->Exec, (target, level,
2014                                         xoffset, yoffset, zoffset,
2015                                         x, y, width, height));
2016   }
2017}
2018
2019
2020static void GLAPIENTRY
2021save_CullFace(GLenum mode)
2022{
2023   GET_CURRENT_CONTEXT(ctx);
2024   Node *n;
2025   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2026   n = alloc_instruction(ctx, OPCODE_CULL_FACE, 1);
2027   if (n) {
2028      n[1].e = mode;
2029   }
2030   if (ctx->ExecuteFlag) {
2031      CALL_CullFace(ctx->Exec, (mode));
2032   }
2033}
2034
2035
2036static void GLAPIENTRY
2037save_DepthFunc(GLenum func)
2038{
2039   GET_CURRENT_CONTEXT(ctx);
2040   Node *n;
2041   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2042   n = alloc_instruction(ctx, OPCODE_DEPTH_FUNC, 1);
2043   if (n) {
2044      n[1].e = func;
2045   }
2046   if (ctx->ExecuteFlag) {
2047      CALL_DepthFunc(ctx->Exec, (func));
2048   }
2049}
2050
2051
2052static void GLAPIENTRY
2053save_DepthMask(GLboolean mask)
2054{
2055   GET_CURRENT_CONTEXT(ctx);
2056   Node *n;
2057   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2058   n = alloc_instruction(ctx, OPCODE_DEPTH_MASK, 1);
2059   if (n) {
2060      n[1].b = mask;
2061   }
2062   if (ctx->ExecuteFlag) {
2063      CALL_DepthMask(ctx->Exec, (mask));
2064   }
2065}
2066
2067
2068static void GLAPIENTRY
2069save_DepthRange(GLclampd nearval, GLclampd farval)
2070{
2071   GET_CURRENT_CONTEXT(ctx);
2072   Node *n;
2073   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2074   n = alloc_instruction(ctx, OPCODE_DEPTH_RANGE, 2);
2075   if (n) {
2076      n[1].f = (GLfloat) nearval;
2077      n[2].f = (GLfloat) farval;
2078   }
2079   if (ctx->ExecuteFlag) {
2080      CALL_DepthRange(ctx->Exec, (nearval, farval));
2081   }
2082}
2083
2084
2085static void GLAPIENTRY
2086save_Disable(GLenum cap)
2087{
2088   GET_CURRENT_CONTEXT(ctx);
2089   Node *n;
2090   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2091   n = alloc_instruction(ctx, OPCODE_DISABLE, 1);
2092   if (n) {
2093      n[1].e = cap;
2094   }
2095   if (ctx->ExecuteFlag) {
2096      CALL_Disable(ctx->Exec, (cap));
2097   }
2098}
2099
2100
2101static void GLAPIENTRY
2102save_DisableIndexed(GLuint index, GLenum cap)
2103{
2104   GET_CURRENT_CONTEXT(ctx);
2105   Node *n;
2106   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2107   n = alloc_instruction(ctx, OPCODE_DISABLE_INDEXED, 2);
2108   if (n) {
2109      n[1].ui = index;
2110      n[2].e = cap;
2111   }
2112   if (ctx->ExecuteFlag) {
2113      CALL_Disablei(ctx->Exec, (index, cap));
2114   }
2115}
2116
2117
2118static void GLAPIENTRY
2119save_DrawBuffer(GLenum mode)
2120{
2121   GET_CURRENT_CONTEXT(ctx);
2122   Node *n;
2123   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2124   n = alloc_instruction(ctx, OPCODE_DRAW_BUFFER, 1);
2125   if (n) {
2126      n[1].e = mode;
2127   }
2128   if (ctx->ExecuteFlag) {
2129      CALL_DrawBuffer(ctx->Exec, (mode));
2130   }
2131}
2132
2133
2134static void GLAPIENTRY
2135save_DrawPixels(GLsizei width, GLsizei height,
2136                GLenum format, GLenum type, const GLvoid * pixels)
2137{
2138   GET_CURRENT_CONTEXT(ctx);
2139   Node *n;
2140
2141   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2142
2143   n = alloc_instruction(ctx, OPCODE_DRAW_PIXELS, 4 + POINTER_DWORDS);
2144   if (n) {
2145      n[1].i = width;
2146      n[2].i = height;
2147      n[3].e = format;
2148      n[4].e = type;
2149      save_pointer(&n[5],
2150                   unpack_image(ctx, 2, width, height, 1, format, type,
2151                                pixels, &ctx->Unpack));
2152   }
2153   if (ctx->ExecuteFlag) {
2154      CALL_DrawPixels(ctx->Exec, (width, height, format, type, pixels));
2155   }
2156}
2157
2158
2159
2160static void GLAPIENTRY
2161save_Enable(GLenum cap)
2162{
2163   GET_CURRENT_CONTEXT(ctx);
2164   Node *n;
2165   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2166   n = alloc_instruction(ctx, OPCODE_ENABLE, 1);
2167   if (n) {
2168      n[1].e = cap;
2169   }
2170   if (ctx->ExecuteFlag) {
2171      CALL_Enable(ctx->Exec, (cap));
2172   }
2173}
2174
2175
2176
2177static void GLAPIENTRY
2178save_EnableIndexed(GLuint index, GLenum cap)
2179{
2180   GET_CURRENT_CONTEXT(ctx);
2181   Node *n;
2182   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2183   n = alloc_instruction(ctx, OPCODE_ENABLE_INDEXED, 2);
2184   if (n) {
2185      n[1].ui = index;
2186      n[2].e = cap;
2187   }
2188   if (ctx->ExecuteFlag) {
2189      CALL_Enablei(ctx->Exec, (index, cap));
2190   }
2191}
2192
2193
2194
2195static void GLAPIENTRY
2196save_EvalMesh1(GLenum mode, GLint i1, GLint i2)
2197{
2198   GET_CURRENT_CONTEXT(ctx);
2199   Node *n;
2200   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2201   n = alloc_instruction(ctx, OPCODE_EVALMESH1, 3);
2202   if (n) {
2203      n[1].e = mode;
2204      n[2].i = i1;
2205      n[3].i = i2;
2206   }
2207   if (ctx->ExecuteFlag) {
2208      CALL_EvalMesh1(ctx->Exec, (mode, i1, i2));
2209   }
2210}
2211
2212
2213static void GLAPIENTRY
2214save_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
2215{
2216   GET_CURRENT_CONTEXT(ctx);
2217   Node *n;
2218   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2219   n = alloc_instruction(ctx, OPCODE_EVALMESH2, 5);
2220   if (n) {
2221      n[1].e = mode;
2222      n[2].i = i1;
2223      n[3].i = i2;
2224      n[4].i = j1;
2225      n[5].i = j2;
2226   }
2227   if (ctx->ExecuteFlag) {
2228      CALL_EvalMesh2(ctx->Exec, (mode, i1, i2, j1, j2));
2229   }
2230}
2231
2232
2233
2234
2235static void GLAPIENTRY
2236save_Fogfv(GLenum pname, const GLfloat *params)
2237{
2238   GET_CURRENT_CONTEXT(ctx);
2239   Node *n;
2240   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2241   n = alloc_instruction(ctx, OPCODE_FOG, 5);
2242   if (n) {
2243      n[1].e = pname;
2244      n[2].f = params[0];
2245      n[3].f = params[1];
2246      n[4].f = params[2];
2247      n[5].f = params[3];
2248   }
2249   if (ctx->ExecuteFlag) {
2250      CALL_Fogfv(ctx->Exec, (pname, params));
2251   }
2252}
2253
2254
2255static void GLAPIENTRY
2256save_Fogf(GLenum pname, GLfloat param)
2257{
2258   GLfloat parray[4];
2259   parray[0] = param;
2260   parray[1] = parray[2] = parray[3] = 0.0F;
2261   save_Fogfv(pname, parray);
2262}
2263
2264
2265static void GLAPIENTRY
2266save_Fogiv(GLenum pname, const GLint *params)
2267{
2268   GLfloat p[4];
2269   switch (pname) {
2270   case GL_FOG_MODE:
2271   case GL_FOG_DENSITY:
2272   case GL_FOG_START:
2273   case GL_FOG_END:
2274   case GL_FOG_INDEX:
2275      p[0] = (GLfloat) *params;
2276      p[1] = 0.0f;
2277      p[2] = 0.0f;
2278      p[3] = 0.0f;
2279      break;
2280   case GL_FOG_COLOR:
2281      p[0] = INT_TO_FLOAT(params[0]);
2282      p[1] = INT_TO_FLOAT(params[1]);
2283      p[2] = INT_TO_FLOAT(params[2]);
2284      p[3] = INT_TO_FLOAT(params[3]);
2285      break;
2286   default:
2287      /* Error will be caught later in gl_Fogfv */
2288      ASSIGN_4V(p, 0.0F, 0.0F, 0.0F, 0.0F);
2289   }
2290   save_Fogfv(pname, p);
2291}
2292
2293
2294static void GLAPIENTRY
2295save_Fogi(GLenum pname, GLint param)
2296{
2297   GLint parray[4];
2298   parray[0] = param;
2299   parray[1] = parray[2] = parray[3] = 0;
2300   save_Fogiv(pname, parray);
2301}
2302
2303
2304static void GLAPIENTRY
2305save_FrontFace(GLenum mode)
2306{
2307   GET_CURRENT_CONTEXT(ctx);
2308   Node *n;
2309   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2310   n = alloc_instruction(ctx, OPCODE_FRONT_FACE, 1);
2311   if (n) {
2312      n[1].e = mode;
2313   }
2314   if (ctx->ExecuteFlag) {
2315      CALL_FrontFace(ctx->Exec, (mode));
2316   }
2317}
2318
2319
2320static void GLAPIENTRY
2321save_Frustum(GLdouble left, GLdouble right,
2322             GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval)
2323{
2324   GET_CURRENT_CONTEXT(ctx);
2325   Node *n;
2326   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2327   n = alloc_instruction(ctx, OPCODE_FRUSTUM, 6);
2328   if (n) {
2329      n[1].f = (GLfloat) left;
2330      n[2].f = (GLfloat) right;
2331      n[3].f = (GLfloat) bottom;
2332      n[4].f = (GLfloat) top;
2333      n[5].f = (GLfloat) nearval;
2334      n[6].f = (GLfloat) farval;
2335   }
2336   if (ctx->ExecuteFlag) {
2337      CALL_Frustum(ctx->Exec, (left, right, bottom, top, nearval, farval));
2338   }
2339}
2340
2341
2342static void GLAPIENTRY
2343save_Hint(GLenum target, GLenum mode)
2344{
2345   GET_CURRENT_CONTEXT(ctx);
2346   Node *n;
2347   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2348   n = alloc_instruction(ctx, OPCODE_HINT, 2);
2349   if (n) {
2350      n[1].e = target;
2351      n[2].e = mode;
2352   }
2353   if (ctx->ExecuteFlag) {
2354      CALL_Hint(ctx->Exec, (target, mode));
2355   }
2356}
2357
2358
2359static void GLAPIENTRY
2360save_IndexMask(GLuint mask)
2361{
2362   GET_CURRENT_CONTEXT(ctx);
2363   Node *n;
2364   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2365   n = alloc_instruction(ctx, OPCODE_INDEX_MASK, 1);
2366   if (n) {
2367      n[1].ui = mask;
2368   }
2369   if (ctx->ExecuteFlag) {
2370      CALL_IndexMask(ctx->Exec, (mask));
2371   }
2372}
2373
2374
2375static void GLAPIENTRY
2376save_InitNames(void)
2377{
2378   GET_CURRENT_CONTEXT(ctx);
2379   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2380   (void) alloc_instruction(ctx, OPCODE_INIT_NAMES, 0);
2381   if (ctx->ExecuteFlag) {
2382      CALL_InitNames(ctx->Exec, ());
2383   }
2384}
2385
2386
2387static void GLAPIENTRY
2388save_Lightfv(GLenum light, GLenum pname, const GLfloat *params)
2389{
2390   GET_CURRENT_CONTEXT(ctx);
2391   Node *n;
2392   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2393   n = alloc_instruction(ctx, OPCODE_LIGHT, 6);
2394   if (n) {
2395      GLint i, nParams;
2396      n[1].e = light;
2397      n[2].e = pname;
2398      switch (pname) {
2399      case GL_AMBIENT:
2400         nParams = 4;
2401         break;
2402      case GL_DIFFUSE:
2403         nParams = 4;
2404         break;
2405      case GL_SPECULAR:
2406         nParams = 4;
2407         break;
2408      case GL_POSITION:
2409         nParams = 4;
2410         break;
2411      case GL_SPOT_DIRECTION:
2412         nParams = 3;
2413         break;
2414      case GL_SPOT_EXPONENT:
2415         nParams = 1;
2416         break;
2417      case GL_SPOT_CUTOFF:
2418         nParams = 1;
2419         break;
2420      case GL_CONSTANT_ATTENUATION:
2421         nParams = 1;
2422         break;
2423      case GL_LINEAR_ATTENUATION:
2424         nParams = 1;
2425         break;
2426      case GL_QUADRATIC_ATTENUATION:
2427         nParams = 1;
2428         break;
2429      default:
2430         nParams = 0;
2431      }
2432      for (i = 0; i < nParams; i++) {
2433         n[3 + i].f = params[i];
2434      }
2435   }
2436   if (ctx->ExecuteFlag) {
2437      CALL_Lightfv(ctx->Exec, (light, pname, params));
2438   }
2439}
2440
2441
2442static void GLAPIENTRY
2443save_Lightf(GLenum light, GLenum pname, GLfloat param)
2444{
2445   GLfloat parray[4];
2446   parray[0] = param;
2447   parray[1] = parray[2] = parray[3] = 0.0F;
2448   save_Lightfv(light, pname, parray);
2449}
2450
2451
2452static void GLAPIENTRY
2453save_Lightiv(GLenum light, GLenum pname, const GLint *params)
2454{
2455   GLfloat fparam[4];
2456   switch (pname) {
2457   case GL_AMBIENT:
2458   case GL_DIFFUSE:
2459   case GL_SPECULAR:
2460      fparam[0] = INT_TO_FLOAT(params[0]);
2461      fparam[1] = INT_TO_FLOAT(params[1]);
2462      fparam[2] = INT_TO_FLOAT(params[2]);
2463      fparam[3] = INT_TO_FLOAT(params[3]);
2464      break;
2465   case GL_POSITION:
2466      fparam[0] = (GLfloat) params[0];
2467      fparam[1] = (GLfloat) params[1];
2468      fparam[2] = (GLfloat) params[2];
2469      fparam[3] = (GLfloat) params[3];
2470      break;
2471   case GL_SPOT_DIRECTION:
2472      fparam[0] = (GLfloat) params[0];
2473      fparam[1] = (GLfloat) params[1];
2474      fparam[2] = (GLfloat) params[2];
2475      break;
2476   case GL_SPOT_EXPONENT:
2477   case GL_SPOT_CUTOFF:
2478   case GL_CONSTANT_ATTENUATION:
2479   case GL_LINEAR_ATTENUATION:
2480   case GL_QUADRATIC_ATTENUATION:
2481      fparam[0] = (GLfloat) params[0];
2482      break;
2483   default:
2484      /* error will be caught later in gl_Lightfv */
2485      ;
2486   }
2487   save_Lightfv(light, pname, fparam);
2488}
2489
2490
2491static void GLAPIENTRY
2492save_Lighti(GLenum light, GLenum pname, GLint param)
2493{
2494   GLint parray[4];
2495   parray[0] = param;
2496   parray[1] = parray[2] = parray[3] = 0;
2497   save_Lightiv(light, pname, parray);
2498}
2499
2500
2501static void GLAPIENTRY
2502save_LightModelfv(GLenum pname, const GLfloat *params)
2503{
2504   GET_CURRENT_CONTEXT(ctx);
2505   Node *n;
2506   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2507   n = alloc_instruction(ctx, OPCODE_LIGHT_MODEL, 5);
2508   if (n) {
2509      n[1].e = pname;
2510      n[2].f = params[0];
2511      n[3].f = params[1];
2512      n[4].f = params[2];
2513      n[5].f = params[3];
2514   }
2515   if (ctx->ExecuteFlag) {
2516      CALL_LightModelfv(ctx->Exec, (pname, params));
2517   }
2518}
2519
2520
2521static void GLAPIENTRY
2522save_LightModelf(GLenum pname, GLfloat param)
2523{
2524   GLfloat parray[4];
2525   parray[0] = param;
2526   parray[1] = parray[2] = parray[3] = 0.0F;
2527   save_LightModelfv(pname, parray);
2528}
2529
2530
2531static void GLAPIENTRY
2532save_LightModeliv(GLenum pname, const GLint *params)
2533{
2534   GLfloat fparam[4];
2535   switch (pname) {
2536   case GL_LIGHT_MODEL_AMBIENT:
2537      fparam[0] = INT_TO_FLOAT(params[0]);
2538      fparam[1] = INT_TO_FLOAT(params[1]);
2539      fparam[2] = INT_TO_FLOAT(params[2]);
2540      fparam[3] = INT_TO_FLOAT(params[3]);
2541      break;
2542   case GL_LIGHT_MODEL_LOCAL_VIEWER:
2543   case GL_LIGHT_MODEL_TWO_SIDE:
2544   case GL_LIGHT_MODEL_COLOR_CONTROL:
2545      fparam[0] = (GLfloat) params[0];
2546      fparam[1] = 0.0F;
2547      fparam[2] = 0.0F;
2548      fparam[3] = 0.0F;
2549      break;
2550   default:
2551      /* Error will be caught later in gl_LightModelfv */
2552      ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F);
2553   }
2554   save_LightModelfv(pname, fparam);
2555}
2556
2557
2558static void GLAPIENTRY
2559save_LightModeli(GLenum pname, GLint param)
2560{
2561   GLint parray[4];
2562   parray[0] = param;
2563   parray[1] = parray[2] = parray[3] = 0;
2564   save_LightModeliv(pname, parray);
2565}
2566
2567
2568static void GLAPIENTRY
2569save_LineStipple(GLint factor, GLushort pattern)
2570{
2571   GET_CURRENT_CONTEXT(ctx);
2572   Node *n;
2573   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2574   n = alloc_instruction(ctx, OPCODE_LINE_STIPPLE, 2);
2575   if (n) {
2576      n[1].i = factor;
2577      n[2].us = pattern;
2578   }
2579   if (ctx->ExecuteFlag) {
2580      CALL_LineStipple(ctx->Exec, (factor, pattern));
2581   }
2582}
2583
2584
2585static void GLAPIENTRY
2586save_LineWidth(GLfloat width)
2587{
2588   GET_CURRENT_CONTEXT(ctx);
2589   Node *n;
2590   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2591   n = alloc_instruction(ctx, OPCODE_LINE_WIDTH, 1);
2592   if (n) {
2593      n[1].f = width;
2594   }
2595   if (ctx->ExecuteFlag) {
2596      CALL_LineWidth(ctx->Exec, (width));
2597   }
2598}
2599
2600
2601static void GLAPIENTRY
2602save_ListBase(GLuint base)
2603{
2604   GET_CURRENT_CONTEXT(ctx);
2605   Node *n;
2606   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2607   n = alloc_instruction(ctx, OPCODE_LIST_BASE, 1);
2608   if (n) {
2609      n[1].ui = base;
2610   }
2611   if (ctx->ExecuteFlag) {
2612      CALL_ListBase(ctx->Exec, (base));
2613   }
2614}
2615
2616
2617static void GLAPIENTRY
2618save_LoadIdentity(void)
2619{
2620   GET_CURRENT_CONTEXT(ctx);
2621   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2622   (void) alloc_instruction(ctx, OPCODE_LOAD_IDENTITY, 0);
2623   if (ctx->ExecuteFlag) {
2624      CALL_LoadIdentity(ctx->Exec, ());
2625   }
2626}
2627
2628
2629static void GLAPIENTRY
2630save_LoadMatrixf(const GLfloat * m)
2631{
2632   GET_CURRENT_CONTEXT(ctx);
2633   Node *n;
2634   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2635   n = alloc_instruction(ctx, OPCODE_LOAD_MATRIX, 16);
2636   if (n) {
2637      GLuint i;
2638      for (i = 0; i < 16; i++) {
2639         n[1 + i].f = m[i];
2640      }
2641   }
2642   if (ctx->ExecuteFlag) {
2643      CALL_LoadMatrixf(ctx->Exec, (m));
2644   }
2645}
2646
2647
2648static void GLAPIENTRY
2649save_LoadMatrixd(const GLdouble * m)
2650{
2651   GLfloat f[16];
2652   GLint i;
2653   for (i = 0; i < 16; i++) {
2654      f[i] = (GLfloat) m[i];
2655   }
2656   save_LoadMatrixf(f);
2657}
2658
2659
2660static void GLAPIENTRY
2661save_LoadName(GLuint name)
2662{
2663   GET_CURRENT_CONTEXT(ctx);
2664   Node *n;
2665   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2666   n = alloc_instruction(ctx, OPCODE_LOAD_NAME, 1);
2667   if (n) {
2668      n[1].ui = name;
2669   }
2670   if (ctx->ExecuteFlag) {
2671      CALL_LoadName(ctx->Exec, (name));
2672   }
2673}
2674
2675
2676static void GLAPIENTRY
2677save_LogicOp(GLenum opcode)
2678{
2679   GET_CURRENT_CONTEXT(ctx);
2680   Node *n;
2681   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2682   n = alloc_instruction(ctx, OPCODE_LOGIC_OP, 1);
2683   if (n) {
2684      n[1].e = opcode;
2685   }
2686   if (ctx->ExecuteFlag) {
2687      CALL_LogicOp(ctx->Exec, (opcode));
2688   }
2689}
2690
2691
2692static void GLAPIENTRY
2693save_Map1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride,
2694           GLint order, const GLdouble * points)
2695{
2696   GET_CURRENT_CONTEXT(ctx);
2697   Node *n;
2698   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2699   n = alloc_instruction(ctx, OPCODE_MAP1, 5 + POINTER_DWORDS);
2700   if (n) {
2701      GLfloat *pnts = _mesa_copy_map_points1d(target, stride, order, points);
2702      n[1].e = target;
2703      n[2].f = (GLfloat) u1;
2704      n[3].f = (GLfloat) u2;
2705      n[4].i = _mesa_evaluator_components(target);      /* stride */
2706      n[5].i = order;
2707      save_pointer(&n[6], pnts);
2708   }
2709   if (ctx->ExecuteFlag) {
2710      CALL_Map1d(ctx->Exec, (target, u1, u2, stride, order, points));
2711   }
2712}
2713
2714static void GLAPIENTRY
2715save_Map1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
2716           GLint order, const GLfloat * points)
2717{
2718   GET_CURRENT_CONTEXT(ctx);
2719   Node *n;
2720   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2721   n = alloc_instruction(ctx, OPCODE_MAP1, 5 + POINTER_DWORDS);
2722   if (n) {
2723      GLfloat *pnts = _mesa_copy_map_points1f(target, stride, order, points);
2724      n[1].e = target;
2725      n[2].f = u1;
2726      n[3].f = u2;
2727      n[4].i = _mesa_evaluator_components(target);      /* stride */
2728      n[5].i = order;
2729      save_pointer(&n[6], pnts);
2730   }
2731   if (ctx->ExecuteFlag) {
2732      CALL_Map1f(ctx->Exec, (target, u1, u2, stride, order, points));
2733   }
2734}
2735
2736
2737static void GLAPIENTRY
2738save_Map2d(GLenum target,
2739           GLdouble u1, GLdouble u2, GLint ustride, GLint uorder,
2740           GLdouble v1, GLdouble v2, GLint vstride, GLint vorder,
2741           const GLdouble * points)
2742{
2743   GET_CURRENT_CONTEXT(ctx);
2744   Node *n;
2745   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2746   n = alloc_instruction(ctx, OPCODE_MAP2, 9 + POINTER_DWORDS);
2747   if (n) {
2748      GLfloat *pnts = _mesa_copy_map_points2d(target, ustride, uorder,
2749                                              vstride, vorder, points);
2750      n[1].e = target;
2751      n[2].f = (GLfloat) u1;
2752      n[3].f = (GLfloat) u2;
2753      n[4].f = (GLfloat) v1;
2754      n[5].f = (GLfloat) v2;
2755      /* XXX verify these strides are correct */
2756      n[6].i = _mesa_evaluator_components(target) * vorder;     /*ustride */
2757      n[7].i = _mesa_evaluator_components(target);      /*vstride */
2758      n[8].i = uorder;
2759      n[9].i = vorder;
2760      save_pointer(&n[10], pnts);
2761   }
2762   if (ctx->ExecuteFlag) {
2763      CALL_Map2d(ctx->Exec, (target,
2764                             u1, u2, ustride, uorder,
2765                             v1, v2, vstride, vorder, points));
2766   }
2767}
2768
2769
2770static void GLAPIENTRY
2771save_Map2f(GLenum target,
2772           GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
2773           GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
2774           const GLfloat * points)
2775{
2776   GET_CURRENT_CONTEXT(ctx);
2777   Node *n;
2778   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2779   n = alloc_instruction(ctx, OPCODE_MAP2, 9 + POINTER_DWORDS);
2780   if (n) {
2781      GLfloat *pnts = _mesa_copy_map_points2f(target, ustride, uorder,
2782                                              vstride, vorder, points);
2783      n[1].e = target;
2784      n[2].f = u1;
2785      n[3].f = u2;
2786      n[4].f = v1;
2787      n[5].f = v2;
2788      /* XXX verify these strides are correct */
2789      n[6].i = _mesa_evaluator_components(target) * vorder;     /*ustride */
2790      n[7].i = _mesa_evaluator_components(target);      /*vstride */
2791      n[8].i = uorder;
2792      n[9].i = vorder;
2793      save_pointer(&n[10], pnts);
2794   }
2795   if (ctx->ExecuteFlag) {
2796      CALL_Map2f(ctx->Exec, (target, u1, u2, ustride, uorder,
2797                             v1, v2, vstride, vorder, points));
2798   }
2799}
2800
2801
2802static void GLAPIENTRY
2803save_MapGrid1f(GLint un, GLfloat u1, GLfloat u2)
2804{
2805   GET_CURRENT_CONTEXT(ctx);
2806   Node *n;
2807   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2808   n = alloc_instruction(ctx, OPCODE_MAPGRID1, 3);
2809   if (n) {
2810      n[1].i = un;
2811      n[2].f = u1;
2812      n[3].f = u2;
2813   }
2814   if (ctx->ExecuteFlag) {
2815      CALL_MapGrid1f(ctx->Exec, (un, u1, u2));
2816   }
2817}
2818
2819
2820static void GLAPIENTRY
2821save_MapGrid1d(GLint un, GLdouble u1, GLdouble u2)
2822{
2823   save_MapGrid1f(un, (GLfloat) u1, (GLfloat) u2);
2824}
2825
2826
2827static void GLAPIENTRY
2828save_MapGrid2f(GLint un, GLfloat u1, GLfloat u2,
2829               GLint vn, GLfloat v1, GLfloat v2)
2830{
2831   GET_CURRENT_CONTEXT(ctx);
2832   Node *n;
2833   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2834   n = alloc_instruction(ctx, OPCODE_MAPGRID2, 6);
2835   if (n) {
2836      n[1].i = un;
2837      n[2].f = u1;
2838      n[3].f = u2;
2839      n[4].i = vn;
2840      n[5].f = v1;
2841      n[6].f = v2;
2842   }
2843   if (ctx->ExecuteFlag) {
2844      CALL_MapGrid2f(ctx->Exec, (un, u1, u2, vn, v1, v2));
2845   }
2846}
2847
2848
2849
2850static void GLAPIENTRY
2851save_MapGrid2d(GLint un, GLdouble u1, GLdouble u2,
2852               GLint vn, GLdouble v1, GLdouble v2)
2853{
2854   save_MapGrid2f(un, (GLfloat) u1, (GLfloat) u2,
2855                  vn, (GLfloat) v1, (GLfloat) v2);
2856}
2857
2858
2859static void GLAPIENTRY
2860save_MatrixMode(GLenum mode)
2861{
2862   GET_CURRENT_CONTEXT(ctx);
2863   Node *n;
2864   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2865   n = alloc_instruction(ctx, OPCODE_MATRIX_MODE, 1);
2866   if (n) {
2867      n[1].e = mode;
2868   }
2869   if (ctx->ExecuteFlag) {
2870      CALL_MatrixMode(ctx->Exec, (mode));
2871   }
2872}
2873
2874
2875static void GLAPIENTRY
2876save_MultMatrixf(const GLfloat * m)
2877{
2878   GET_CURRENT_CONTEXT(ctx);
2879   Node *n;
2880   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2881   n = alloc_instruction(ctx, OPCODE_MULT_MATRIX, 16);
2882   if (n) {
2883      GLuint i;
2884      for (i = 0; i < 16; i++) {
2885         n[1 + i].f = m[i];
2886      }
2887   }
2888   if (ctx->ExecuteFlag) {
2889      CALL_MultMatrixf(ctx->Exec, (m));
2890   }
2891}
2892
2893
2894static void GLAPIENTRY
2895save_MultMatrixd(const GLdouble * m)
2896{
2897   GLfloat f[16];
2898   GLint i;
2899   for (i = 0; i < 16; i++) {
2900      f[i] = (GLfloat) m[i];
2901   }
2902   save_MultMatrixf(f);
2903}
2904
2905
2906static void GLAPIENTRY
2907save_NewList(GLuint name, GLenum mode)
2908{
2909   GET_CURRENT_CONTEXT(ctx);
2910   /* It's an error to call this function while building a display list */
2911   _mesa_error(ctx, GL_INVALID_OPERATION, "glNewList");
2912   (void) name;
2913   (void) mode;
2914}
2915
2916
2917
2918static void GLAPIENTRY
2919save_Ortho(GLdouble left, GLdouble right,
2920           GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval)
2921{
2922   GET_CURRENT_CONTEXT(ctx);
2923   Node *n;
2924   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2925   n = alloc_instruction(ctx, OPCODE_ORTHO, 6);
2926   if (n) {
2927      n[1].f = (GLfloat) left;
2928      n[2].f = (GLfloat) right;
2929      n[3].f = (GLfloat) bottom;
2930      n[4].f = (GLfloat) top;
2931      n[5].f = (GLfloat) nearval;
2932      n[6].f = (GLfloat) farval;
2933   }
2934   if (ctx->ExecuteFlag) {
2935      CALL_Ortho(ctx->Exec, (left, right, bottom, top, nearval, farval));
2936   }
2937}
2938
2939
2940static void GLAPIENTRY
2941save_PixelMapfv(GLenum map, GLint mapsize, const GLfloat *values)
2942{
2943   GET_CURRENT_CONTEXT(ctx);
2944   Node *n;
2945   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2946   n = alloc_instruction(ctx, OPCODE_PIXEL_MAP, 2 + POINTER_DWORDS);
2947   if (n) {
2948      n[1].e = map;
2949      n[2].i = mapsize;
2950      save_pointer(&n[3], memdup(values, mapsize * sizeof(GLfloat)));
2951   }
2952   if (ctx->ExecuteFlag) {
2953      CALL_PixelMapfv(ctx->Exec, (map, mapsize, values));
2954   }
2955}
2956
2957
2958static void GLAPIENTRY
2959save_PixelMapuiv(GLenum map, GLint mapsize, const GLuint *values)
2960{
2961   GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
2962   GLint i;
2963   if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
2964      for (i = 0; i < mapsize; i++) {
2965         fvalues[i] = (GLfloat) values[i];
2966      }
2967   }
2968   else {
2969      for (i = 0; i < mapsize; i++) {
2970         fvalues[i] = UINT_TO_FLOAT(values[i]);
2971      }
2972   }
2973   save_PixelMapfv(map, mapsize, fvalues);
2974}
2975
2976
2977static void GLAPIENTRY
2978save_PixelMapusv(GLenum map, GLint mapsize, const GLushort *values)
2979{
2980   GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
2981   GLint i;
2982   if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
2983      for (i = 0; i < mapsize; i++) {
2984         fvalues[i] = (GLfloat) values[i];
2985      }
2986   }
2987   else {
2988      for (i = 0; i < mapsize; i++) {
2989         fvalues[i] = USHORT_TO_FLOAT(values[i]);
2990      }
2991   }
2992   save_PixelMapfv(map, mapsize, fvalues);
2993}
2994
2995
2996static void GLAPIENTRY
2997save_PixelTransferf(GLenum pname, GLfloat param)
2998{
2999   GET_CURRENT_CONTEXT(ctx);
3000   Node *n;
3001   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3002   n = alloc_instruction(ctx, OPCODE_PIXEL_TRANSFER, 2);
3003   if (n) {
3004      n[1].e = pname;
3005      n[2].f = param;
3006   }
3007   if (ctx->ExecuteFlag) {
3008      CALL_PixelTransferf(ctx->Exec, (pname, param));
3009   }
3010}
3011
3012
3013static void GLAPIENTRY
3014save_PixelTransferi(GLenum pname, GLint param)
3015{
3016   save_PixelTransferf(pname, (GLfloat) param);
3017}
3018
3019
3020static void GLAPIENTRY
3021save_PixelZoom(GLfloat xfactor, GLfloat yfactor)
3022{
3023   GET_CURRENT_CONTEXT(ctx);
3024   Node *n;
3025   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3026   n = alloc_instruction(ctx, OPCODE_PIXEL_ZOOM, 2);
3027   if (n) {
3028      n[1].f = xfactor;
3029      n[2].f = yfactor;
3030   }
3031   if (ctx->ExecuteFlag) {
3032      CALL_PixelZoom(ctx->Exec, (xfactor, yfactor));
3033   }
3034}
3035
3036
3037static void GLAPIENTRY
3038save_PointParameterfvEXT(GLenum pname, const GLfloat *params)
3039{
3040   GET_CURRENT_CONTEXT(ctx);
3041   Node *n;
3042   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3043   n = alloc_instruction(ctx, OPCODE_POINT_PARAMETERS, 4);
3044   if (n) {
3045      n[1].e = pname;
3046      n[2].f = params[0];
3047      n[3].f = params[1];
3048      n[4].f = params[2];
3049   }
3050   if (ctx->ExecuteFlag) {
3051      CALL_PointParameterfv(ctx->Exec, (pname, params));
3052   }
3053}
3054
3055
3056static void GLAPIENTRY
3057save_PointParameterfEXT(GLenum pname, GLfloat param)
3058{
3059   GLfloat parray[3];
3060   parray[0] = param;
3061   parray[1] = parray[2] = 0.0F;
3062   save_PointParameterfvEXT(pname, parray);
3063}
3064
3065static void GLAPIENTRY
3066save_PointParameteriNV(GLenum pname, GLint param)
3067{
3068   GLfloat parray[3];
3069   parray[0] = (GLfloat) param;
3070   parray[1] = parray[2] = 0.0F;
3071   save_PointParameterfvEXT(pname, parray);
3072}
3073
3074static void GLAPIENTRY
3075save_PointParameterivNV(GLenum pname, const GLint * param)
3076{
3077   GLfloat parray[3];
3078   parray[0] = (GLfloat) param[0];
3079   parray[1] = parray[2] = 0.0F;
3080   save_PointParameterfvEXT(pname, parray);
3081}
3082
3083
3084static void GLAPIENTRY
3085save_PointSize(GLfloat size)
3086{
3087   GET_CURRENT_CONTEXT(ctx);
3088   Node *n;
3089   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3090   n = alloc_instruction(ctx, OPCODE_POINT_SIZE, 1);
3091   if (n) {
3092      n[1].f = size;
3093   }
3094   if (ctx->ExecuteFlag) {
3095      CALL_PointSize(ctx->Exec, (size));
3096   }
3097}
3098
3099
3100static void GLAPIENTRY
3101save_PolygonMode(GLenum face, GLenum mode)
3102{
3103   GET_CURRENT_CONTEXT(ctx);
3104   Node *n;
3105   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3106   n = alloc_instruction(ctx, OPCODE_POLYGON_MODE, 2);
3107   if (n) {
3108      n[1].e = face;
3109      n[2].e = mode;
3110   }
3111   if (ctx->ExecuteFlag) {
3112      CALL_PolygonMode(ctx->Exec, (face, mode));
3113   }
3114}
3115
3116
3117static void GLAPIENTRY
3118save_PolygonStipple(const GLubyte * pattern)
3119{
3120   GET_CURRENT_CONTEXT(ctx);
3121   Node *n;
3122
3123   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3124
3125   n = alloc_instruction(ctx, OPCODE_POLYGON_STIPPLE, POINTER_DWORDS);
3126   if (n) {
3127      save_pointer(&n[1],
3128                   unpack_image(ctx, 2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP,
3129                                pattern, &ctx->Unpack));
3130   }
3131   if (ctx->ExecuteFlag) {
3132      CALL_PolygonStipple(ctx->Exec, ((GLubyte *) pattern));
3133   }
3134}
3135
3136
3137static void GLAPIENTRY
3138save_PolygonOffset(GLfloat factor, GLfloat units)
3139{
3140   GET_CURRENT_CONTEXT(ctx);
3141   Node *n;
3142   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3143   n = alloc_instruction(ctx, OPCODE_POLYGON_OFFSET, 2);
3144   if (n) {
3145      n[1].f = factor;
3146      n[2].f = units;
3147   }
3148   if (ctx->ExecuteFlag) {
3149      CALL_PolygonOffset(ctx->Exec, (factor, units));
3150   }
3151}
3152
3153
3154static void GLAPIENTRY
3155save_PolygonOffsetEXT(GLfloat factor, GLfloat bias)
3156{
3157   GET_CURRENT_CONTEXT(ctx);
3158   /* XXX mult by DepthMaxF here??? */
3159   save_PolygonOffset(factor, ctx->DrawBuffer->_DepthMaxF * bias);
3160}
3161
3162
3163static void GLAPIENTRY
3164save_PopAttrib(void)
3165{
3166   GET_CURRENT_CONTEXT(ctx);
3167   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3168   (void) alloc_instruction(ctx, OPCODE_POP_ATTRIB, 0);
3169   if (ctx->ExecuteFlag) {
3170      CALL_PopAttrib(ctx->Exec, ());
3171   }
3172}
3173
3174
3175static void GLAPIENTRY
3176save_PopMatrix(void)
3177{
3178   GET_CURRENT_CONTEXT(ctx);
3179   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3180   (void) alloc_instruction(ctx, OPCODE_POP_MATRIX, 0);
3181   if (ctx->ExecuteFlag) {
3182      CALL_PopMatrix(ctx->Exec, ());
3183   }
3184}
3185
3186
3187static void GLAPIENTRY
3188save_PopName(void)
3189{
3190   GET_CURRENT_CONTEXT(ctx);
3191   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3192   (void) alloc_instruction(ctx, OPCODE_POP_NAME, 0);
3193   if (ctx->ExecuteFlag) {
3194      CALL_PopName(ctx->Exec, ());
3195   }
3196}
3197
3198
3199static void GLAPIENTRY
3200save_PrioritizeTextures(GLsizei num, const GLuint * textures,
3201                        const GLclampf * priorities)
3202{
3203   GET_CURRENT_CONTEXT(ctx);
3204   GLint i;
3205   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3206
3207   for (i = 0; i < num; i++) {
3208      Node *n;
3209      n = alloc_instruction(ctx, OPCODE_PRIORITIZE_TEXTURE, 2);
3210      if (n) {
3211         n[1].ui = textures[i];
3212         n[2].f = priorities[i];
3213      }
3214   }
3215   if (ctx->ExecuteFlag) {
3216      CALL_PrioritizeTextures(ctx->Exec, (num, textures, priorities));
3217   }
3218}
3219
3220
3221static void GLAPIENTRY
3222save_PushAttrib(GLbitfield mask)
3223{
3224   GET_CURRENT_CONTEXT(ctx);
3225   Node *n;
3226   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3227   n = alloc_instruction(ctx, OPCODE_PUSH_ATTRIB, 1);
3228   if (n) {
3229      n[1].bf = mask;
3230   }
3231   if (ctx->ExecuteFlag) {
3232      CALL_PushAttrib(ctx->Exec, (mask));
3233   }
3234}
3235
3236
3237static void GLAPIENTRY
3238save_PushMatrix(void)
3239{
3240   GET_CURRENT_CONTEXT(ctx);
3241   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3242   (void) alloc_instruction(ctx, OPCODE_PUSH_MATRIX, 0);
3243   if (ctx->ExecuteFlag) {
3244      CALL_PushMatrix(ctx->Exec, ());
3245   }
3246}
3247
3248
3249static void GLAPIENTRY
3250save_PushName(GLuint name)
3251{
3252   GET_CURRENT_CONTEXT(ctx);
3253   Node *n;
3254   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3255   n = alloc_instruction(ctx, OPCODE_PUSH_NAME, 1);
3256   if (n) {
3257      n[1].ui = name;
3258   }
3259   if (ctx->ExecuteFlag) {
3260      CALL_PushName(ctx->Exec, (name));
3261   }
3262}
3263
3264
3265static void GLAPIENTRY
3266save_RasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3267{
3268   GET_CURRENT_CONTEXT(ctx);
3269   Node *n;
3270   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3271   n = alloc_instruction(ctx, OPCODE_RASTER_POS, 4);
3272   if (n) {
3273      n[1].f = x;
3274      n[2].f = y;
3275      n[3].f = z;
3276      n[4].f = w;
3277   }
3278   if (ctx->ExecuteFlag) {
3279      CALL_RasterPos4f(ctx->Exec, (x, y, z, w));
3280   }
3281}
3282
3283static void GLAPIENTRY
3284save_RasterPos2d(GLdouble x, GLdouble y)
3285{
3286   save_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
3287}
3288
3289static void GLAPIENTRY
3290save_RasterPos2f(GLfloat x, GLfloat y)
3291{
3292   save_RasterPos4f(x, y, 0.0F, 1.0F);
3293}
3294
3295static void GLAPIENTRY
3296save_RasterPos2i(GLint x, GLint y)
3297{
3298   save_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
3299}
3300
3301static void GLAPIENTRY
3302save_RasterPos2s(GLshort x, GLshort y)
3303{
3304   save_RasterPos4f(x, y, 0.0F, 1.0F);
3305}
3306
3307static void GLAPIENTRY
3308save_RasterPos3d(GLdouble x, GLdouble y, GLdouble z)
3309{
3310   save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
3311}
3312
3313static void GLAPIENTRY
3314save_RasterPos3f(GLfloat x, GLfloat y, GLfloat z)
3315{
3316   save_RasterPos4f(x, y, z, 1.0F);
3317}
3318
3319static void GLAPIENTRY
3320save_RasterPos3i(GLint x, GLint y, GLint z)
3321{
3322   save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
3323}
3324
3325static void GLAPIENTRY
3326save_RasterPos3s(GLshort x, GLshort y, GLshort z)
3327{
3328   save_RasterPos4f(x, y, z, 1.0F);
3329}
3330
3331static void GLAPIENTRY
3332save_RasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
3333{
3334   save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
3335}
3336
3337static void GLAPIENTRY
3338save_RasterPos4i(GLint x, GLint y, GLint z, GLint w)
3339{
3340   save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
3341}
3342
3343static void GLAPIENTRY
3344save_RasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
3345{
3346   save_RasterPos4f(x, y, z, w);
3347}
3348
3349static void GLAPIENTRY
3350save_RasterPos2dv(const GLdouble * v)
3351{
3352   save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
3353}
3354
3355static void GLAPIENTRY
3356save_RasterPos2fv(const GLfloat * v)
3357{
3358   save_RasterPos4f(v[0], v[1], 0.0F, 1.0F);
3359}
3360
3361static void GLAPIENTRY
3362save_RasterPos2iv(const GLint * v)
3363{
3364   save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
3365}
3366
3367static void GLAPIENTRY
3368save_RasterPos2sv(const GLshort * v)
3369{
3370   save_RasterPos4f(v[0], v[1], 0.0F, 1.0F);
3371}
3372
3373static void GLAPIENTRY
3374save_RasterPos3dv(const GLdouble * v)
3375{
3376   save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
3377}
3378
3379static void GLAPIENTRY
3380save_RasterPos3fv(const GLfloat * v)
3381{
3382   save_RasterPos4f(v[0], v[1], v[2], 1.0F);
3383}
3384
3385static void GLAPIENTRY
3386save_RasterPos3iv(const GLint * v)
3387{
3388   save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
3389}
3390
3391static void GLAPIENTRY
3392save_RasterPos3sv(const GLshort * v)
3393{
3394   save_RasterPos4f(v[0], v[1], v[2], 1.0F);
3395}
3396
3397static void GLAPIENTRY
3398save_RasterPos4dv(const GLdouble * v)
3399{
3400   save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1],
3401                    (GLfloat) v[2], (GLfloat) v[3]);
3402}
3403
3404static void GLAPIENTRY
3405save_RasterPos4fv(const GLfloat * v)
3406{
3407   save_RasterPos4f(v[0], v[1], v[2], v[3]);
3408}
3409
3410static void GLAPIENTRY
3411save_RasterPos4iv(const GLint * v)
3412{
3413   save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1],
3414                    (GLfloat) v[2], (GLfloat) v[3]);
3415}
3416
3417static void GLAPIENTRY
3418save_RasterPos4sv(const GLshort * v)
3419{
3420   save_RasterPos4f(v[0], v[1], v[2], v[3]);
3421}
3422
3423
3424static void GLAPIENTRY
3425save_PassThrough(GLfloat token)
3426{
3427   GET_CURRENT_CONTEXT(ctx);
3428   Node *n;
3429   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3430   n = alloc_instruction(ctx, OPCODE_PASSTHROUGH, 1);
3431   if (n) {
3432      n[1].f = token;
3433   }
3434   if (ctx->ExecuteFlag) {
3435      CALL_PassThrough(ctx->Exec, (token));
3436   }
3437}
3438
3439
3440static void GLAPIENTRY
3441save_ReadBuffer(GLenum mode)
3442{
3443   GET_CURRENT_CONTEXT(ctx);
3444   Node *n;
3445   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3446   n = alloc_instruction(ctx, OPCODE_READ_BUFFER, 1);
3447   if (n) {
3448      n[1].e = mode;
3449   }
3450   if (ctx->ExecuteFlag) {
3451      CALL_ReadBuffer(ctx->Exec, (mode));
3452   }
3453}
3454
3455
3456static void GLAPIENTRY
3457save_Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
3458{
3459   GET_CURRENT_CONTEXT(ctx);
3460   Node *n;
3461   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3462   n = alloc_instruction(ctx, OPCODE_ROTATE, 4);
3463   if (n) {
3464      n[1].f = angle;
3465      n[2].f = x;
3466      n[3].f = y;
3467      n[4].f = z;
3468   }
3469   if (ctx->ExecuteFlag) {
3470      CALL_Rotatef(ctx->Exec, (angle, x, y, z));
3471   }
3472}
3473
3474
3475static void GLAPIENTRY
3476save_Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
3477{
3478   save_Rotatef((GLfloat) angle, (GLfloat) x, (GLfloat) y, (GLfloat) z);
3479}
3480
3481
3482static void GLAPIENTRY
3483save_Scalef(GLfloat x, GLfloat y, GLfloat z)
3484{
3485   GET_CURRENT_CONTEXT(ctx);
3486   Node *n;
3487   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3488   n = alloc_instruction(ctx, OPCODE_SCALE, 3);
3489   if (n) {
3490      n[1].f = x;
3491      n[2].f = y;
3492      n[3].f = z;
3493   }
3494   if (ctx->ExecuteFlag) {
3495      CALL_Scalef(ctx->Exec, (x, y, z));
3496   }
3497}
3498
3499
3500static void GLAPIENTRY
3501save_Scaled(GLdouble x, GLdouble y, GLdouble z)
3502{
3503   save_Scalef((GLfloat) x, (GLfloat) y, (GLfloat) z);
3504}
3505
3506
3507static void GLAPIENTRY
3508save_Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3509{
3510   GET_CURRENT_CONTEXT(ctx);
3511   Node *n;
3512   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3513   n = alloc_instruction(ctx, OPCODE_SCISSOR, 4);
3514   if (n) {
3515      n[1].i = x;
3516      n[2].i = y;
3517      n[3].i = width;
3518      n[4].i = height;
3519   }
3520   if (ctx->ExecuteFlag) {
3521      CALL_Scissor(ctx->Exec, (x, y, width, height));
3522   }
3523}
3524
3525
3526static void GLAPIENTRY
3527save_ShadeModel(GLenum mode)
3528{
3529   GET_CURRENT_CONTEXT(ctx);
3530   Node *n;
3531   ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx);
3532
3533   if (ctx->ExecuteFlag) {
3534      CALL_ShadeModel(ctx->Exec, (mode));
3535   }
3536
3537   /* Don't compile this call if it's a no-op.
3538    * By avoiding this state change we have a better chance of
3539    * coalescing subsequent drawing commands into one batch.
3540    */
3541   if (ctx->ListState.Current.ShadeModel == mode)
3542      return;
3543
3544   SAVE_FLUSH_VERTICES(ctx);
3545
3546   ctx->ListState.Current.ShadeModel = mode;
3547
3548   n = alloc_instruction(ctx, OPCODE_SHADE_MODEL, 1);
3549   if (n) {
3550      n[1].e = mode;
3551   }
3552}
3553
3554
3555static void GLAPIENTRY
3556save_StencilFunc(GLenum func, GLint ref, GLuint mask)
3557{
3558   GET_CURRENT_CONTEXT(ctx);
3559   Node *n;
3560   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3561   n = alloc_instruction(ctx, OPCODE_STENCIL_FUNC, 3);
3562   if (n) {
3563      n[1].e = func;
3564      n[2].i = ref;
3565      n[3].ui = mask;
3566   }
3567   if (ctx->ExecuteFlag) {
3568      CALL_StencilFunc(ctx->Exec, (func, ref, mask));
3569   }
3570}
3571
3572
3573static void GLAPIENTRY
3574save_StencilMask(GLuint mask)
3575{
3576   GET_CURRENT_CONTEXT(ctx);
3577   Node *n;
3578   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3579   n = alloc_instruction(ctx, OPCODE_STENCIL_MASK, 1);
3580   if (n) {
3581      n[1].ui = mask;
3582   }
3583   if (ctx->ExecuteFlag) {
3584      CALL_StencilMask(ctx->Exec, (mask));
3585   }
3586}
3587
3588
3589static void GLAPIENTRY
3590save_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3591{
3592   GET_CURRENT_CONTEXT(ctx);
3593   Node *n;
3594   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3595   n = alloc_instruction(ctx, OPCODE_STENCIL_OP, 3);
3596   if (n) {
3597      n[1].e = fail;
3598      n[2].e = zfail;
3599      n[3].e = zpass;
3600   }
3601   if (ctx->ExecuteFlag) {
3602      CALL_StencilOp(ctx->Exec, (fail, zfail, zpass));
3603   }
3604}
3605
3606
3607static void GLAPIENTRY
3608save_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3609{
3610   GET_CURRENT_CONTEXT(ctx);
3611   Node *n;
3612   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3613   n = alloc_instruction(ctx, OPCODE_STENCIL_FUNC_SEPARATE, 4);
3614   if (n) {
3615      n[1].e = face;
3616      n[2].e = func;
3617      n[3].i = ref;
3618      n[4].ui = mask;
3619   }
3620   if (ctx->ExecuteFlag) {
3621      CALL_StencilFuncSeparate(ctx->Exec, (face, func, ref, mask));
3622   }
3623}
3624
3625
3626static void GLAPIENTRY
3627save_StencilFuncSeparateATI(GLenum frontfunc, GLenum backfunc, GLint ref,
3628                            GLuint mask)
3629{
3630   GET_CURRENT_CONTEXT(ctx);
3631   Node *n;
3632   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3633   /* GL_FRONT */
3634   n = alloc_instruction(ctx, OPCODE_STENCIL_FUNC_SEPARATE, 4);
3635   if (n) {
3636      n[1].e = GL_FRONT;
3637      n[2].e = frontfunc;
3638      n[3].i = ref;
3639      n[4].ui = mask;
3640   }
3641   /* GL_BACK */
3642   n = alloc_instruction(ctx, OPCODE_STENCIL_FUNC_SEPARATE, 4);
3643   if (n) {
3644      n[1].e = GL_BACK;
3645      n[2].e = backfunc;
3646      n[3].i = ref;
3647      n[4].ui = mask;
3648   }
3649   if (ctx->ExecuteFlag) {
3650      CALL_StencilFuncSeparate(ctx->Exec, (GL_FRONT, frontfunc, ref, mask));
3651      CALL_StencilFuncSeparate(ctx->Exec, (GL_BACK, backfunc, ref, mask));
3652   }
3653}
3654
3655
3656static void GLAPIENTRY
3657save_StencilMaskSeparate(GLenum face, GLuint mask)
3658{
3659   GET_CURRENT_CONTEXT(ctx);
3660   Node *n;
3661   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3662   n = alloc_instruction(ctx, OPCODE_STENCIL_MASK_SEPARATE, 2);
3663   if (n) {
3664      n[1].e = face;
3665      n[2].ui = mask;
3666   }
3667   if (ctx->ExecuteFlag) {
3668      CALL_StencilMaskSeparate(ctx->Exec, (face, mask));
3669   }
3670}
3671
3672
3673static void GLAPIENTRY
3674save_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3675{
3676   GET_CURRENT_CONTEXT(ctx);
3677   Node *n;
3678   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3679   n = alloc_instruction(ctx, OPCODE_STENCIL_OP_SEPARATE, 4);
3680   if (n) {
3681      n[1].e = face;
3682      n[2].e = fail;
3683      n[3].e = zfail;
3684      n[4].e = zpass;
3685   }
3686   if (ctx->ExecuteFlag) {
3687      CALL_StencilOpSeparate(ctx->Exec, (face, fail, zfail, zpass));
3688   }
3689}
3690
3691
3692static void GLAPIENTRY
3693save_TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
3694{
3695   GET_CURRENT_CONTEXT(ctx);
3696   Node *n;
3697   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3698   n = alloc_instruction(ctx, OPCODE_TEXENV, 6);
3699   if (n) {
3700      n[1].e = target;
3701      n[2].e = pname;
3702      if (pname == GL_TEXTURE_ENV_COLOR) {
3703         n[3].f = params[0];
3704         n[4].f = params[1];
3705         n[5].f = params[2];
3706         n[6].f = params[3];
3707      }
3708      else {
3709         n[3].f = params[0];
3710         n[4].f = n[5].f = n[6].f = 0.0F;
3711      }
3712   }
3713   if (ctx->ExecuteFlag) {
3714      CALL_TexEnvfv(ctx->Exec, (target, pname, params));
3715   }
3716}
3717
3718
3719static void GLAPIENTRY
3720save_TexEnvf(GLenum target, GLenum pname, GLfloat param)
3721{
3722   GLfloat parray[4];
3723   parray[0] = (GLfloat) param;
3724   parray[1] = parray[2] = parray[3] = 0.0F;
3725   save_TexEnvfv(target, pname, parray);
3726}
3727
3728
3729static void GLAPIENTRY
3730save_TexEnvi(GLenum target, GLenum pname, GLint param)
3731{
3732   GLfloat p[4];
3733   p[0] = (GLfloat) param;
3734   p[1] = p[2] = p[3] = 0.0F;
3735   save_TexEnvfv(target, pname, p);
3736}
3737
3738
3739static void GLAPIENTRY
3740save_TexEnviv(GLenum target, GLenum pname, const GLint * param)
3741{
3742   GLfloat p[4];
3743   if (pname == GL_TEXTURE_ENV_COLOR) {
3744      p[0] = INT_TO_FLOAT(param[0]);
3745      p[1] = INT_TO_FLOAT(param[1]);
3746      p[2] = INT_TO_FLOAT(param[2]);
3747      p[3] = INT_TO_FLOAT(param[3]);
3748   }
3749   else {
3750      p[0] = (GLfloat) param[0];
3751      p[1] = p[2] = p[3] = 0.0F;
3752   }
3753   save_TexEnvfv(target, pname, p);
3754}
3755
3756
3757static void GLAPIENTRY
3758save_TexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
3759{
3760   GET_CURRENT_CONTEXT(ctx);
3761   Node *n;
3762   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3763   n = alloc_instruction(ctx, OPCODE_TEXGEN, 6);
3764   if (n) {
3765      n[1].e = coord;
3766      n[2].e = pname;
3767      n[3].f = params[0];
3768      n[4].f = params[1];
3769      n[5].f = params[2];
3770      n[6].f = params[3];
3771   }
3772   if (ctx->ExecuteFlag) {
3773      CALL_TexGenfv(ctx->Exec, (coord, pname, params));
3774   }
3775}
3776
3777
3778static void GLAPIENTRY
3779save_TexGeniv(GLenum coord, GLenum pname, const GLint *params)
3780{
3781   GLfloat p[4];
3782   p[0] = (GLfloat) params[0];
3783   p[1] = (GLfloat) params[1];
3784   p[2] = (GLfloat) params[2];
3785   p[3] = (GLfloat) params[3];
3786   save_TexGenfv(coord, pname, p);
3787}
3788
3789
3790static void GLAPIENTRY
3791save_TexGend(GLenum coord, GLenum pname, GLdouble param)
3792{
3793   GLfloat parray[4];
3794   parray[0] = (GLfloat) param;
3795   parray[1] = parray[2] = parray[3] = 0.0F;
3796   save_TexGenfv(coord, pname, parray);
3797}
3798
3799
3800static void GLAPIENTRY
3801save_TexGendv(GLenum coord, GLenum pname, const GLdouble *params)
3802{
3803   GLfloat p[4];
3804   p[0] = (GLfloat) params[0];
3805   p[1] = (GLfloat) params[1];
3806   p[2] = (GLfloat) params[2];
3807   p[3] = (GLfloat) params[3];
3808   save_TexGenfv(coord, pname, p);
3809}
3810
3811
3812static void GLAPIENTRY
3813save_TexGenf(GLenum coord, GLenum pname, GLfloat param)
3814{
3815   GLfloat parray[4];
3816   parray[0] = param;
3817   parray[1] = parray[2] = parray[3] = 0.0F;
3818   save_TexGenfv(coord, pname, parray);
3819}
3820
3821
3822static void GLAPIENTRY
3823save_TexGeni(GLenum coord, GLenum pname, GLint param)
3824{
3825   GLint parray[4];
3826   parray[0] = param;
3827   parray[1] = parray[2] = parray[3] = 0;
3828   save_TexGeniv(coord, pname, parray);
3829}
3830
3831
3832static void GLAPIENTRY
3833save_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
3834{
3835   GET_CURRENT_CONTEXT(ctx);
3836   Node *n;
3837   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3838   n = alloc_instruction(ctx, OPCODE_TEXPARAMETER, 6);
3839   if (n) {
3840      n[1].e = target;
3841      n[2].e = pname;
3842      n[3].f = params[0];
3843      n[4].f = params[1];
3844      n[5].f = params[2];
3845      n[6].f = params[3];
3846   }
3847   if (ctx->ExecuteFlag) {
3848      CALL_TexParameterfv(ctx->Exec, (target, pname, params));
3849   }
3850}
3851
3852
3853static void GLAPIENTRY
3854save_TexParameterf(GLenum target, GLenum pname, GLfloat param)
3855{
3856   GLfloat parray[4];
3857   parray[0] = param;
3858   parray[1] = parray[2] = parray[3] = 0.0F;
3859   save_TexParameterfv(target, pname, parray);
3860}
3861
3862
3863static void GLAPIENTRY
3864save_TexParameteri(GLenum target, GLenum pname, GLint param)
3865{
3866   GLfloat fparam[4];
3867   fparam[0] = (GLfloat) param;
3868   fparam[1] = fparam[2] = fparam[3] = 0.0F;
3869   save_TexParameterfv(target, pname, fparam);
3870}
3871
3872
3873static void GLAPIENTRY
3874save_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
3875{
3876   GLfloat fparam[4];
3877   fparam[0] = (GLfloat) params[0];
3878   fparam[1] = fparam[2] = fparam[3] = 0.0F;
3879   save_TexParameterfv(target, pname, fparam);
3880}
3881
3882
3883static void GLAPIENTRY
3884save_TexImage1D(GLenum target,
3885                GLint level, GLint components,
3886                GLsizei width, GLint border,
3887                GLenum format, GLenum type, const GLvoid * pixels)
3888{
3889   GET_CURRENT_CONTEXT(ctx);
3890   if (target == GL_PROXY_TEXTURE_1D) {
3891      /* don't compile, execute immediately */
3892      CALL_TexImage1D(ctx->Exec, (target, level, components, width,
3893                                  border, format, type, pixels));
3894   }
3895   else {
3896      Node *n;
3897      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3898      n = alloc_instruction(ctx, OPCODE_TEX_IMAGE1D, 7 + POINTER_DWORDS);
3899      if (n) {
3900         n[1].e = target;
3901         n[2].i = level;
3902         n[3].i = components;
3903         n[4].i = (GLint) width;
3904         n[5].i = border;
3905         n[6].e = format;
3906         n[7].e = type;
3907         save_pointer(&n[8],
3908                      unpack_image(ctx, 1, width, 1, 1, format, type,
3909                                   pixels, &ctx->Unpack));
3910      }
3911      if (ctx->ExecuteFlag) {
3912         CALL_TexImage1D(ctx->Exec, (target, level, components, width,
3913                                     border, format, type, pixels));
3914      }
3915   }
3916}
3917
3918
3919static void GLAPIENTRY
3920save_TexImage2D(GLenum target,
3921                GLint level, GLint components,
3922                GLsizei width, GLsizei height, GLint border,
3923                GLenum format, GLenum type, const GLvoid * pixels)
3924{
3925   GET_CURRENT_CONTEXT(ctx);
3926   if (target == GL_PROXY_TEXTURE_2D) {
3927      /* don't compile, execute immediately */
3928      CALL_TexImage2D(ctx->Exec, (target, level, components, width,
3929                                  height, border, format, type, pixels));
3930   }
3931   else {
3932      Node *n;
3933      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3934      n = alloc_instruction(ctx, OPCODE_TEX_IMAGE2D, 8 + POINTER_DWORDS);
3935      if (n) {
3936         n[1].e = target;
3937         n[2].i = level;
3938         n[3].i = components;
3939         n[4].i = (GLint) width;
3940         n[5].i = (GLint) height;
3941         n[6].i = border;
3942         n[7].e = format;
3943         n[8].e = type;
3944         save_pointer(&n[9],
3945                      unpack_image(ctx, 2, width, height, 1, format, type,
3946                                   pixels, &ctx->Unpack));
3947      }
3948      if (ctx->ExecuteFlag) {
3949         CALL_TexImage2D(ctx->Exec, (target, level, components, width,
3950                                     height, border, format, type, pixels));
3951      }
3952   }
3953}
3954
3955
3956static void GLAPIENTRY
3957save_TexImage3D(GLenum target,
3958                GLint level, GLint internalFormat,
3959                GLsizei width, GLsizei height, GLsizei depth,
3960                GLint border,
3961                GLenum format, GLenum type, const GLvoid * pixels)
3962{
3963   GET_CURRENT_CONTEXT(ctx);
3964   if (target == GL_PROXY_TEXTURE_3D) {
3965      /* don't compile, execute immediately */
3966      CALL_TexImage3D(ctx->Exec, (target, level, internalFormat, width,
3967                                  height, depth, border, format, type,
3968                                  pixels));
3969   }
3970   else {
3971      Node *n;
3972      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3973      n = alloc_instruction(ctx, OPCODE_TEX_IMAGE3D, 9 + POINTER_DWORDS);
3974      if (n) {
3975         n[1].e = target;
3976         n[2].i = level;
3977         n[3].i = (GLint) internalFormat;
3978         n[4].i = (GLint) width;
3979         n[5].i = (GLint) height;
3980         n[6].i = (GLint) depth;
3981         n[7].i = border;
3982         n[8].e = format;
3983         n[9].e = type;
3984         save_pointer(&n[10],
3985                      unpack_image(ctx, 3, width, height, depth, format, type,
3986                                   pixels, &ctx->Unpack));
3987      }
3988      if (ctx->ExecuteFlag) {
3989         CALL_TexImage3D(ctx->Exec, (target, level, internalFormat, width,
3990                                     height, depth, border, format, type,
3991                                     pixels));
3992      }
3993   }
3994}
3995
3996
3997static void GLAPIENTRY
3998save_TexSubImage1D(GLenum target, GLint level, GLint xoffset,
3999                   GLsizei width, GLenum format, GLenum type,
4000                   const GLvoid * pixels)
4001{
4002   GET_CURRENT_CONTEXT(ctx);
4003   Node *n;
4004
4005   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4006
4007   n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE1D, 6 + POINTER_DWORDS);
4008   if (n) {
4009      n[1].e = target;
4010      n[2].i = level;
4011      n[3].i = xoffset;
4012      n[4].i = (GLint) width;
4013      n[5].e = format;
4014      n[6].e = type;
4015      save_pointer(&n[7],
4016                   unpack_image(ctx, 1, width, 1, 1, format, type,
4017                                pixels, &ctx->Unpack));
4018   }
4019   if (ctx->ExecuteFlag) {
4020      CALL_TexSubImage1D(ctx->Exec, (target, level, xoffset, width,
4021                                     format, type, pixels));
4022   }
4023}
4024
4025
4026static void GLAPIENTRY
4027save_TexSubImage2D(GLenum target, GLint level,
4028                   GLint xoffset, GLint yoffset,
4029                   GLsizei width, GLsizei height,
4030                   GLenum format, GLenum type, const GLvoid * pixels)
4031{
4032   GET_CURRENT_CONTEXT(ctx);
4033   Node *n;
4034
4035   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4036
4037   n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE2D, 8 + POINTER_DWORDS);
4038   if (n) {
4039      n[1].e = target;
4040      n[2].i = level;
4041      n[3].i = xoffset;
4042      n[4].i = yoffset;
4043      n[5].i = (GLint) width;
4044      n[6].i = (GLint) height;
4045      n[7].e = format;
4046      n[8].e = type;
4047      save_pointer(&n[9],
4048                   unpack_image(ctx, 2, width, height, 1, format, type,
4049                                pixels, &ctx->Unpack));
4050   }
4051   if (ctx->ExecuteFlag) {
4052      CALL_TexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset,
4053                                     width, height, format, type, pixels));
4054   }
4055}
4056
4057
4058static void GLAPIENTRY
4059save_TexSubImage3D(GLenum target, GLint level,
4060                   GLint xoffset, GLint yoffset, GLint zoffset,
4061                   GLsizei width, GLsizei height, GLsizei depth,
4062                   GLenum format, GLenum type, const GLvoid * pixels)
4063{
4064   GET_CURRENT_CONTEXT(ctx);
4065   Node *n;
4066
4067   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4068
4069   n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE3D, 10 + POINTER_DWORDS);
4070   if (n) {
4071      n[1].e = target;
4072      n[2].i = level;
4073      n[3].i = xoffset;
4074      n[4].i = yoffset;
4075      n[5].i = zoffset;
4076      n[6].i = (GLint) width;
4077      n[7].i = (GLint) height;
4078      n[8].i = (GLint) depth;
4079      n[9].e = format;
4080      n[10].e = type;
4081      save_pointer(&n[11],
4082                   unpack_image(ctx, 3, width, height, depth, format, type,
4083                                pixels, &ctx->Unpack));
4084   }
4085   if (ctx->ExecuteFlag) {
4086      CALL_TexSubImage3D(ctx->Exec, (target, level,
4087                                     xoffset, yoffset, zoffset,
4088                                     width, height, depth, format, type,
4089                                     pixels));
4090   }
4091}
4092
4093
4094static void GLAPIENTRY
4095save_Translatef(GLfloat x, GLfloat y, GLfloat z)
4096{
4097   GET_CURRENT_CONTEXT(ctx);
4098   Node *n;
4099   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4100   n = alloc_instruction(ctx, OPCODE_TRANSLATE, 3);
4101   if (n) {
4102      n[1].f = x;
4103      n[2].f = y;
4104      n[3].f = z;
4105   }
4106   if (ctx->ExecuteFlag) {
4107      CALL_Translatef(ctx->Exec, (x, y, z));
4108   }
4109}
4110
4111
4112static void GLAPIENTRY
4113save_Translated(GLdouble x, GLdouble y, GLdouble z)
4114{
4115   save_Translatef((GLfloat) x, (GLfloat) y, (GLfloat) z);
4116}
4117
4118
4119
4120static void GLAPIENTRY
4121save_Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
4122{
4123   GET_CURRENT_CONTEXT(ctx);
4124   Node *n;
4125   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4126   n = alloc_instruction(ctx, OPCODE_VIEWPORT, 4);
4127   if (n) {
4128      n[1].i = x;
4129      n[2].i = y;
4130      n[3].i = (GLint) width;
4131      n[4].i = (GLint) height;
4132   }
4133   if (ctx->ExecuteFlag) {
4134      CALL_Viewport(ctx->Exec, (x, y, width, height));
4135   }
4136}
4137
4138
4139static void GLAPIENTRY
4140save_WindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4141{
4142   GET_CURRENT_CONTEXT(ctx);
4143   Node *n;
4144   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4145   n = alloc_instruction(ctx, OPCODE_WINDOW_POS, 4);
4146   if (n) {
4147      n[1].f = x;
4148      n[2].f = y;
4149      n[3].f = z;
4150      n[4].f = w;
4151   }
4152   if (ctx->ExecuteFlag) {
4153      CALL_WindowPos4fMESA(ctx->Exec, (x, y, z, w));
4154   }
4155}
4156
4157static void GLAPIENTRY
4158save_WindowPos2dMESA(GLdouble x, GLdouble y)
4159{
4160   save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
4161}
4162
4163static void GLAPIENTRY
4164save_WindowPos2fMESA(GLfloat x, GLfloat y)
4165{
4166   save_WindowPos4fMESA(x, y, 0.0F, 1.0F);
4167}
4168
4169static void GLAPIENTRY
4170save_WindowPos2iMESA(GLint x, GLint y)
4171{
4172   save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
4173}
4174
4175static void GLAPIENTRY
4176save_WindowPos2sMESA(GLshort x, GLshort y)
4177{
4178   save_WindowPos4fMESA(x, y, 0.0F, 1.0F);
4179}
4180
4181static void GLAPIENTRY
4182save_WindowPos3dMESA(GLdouble x, GLdouble y, GLdouble z)
4183{
4184   save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
4185}
4186
4187static void GLAPIENTRY
4188save_WindowPos3fMESA(GLfloat x, GLfloat y, GLfloat z)
4189{
4190   save_WindowPos4fMESA(x, y, z, 1.0F);
4191}
4192
4193static void GLAPIENTRY
4194save_WindowPos3iMESA(GLint x, GLint y, GLint z)
4195{
4196   save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
4197}
4198
4199static void GLAPIENTRY
4200save_WindowPos3sMESA(GLshort x, GLshort y, GLshort z)
4201{
4202   save_WindowPos4fMESA(x, y, z, 1.0F);
4203}
4204
4205static void GLAPIENTRY
4206save_WindowPos4dMESA(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
4207{
4208   save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
4209}
4210
4211static void GLAPIENTRY
4212save_WindowPos4iMESA(GLint x, GLint y, GLint z, GLint w)
4213{
4214   save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
4215}
4216
4217static void GLAPIENTRY
4218save_WindowPos4sMESA(GLshort x, GLshort y, GLshort z, GLshort w)
4219{
4220   save_WindowPos4fMESA(x, y, z, w);
4221}
4222
4223static void GLAPIENTRY
4224save_WindowPos2dvMESA(const GLdouble * v)
4225{
4226   save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
4227}
4228
4229static void GLAPIENTRY
4230save_WindowPos2fvMESA(const GLfloat * v)
4231{
4232   save_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F);
4233}
4234
4235static void GLAPIENTRY
4236save_WindowPos2ivMESA(const GLint * v)
4237{
4238   save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
4239}
4240
4241static void GLAPIENTRY
4242save_WindowPos2svMESA(const GLshort * v)
4243{
4244   save_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F);
4245}
4246
4247static void GLAPIENTRY
4248save_WindowPos3dvMESA(const GLdouble * v)
4249{
4250   save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
4251}
4252
4253static void GLAPIENTRY
4254save_WindowPos3fvMESA(const GLfloat * v)
4255{
4256   save_WindowPos4fMESA(v[0], v[1], v[2], 1.0F);
4257}
4258
4259static void GLAPIENTRY
4260save_WindowPos3ivMESA(const GLint * v)
4261{
4262   save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
4263}
4264
4265static void GLAPIENTRY
4266save_WindowPos3svMESA(const GLshort * v)
4267{
4268   save_WindowPos4fMESA(v[0], v[1], v[2], 1.0F);
4269}
4270
4271static void GLAPIENTRY
4272save_WindowPos4dvMESA(const GLdouble * v)
4273{
4274   save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1],
4275                        (GLfloat) v[2], (GLfloat) v[3]);
4276}
4277
4278static void GLAPIENTRY
4279save_WindowPos4fvMESA(const GLfloat * v)
4280{
4281   save_WindowPos4fMESA(v[0], v[1], v[2], v[3]);
4282}
4283
4284static void GLAPIENTRY
4285save_WindowPos4ivMESA(const GLint * v)
4286{
4287   save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1],
4288                        (GLfloat) v[2], (GLfloat) v[3]);
4289}
4290
4291static void GLAPIENTRY
4292save_WindowPos4svMESA(const GLshort * v)
4293{
4294   save_WindowPos4fMESA(v[0], v[1], v[2], v[3]);
4295}
4296
4297
4298
4299/* GL_ARB_multitexture */
4300static void GLAPIENTRY
4301save_ActiveTextureARB(GLenum target)
4302{
4303   GET_CURRENT_CONTEXT(ctx);
4304   Node *n;
4305   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4306   n = alloc_instruction(ctx, OPCODE_ACTIVE_TEXTURE, 1);
4307   if (n) {
4308      n[1].e = target;
4309   }
4310   if (ctx->ExecuteFlag) {
4311      CALL_ActiveTexture(ctx->Exec, (target));
4312   }
4313}
4314
4315
4316/* GL_ARB_transpose_matrix */
4317
4318static void GLAPIENTRY
4319save_LoadTransposeMatrixdARB(const GLdouble m[16])
4320{
4321   GLfloat tm[16];
4322   _math_transposefd(tm, m);
4323   save_LoadMatrixf(tm);
4324}
4325
4326
4327static void GLAPIENTRY
4328save_LoadTransposeMatrixfARB(const GLfloat m[16])
4329{
4330   GLfloat tm[16];
4331   _math_transposef(tm, m);
4332   save_LoadMatrixf(tm);
4333}
4334
4335
4336static void GLAPIENTRY
4337save_MultTransposeMatrixdARB(const GLdouble m[16])
4338{
4339   GLfloat tm[16];
4340   _math_transposefd(tm, m);
4341   save_MultMatrixf(tm);
4342}
4343
4344
4345static void GLAPIENTRY
4346save_MultTransposeMatrixfARB(const GLfloat m[16])
4347{
4348   GLfloat tm[16];
4349   _math_transposef(tm, m);
4350   save_MultMatrixf(tm);
4351}
4352
4353static GLvoid *copy_data(const GLvoid *data, GLsizei size, const char *func)
4354{
4355   GET_CURRENT_CONTEXT(ctx);
4356   GLvoid *image;
4357
4358   if (!data)
4359      return NULL;
4360
4361   image = malloc(size);
4362   if (!image) {
4363      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
4364      return NULL;
4365   }
4366   memcpy(image, data, size);
4367
4368   return image;
4369}
4370
4371
4372/* GL_ARB_texture_compression */
4373static void GLAPIENTRY
4374save_CompressedTexImage1DARB(GLenum target, GLint level,
4375                             GLenum internalFormat, GLsizei width,
4376                             GLint border, GLsizei imageSize,
4377                             const GLvoid * data)
4378{
4379   GET_CURRENT_CONTEXT(ctx);
4380   if (target == GL_PROXY_TEXTURE_1D) {
4381      /* don't compile, execute immediately */
4382      CALL_CompressedTexImage1D(ctx->Exec, (target, level, internalFormat,
4383                                               width, border, imageSize,
4384                                               data));
4385   }
4386   else {
4387      Node *n;
4388      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4389
4390      n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D,
4391                            6 + POINTER_DWORDS);
4392      if (n) {
4393         n[1].e = target;
4394         n[2].i = level;
4395         n[3].e = internalFormat;
4396         n[4].i = (GLint) width;
4397         n[5].i = border;
4398         n[6].i = imageSize;
4399         save_pointer(&n[7],
4400                      copy_data(data, imageSize, "glCompressedTexImage1DARB"));
4401      }
4402      if (ctx->ExecuteFlag) {
4403         CALL_CompressedTexImage1D(ctx->Exec,
4404                                      (target, level, internalFormat, width,
4405                                       border, imageSize, data));
4406      }
4407   }
4408}
4409
4410
4411static void GLAPIENTRY
4412save_CompressedTexImage2DARB(GLenum target, GLint level,
4413                             GLenum internalFormat, GLsizei width,
4414                             GLsizei height, GLint border, GLsizei imageSize,
4415                             const GLvoid * data)
4416{
4417   GET_CURRENT_CONTEXT(ctx);
4418   if (target == GL_PROXY_TEXTURE_2D) {
4419      /* don't compile, execute immediately */
4420      CALL_CompressedTexImage2D(ctx->Exec, (target, level, internalFormat,
4421                                               width, height, border,
4422                                               imageSize, data));
4423   }
4424   else {
4425      Node *n;
4426      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4427
4428      n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D,
4429                            7 + POINTER_DWORDS);
4430      if (n) {
4431         n[1].e = target;
4432         n[2].i = level;
4433         n[3].e = internalFormat;
4434         n[4].i = (GLint) width;
4435         n[5].i = (GLint) height;
4436         n[6].i = border;
4437         n[7].i = imageSize;
4438         save_pointer(&n[8],
4439                      copy_data(data, imageSize, "glCompressedTexImage2DARB"));
4440      }
4441      if (ctx->ExecuteFlag) {
4442         CALL_CompressedTexImage2D(ctx->Exec,
4443                                      (target, level, internalFormat, width,
4444                                       height, border, imageSize, data));
4445      }
4446   }
4447}
4448
4449
4450static void GLAPIENTRY
4451save_CompressedTexImage3DARB(GLenum target, GLint level,
4452                             GLenum internalFormat, GLsizei width,
4453                             GLsizei height, GLsizei depth, GLint border,
4454                             GLsizei imageSize, const GLvoid * data)
4455{
4456   GET_CURRENT_CONTEXT(ctx);
4457   if (target == GL_PROXY_TEXTURE_3D) {
4458      /* don't compile, execute immediately */
4459      CALL_CompressedTexImage3D(ctx->Exec, (target, level, internalFormat,
4460                                               width, height, depth, border,
4461                                               imageSize, data));
4462   }
4463   else {
4464      Node *n;
4465      ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4466
4467      n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D,
4468                            8 + POINTER_DWORDS);
4469      if (n) {
4470         n[1].e = target;
4471         n[2].i = level;
4472         n[3].e = internalFormat;
4473         n[4].i = (GLint) width;
4474         n[5].i = (GLint) height;
4475         n[6].i = (GLint) depth;
4476         n[7].i = border;
4477         n[8].i = imageSize;
4478         save_pointer(&n[9],
4479                      copy_data(data, imageSize, "glCompressedTexImage3DARB"));
4480      }
4481      if (ctx->ExecuteFlag) {
4482         CALL_CompressedTexImage3D(ctx->Exec,
4483                                      (target, level, internalFormat, width,
4484                                       height, depth, border, imageSize,
4485                                       data));
4486      }
4487   }
4488}
4489
4490
4491static void GLAPIENTRY
4492save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
4493                                GLsizei width, GLenum format,
4494                                GLsizei imageSize, const GLvoid * data)
4495{
4496   Node *n;
4497   GET_CURRENT_CONTEXT(ctx);
4498   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4499
4500   n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D,
4501                         6 + POINTER_DWORDS);
4502   if (n) {
4503      n[1].e = target;
4504      n[2].i = level;
4505      n[3].i = xoffset;
4506      n[4].i = (GLint) width;
4507      n[5].e = format;
4508      n[6].i = imageSize;
4509      save_pointer(&n[7],
4510                   copy_data(data, imageSize, "glCompressedTexSubImage1DARB"));
4511   }
4512   if (ctx->ExecuteFlag) {
4513      CALL_CompressedTexSubImage1D(ctx->Exec, (target, level, xoffset,
4514                                                  width, format, imageSize,
4515                                                  data));
4516   }
4517}
4518
4519
4520static void GLAPIENTRY
4521save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
4522                                GLint yoffset, GLsizei width, GLsizei height,
4523                                GLenum format, GLsizei imageSize,
4524                                const GLvoid * data)
4525{
4526   Node *n;
4527   GET_CURRENT_CONTEXT(ctx);
4528   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4529
4530   n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D,
4531                         8 + POINTER_DWORDS);
4532   if (n) {
4533      n[1].e = target;
4534      n[2].i = level;
4535      n[3].i = xoffset;
4536      n[4].i = yoffset;
4537      n[5].i = (GLint) width;
4538      n[6].i = (GLint) height;
4539      n[7].e = format;
4540      n[8].i = imageSize;
4541      save_pointer(&n[9],
4542                   copy_data(data, imageSize, "glCompressedTexSubImage2DARB"));
4543   }
4544   if (ctx->ExecuteFlag) {
4545      CALL_CompressedTexSubImage2D(ctx->Exec,
4546                                      (target, level, xoffset, yoffset, width,
4547                                       height, format, imageSize, data));
4548   }
4549}
4550
4551
4552static void GLAPIENTRY
4553save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
4554                                GLint yoffset, GLint zoffset, GLsizei width,
4555                                GLsizei height, GLsizei depth, GLenum format,
4556                                GLsizei imageSize, const GLvoid * data)
4557{
4558   Node *n;
4559   GET_CURRENT_CONTEXT(ctx);
4560   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4561
4562   n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D,
4563                         10 + POINTER_DWORDS);
4564   if (n) {
4565      n[1].e = target;
4566      n[2].i = level;
4567      n[3].i = xoffset;
4568      n[4].i = yoffset;
4569      n[5].i = zoffset;
4570      n[6].i = (GLint) width;
4571      n[7].i = (GLint) height;
4572      n[8].i = (GLint) depth;
4573      n[9].e = format;
4574      n[10].i = imageSize;
4575      save_pointer(&n[11],
4576                   copy_data(data, imageSize, "glCompressedTexSubImage3DARB"));
4577   }
4578   if (ctx->ExecuteFlag) {
4579      CALL_CompressedTexSubImage3D(ctx->Exec,
4580                                      (target, level, xoffset, yoffset,
4581                                       zoffset, width, height, depth, format,
4582                                       imageSize, data));
4583   }
4584}
4585
4586
4587/* GL_ARB_multisample */
4588static void GLAPIENTRY
4589save_SampleCoverageARB(GLclampf value, GLboolean invert)
4590{
4591   GET_CURRENT_CONTEXT(ctx);
4592   Node *n;
4593   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4594   n = alloc_instruction(ctx, OPCODE_SAMPLE_COVERAGE, 2);
4595   if (n) {
4596      n[1].f = value;
4597      n[2].b = invert;
4598   }
4599   if (ctx->ExecuteFlag) {
4600      CALL_SampleCoverage(ctx->Exec, (value, invert));
4601   }
4602}
4603
4604
4605/*
4606 * GL_NV_fragment_program
4607 */
4608static void GLAPIENTRY
4609save_BindProgramNV(GLenum target, GLuint id)
4610{
4611   GET_CURRENT_CONTEXT(ctx);
4612   Node *n;
4613   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4614   n = alloc_instruction(ctx, OPCODE_BIND_PROGRAM_NV, 2);
4615   if (n) {
4616      n[1].e = target;
4617      n[2].ui = id;
4618   }
4619   if (ctx->ExecuteFlag) {
4620      CALL_BindProgramARB(ctx->Exec, (target, id));
4621   }
4622}
4623
4624static void GLAPIENTRY
4625save_ProgramEnvParameter4fARB(GLenum target, GLuint index,
4626                              GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4627{
4628   GET_CURRENT_CONTEXT(ctx);
4629   Node *n;
4630   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4631   n = alloc_instruction(ctx, OPCODE_PROGRAM_ENV_PARAMETER_ARB, 6);
4632   if (n) {
4633      n[1].e = target;
4634      n[2].ui = index;
4635      n[3].f = x;
4636      n[4].f = y;
4637      n[5].f = z;
4638      n[6].f = w;
4639   }
4640   if (ctx->ExecuteFlag) {
4641      CALL_ProgramEnvParameter4fARB(ctx->Exec, (target, index, x, y, z, w));
4642   }
4643}
4644
4645
4646static void GLAPIENTRY
4647save_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
4648                               const GLfloat *params)
4649{
4650   save_ProgramEnvParameter4fARB(target, index, params[0], params[1],
4651                                 params[2], params[3]);
4652}
4653
4654
4655static void GLAPIENTRY
4656save_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
4657				const GLfloat * params)
4658{
4659   GET_CURRENT_CONTEXT(ctx);
4660   Node *n;
4661   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4662
4663   if (count > 0) {
4664      GLint i;
4665      const GLfloat * p = params;
4666
4667      for (i = 0 ; i < count ; i++) {
4668	 n = alloc_instruction(ctx, OPCODE_PROGRAM_ENV_PARAMETER_ARB, 6);
4669	 if (n) {
4670	    n[1].e = target;
4671	    n[2].ui = index;
4672	    n[3].f = p[0];
4673	    n[4].f = p[1];
4674	    n[5].f = p[2];
4675	    n[6].f = p[3];
4676	    p += 4;
4677	 }
4678      }
4679   }
4680
4681   if (ctx->ExecuteFlag) {
4682      CALL_ProgramEnvParameters4fvEXT(ctx->Exec, (target, index, count, params));
4683   }
4684}
4685
4686
4687static void GLAPIENTRY
4688save_ProgramEnvParameter4dARB(GLenum target, GLuint index,
4689                              GLdouble x, GLdouble y, GLdouble z, GLdouble w)
4690{
4691   save_ProgramEnvParameter4fARB(target, index,
4692                                 (GLfloat) x,
4693                                 (GLfloat) y, (GLfloat) z, (GLfloat) w);
4694}
4695
4696
4697static void GLAPIENTRY
4698save_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
4699                               const GLdouble *params)
4700{
4701   save_ProgramEnvParameter4fARB(target, index,
4702                                 (GLfloat) params[0],
4703                                 (GLfloat) params[1],
4704                                 (GLfloat) params[2], (GLfloat) params[3]);
4705}
4706
4707
4708static void GLAPIENTRY
4709save_ProgramLocalParameter4fARB(GLenum target, GLuint index,
4710                                GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4711{
4712   GET_CURRENT_CONTEXT(ctx);
4713   Node *n;
4714   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4715   n = alloc_instruction(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6);
4716   if (n) {
4717      n[1].e = target;
4718      n[2].ui = index;
4719      n[3].f = x;
4720      n[4].f = y;
4721      n[5].f = z;
4722      n[6].f = w;
4723   }
4724   if (ctx->ExecuteFlag) {
4725      CALL_ProgramLocalParameter4fARB(ctx->Exec, (target, index, x, y, z, w));
4726   }
4727}
4728
4729
4730static void GLAPIENTRY
4731save_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
4732                                 const GLfloat *params)
4733{
4734   GET_CURRENT_CONTEXT(ctx);
4735   Node *n;
4736   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4737   n = alloc_instruction(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6);
4738   if (n) {
4739      n[1].e = target;
4740      n[2].ui = index;
4741      n[3].f = params[0];
4742      n[4].f = params[1];
4743      n[5].f = params[2];
4744      n[6].f = params[3];
4745   }
4746   if (ctx->ExecuteFlag) {
4747      CALL_ProgramLocalParameter4fvARB(ctx->Exec, (target, index, params));
4748   }
4749}
4750
4751
4752static void GLAPIENTRY
4753save_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
4754				  const GLfloat *params)
4755{
4756   GET_CURRENT_CONTEXT(ctx);
4757   Node *n;
4758   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4759
4760   if (count > 0) {
4761      GLint i;
4762      const GLfloat * p = params;
4763
4764      for (i = 0 ; i < count ; i++) {
4765	 n = alloc_instruction(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6);
4766	 if (n) {
4767	    n[1].e = target;
4768	    n[2].ui = index;
4769	    n[3].f = p[0];
4770	    n[4].f = p[1];
4771	    n[5].f = p[2];
4772	    n[6].f = p[3];
4773	    p += 4;
4774	 }
4775      }
4776   }
4777
4778   if (ctx->ExecuteFlag) {
4779      CALL_ProgramLocalParameters4fvEXT(ctx->Exec, (target, index, count, params));
4780   }
4781}
4782
4783
4784static void GLAPIENTRY
4785save_ProgramLocalParameter4dARB(GLenum target, GLuint index,
4786                                GLdouble x, GLdouble y,
4787                                GLdouble z, GLdouble w)
4788{
4789   GET_CURRENT_CONTEXT(ctx);
4790   Node *n;
4791   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4792   n = alloc_instruction(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6);
4793   if (n) {
4794      n[1].e = target;
4795      n[2].ui = index;
4796      n[3].f = (GLfloat) x;
4797      n[4].f = (GLfloat) y;
4798      n[5].f = (GLfloat) z;
4799      n[6].f = (GLfloat) w;
4800   }
4801   if (ctx->ExecuteFlag) {
4802      CALL_ProgramLocalParameter4dARB(ctx->Exec, (target, index, x, y, z, w));
4803   }
4804}
4805
4806
4807static void GLAPIENTRY
4808save_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
4809                                 const GLdouble *params)
4810{
4811   GET_CURRENT_CONTEXT(ctx);
4812   Node *n;
4813   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4814   n = alloc_instruction(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6);
4815   if (n) {
4816      n[1].e = target;
4817      n[2].ui = index;
4818      n[3].f = (GLfloat) params[0];
4819      n[4].f = (GLfloat) params[1];
4820      n[5].f = (GLfloat) params[2];
4821      n[6].f = (GLfloat) params[3];
4822   }
4823   if (ctx->ExecuteFlag) {
4824      CALL_ProgramLocalParameter4dvARB(ctx->Exec, (target, index, params));
4825   }
4826}
4827
4828
4829/* GL_EXT_stencil_two_side */
4830static void GLAPIENTRY
4831save_ActiveStencilFaceEXT(GLenum face)
4832{
4833   GET_CURRENT_CONTEXT(ctx);
4834   Node *n;
4835   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4836   n = alloc_instruction(ctx, OPCODE_ACTIVE_STENCIL_FACE_EXT, 1);
4837   if (n) {
4838      n[1].e = face;
4839   }
4840   if (ctx->ExecuteFlag) {
4841      CALL_ActiveStencilFaceEXT(ctx->Exec, (face));
4842   }
4843}
4844
4845
4846/* GL_EXT_depth_bounds_test */
4847static void GLAPIENTRY
4848save_DepthBoundsEXT(GLclampd zmin, GLclampd zmax)
4849{
4850   GET_CURRENT_CONTEXT(ctx);
4851   Node *n;
4852   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4853   n = alloc_instruction(ctx, OPCODE_DEPTH_BOUNDS_EXT, 2);
4854   if (n) {
4855      n[1].f = (GLfloat) zmin;
4856      n[2].f = (GLfloat) zmax;
4857   }
4858   if (ctx->ExecuteFlag) {
4859      CALL_DepthBoundsEXT(ctx->Exec, (zmin, zmax));
4860   }
4861}
4862
4863
4864
4865static void GLAPIENTRY
4866save_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
4867                      const GLvoid * string)
4868{
4869   GET_CURRENT_CONTEXT(ctx);
4870   Node *n;
4871
4872   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4873
4874   n = alloc_instruction(ctx, OPCODE_PROGRAM_STRING_ARB, 3 + POINTER_DWORDS);
4875   if (n) {
4876      GLubyte *programCopy = malloc(len);
4877      if (!programCopy) {
4878         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
4879         return;
4880      }
4881      memcpy(programCopy, string, len);
4882      n[1].e = target;
4883      n[2].e = format;
4884      n[3].i = len;
4885      save_pointer(&n[4], programCopy);
4886   }
4887   if (ctx->ExecuteFlag) {
4888      CALL_ProgramStringARB(ctx->Exec, (target, format, len, string));
4889   }
4890}
4891
4892
4893static void GLAPIENTRY
4894save_BeginQueryARB(GLenum target, GLuint id)
4895{
4896   GET_CURRENT_CONTEXT(ctx);
4897   Node *n;
4898   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4899   n = alloc_instruction(ctx, OPCODE_BEGIN_QUERY_ARB, 2);
4900   if (n) {
4901      n[1].e = target;
4902      n[2].ui = id;
4903   }
4904   if (ctx->ExecuteFlag) {
4905      CALL_BeginQuery(ctx->Exec, (target, id));
4906   }
4907}
4908
4909static void GLAPIENTRY
4910save_EndQueryARB(GLenum target)
4911{
4912   GET_CURRENT_CONTEXT(ctx);
4913   Node *n;
4914   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4915   n = alloc_instruction(ctx, OPCODE_END_QUERY_ARB, 1);
4916   if (n) {
4917      n[1].e = target;
4918   }
4919   if (ctx->ExecuteFlag) {
4920      CALL_EndQuery(ctx->Exec, (target));
4921   }
4922}
4923
4924static void GLAPIENTRY
4925save_QueryCounter(GLuint id, GLenum target)
4926{
4927   GET_CURRENT_CONTEXT(ctx);
4928   Node *n;
4929   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4930   n = alloc_instruction(ctx, OPCODE_QUERY_COUNTER, 2);
4931   if (n) {
4932      n[1].ui = id;
4933      n[2].e = target;
4934   }
4935   if (ctx->ExecuteFlag) {
4936      CALL_QueryCounter(ctx->Exec, (id, target));
4937   }
4938}
4939
4940static void GLAPIENTRY
4941save_BeginQueryIndexed(GLenum target, GLuint index, GLuint id)
4942{
4943   GET_CURRENT_CONTEXT(ctx);
4944   Node *n;
4945   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4946   n = alloc_instruction(ctx, OPCODE_BEGIN_QUERY_INDEXED, 3);
4947   if (n) {
4948      n[1].e = target;
4949      n[2].ui = index;
4950      n[3].ui = id;
4951   }
4952   if (ctx->ExecuteFlag) {
4953      CALL_BeginQueryIndexed(ctx->Exec, (target, index, id));
4954   }
4955}
4956
4957static void GLAPIENTRY
4958save_EndQueryIndexed(GLenum target, GLuint index)
4959{
4960   GET_CURRENT_CONTEXT(ctx);
4961   Node *n;
4962   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4963   n = alloc_instruction(ctx, OPCODE_END_QUERY_INDEXED, 2);
4964   if (n) {
4965      n[1].e = target;
4966      n[2].ui = index;
4967   }
4968   if (ctx->ExecuteFlag) {
4969      CALL_EndQueryIndexed(ctx->Exec, (target, index));
4970   }
4971}
4972
4973
4974static void GLAPIENTRY
4975save_DrawBuffersARB(GLsizei count, const GLenum * buffers)
4976{
4977   GET_CURRENT_CONTEXT(ctx);
4978   Node *n;
4979   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
4980   n = alloc_instruction(ctx, OPCODE_DRAW_BUFFERS_ARB, 1 + MAX_DRAW_BUFFERS);
4981   if (n) {
4982      GLint i;
4983      n[1].i = count;
4984      if (count > MAX_DRAW_BUFFERS)
4985         count = MAX_DRAW_BUFFERS;
4986      for (i = 0; i < count; i++) {
4987         n[2 + i].e = buffers[i];
4988      }
4989   }
4990   if (ctx->ExecuteFlag) {
4991      CALL_DrawBuffers(ctx->Exec, (count, buffers));
4992   }
4993}
4994
4995static void GLAPIENTRY
4996save_BindFragmentShaderATI(GLuint id)
4997{
4998   GET_CURRENT_CONTEXT(ctx);
4999   Node *n;
5000
5001   n = alloc_instruction(ctx, OPCODE_BIND_FRAGMENT_SHADER_ATI, 1);
5002   if (n) {
5003      n[1].ui = id;
5004   }
5005   if (ctx->ExecuteFlag) {
5006      CALL_BindFragmentShaderATI(ctx->Exec, (id));
5007   }
5008}
5009
5010static void GLAPIENTRY
5011save_SetFragmentShaderConstantATI(GLuint dst, const GLfloat *value)
5012{
5013   GET_CURRENT_CONTEXT(ctx);
5014   Node *n;
5015
5016   n = alloc_instruction(ctx, OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI, 5);
5017   if (n) {
5018      n[1].ui = dst;
5019      n[2].f = value[0];
5020      n[3].f = value[1];
5021      n[4].f = value[2];
5022      n[5].f = value[3];
5023   }
5024   if (ctx->ExecuteFlag) {
5025      CALL_SetFragmentShaderConstantATI(ctx->Exec, (dst, value));
5026   }
5027}
5028
5029static void GLAPIENTRY
5030save_Attr1fNV(GLenum attr, GLfloat x)
5031{
5032   GET_CURRENT_CONTEXT(ctx);
5033   Node *n;
5034   SAVE_FLUSH_VERTICES(ctx);
5035   n = alloc_instruction(ctx, OPCODE_ATTR_1F_NV, 2);
5036   if (n) {
5037      n[1].e = attr;
5038      n[2].f = x;
5039   }
5040
5041   ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
5042   ctx->ListState.ActiveAttribSize[attr] = 1;
5043   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, 0, 0, 1);
5044
5045   if (ctx->ExecuteFlag) {
5046      CALL_VertexAttrib1fNV(ctx->Exec, (attr, x));
5047   }
5048}
5049
5050static void GLAPIENTRY
5051save_Attr2fNV(GLenum attr, GLfloat x, GLfloat y)
5052{
5053   GET_CURRENT_CONTEXT(ctx);
5054   Node *n;
5055   SAVE_FLUSH_VERTICES(ctx);
5056   n = alloc_instruction(ctx, OPCODE_ATTR_2F_NV, 3);
5057   if (n) {
5058      n[1].e = attr;
5059      n[2].f = x;
5060      n[3].f = y;
5061   }
5062
5063   ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
5064   ctx->ListState.ActiveAttribSize[attr] = 2;
5065   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, 0, 1);
5066
5067   if (ctx->ExecuteFlag) {
5068      CALL_VertexAttrib2fNV(ctx->Exec, (attr, x, y));
5069   }
5070}
5071
5072static void GLAPIENTRY
5073save_Attr3fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z)
5074{
5075   GET_CURRENT_CONTEXT(ctx);
5076   Node *n;
5077   SAVE_FLUSH_VERTICES(ctx);
5078   n = alloc_instruction(ctx, OPCODE_ATTR_3F_NV, 4);
5079   if (n) {
5080      n[1].e = attr;
5081      n[2].f = x;
5082      n[3].f = y;
5083      n[4].f = z;
5084   }
5085
5086   ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
5087   ctx->ListState.ActiveAttribSize[attr] = 3;
5088   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, 1);
5089
5090   if (ctx->ExecuteFlag) {
5091      CALL_VertexAttrib3fNV(ctx->Exec, (attr, x, y, z));
5092   }
5093}
5094
5095static void GLAPIENTRY
5096save_Attr4fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5097{
5098   GET_CURRENT_CONTEXT(ctx);
5099   Node *n;
5100   SAVE_FLUSH_VERTICES(ctx);
5101   n = alloc_instruction(ctx, OPCODE_ATTR_4F_NV, 5);
5102   if (n) {
5103      n[1].e = attr;
5104      n[2].f = x;
5105      n[3].f = y;
5106      n[4].f = z;
5107      n[5].f = w;
5108   }
5109
5110   ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
5111   ctx->ListState.ActiveAttribSize[attr] = 4;
5112   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, w);
5113
5114   if (ctx->ExecuteFlag) {
5115      CALL_VertexAttrib4fNV(ctx->Exec, (attr, x, y, z, w));
5116   }
5117}
5118
5119
5120static void GLAPIENTRY
5121save_Attr1fARB(GLenum attr, GLfloat x)
5122{
5123   GET_CURRENT_CONTEXT(ctx);
5124   Node *n;
5125   SAVE_FLUSH_VERTICES(ctx);
5126   n = alloc_instruction(ctx, OPCODE_ATTR_1F_ARB, 2);
5127   if (n) {
5128      n[1].e = attr;
5129      n[2].f = x;
5130   }
5131
5132   ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
5133   ctx->ListState.ActiveAttribSize[attr] = 1;
5134   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, 0, 0, 1);
5135
5136   if (ctx->ExecuteFlag) {
5137      CALL_VertexAttrib1fARB(ctx->Exec, (attr, x));
5138   }
5139}
5140
5141static void GLAPIENTRY
5142save_Attr2fARB(GLenum attr, GLfloat x, GLfloat y)
5143{
5144   GET_CURRENT_CONTEXT(ctx);
5145   Node *n;
5146   SAVE_FLUSH_VERTICES(ctx);
5147   n = alloc_instruction(ctx, OPCODE_ATTR_2F_ARB, 3);
5148   if (n) {
5149      n[1].e = attr;
5150      n[2].f = x;
5151      n[3].f = y;
5152   }
5153
5154   ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
5155   ctx->ListState.ActiveAttribSize[attr] = 2;
5156   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, 0, 1);
5157
5158   if (ctx->ExecuteFlag) {
5159      CALL_VertexAttrib2fARB(ctx->Exec, (attr, x, y));
5160   }
5161}
5162
5163static void GLAPIENTRY
5164save_Attr3fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z)
5165{
5166   GET_CURRENT_CONTEXT(ctx);
5167   Node *n;
5168   SAVE_FLUSH_VERTICES(ctx);
5169   n = alloc_instruction(ctx, OPCODE_ATTR_3F_ARB, 4);
5170   if (n) {
5171      n[1].e = attr;
5172      n[2].f = x;
5173      n[3].f = y;
5174      n[4].f = z;
5175   }
5176
5177   ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
5178   ctx->ListState.ActiveAttribSize[attr] = 3;
5179   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, 1);
5180
5181   if (ctx->ExecuteFlag) {
5182      CALL_VertexAttrib3fARB(ctx->Exec, (attr, x, y, z));
5183   }
5184}
5185
5186static void GLAPIENTRY
5187save_Attr4fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5188{
5189   GET_CURRENT_CONTEXT(ctx);
5190   Node *n;
5191   SAVE_FLUSH_VERTICES(ctx);
5192   n = alloc_instruction(ctx, OPCODE_ATTR_4F_ARB, 5);
5193   if (n) {
5194      n[1].e = attr;
5195      n[2].f = x;
5196      n[3].f = y;
5197      n[4].f = z;
5198      n[5].f = w;
5199   }
5200
5201   ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
5202   ctx->ListState.ActiveAttribSize[attr] = 4;
5203   ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, w);
5204
5205   if (ctx->ExecuteFlag) {
5206      CALL_VertexAttrib4fARB(ctx->Exec, (attr, x, y, z, w));
5207   }
5208}
5209
5210
5211static void GLAPIENTRY
5212save_EvalCoord1f(GLfloat x)
5213{
5214   GET_CURRENT_CONTEXT(ctx);
5215   Node *n;
5216   SAVE_FLUSH_VERTICES(ctx);
5217   n = alloc_instruction(ctx, OPCODE_EVAL_C1, 1);
5218   if (n) {
5219      n[1].f = x;
5220   }
5221   if (ctx->ExecuteFlag) {
5222      CALL_EvalCoord1f(ctx->Exec, (x));
5223   }
5224}
5225
5226static void GLAPIENTRY
5227save_EvalCoord1fv(const GLfloat * v)
5228{
5229   save_EvalCoord1f(v[0]);
5230}
5231
5232static void GLAPIENTRY
5233save_EvalCoord2f(GLfloat x, GLfloat y)
5234{
5235   GET_CURRENT_CONTEXT(ctx);
5236   Node *n;
5237   SAVE_FLUSH_VERTICES(ctx);
5238   n = alloc_instruction(ctx, OPCODE_EVAL_C2, 2);
5239   if (n) {
5240      n[1].f = x;
5241      n[2].f = y;
5242   }
5243   if (ctx->ExecuteFlag) {
5244      CALL_EvalCoord2f(ctx->Exec, (x, y));
5245   }
5246}
5247
5248static void GLAPIENTRY
5249save_EvalCoord2fv(const GLfloat * v)
5250{
5251   save_EvalCoord2f(v[0], v[1]);
5252}
5253
5254
5255static void GLAPIENTRY
5256save_EvalPoint1(GLint x)
5257{
5258   GET_CURRENT_CONTEXT(ctx);
5259   Node *n;
5260   SAVE_FLUSH_VERTICES(ctx);
5261   n = alloc_instruction(ctx, OPCODE_EVAL_P1, 1);
5262   if (n) {
5263      n[1].i = x;
5264   }
5265   if (ctx->ExecuteFlag) {
5266      CALL_EvalPoint1(ctx->Exec, (x));
5267   }
5268}
5269
5270static void GLAPIENTRY
5271save_EvalPoint2(GLint x, GLint y)
5272{
5273   GET_CURRENT_CONTEXT(ctx);
5274   Node *n;
5275   SAVE_FLUSH_VERTICES(ctx);
5276   n = alloc_instruction(ctx, OPCODE_EVAL_P2, 2);
5277   if (n) {
5278      n[1].i = x;
5279      n[2].i = y;
5280   }
5281   if (ctx->ExecuteFlag) {
5282      CALL_EvalPoint2(ctx->Exec, (x, y));
5283   }
5284}
5285
5286static void GLAPIENTRY
5287save_Indexf(GLfloat x)
5288{
5289   save_Attr1fNV(VERT_ATTRIB_COLOR_INDEX, x);
5290}
5291
5292static void GLAPIENTRY
5293save_Indexfv(const GLfloat * v)
5294{
5295   save_Attr1fNV(VERT_ATTRIB_COLOR_INDEX, v[0]);
5296}
5297
5298static void GLAPIENTRY
5299save_EdgeFlag(GLboolean x)
5300{
5301   save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? 1.0f : 0.0f);
5302}
5303
5304
5305/**
5306 * Compare 'count' elements of vectors 'a' and 'b'.
5307 * \return GL_TRUE if equal, GL_FALSE if different.
5308 */
5309static inline GLboolean
5310compare_vec(const GLfloat *a, const GLfloat *b, GLuint count)
5311{
5312   return memcmp( a, b, count * sizeof(GLfloat) ) == 0;
5313}
5314
5315
5316/**
5317 * This glMaterial function is used for glMaterial calls that are outside
5318 * a glBegin/End pair.  For glMaterial inside glBegin/End, see the VBO code.
5319 */
5320static void GLAPIENTRY
5321save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
5322{
5323   GET_CURRENT_CONTEXT(ctx);
5324   Node *n;
5325   int args, i;
5326   GLuint bitmask;
5327
5328   switch (face) {
5329   case GL_BACK:
5330   case GL_FRONT:
5331   case GL_FRONT_AND_BACK:
5332      break;
5333   default:
5334      _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(face)");
5335      return;
5336   }
5337
5338   switch (pname) {
5339   case GL_EMISSION:
5340   case GL_AMBIENT:
5341   case GL_DIFFUSE:
5342   case GL_SPECULAR:
5343   case GL_AMBIENT_AND_DIFFUSE:
5344      args = 4;
5345      break;
5346   case GL_SHININESS:
5347      args = 1;
5348      break;
5349   case GL_COLOR_INDEXES:
5350      args = 3;
5351      break;
5352   default:
5353      _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(pname)");
5354      return;
5355   }
5356
5357   if (ctx->ExecuteFlag) {
5358      CALL_Materialfv(ctx->Exec, (face, pname, param));
5359   }
5360
5361   bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, NULL);
5362
5363   /* Try to eliminate redundant statechanges.  Because it is legal to
5364    * call glMaterial even inside begin/end calls, don't need to worry
5365    * about ctx->Driver.CurrentSavePrimitive here.
5366    */
5367   for (i = 0; i < MAT_ATTRIB_MAX; i++) {
5368      if (bitmask & (1 << i)) {
5369         if (ctx->ListState.ActiveMaterialSize[i] == args &&
5370             compare_vec(ctx->ListState.CurrentMaterial[i], param, args)) {
5371            /* no change in material value */
5372            bitmask &= ~(1 << i);
5373         }
5374         else {
5375            ctx->ListState.ActiveMaterialSize[i] = args;
5376            COPY_SZ_4V(ctx->ListState.CurrentMaterial[i], args, param);
5377         }
5378      }
5379   }
5380
5381   /* If this call has no effect, return early */
5382   if (bitmask == 0)
5383      return;
5384
5385   SAVE_FLUSH_VERTICES(ctx);
5386
5387   n = alloc_instruction(ctx, OPCODE_MATERIAL, 6);
5388   if (n) {
5389      n[1].e = face;
5390      n[2].e = pname;
5391      for (i = 0; i < args; i++)
5392         n[3 + i].f = param[i];
5393   }
5394}
5395
5396static void GLAPIENTRY
5397save_Begin(GLenum mode)
5398{
5399   GET_CURRENT_CONTEXT(ctx);
5400
5401   if (!_mesa_is_valid_prim_mode(ctx, mode)) {
5402      /* compile this error into the display list */
5403      _mesa_compile_error(ctx, GL_INVALID_ENUM, "glBegin(mode)");
5404   }
5405   else if (_mesa_inside_dlist_begin_end(ctx)) {
5406      /* compile this error into the display list */
5407      _mesa_compile_error(ctx, GL_INVALID_OPERATION, "recursive glBegin");
5408   }
5409   else {
5410      Node *n;
5411
5412      ctx->Driver.CurrentSavePrimitive = mode;
5413
5414      /* Give the driver an opportunity to hook in an optimized
5415       * display list compiler.
5416       */
5417      if (ctx->Driver.NotifySaveBegin(ctx, mode))
5418         return;
5419
5420      SAVE_FLUSH_VERTICES(ctx);
5421      n = alloc_instruction(ctx, OPCODE_BEGIN, 1);
5422      if (n) {
5423         n[1].e = mode;
5424      }
5425
5426      if (ctx->ExecuteFlag) {
5427         CALL_Begin(ctx->Exec, (mode));
5428      }
5429   }
5430}
5431
5432static void GLAPIENTRY
5433save_End(void)
5434{
5435   GET_CURRENT_CONTEXT(ctx);
5436   SAVE_FLUSH_VERTICES(ctx);
5437   (void) alloc_instruction(ctx, OPCODE_END, 0);
5438   ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
5439   if (ctx->ExecuteFlag) {
5440      CALL_End(ctx->Exec, ());
5441   }
5442}
5443
5444static void GLAPIENTRY
5445save_Rectf(GLfloat a, GLfloat b, GLfloat c, GLfloat d)
5446{
5447   GET_CURRENT_CONTEXT(ctx);
5448   Node *n;
5449   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5450   n = alloc_instruction(ctx, OPCODE_RECTF, 4);
5451   if (n) {
5452      n[1].f = a;
5453      n[2].f = b;
5454      n[3].f = c;
5455      n[4].f = d;
5456   }
5457   if (ctx->ExecuteFlag) {
5458      CALL_Rectf(ctx->Exec, (a, b, c, d));
5459   }
5460}
5461
5462
5463static void GLAPIENTRY
5464save_Vertex2f(GLfloat x, GLfloat y)
5465{
5466   save_Attr2fNV(VERT_ATTRIB_POS, x, y);
5467}
5468
5469static void GLAPIENTRY
5470save_Vertex2fv(const GLfloat * v)
5471{
5472   save_Attr2fNV(VERT_ATTRIB_POS, v[0], v[1]);
5473}
5474
5475static void GLAPIENTRY
5476save_Vertex3f(GLfloat x, GLfloat y, GLfloat z)
5477{
5478   save_Attr3fNV(VERT_ATTRIB_POS, x, y, z);
5479}
5480
5481static void GLAPIENTRY
5482save_Vertex3fv(const GLfloat * v)
5483{
5484   save_Attr3fNV(VERT_ATTRIB_POS, v[0], v[1], v[2]);
5485}
5486
5487static void GLAPIENTRY
5488save_Vertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5489{
5490   save_Attr4fNV(VERT_ATTRIB_POS, x, y, z, w);
5491}
5492
5493static void GLAPIENTRY
5494save_Vertex4fv(const GLfloat * v)
5495{
5496   save_Attr4fNV(VERT_ATTRIB_POS, v[0], v[1], v[2], v[3]);
5497}
5498
5499static void GLAPIENTRY
5500save_TexCoord1f(GLfloat x)
5501{
5502   save_Attr1fNV(VERT_ATTRIB_TEX0, x);
5503}
5504
5505static void GLAPIENTRY
5506save_TexCoord1fv(const GLfloat * v)
5507{
5508   save_Attr1fNV(VERT_ATTRIB_TEX0, v[0]);
5509}
5510
5511static void GLAPIENTRY
5512save_TexCoord2f(GLfloat x, GLfloat y)
5513{
5514   save_Attr2fNV(VERT_ATTRIB_TEX0, x, y);
5515}
5516
5517static void GLAPIENTRY
5518save_TexCoord2fv(const GLfloat * v)
5519{
5520   save_Attr2fNV(VERT_ATTRIB_TEX0, v[0], v[1]);
5521}
5522
5523static void GLAPIENTRY
5524save_TexCoord3f(GLfloat x, GLfloat y, GLfloat z)
5525{
5526   save_Attr3fNV(VERT_ATTRIB_TEX0, x, y, z);
5527}
5528
5529static void GLAPIENTRY
5530save_TexCoord3fv(const GLfloat * v)
5531{
5532   save_Attr3fNV(VERT_ATTRIB_TEX0, v[0], v[1], v[2]);
5533}
5534
5535static void GLAPIENTRY
5536save_TexCoord4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5537{
5538   save_Attr4fNV(VERT_ATTRIB_TEX0, x, y, z, w);
5539}
5540
5541static void GLAPIENTRY
5542save_TexCoord4fv(const GLfloat * v)
5543{
5544   save_Attr4fNV(VERT_ATTRIB_TEX0, v[0], v[1], v[2], v[3]);
5545}
5546
5547static void GLAPIENTRY
5548save_Normal3f(GLfloat x, GLfloat y, GLfloat z)
5549{
5550   save_Attr3fNV(VERT_ATTRIB_NORMAL, x, y, z);
5551}
5552
5553static void GLAPIENTRY
5554save_Normal3fv(const GLfloat * v)
5555{
5556   save_Attr3fNV(VERT_ATTRIB_NORMAL, v[0], v[1], v[2]);
5557}
5558
5559static void GLAPIENTRY
5560save_FogCoordfEXT(GLfloat x)
5561{
5562   save_Attr1fNV(VERT_ATTRIB_FOG, x);
5563}
5564
5565static void GLAPIENTRY
5566save_FogCoordfvEXT(const GLfloat * v)
5567{
5568   save_Attr1fNV(VERT_ATTRIB_FOG, v[0]);
5569}
5570
5571static void GLAPIENTRY
5572save_Color3f(GLfloat x, GLfloat y, GLfloat z)
5573{
5574   save_Attr3fNV(VERT_ATTRIB_COLOR0, x, y, z);
5575}
5576
5577static void GLAPIENTRY
5578save_Color3fv(const GLfloat * v)
5579{
5580   save_Attr3fNV(VERT_ATTRIB_COLOR0, v[0], v[1], v[2]);
5581}
5582
5583static void GLAPIENTRY
5584save_Color4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5585{
5586   save_Attr4fNV(VERT_ATTRIB_COLOR0, x, y, z, w);
5587}
5588
5589static void GLAPIENTRY
5590save_Color4fv(const GLfloat * v)
5591{
5592   save_Attr4fNV(VERT_ATTRIB_COLOR0, v[0], v[1], v[2], v[3]);
5593}
5594
5595static void GLAPIENTRY
5596save_SecondaryColor3fEXT(GLfloat x, GLfloat y, GLfloat z)
5597{
5598   save_Attr3fNV(VERT_ATTRIB_COLOR1, x, y, z);
5599}
5600
5601static void GLAPIENTRY
5602save_SecondaryColor3fvEXT(const GLfloat * v)
5603{
5604   save_Attr3fNV(VERT_ATTRIB_COLOR1, v[0], v[1], v[2]);
5605}
5606
5607
5608/* Just call the respective ATTR for texcoord
5609 */
5610static void GLAPIENTRY
5611save_MultiTexCoord1f(GLenum target, GLfloat x)
5612{
5613   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
5614   save_Attr1fNV(attr, x);
5615}
5616
5617static void GLAPIENTRY
5618save_MultiTexCoord1fv(GLenum target, const GLfloat * v)
5619{
5620   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
5621   save_Attr1fNV(attr, v[0]);
5622}
5623
5624static void GLAPIENTRY
5625save_MultiTexCoord2f(GLenum target, GLfloat x, GLfloat y)
5626{
5627   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
5628   save_Attr2fNV(attr, x, y);
5629}
5630
5631static void GLAPIENTRY
5632save_MultiTexCoord2fv(GLenum target, const GLfloat * v)
5633{
5634   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
5635   save_Attr2fNV(attr, v[0], v[1]);
5636}
5637
5638static void GLAPIENTRY
5639save_MultiTexCoord3f(GLenum target, GLfloat x, GLfloat y, GLfloat z)
5640{
5641   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
5642   save_Attr3fNV(attr, x, y, z);
5643}
5644
5645static void GLAPIENTRY
5646save_MultiTexCoord3fv(GLenum target, const GLfloat * v)
5647{
5648   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
5649   save_Attr3fNV(attr, v[0], v[1], v[2]);
5650}
5651
5652static void GLAPIENTRY
5653save_MultiTexCoord4f(GLenum target, GLfloat x, GLfloat y,
5654                     GLfloat z, GLfloat w)
5655{
5656   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
5657   save_Attr4fNV(attr, x, y, z, w);
5658}
5659
5660static void GLAPIENTRY
5661save_MultiTexCoord4fv(GLenum target, const GLfloat * v)
5662{
5663   GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
5664   save_Attr4fNV(attr, v[0], v[1], v[2], v[3]);
5665}
5666
5667
5668/**
5669 * Record a GL_INVALID_VALUE error when a invalid vertex attribute
5670 * index is found.
5671 */
5672static void
5673index_error(void)
5674{
5675   GET_CURRENT_CONTEXT(ctx);
5676   _mesa_error(ctx, GL_INVALID_VALUE, "VertexAttribf(index)");
5677}
5678
5679
5680
5681static void GLAPIENTRY
5682save_VertexAttrib1fARB(GLuint index, GLfloat x)
5683{
5684   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
5685      save_Attr1fARB(index, x);
5686   else
5687      index_error();
5688}
5689
5690static void GLAPIENTRY
5691save_VertexAttrib1fvARB(GLuint index, const GLfloat * v)
5692{
5693   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
5694      save_Attr1fARB(index, v[0]);
5695   else
5696      index_error();
5697}
5698
5699static void GLAPIENTRY
5700save_VertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y)
5701{
5702   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
5703      save_Attr2fARB(index, x, y);
5704   else
5705      index_error();
5706}
5707
5708static void GLAPIENTRY
5709save_VertexAttrib2fvARB(GLuint index, const GLfloat * v)
5710{
5711   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
5712      save_Attr2fARB(index, v[0], v[1]);
5713   else
5714      index_error();
5715}
5716
5717static void GLAPIENTRY
5718save_VertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5719{
5720   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
5721      save_Attr3fARB(index, x, y, z);
5722   else
5723      index_error();
5724}
5725
5726static void GLAPIENTRY
5727save_VertexAttrib3fvARB(GLuint index, const GLfloat * v)
5728{
5729   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
5730      save_Attr3fARB(index, v[0], v[1], v[2]);
5731   else
5732      index_error();
5733}
5734
5735static void GLAPIENTRY
5736save_VertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z,
5737                       GLfloat w)
5738{
5739   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
5740      save_Attr4fARB(index, x, y, z, w);
5741   else
5742      index_error();
5743}
5744
5745static void GLAPIENTRY
5746save_VertexAttrib4fvARB(GLuint index, const GLfloat * v)
5747{
5748   if (index < MAX_VERTEX_GENERIC_ATTRIBS)
5749      save_Attr4fARB(index, v[0], v[1], v[2], v[3]);
5750   else
5751      index_error();
5752}
5753
5754static void GLAPIENTRY
5755save_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5756                        GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5757                        GLbitfield mask, GLenum filter)
5758{
5759   GET_CURRENT_CONTEXT(ctx);
5760   Node *n;
5761   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5762   n = alloc_instruction(ctx, OPCODE_BLIT_FRAMEBUFFER, 10);
5763   if (n) {
5764      n[1].i = srcX0;
5765      n[2].i = srcY0;
5766      n[3].i = srcX1;
5767      n[4].i = srcY1;
5768      n[5].i = dstX0;
5769      n[6].i = dstY0;
5770      n[7].i = dstX1;
5771      n[8].i = dstY1;
5772      n[9].i = mask;
5773      n[10].e = filter;
5774   }
5775   if (ctx->ExecuteFlag) {
5776      CALL_BlitFramebuffer(ctx->Exec, (srcX0, srcY0, srcX1, srcY1,
5777                                          dstX0, dstY0, dstX1, dstY1,
5778                                          mask, filter));
5779   }
5780}
5781
5782
5783/** GL_EXT_provoking_vertex */
5784static void GLAPIENTRY
5785save_ProvokingVertexEXT(GLenum mode)
5786{
5787   GET_CURRENT_CONTEXT(ctx);
5788   Node *n;
5789   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5790   n = alloc_instruction(ctx, OPCODE_PROVOKING_VERTEX, 1);
5791   if (n) {
5792      n[1].e = mode;
5793   }
5794   if (ctx->ExecuteFlag) {
5795      /*CALL_ProvokingVertex(ctx->Exec, (mode));*/
5796      _mesa_ProvokingVertex(mode);
5797   }
5798}
5799
5800
5801/** GL_EXT_transform_feedback */
5802static void GLAPIENTRY
5803save_BeginTransformFeedback(GLenum mode)
5804{
5805   GET_CURRENT_CONTEXT(ctx);
5806   Node *n;
5807   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5808   n = alloc_instruction(ctx, OPCODE_BEGIN_TRANSFORM_FEEDBACK, 1);
5809   if (n) {
5810      n[1].e = mode;
5811   }
5812   if (ctx->ExecuteFlag) {
5813      CALL_BeginTransformFeedback(ctx->Exec, (mode));
5814   }
5815}
5816
5817
5818/** GL_EXT_transform_feedback */
5819static void GLAPIENTRY
5820save_EndTransformFeedback(void)
5821{
5822   GET_CURRENT_CONTEXT(ctx);
5823   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5824   (void) alloc_instruction(ctx, OPCODE_END_TRANSFORM_FEEDBACK, 0);
5825   if (ctx->ExecuteFlag) {
5826      CALL_EndTransformFeedback(ctx->Exec, ());
5827   }
5828}
5829
5830static void GLAPIENTRY
5831save_BindTransformFeedback(GLenum target, GLuint name)
5832{
5833   GET_CURRENT_CONTEXT(ctx);
5834   Node *n;
5835   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5836   n = alloc_instruction(ctx, OPCODE_BIND_TRANSFORM_FEEDBACK, 2);
5837   if (n) {
5838      n[1].e = target;
5839      n[2].ui = name;
5840   }
5841   if (ctx->ExecuteFlag) {
5842      CALL_BindTransformFeedback(ctx->Exec, (target, name));
5843   }
5844}
5845
5846static void GLAPIENTRY
5847save_PauseTransformFeedback(void)
5848{
5849   GET_CURRENT_CONTEXT(ctx);
5850   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5851   (void) alloc_instruction(ctx, OPCODE_PAUSE_TRANSFORM_FEEDBACK, 0);
5852   if (ctx->ExecuteFlag) {
5853      CALL_PauseTransformFeedback(ctx->Exec, ());
5854   }
5855}
5856
5857static void GLAPIENTRY
5858save_ResumeTransformFeedback(void)
5859{
5860   GET_CURRENT_CONTEXT(ctx);
5861   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5862   (void) alloc_instruction(ctx, OPCODE_RESUME_TRANSFORM_FEEDBACK, 0);
5863   if (ctx->ExecuteFlag) {
5864      CALL_ResumeTransformFeedback(ctx->Exec, ());
5865   }
5866}
5867
5868static void GLAPIENTRY
5869save_DrawTransformFeedback(GLenum mode, GLuint name)
5870{
5871   GET_CURRENT_CONTEXT(ctx);
5872   Node *n;
5873   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5874   n = alloc_instruction(ctx, OPCODE_DRAW_TRANSFORM_FEEDBACK, 2);
5875   if (n) {
5876      n[1].e = mode;
5877      n[2].ui = name;
5878   }
5879   if (ctx->ExecuteFlag) {
5880      CALL_DrawTransformFeedback(ctx->Exec, (mode, name));
5881   }
5882}
5883
5884static void GLAPIENTRY
5885save_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream)
5886{
5887   GET_CURRENT_CONTEXT(ctx);
5888   Node *n;
5889   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5890   n = alloc_instruction(ctx, OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM, 3);
5891   if (n) {
5892      n[1].e = mode;
5893      n[2].ui = name;
5894      n[3].ui = stream;
5895   }
5896   if (ctx->ExecuteFlag) {
5897      CALL_DrawTransformFeedbackStream(ctx->Exec, (mode, name, stream));
5898   }
5899}
5900
5901static void GLAPIENTRY
5902save_DrawTransformFeedbackInstanced(GLenum mode, GLuint name,
5903                                    GLsizei primcount)
5904{
5905   GET_CURRENT_CONTEXT(ctx);
5906   Node *n;
5907   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5908   n = alloc_instruction(ctx, OPCODE_DRAW_TRANSFORM_FEEDBACK_INSTANCED, 3);
5909   if (n) {
5910      n[1].e = mode;
5911      n[2].ui = name;
5912      n[3].si = primcount;
5913   }
5914   if (ctx->ExecuteFlag) {
5915      CALL_DrawTransformFeedbackInstanced(ctx->Exec, (mode, name, primcount));
5916   }
5917}
5918
5919static void GLAPIENTRY
5920save_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name,
5921                                          GLuint stream, GLsizei primcount)
5922{
5923   GET_CURRENT_CONTEXT(ctx);
5924   Node *n;
5925   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5926   n = alloc_instruction(ctx, OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM_INSTANCED, 4);
5927   if (n) {
5928      n[1].e = mode;
5929      n[2].ui = name;
5930      n[3].ui = stream;
5931      n[4].si = primcount;
5932   }
5933   if (ctx->ExecuteFlag) {
5934      CALL_DrawTransformFeedbackStreamInstanced(ctx->Exec, (mode, name, stream,
5935                                                            primcount));
5936   }
5937}
5938
5939/* aka UseProgram() */
5940static void GLAPIENTRY
5941save_UseProgramObjectARB(GLhandleARB program)
5942{
5943   GET_CURRENT_CONTEXT(ctx);
5944   Node *n;
5945   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5946   n = alloc_instruction(ctx, OPCODE_USE_PROGRAM, 1);
5947   if (n) {
5948      n[1].ui = program;
5949   }
5950   if (ctx->ExecuteFlag) {
5951      CALL_UseProgram(ctx->Exec, (program));
5952   }
5953}
5954
5955
5956static void GLAPIENTRY
5957save_Uniform1fARB(GLint location, GLfloat x)
5958{
5959   GET_CURRENT_CONTEXT(ctx);
5960   Node *n;
5961   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5962   n = alloc_instruction(ctx, OPCODE_UNIFORM_1F, 2);
5963   if (n) {
5964      n[1].i = location;
5965      n[2].f = x;
5966   }
5967   if (ctx->ExecuteFlag) {
5968      CALL_Uniform1f(ctx->Exec, (location, x));
5969   }
5970}
5971
5972
5973static void GLAPIENTRY
5974save_Uniform2fARB(GLint location, GLfloat x, GLfloat y)
5975{
5976   GET_CURRENT_CONTEXT(ctx);
5977   Node *n;
5978   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5979   n = alloc_instruction(ctx, OPCODE_UNIFORM_2F, 3);
5980   if (n) {
5981      n[1].i = location;
5982      n[2].f = x;
5983      n[3].f = y;
5984   }
5985   if (ctx->ExecuteFlag) {
5986      CALL_Uniform2f(ctx->Exec, (location, x, y));
5987   }
5988}
5989
5990
5991static void GLAPIENTRY
5992save_Uniform3fARB(GLint location, GLfloat x, GLfloat y, GLfloat z)
5993{
5994   GET_CURRENT_CONTEXT(ctx);
5995   Node *n;
5996   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
5997   n = alloc_instruction(ctx, OPCODE_UNIFORM_3F, 4);
5998   if (n) {
5999      n[1].i = location;
6000      n[2].f = x;
6001      n[3].f = y;
6002      n[4].f = z;
6003   }
6004   if (ctx->ExecuteFlag) {
6005      CALL_Uniform3f(ctx->Exec, (location, x, y, z));
6006   }
6007}
6008
6009
6010static void GLAPIENTRY
6011save_Uniform4fARB(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6012{
6013   GET_CURRENT_CONTEXT(ctx);
6014   Node *n;
6015   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6016   n = alloc_instruction(ctx, OPCODE_UNIFORM_4F, 5);
6017   if (n) {
6018      n[1].i = location;
6019      n[2].f = x;
6020      n[3].f = y;
6021      n[4].f = z;
6022      n[5].f = w;
6023   }
6024   if (ctx->ExecuteFlag) {
6025      CALL_Uniform4f(ctx->Exec, (location, x, y, z, w));
6026   }
6027}
6028
6029
6030static void GLAPIENTRY
6031save_Uniform1fvARB(GLint location, GLsizei count, const GLfloat *v)
6032{
6033   GET_CURRENT_CONTEXT(ctx);
6034   Node *n;
6035   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6036   n = alloc_instruction(ctx, OPCODE_UNIFORM_1FV, 2 + POINTER_DWORDS);
6037   if (n) {
6038      n[1].i = location;
6039      n[2].i = count;
6040      save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLfloat)));
6041   }
6042   if (ctx->ExecuteFlag) {
6043      CALL_Uniform1fv(ctx->Exec, (location, count, v));
6044   }
6045}
6046
6047static void GLAPIENTRY
6048save_Uniform2fvARB(GLint location, GLsizei count, const GLfloat *v)
6049{
6050   GET_CURRENT_CONTEXT(ctx);
6051   Node *n;
6052   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6053   n = alloc_instruction(ctx, OPCODE_UNIFORM_2FV, 2 + POINTER_DWORDS);
6054   if (n) {
6055      n[1].i = location;
6056      n[2].i = count;
6057      save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLfloat)));
6058   }
6059   if (ctx->ExecuteFlag) {
6060      CALL_Uniform2fv(ctx->Exec, (location, count, v));
6061   }
6062}
6063
6064static void GLAPIENTRY
6065save_Uniform3fvARB(GLint location, GLsizei count, const GLfloat *v)
6066{
6067   GET_CURRENT_CONTEXT(ctx);
6068   Node *n;
6069   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6070   n = alloc_instruction(ctx, OPCODE_UNIFORM_3FV, 2 + POINTER_DWORDS);
6071   if (n) {
6072      n[1].i = location;
6073      n[2].i = count;
6074      save_pointer(&n[3], memdup(v, count * 3 * sizeof(GLfloat)));
6075   }
6076   if (ctx->ExecuteFlag) {
6077      CALL_Uniform3fv(ctx->Exec, (location, count, v));
6078   }
6079}
6080
6081static void GLAPIENTRY
6082save_Uniform4fvARB(GLint location, GLsizei count, const GLfloat *v)
6083{
6084   GET_CURRENT_CONTEXT(ctx);
6085   Node *n;
6086   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6087   n = alloc_instruction(ctx, OPCODE_UNIFORM_4FV, 2 + POINTER_DWORDS);
6088   if (n) {
6089      n[1].i = location;
6090      n[2].i = count;
6091      save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLfloat)));
6092   }
6093   if (ctx->ExecuteFlag) {
6094      CALL_Uniform4fv(ctx->Exec, (location, count, v));
6095   }
6096}
6097
6098
6099static void GLAPIENTRY
6100save_Uniform1iARB(GLint location, GLint x)
6101{
6102   GET_CURRENT_CONTEXT(ctx);
6103   Node *n;
6104   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6105   n = alloc_instruction(ctx, OPCODE_UNIFORM_1I, 2);
6106   if (n) {
6107      n[1].i = location;
6108      n[2].i = x;
6109   }
6110   if (ctx->ExecuteFlag) {
6111      CALL_Uniform1i(ctx->Exec, (location, x));
6112   }
6113}
6114
6115static void GLAPIENTRY
6116save_Uniform2iARB(GLint location, GLint x, GLint y)
6117{
6118   GET_CURRENT_CONTEXT(ctx);
6119   Node *n;
6120   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6121   n = alloc_instruction(ctx, OPCODE_UNIFORM_2I, 3);
6122   if (n) {
6123      n[1].i = location;
6124      n[2].i = x;
6125      n[3].i = y;
6126   }
6127   if (ctx->ExecuteFlag) {
6128      CALL_Uniform2i(ctx->Exec, (location, x, y));
6129   }
6130}
6131
6132static void GLAPIENTRY
6133save_Uniform3iARB(GLint location, GLint x, GLint y, GLint z)
6134{
6135   GET_CURRENT_CONTEXT(ctx);
6136   Node *n;
6137   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6138   n = alloc_instruction(ctx, OPCODE_UNIFORM_3I, 4);
6139   if (n) {
6140      n[1].i = location;
6141      n[2].i = x;
6142      n[3].i = y;
6143      n[4].i = z;
6144   }
6145   if (ctx->ExecuteFlag) {
6146      CALL_Uniform3i(ctx->Exec, (location, x, y, z));
6147   }
6148}
6149
6150static void GLAPIENTRY
6151save_Uniform4iARB(GLint location, GLint x, GLint y, GLint z, GLint w)
6152{
6153   GET_CURRENT_CONTEXT(ctx);
6154   Node *n;
6155   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6156   n = alloc_instruction(ctx, OPCODE_UNIFORM_4I, 5);
6157   if (n) {
6158      n[1].i = location;
6159      n[2].i = x;
6160      n[3].i = y;
6161      n[4].i = z;
6162      n[5].i = w;
6163   }
6164   if (ctx->ExecuteFlag) {
6165      CALL_Uniform4i(ctx->Exec, (location, x, y, z, w));
6166   }
6167}
6168
6169
6170
6171static void GLAPIENTRY
6172save_Uniform1ivARB(GLint location, GLsizei count, const GLint *v)
6173{
6174   GET_CURRENT_CONTEXT(ctx);
6175   Node *n;
6176   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6177   n = alloc_instruction(ctx, OPCODE_UNIFORM_1IV, 2 + POINTER_DWORDS);
6178   if (n) {
6179      n[1].i = location;
6180      n[2].i = count;
6181      save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLint)));
6182   }
6183   if (ctx->ExecuteFlag) {
6184      CALL_Uniform1iv(ctx->Exec, (location, count, v));
6185   }
6186}
6187
6188static void GLAPIENTRY
6189save_Uniform2ivARB(GLint location, GLsizei count, const GLint *v)
6190{
6191   GET_CURRENT_CONTEXT(ctx);
6192   Node *n;
6193   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6194   n = alloc_instruction(ctx, OPCODE_UNIFORM_2IV, 2 + POINTER_DWORDS);
6195   if (n) {
6196      n[1].i = location;
6197      n[2].i = count;
6198      save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLint)));
6199   }
6200   if (ctx->ExecuteFlag) {
6201      CALL_Uniform2iv(ctx->Exec, (location, count, v));
6202   }
6203}
6204
6205static void GLAPIENTRY
6206save_Uniform3ivARB(GLint location, GLsizei count, const GLint *v)
6207{
6208   GET_CURRENT_CONTEXT(ctx);
6209   Node *n;
6210   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6211   n = alloc_instruction(ctx, OPCODE_UNIFORM_3IV, 2 + POINTER_DWORDS);
6212   if (n) {
6213      n[1].i = location;
6214      n[2].i = count;
6215      save_pointer(&n[3], memdup(v, count * 3 * sizeof(GLint)));
6216   }
6217   if (ctx->ExecuteFlag) {
6218      CALL_Uniform3iv(ctx->Exec, (location, count, v));
6219   }
6220}
6221
6222static void GLAPIENTRY
6223save_Uniform4ivARB(GLint location, GLsizei count, const GLint *v)
6224{
6225   GET_CURRENT_CONTEXT(ctx);
6226   Node *n;
6227   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6228   n = alloc_instruction(ctx, OPCODE_UNIFORM_4IV, 2 + POINTER_DWORDS);
6229   if (n) {
6230      n[1].i = location;
6231      n[2].i = count;
6232      save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLfloat)));
6233   }
6234   if (ctx->ExecuteFlag) {
6235      CALL_Uniform4iv(ctx->Exec, (location, count, v));
6236   }
6237}
6238
6239
6240
6241static void GLAPIENTRY
6242save_Uniform1ui(GLint location, GLuint x)
6243{
6244   GET_CURRENT_CONTEXT(ctx);
6245   Node *n;
6246   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6247   n = alloc_instruction(ctx, OPCODE_UNIFORM_1UI, 2);
6248   if (n) {
6249      n[1].i = location;
6250      n[2].i = x;
6251   }
6252   if (ctx->ExecuteFlag) {
6253      /*CALL_Uniform1ui(ctx->Exec, (location, x));*/
6254   }
6255}
6256
6257static void GLAPIENTRY
6258save_Uniform2ui(GLint location, GLuint x, GLuint y)
6259{
6260   GET_CURRENT_CONTEXT(ctx);
6261   Node *n;
6262   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6263   n = alloc_instruction(ctx, OPCODE_UNIFORM_2UI, 3);
6264   if (n) {
6265      n[1].i = location;
6266      n[2].i = x;
6267      n[3].i = y;
6268   }
6269   if (ctx->ExecuteFlag) {
6270      /*CALL_Uniform2ui(ctx->Exec, (location, x, y));*/
6271   }
6272}
6273
6274static void GLAPIENTRY
6275save_Uniform3ui(GLint location, GLuint x, GLuint y, GLuint z)
6276{
6277   GET_CURRENT_CONTEXT(ctx);
6278   Node *n;
6279   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6280   n = alloc_instruction(ctx, OPCODE_UNIFORM_3UI, 4);
6281   if (n) {
6282      n[1].i = location;
6283      n[2].i = x;
6284      n[3].i = y;
6285      n[4].i = z;
6286   }
6287   if (ctx->ExecuteFlag) {
6288      /*CALL_Uniform3ui(ctx->Exec, (location, x, y, z));*/
6289   }
6290}
6291
6292static void GLAPIENTRY
6293save_Uniform4ui(GLint location, GLuint x, GLuint y, GLuint z, GLuint w)
6294{
6295   GET_CURRENT_CONTEXT(ctx);
6296   Node *n;
6297   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6298   n = alloc_instruction(ctx, OPCODE_UNIFORM_4UI, 5);
6299   if (n) {
6300      n[1].i = location;
6301      n[2].i = x;
6302      n[3].i = y;
6303      n[4].i = z;
6304      n[5].i = w;
6305   }
6306   if (ctx->ExecuteFlag) {
6307      /*CALL_Uniform4ui(ctx->Exec, (location, x, y, z, w));*/
6308   }
6309}
6310
6311
6312
6313static void GLAPIENTRY
6314save_Uniform1uiv(GLint location, GLsizei count, const GLuint *v)
6315{
6316   GET_CURRENT_CONTEXT(ctx);
6317   Node *n;
6318   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6319   n = alloc_instruction(ctx, OPCODE_UNIFORM_1UIV, 2 + POINTER_DWORDS);
6320   if (n) {
6321      n[1].i = location;
6322      n[2].i = count;
6323      save_pointer(&n[3], memdup(v, count * 1 * sizeof(*v)));
6324   }
6325   if (ctx->ExecuteFlag) {
6326      /*CALL_Uniform1uiv(ctx->Exec, (location, count, v));*/
6327   }
6328}
6329
6330static void GLAPIENTRY
6331save_Uniform2uiv(GLint location, GLsizei count, const GLuint *v)
6332{
6333   GET_CURRENT_CONTEXT(ctx);
6334   Node *n;
6335   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6336   n = alloc_instruction(ctx, OPCODE_UNIFORM_2UIV, 2 + POINTER_DWORDS);
6337   if (n) {
6338      n[1].i = location;
6339      n[2].i = count;
6340      save_pointer(&n[3], memdup(v, count * 2 * sizeof(*v)));
6341   }
6342   if (ctx->ExecuteFlag) {
6343      /*CALL_Uniform2uiv(ctx->Exec, (location, count, v));*/
6344   }
6345}
6346
6347static void GLAPIENTRY
6348save_Uniform3uiv(GLint location, GLsizei count, const GLuint *v)
6349{
6350   GET_CURRENT_CONTEXT(ctx);
6351   Node *n;
6352   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6353   n = alloc_instruction(ctx, OPCODE_UNIFORM_3UIV, 2 + POINTER_DWORDS);
6354   if (n) {
6355      n[1].i = location;
6356      n[2].i = count;
6357      save_pointer(&n[3], memdup(v, count * 3 * sizeof(*v)));
6358   }
6359   if (ctx->ExecuteFlag) {
6360      /*CALL_Uniform3uiv(ctx->Exec, (location, count, v));*/
6361   }
6362}
6363
6364static void GLAPIENTRY
6365save_Uniform4uiv(GLint location, GLsizei count, const GLuint *v)
6366{
6367   GET_CURRENT_CONTEXT(ctx);
6368   Node *n;
6369   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6370   n = alloc_instruction(ctx, OPCODE_UNIFORM_4UIV, 2 + POINTER_DWORDS);
6371   if (n) {
6372      n[1].i = location;
6373      n[2].i = count;
6374      save_pointer(&n[3], memdup(v, count * 4 * sizeof(*v)));
6375   }
6376   if (ctx->ExecuteFlag) {
6377      /*CALL_Uniform4uiv(ctx->Exec, (location, count, v));*/
6378   }
6379}
6380
6381
6382
6383static void GLAPIENTRY
6384save_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
6385                         const GLfloat *m)
6386{
6387   GET_CURRENT_CONTEXT(ctx);
6388   Node *n;
6389   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6390   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX22, 3 + POINTER_DWORDS);
6391   if (n) {
6392      n[1].i = location;
6393      n[2].i = count;
6394      n[3].b = transpose;
6395      save_pointer(&n[4], memdup(m, count * 2 * 2 * sizeof(GLfloat)));
6396   }
6397   if (ctx->ExecuteFlag) {
6398      CALL_UniformMatrix2fv(ctx->Exec, (location, count, transpose, m));
6399   }
6400}
6401
6402static void GLAPIENTRY
6403save_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
6404                         const GLfloat *m)
6405{
6406   GET_CURRENT_CONTEXT(ctx);
6407   Node *n;
6408   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6409   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX33, 3 + POINTER_DWORDS);
6410   if (n) {
6411      n[1].i = location;
6412      n[2].i = count;
6413      n[3].b = transpose;
6414      save_pointer(&n[4], memdup(m, count * 3 * 3 * sizeof(GLfloat)));
6415   }
6416   if (ctx->ExecuteFlag) {
6417      CALL_UniformMatrix3fv(ctx->Exec, (location, count, transpose, m));
6418   }
6419}
6420
6421static void GLAPIENTRY
6422save_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
6423                         const GLfloat *m)
6424{
6425   GET_CURRENT_CONTEXT(ctx);
6426   Node *n;
6427   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6428   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX44, 3 + POINTER_DWORDS);
6429   if (n) {
6430      n[1].i = location;
6431      n[2].i = count;
6432      n[3].b = transpose;
6433      save_pointer(&n[4], memdup(m, count * 4 * 4 * sizeof(GLfloat)));
6434   }
6435   if (ctx->ExecuteFlag) {
6436      CALL_UniformMatrix4fv(ctx->Exec, (location, count, transpose, m));
6437   }
6438}
6439
6440
6441static void GLAPIENTRY
6442save_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
6443                        const GLfloat *m)
6444{
6445   GET_CURRENT_CONTEXT(ctx);
6446   Node *n;
6447   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6448   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX23, 3 + POINTER_DWORDS);
6449   if (n) {
6450      n[1].i = location;
6451      n[2].i = count;
6452      n[3].b = transpose;
6453      save_pointer(&n[4], memdup(m, count * 2 * 3 * sizeof(GLfloat)));
6454   }
6455   if (ctx->ExecuteFlag) {
6456      CALL_UniformMatrix2x3fv(ctx->Exec, (location, count, transpose, m));
6457   }
6458}
6459
6460static void GLAPIENTRY
6461save_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
6462                        const GLfloat *m)
6463{
6464   GET_CURRENT_CONTEXT(ctx);
6465   Node *n;
6466   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6467   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX32, 3 + POINTER_DWORDS);
6468   if (n) {
6469      n[1].i = location;
6470      n[2].i = count;
6471      n[3].b = transpose;
6472      save_pointer(&n[4], memdup(m, count * 3 * 2 * sizeof(GLfloat)));
6473   }
6474   if (ctx->ExecuteFlag) {
6475      CALL_UniformMatrix3x2fv(ctx->Exec, (location, count, transpose, m));
6476   }
6477}
6478
6479
6480static void GLAPIENTRY
6481save_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
6482                        const GLfloat *m)
6483{
6484   GET_CURRENT_CONTEXT(ctx);
6485   Node *n;
6486   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6487   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX24, 3 + POINTER_DWORDS);
6488   if (n) {
6489      n[1].i = location;
6490      n[2].i = count;
6491      n[3].b = transpose;
6492      save_pointer(&n[4], memdup(m, count * 2 * 4 * sizeof(GLfloat)));
6493   }
6494   if (ctx->ExecuteFlag) {
6495      CALL_UniformMatrix2x4fv(ctx->Exec, (location, count, transpose, m));
6496   }
6497}
6498
6499static void GLAPIENTRY
6500save_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
6501                        const GLfloat *m)
6502{
6503   GET_CURRENT_CONTEXT(ctx);
6504   Node *n;
6505   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6506   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX42, 3 + POINTER_DWORDS);
6507   if (n) {
6508      n[1].i = location;
6509      n[2].i = count;
6510      n[3].b = transpose;
6511      save_pointer(&n[4], memdup(m, count * 4 * 2 * sizeof(GLfloat)));
6512   }
6513   if (ctx->ExecuteFlag) {
6514      CALL_UniformMatrix4x2fv(ctx->Exec, (location, count, transpose, m));
6515   }
6516}
6517
6518
6519static void GLAPIENTRY
6520save_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
6521                        const GLfloat *m)
6522{
6523   GET_CURRENT_CONTEXT(ctx);
6524   Node *n;
6525   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6526   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX34, 3 + POINTER_DWORDS);
6527   if (n) {
6528      n[1].i = location;
6529      n[2].i = count;
6530      n[3].b = transpose;
6531      save_pointer(&n[4], memdup(m, count * 3 * 4 * sizeof(GLfloat)));
6532   }
6533   if (ctx->ExecuteFlag) {
6534      CALL_UniformMatrix3x4fv(ctx->Exec, (location, count, transpose, m));
6535   }
6536}
6537
6538static void GLAPIENTRY
6539save_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
6540                        const GLfloat *m)
6541{
6542   GET_CURRENT_CONTEXT(ctx);
6543   Node *n;
6544   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6545   n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX43, 3 + POINTER_DWORDS);
6546   if (n) {
6547      n[1].i = location;
6548      n[2].i = count;
6549      n[3].b = transpose;
6550      save_pointer(&n[4], memdup(m, count * 4 * 3 * sizeof(GLfloat)));
6551   }
6552   if (ctx->ExecuteFlag) {
6553      CALL_UniformMatrix4x3fv(ctx->Exec, (location, count, transpose, m));
6554   }
6555}
6556
6557static void GLAPIENTRY
6558save_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
6559{
6560   GET_CURRENT_CONTEXT(ctx);
6561   Node *n;
6562   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6563   n = alloc_instruction(ctx, OPCODE_USE_PROGRAM_STAGES, 3);
6564   if (n) {
6565      n[1].ui = pipeline;
6566      n[2].ui = stages;
6567      n[3].ui = program;
6568   }
6569   if (ctx->ExecuteFlag) {
6570      CALL_UseProgramStages(ctx->Exec, (pipeline, stages, program));
6571   }
6572}
6573
6574static void GLAPIENTRY
6575save_ProgramUniform1f(GLuint program, GLint location, GLfloat x)
6576{
6577   GET_CURRENT_CONTEXT(ctx);
6578   Node *n;
6579   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6580   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1F, 3);
6581   if (n) {
6582      n[1].ui = program;
6583      n[2].i = location;
6584      n[3].f = x;
6585   }
6586   if (ctx->ExecuteFlag) {
6587      CALL_ProgramUniform1f(ctx->Exec, (program, location, x));
6588   }
6589}
6590
6591static void GLAPIENTRY
6592save_ProgramUniform2f(GLuint program, GLint location, GLfloat x, GLfloat y)
6593{
6594   GET_CURRENT_CONTEXT(ctx);
6595   Node *n;
6596   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6597   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2F, 4);
6598   if (n) {
6599      n[1].ui = program;
6600      n[2].i = location;
6601      n[3].f = x;
6602      n[4].f = y;
6603   }
6604   if (ctx->ExecuteFlag) {
6605      CALL_ProgramUniform2f(ctx->Exec, (program, location, x, y));
6606   }
6607}
6608
6609static void GLAPIENTRY
6610save_ProgramUniform3f(GLuint program, GLint location,
6611                      GLfloat x, GLfloat y, GLfloat z)
6612{
6613   GET_CURRENT_CONTEXT(ctx);
6614   Node *n;
6615   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6616   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3F, 5);
6617   if (n) {
6618      n[1].ui = program;
6619      n[2].i = location;
6620      n[3].f = x;
6621      n[4].f = y;
6622      n[5].f = z;
6623   }
6624   if (ctx->ExecuteFlag) {
6625      CALL_ProgramUniform3f(ctx->Exec, (program, location, x, y, z));
6626   }
6627}
6628
6629static void GLAPIENTRY
6630save_ProgramUniform4f(GLuint program, GLint location,
6631                      GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6632{
6633   GET_CURRENT_CONTEXT(ctx);
6634   Node *n;
6635   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6636   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4F, 6);
6637   if (n) {
6638      n[1].ui = program;
6639      n[2].i = location;
6640      n[3].f = x;
6641      n[4].f = y;
6642      n[5].f = z;
6643      n[6].f = w;
6644   }
6645   if (ctx->ExecuteFlag) {
6646      CALL_ProgramUniform4f(ctx->Exec, (program, location, x, y, z, w));
6647   }
6648}
6649
6650static void GLAPIENTRY
6651save_ProgramUniform1fv(GLuint program, GLint location, GLsizei count,
6652                       const GLfloat *v)
6653{
6654   GET_CURRENT_CONTEXT(ctx);
6655   Node *n;
6656   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6657   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1FV, 3 + POINTER_DWORDS);
6658   if (n) {
6659      n[1].ui = program;
6660      n[2].i = location;
6661      n[3].i = count;
6662      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLfloat)));
6663   }
6664   if (ctx->ExecuteFlag) {
6665      CALL_ProgramUniform1fv(ctx->Exec, (program, location, count, v));
6666   }
6667}
6668
6669static void GLAPIENTRY
6670save_ProgramUniform2fv(GLuint program, GLint location, GLsizei count,
6671                       const GLfloat *v)
6672{
6673   GET_CURRENT_CONTEXT(ctx);
6674   Node *n;
6675   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6676   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2FV, 3 + POINTER_DWORDS);
6677   if (n) {
6678      n[1].ui = program;
6679      n[2].i = location;
6680      n[3].i = count;
6681      save_pointer(&n[4], memdup(v, count * 2 * sizeof(GLfloat)));
6682   }
6683   if (ctx->ExecuteFlag) {
6684      CALL_ProgramUniform2fv(ctx->Exec, (program, location, count, v));
6685   }
6686}
6687
6688static void GLAPIENTRY
6689save_ProgramUniform3fv(GLuint program, GLint location, GLsizei count,
6690                       const GLfloat *v)
6691{
6692   GET_CURRENT_CONTEXT(ctx);
6693   Node *n;
6694   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6695   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3FV, 3 + POINTER_DWORDS);
6696   if (n) {
6697      n[1].ui = program;
6698      n[2].i = location;
6699      n[3].i = count;
6700      save_pointer(&n[4], memdup(v, count * 3 * sizeof(GLfloat)));
6701   }
6702   if (ctx->ExecuteFlag) {
6703      CALL_ProgramUniform3fv(ctx->Exec, (program, location, count, v));
6704   }
6705}
6706
6707static void GLAPIENTRY
6708save_ProgramUniform4fv(GLuint program, GLint location, GLsizei count,
6709                       const GLfloat *v)
6710{
6711   GET_CURRENT_CONTEXT(ctx);
6712   Node *n;
6713   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6714   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4FV, 3 + POINTER_DWORDS);
6715   if (n) {
6716      n[1].ui = program;
6717      n[2].i = location;
6718      n[3].i = count;
6719      save_pointer(&n[4], memdup(v, count * 4 * sizeof(GLfloat)));
6720   }
6721   if (ctx->ExecuteFlag) {
6722      CALL_ProgramUniform4fv(ctx->Exec, (program, location, count, v));
6723   }
6724}
6725
6726static void GLAPIENTRY
6727save_ProgramUniform1i(GLuint program, GLint location, GLint x)
6728{
6729   GET_CURRENT_CONTEXT(ctx);
6730   Node *n;
6731   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6732   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1I, 3);
6733   if (n) {
6734      n[1].ui = program;
6735      n[2].i = location;
6736      n[3].i = x;
6737   }
6738   if (ctx->ExecuteFlag) {
6739      CALL_ProgramUniform1i(ctx->Exec, (program, location, x));
6740   }
6741}
6742
6743static void GLAPIENTRY
6744save_ProgramUniform2i(GLuint program, GLint location, GLint x, GLint y)
6745{
6746   GET_CURRENT_CONTEXT(ctx);
6747   Node *n;
6748   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6749   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2I, 4);
6750   if (n) {
6751      n[1].ui = program;
6752      n[2].i = location;
6753      n[3].i = x;
6754      n[4].i = y;
6755   }
6756   if (ctx->ExecuteFlag) {
6757      CALL_ProgramUniform2i(ctx->Exec, (program, location, x, y));
6758   }
6759}
6760
6761static void GLAPIENTRY
6762save_ProgramUniform3i(GLuint program, GLint location,
6763                      GLint x, GLint y, GLint z)
6764{
6765   GET_CURRENT_CONTEXT(ctx);
6766   Node *n;
6767   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6768   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3I, 5);
6769   if (n) {
6770      n[1].ui = program;
6771      n[2].i = location;
6772      n[3].i = x;
6773      n[4].i = y;
6774      n[5].i = z;
6775   }
6776   if (ctx->ExecuteFlag) {
6777      CALL_ProgramUniform3i(ctx->Exec, (program, location, x, y, z));
6778   }
6779}
6780
6781static void GLAPIENTRY
6782save_ProgramUniform4i(GLuint program, GLint location,
6783                      GLint x, GLint y, GLint z, GLint w)
6784{
6785   GET_CURRENT_CONTEXT(ctx);
6786   Node *n;
6787   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6788   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4I, 6);
6789   if (n) {
6790      n[1].ui = program;
6791      n[2].i = location;
6792      n[3].i = x;
6793      n[4].i = y;
6794      n[5].i = z;
6795      n[6].i = w;
6796   }
6797   if (ctx->ExecuteFlag) {
6798      CALL_ProgramUniform4i(ctx->Exec, (program, location, x, y, z, w));
6799   }
6800}
6801
6802static void GLAPIENTRY
6803save_ProgramUniform1iv(GLuint program, GLint location, GLsizei count,
6804                       const GLint *v)
6805{
6806   GET_CURRENT_CONTEXT(ctx);
6807   Node *n;
6808   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6809   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1IV, 3 + POINTER_DWORDS);
6810   if (n) {
6811      n[1].ui = program;
6812      n[2].i = location;
6813      n[3].i = count;
6814      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLint)));
6815   }
6816   if (ctx->ExecuteFlag) {
6817      CALL_ProgramUniform1iv(ctx->Exec, (program, location, count, v));
6818   }
6819}
6820
6821static void GLAPIENTRY
6822save_ProgramUniform2iv(GLuint program, GLint location, GLsizei count,
6823                       const GLint *v)
6824{
6825   GET_CURRENT_CONTEXT(ctx);
6826   Node *n;
6827   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6828   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2IV, 3 + POINTER_DWORDS);
6829   if (n) {
6830      n[1].ui = program;
6831      n[2].i = location;
6832      n[3].i = count;
6833      save_pointer(&n[4], memdup(v, count * 2 * sizeof(GLint)));
6834   }
6835   if (ctx->ExecuteFlag) {
6836      CALL_ProgramUniform2iv(ctx->Exec, (program, location, count, v));
6837   }
6838}
6839
6840static void GLAPIENTRY
6841save_ProgramUniform3iv(GLuint program, GLint location, GLsizei count,
6842                       const GLint *v)
6843{
6844   GET_CURRENT_CONTEXT(ctx);
6845   Node *n;
6846   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6847   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3IV, 3 + POINTER_DWORDS);
6848   if (n) {
6849      n[1].ui = program;
6850      n[2].i = location;
6851      n[3].i = count;
6852      save_pointer(&n[4], memdup(v, count * 3 * sizeof(GLint)));
6853   }
6854   if (ctx->ExecuteFlag) {
6855      CALL_ProgramUniform3iv(ctx->Exec, (program, location, count, v));
6856   }
6857}
6858
6859static void GLAPIENTRY
6860save_ProgramUniform4iv(GLuint program, GLint location, GLsizei count,
6861                       const GLint *v)
6862{
6863   GET_CURRENT_CONTEXT(ctx);
6864   Node *n;
6865   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6866   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4IV, 3 + POINTER_DWORDS);
6867   if (n) {
6868      n[1].ui = program;
6869      n[2].i = location;
6870      n[3].i = count;
6871      save_pointer(&n[4], memdup(v, count * 4 * sizeof(GLint)));
6872   }
6873   if (ctx->ExecuteFlag) {
6874      CALL_ProgramUniform4iv(ctx->Exec, (program, location, count, v));
6875   }
6876}
6877
6878static void GLAPIENTRY
6879save_ProgramUniform1ui(GLuint program, GLint location, GLuint x)
6880{
6881   GET_CURRENT_CONTEXT(ctx);
6882   Node *n;
6883   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6884   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1UI, 3);
6885   if (n) {
6886      n[1].ui = program;
6887      n[2].i = location;
6888      n[3].ui = x;
6889   }
6890   if (ctx->ExecuteFlag) {
6891      CALL_ProgramUniform1ui(ctx->Exec, (program, location, x));
6892   }
6893}
6894
6895static void GLAPIENTRY
6896save_ProgramUniform2ui(GLuint program, GLint location, GLuint x, GLuint y)
6897{
6898   GET_CURRENT_CONTEXT(ctx);
6899   Node *n;
6900   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6901   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2UI, 4);
6902   if (n) {
6903      n[1].ui = program;
6904      n[2].i = location;
6905      n[3].ui = x;
6906      n[4].ui = y;
6907   }
6908   if (ctx->ExecuteFlag) {
6909      CALL_ProgramUniform2ui(ctx->Exec, (program, location, x, y));
6910   }
6911}
6912
6913static void GLAPIENTRY
6914save_ProgramUniform3ui(GLuint program, GLint location,
6915                       GLuint x, GLuint y, GLuint z)
6916{
6917   GET_CURRENT_CONTEXT(ctx);
6918   Node *n;
6919   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6920   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3UI, 5);
6921   if (n) {
6922      n[1].ui = program;
6923      n[2].i = location;
6924      n[3].ui = x;
6925      n[4].ui = y;
6926      n[5].ui = z;
6927   }
6928   if (ctx->ExecuteFlag) {
6929      CALL_ProgramUniform3ui(ctx->Exec, (program, location, x, y, z));
6930   }
6931}
6932
6933static void GLAPIENTRY
6934save_ProgramUniform4ui(GLuint program, GLint location,
6935                       GLuint x, GLuint y, GLuint z, GLuint w)
6936{
6937   GET_CURRENT_CONTEXT(ctx);
6938   Node *n;
6939   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6940   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4UI, 6);
6941   if (n) {
6942      n[1].ui = program;
6943      n[2].i = location;
6944      n[3].ui = x;
6945      n[4].ui = y;
6946      n[5].ui = z;
6947      n[6].ui = w;
6948   }
6949   if (ctx->ExecuteFlag) {
6950      CALL_ProgramUniform4ui(ctx->Exec, (program, location, x, y, z, w));
6951   }
6952}
6953
6954static void GLAPIENTRY
6955save_ProgramUniform1uiv(GLuint program, GLint location, GLsizei count,
6956                        const GLuint *v)
6957{
6958   GET_CURRENT_CONTEXT(ctx);
6959   Node *n;
6960   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6961   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_1UIV, 3 + POINTER_DWORDS);
6962   if (n) {
6963      n[1].ui = program;
6964      n[2].i = location;
6965      n[3].i = count;
6966      save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLuint)));
6967   }
6968   if (ctx->ExecuteFlag) {
6969      CALL_ProgramUniform1uiv(ctx->Exec, (program, location, count, v));
6970   }
6971}
6972
6973static void GLAPIENTRY
6974save_ProgramUniform2uiv(GLuint program, GLint location, GLsizei count,
6975                        const GLuint *v)
6976{
6977   GET_CURRENT_CONTEXT(ctx);
6978   Node *n;
6979   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6980   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_2UIV, 3 + POINTER_DWORDS);
6981   if (n) {
6982      n[1].ui = program;
6983      n[2].i = location;
6984      n[3].i = count;
6985      save_pointer(&n[4], memdup(v, count * 2 * sizeof(GLuint)));
6986   }
6987   if (ctx->ExecuteFlag) {
6988      CALL_ProgramUniform2uiv(ctx->Exec, (program, location, count, v));
6989   }
6990}
6991
6992static void GLAPIENTRY
6993save_ProgramUniform3uiv(GLuint program, GLint location, GLsizei count,
6994                        const GLuint *v)
6995{
6996   GET_CURRENT_CONTEXT(ctx);
6997   Node *n;
6998   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
6999   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_3UIV, 3 + POINTER_DWORDS);
7000   if (n) {
7001      n[1].ui = program;
7002      n[2].i = location;
7003      n[3].i = count;
7004      save_pointer(&n[4], memdup(v, count * 3 * sizeof(GLuint)));
7005   }
7006   if (ctx->ExecuteFlag) {
7007      CALL_ProgramUniform3uiv(ctx->Exec, (program, location, count, v));
7008   }
7009}
7010
7011static void GLAPIENTRY
7012save_ProgramUniform4uiv(GLuint program, GLint location, GLsizei count,
7013                        const GLuint *v)
7014{
7015   GET_CURRENT_CONTEXT(ctx);
7016   Node *n;
7017   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7018   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_4UIV, 3 + POINTER_DWORDS);
7019   if (n) {
7020      n[1].ui = program;
7021      n[2].i = location;
7022      n[3].i = count;
7023      save_pointer(&n[4], memdup(v, count * 4 * sizeof(GLuint)));
7024   }
7025   if (ctx->ExecuteFlag) {
7026      CALL_ProgramUniform4uiv(ctx->Exec, (program, location, count, v));
7027   }
7028}
7029
7030static void GLAPIENTRY
7031save_ProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count,
7032                             GLboolean transpose, const GLfloat *v)
7033{
7034   GET_CURRENT_CONTEXT(ctx);
7035   Node *n;
7036   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7037   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX22F,
7038                         4 + POINTER_DWORDS);
7039   if (n) {
7040      n[1].ui = program;
7041      n[2].i = location;
7042      n[3].i = count;
7043      n[4].b = transpose;
7044      save_pointer(&n[5], memdup(v, count * 2 * 2 * sizeof(GLfloat)));
7045   }
7046   if (ctx->ExecuteFlag) {
7047      CALL_ProgramUniformMatrix2fv(ctx->Exec,
7048                                   (program, location, count, transpose, v));
7049   }
7050}
7051
7052static void GLAPIENTRY
7053save_ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count,
7054                               GLboolean transpose, const GLfloat *v)
7055{
7056   GET_CURRENT_CONTEXT(ctx);
7057   Node *n;
7058   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7059   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX23F,
7060                         4 + POINTER_DWORDS);
7061   if (n) {
7062      n[1].ui = program;
7063      n[2].i = location;
7064      n[3].i = count;
7065      n[4].b = transpose;
7066      save_pointer(&n[5], memdup(v, count * 2 * 3 * sizeof(GLfloat)));
7067   }
7068   if (ctx->ExecuteFlag) {
7069      CALL_ProgramUniformMatrix2x3fv(ctx->Exec,
7070                                     (program, location, count, transpose, v));
7071   }
7072}
7073
7074static void GLAPIENTRY
7075save_ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count,
7076                               GLboolean transpose, const GLfloat *v)
7077{
7078   GET_CURRENT_CONTEXT(ctx);
7079   Node *n;
7080   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7081   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX24F,
7082                         4 + POINTER_DWORDS);
7083   if (n) {
7084      n[1].ui = program;
7085      n[2].i = location;
7086      n[3].i = count;
7087      n[4].b = transpose;
7088      save_pointer(&n[5], memdup(v, count * 2 * 4 * sizeof(GLfloat)));
7089   }
7090   if (ctx->ExecuteFlag) {
7091      CALL_ProgramUniformMatrix2x4fv(ctx->Exec,
7092                                     (program, location, count, transpose, v));
7093   }
7094}
7095
7096static void GLAPIENTRY
7097save_ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count,
7098                               GLboolean transpose, const GLfloat *v)
7099{
7100   GET_CURRENT_CONTEXT(ctx);
7101   Node *n;
7102   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7103   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX32F,
7104                         4 + POINTER_DWORDS);
7105   if (n) {
7106      n[1].ui = program;
7107      n[2].i = location;
7108      n[3].i = count;
7109      n[4].b = transpose;
7110      save_pointer(&n[5], memdup(v, count * 3 * 2 * sizeof(GLfloat)));
7111   }
7112   if (ctx->ExecuteFlag) {
7113      CALL_ProgramUniformMatrix3x2fv(ctx->Exec,
7114                                     (program, location, count, transpose, v));
7115   }
7116}
7117
7118static void GLAPIENTRY
7119save_ProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count,
7120                             GLboolean transpose, const GLfloat *v)
7121{
7122   GET_CURRENT_CONTEXT(ctx);
7123   Node *n;
7124   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7125   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX33F,
7126                         4 + POINTER_DWORDS);
7127   if (n) {
7128      n[1].ui = program;
7129      n[2].i = location;
7130      n[3].i = count;
7131      n[4].b = transpose;
7132      save_pointer(&n[5], memdup(v, count * 3 * 3 * sizeof(GLfloat)));
7133   }
7134   if (ctx->ExecuteFlag) {
7135      CALL_ProgramUniformMatrix3fv(ctx->Exec,
7136                                   (program, location, count, transpose, v));
7137   }
7138}
7139
7140static void GLAPIENTRY
7141save_ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count,
7142                               GLboolean transpose, const GLfloat *v)
7143{
7144   GET_CURRENT_CONTEXT(ctx);
7145   Node *n;
7146   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7147   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX34F,
7148                         4 + POINTER_DWORDS);
7149   if (n) {
7150      n[1].ui = program;
7151      n[2].i = location;
7152      n[3].i = count;
7153      n[4].b = transpose;
7154      save_pointer(&n[5], memdup(v, count * 3 * 4 * sizeof(GLfloat)));
7155   }
7156   if (ctx->ExecuteFlag) {
7157      CALL_ProgramUniformMatrix3x4fv(ctx->Exec,
7158                                     (program, location, count, transpose, v));
7159   }
7160}
7161
7162static void GLAPIENTRY
7163save_ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count,
7164                               GLboolean transpose, const GLfloat *v)
7165{
7166   GET_CURRENT_CONTEXT(ctx);
7167   Node *n;
7168   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7169   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX42F,
7170                         4 + POINTER_DWORDS);
7171   if (n) {
7172      n[1].ui = program;
7173      n[2].i = location;
7174      n[3].i = count;
7175      n[4].b = transpose;
7176      save_pointer(&n[5], memdup(v, count * 4 * 2 * sizeof(GLfloat)));
7177   }
7178   if (ctx->ExecuteFlag) {
7179      CALL_ProgramUniformMatrix4x2fv(ctx->Exec,
7180                                     (program, location, count, transpose, v));
7181   }
7182}
7183
7184static void GLAPIENTRY
7185save_ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count,
7186                               GLboolean transpose, const GLfloat *v)
7187{
7188   GET_CURRENT_CONTEXT(ctx);
7189   Node *n;
7190   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7191   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX43F,
7192                         4 + POINTER_DWORDS);
7193   if (n) {
7194      n[1].ui = program;
7195      n[2].i = location;
7196      n[3].i = count;
7197      n[4].b = transpose;
7198      save_pointer(&n[5], memdup(v, count * 4 * 3 * sizeof(GLfloat)));
7199   }
7200   if (ctx->ExecuteFlag) {
7201      CALL_ProgramUniformMatrix4x3fv(ctx->Exec,
7202                                     (program, location, count, transpose, v));
7203   }
7204}
7205
7206static void GLAPIENTRY
7207save_ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count,
7208                             GLboolean transpose, const GLfloat *v)
7209{
7210   GET_CURRENT_CONTEXT(ctx);
7211   Node *n;
7212   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7213   n = alloc_instruction(ctx, OPCODE_PROGRAM_UNIFORM_MATRIX44F,
7214                         4 + POINTER_DWORDS);
7215   if (n) {
7216      n[1].ui = program;
7217      n[2].i = location;
7218      n[3].i = count;
7219      n[4].b = transpose;
7220      save_pointer(&n[5], memdup(v, count * 4 * 4 * sizeof(GLfloat)));
7221   }
7222   if (ctx->ExecuteFlag) {
7223      CALL_ProgramUniformMatrix4fv(ctx->Exec,
7224                                   (program, location, count, transpose, v));
7225   }
7226}
7227
7228static void GLAPIENTRY
7229save_ClampColorARB(GLenum target, GLenum clamp)
7230{
7231   GET_CURRENT_CONTEXT(ctx);
7232   Node *n;
7233   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7234   n = alloc_instruction(ctx, OPCODE_CLAMP_COLOR, 2);
7235   if (n) {
7236      n[1].e = target;
7237      n[2].e = clamp;
7238   }
7239   if (ctx->ExecuteFlag) {
7240      CALL_ClampColor(ctx->Exec, (target, clamp));
7241   }
7242}
7243
7244/** GL_EXT_texture_integer */
7245static void GLAPIENTRY
7246save_ClearColorIi(GLint red, GLint green, GLint blue, GLint alpha)
7247{
7248   GET_CURRENT_CONTEXT(ctx);
7249   Node *n;
7250   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7251   n = alloc_instruction(ctx, OPCODE_CLEARCOLOR_I, 4);
7252   if (n) {
7253      n[1].i = red;
7254      n[2].i = green;
7255      n[3].i = blue;
7256      n[4].i = alpha;
7257   }
7258   if (ctx->ExecuteFlag) {
7259      CALL_ClearColorIiEXT(ctx->Exec, (red, green, blue, alpha));
7260   }
7261}
7262
7263/** GL_EXT_texture_integer */
7264static void GLAPIENTRY
7265save_ClearColorIui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
7266{
7267   GET_CURRENT_CONTEXT(ctx);
7268   Node *n;
7269   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7270   n = alloc_instruction(ctx, OPCODE_CLEARCOLOR_UI, 4);
7271   if (n) {
7272      n[1].ui = red;
7273      n[2].ui = green;
7274      n[3].ui = blue;
7275      n[4].ui = alpha;
7276   }
7277   if (ctx->ExecuteFlag) {
7278      CALL_ClearColorIuiEXT(ctx->Exec, (red, green, blue, alpha));
7279   }
7280}
7281
7282/** GL_EXT_texture_integer */
7283static void GLAPIENTRY
7284save_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
7285{
7286   GET_CURRENT_CONTEXT(ctx);
7287   Node *n;
7288   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7289   n = alloc_instruction(ctx, OPCODE_TEXPARAMETER_I, 6);
7290   if (n) {
7291      n[1].e = target;
7292      n[2].e = pname;
7293      n[3].i = params[0];
7294      n[4].i = params[1];
7295      n[5].i = params[2];
7296      n[6].i = params[3];
7297   }
7298   if (ctx->ExecuteFlag) {
7299      CALL_TexParameterIiv(ctx->Exec, (target, pname, params));
7300   }
7301}
7302
7303/** GL_EXT_texture_integer */
7304static void GLAPIENTRY
7305save_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
7306{
7307   GET_CURRENT_CONTEXT(ctx);
7308   Node *n;
7309   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7310   n = alloc_instruction(ctx, OPCODE_TEXPARAMETER_UI, 6);
7311   if (n) {
7312      n[1].e = target;
7313      n[2].e = pname;
7314      n[3].ui = params[0];
7315      n[4].ui = params[1];
7316      n[5].ui = params[2];
7317      n[6].ui = params[3];
7318   }
7319   if (ctx->ExecuteFlag) {
7320      CALL_TexParameterIuiv(ctx->Exec, (target, pname, params));
7321   }
7322}
7323
7324/* GL_ARB_instanced_arrays */
7325static void GLAPIENTRY
7326save_VertexAttribDivisor(GLuint index, GLuint divisor)
7327{
7328   GET_CURRENT_CONTEXT(ctx);
7329   Node *n;
7330   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7331   n = alloc_instruction(ctx, OPCODE_VERTEX_ATTRIB_DIVISOR, 2);
7332   if (n) {
7333      n[1].ui = index;
7334      n[2].ui = divisor;
7335   }
7336   if (ctx->ExecuteFlag) {
7337      CALL_VertexAttribDivisor(ctx->Exec, (index, divisor));
7338   }
7339}
7340
7341
7342/* GL_NV_texture_barrier */
7343static void GLAPIENTRY
7344save_TextureBarrierNV(void)
7345{
7346   GET_CURRENT_CONTEXT(ctx);
7347   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7348   alloc_instruction(ctx, OPCODE_TEXTURE_BARRIER_NV, 0);
7349   if (ctx->ExecuteFlag) {
7350      CALL_TextureBarrierNV(ctx->Exec, ());
7351   }
7352}
7353
7354
7355/* GL_ARB_sampler_objects */
7356static void GLAPIENTRY
7357save_BindSampler(GLuint unit, GLuint sampler)
7358{
7359   Node *n;
7360   GET_CURRENT_CONTEXT(ctx);
7361   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7362   n = alloc_instruction(ctx, OPCODE_BIND_SAMPLER, 2);
7363   if (n) {
7364      n[1].ui = unit;
7365      n[2].ui = sampler;
7366   }
7367   if (ctx->ExecuteFlag) {
7368      CALL_BindSampler(ctx->Exec, (unit, sampler));
7369   }
7370}
7371
7372static void GLAPIENTRY
7373save_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params)
7374{
7375   Node *n;
7376   GET_CURRENT_CONTEXT(ctx);
7377   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7378   n = alloc_instruction(ctx, OPCODE_SAMPLER_PARAMETERIV, 6);
7379   if (n) {
7380      n[1].ui = sampler;
7381      n[2].e = pname;
7382      n[3].i = params[0];
7383      if (pname == GL_TEXTURE_BORDER_COLOR) {
7384         n[4].i = params[1];
7385         n[5].i = params[2];
7386         n[6].i = params[3];
7387      }
7388      else {
7389         n[4].i = n[5].i = n[6].i = 0;
7390      }
7391   }
7392   if (ctx->ExecuteFlag) {
7393      CALL_SamplerParameteriv(ctx->Exec, (sampler, pname, params));
7394   }
7395}
7396
7397static void GLAPIENTRY
7398save_SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
7399{
7400   GLint parray[4];
7401   parray[0] = param;
7402   parray[1] = parray[2] = parray[3] = 0;
7403   save_SamplerParameteriv(sampler, pname, parray);
7404}
7405
7406static void GLAPIENTRY
7407save_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params)
7408{
7409   Node *n;
7410   GET_CURRENT_CONTEXT(ctx);
7411   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7412   n = alloc_instruction(ctx, OPCODE_SAMPLER_PARAMETERFV, 6);
7413   if (n) {
7414      n[1].ui = sampler;
7415      n[2].e = pname;
7416      n[3].f = params[0];
7417      if (pname == GL_TEXTURE_BORDER_COLOR) {
7418         n[4].f = params[1];
7419         n[5].f = params[2];
7420         n[6].f = params[3];
7421      }
7422      else {
7423         n[4].f = n[5].f = n[6].f = 0.0F;
7424      }
7425   }
7426   if (ctx->ExecuteFlag) {
7427      CALL_SamplerParameterfv(ctx->Exec, (sampler, pname, params));
7428   }
7429}
7430
7431static void GLAPIENTRY
7432save_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
7433{
7434   GLfloat parray[4];
7435   parray[0] = param;
7436   parray[1] = parray[2] = parray[3] = 0.0F;
7437   save_SamplerParameterfv(sampler, pname, parray);
7438}
7439
7440static void GLAPIENTRY
7441save_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params)
7442{
7443   Node *n;
7444   GET_CURRENT_CONTEXT(ctx);
7445   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7446   n = alloc_instruction(ctx, OPCODE_SAMPLER_PARAMETERIIV, 6);
7447   if (n) {
7448      n[1].ui = sampler;
7449      n[2].e = pname;
7450      n[3].i = params[0];
7451      if (pname == GL_TEXTURE_BORDER_COLOR) {
7452         n[4].i = params[1];
7453         n[5].i = params[2];
7454         n[6].i = params[3];
7455      }
7456      else {
7457         n[4].i = n[5].i = n[6].i = 0;
7458      }
7459   }
7460   if (ctx->ExecuteFlag) {
7461      CALL_SamplerParameterIiv(ctx->Exec, (sampler, pname, params));
7462   }
7463}
7464
7465static void GLAPIENTRY
7466save_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params)
7467{
7468   Node *n;
7469   GET_CURRENT_CONTEXT(ctx);
7470   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7471   n = alloc_instruction(ctx, OPCODE_SAMPLER_PARAMETERUIV, 6);
7472   if (n) {
7473      n[1].ui = sampler;
7474      n[2].e = pname;
7475      n[3].ui = params[0];
7476      if (pname == GL_TEXTURE_BORDER_COLOR) {
7477         n[4].ui = params[1];
7478         n[5].ui = params[2];
7479         n[6].ui = params[3];
7480      }
7481      else {
7482         n[4].ui = n[5].ui = n[6].ui = 0;
7483      }
7484   }
7485   if (ctx->ExecuteFlag) {
7486      CALL_SamplerParameterIuiv(ctx->Exec, (sampler, pname, params));
7487   }
7488}
7489
7490/* GL_ARB_geometry_shader4 */
7491static void GLAPIENTRY
7492save_ProgramParameteri(GLuint program, GLenum pname, GLint value)
7493{
7494   Node *n;
7495   GET_CURRENT_CONTEXT(ctx);
7496   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7497   n = alloc_instruction(ctx, OPCODE_PROGRAM_PARAMETERI, 3);
7498   if (n) {
7499      n[1].ui = program;
7500      n[2].e = pname;
7501      n[3].i = value;
7502   }
7503   if (ctx->ExecuteFlag) {
7504      CALL_ProgramParameteri(ctx->Exec, (program, pname, value));
7505   }
7506}
7507
7508static void GLAPIENTRY
7509save_FramebufferTexture(GLenum target, GLenum attachment,
7510                        GLuint texture, GLint level)
7511{
7512   Node *n;
7513   GET_CURRENT_CONTEXT(ctx);
7514   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7515   n = alloc_instruction(ctx, OPCODE_FRAMEBUFFER_TEXTURE, 4);
7516   if (n) {
7517      n[1].e = target;
7518      n[2].e = attachment;
7519      n[3].ui = texture;
7520      n[4].i = level;
7521   }
7522   if (ctx->ExecuteFlag) {
7523      CALL_FramebufferTexture(ctx->Exec, (target, attachment, texture, level));
7524   }
7525}
7526
7527static void GLAPIENTRY
7528save_FramebufferTextureFace(GLenum target, GLenum attachment,
7529                            GLuint texture, GLint level, GLenum face)
7530{
7531   Node *n;
7532   GET_CURRENT_CONTEXT(ctx);
7533   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7534   n = alloc_instruction(ctx, OPCODE_FRAMEBUFFER_TEXTURE_FACE, 5);
7535   if (n) {
7536      n[1].e = target;
7537      n[2].e = attachment;
7538      n[3].ui = texture;
7539      n[4].i = level;
7540      n[5].e = face;
7541   }
7542   if (ctx->ExecuteFlag) {
7543      CALL_FramebufferTextureFaceARB(ctx->Exec, (target, attachment, texture,
7544                                                 level, face));
7545   }
7546}
7547
7548
7549
7550static void GLAPIENTRY
7551save_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
7552{
7553   Node *n;
7554   GET_CURRENT_CONTEXT(ctx);
7555   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7556   n = alloc_instruction(ctx, OPCODE_WAIT_SYNC, 4);
7557   if (n) {
7558      union uint64_pair p;
7559      p.uint64 = timeout;
7560      n[1].bf = flags;
7561      n[2].ui = p.uint32[0];
7562      n[3].ui = p.uint32[1];
7563      save_pointer(&n[4], sync);
7564   }
7565   if (ctx->ExecuteFlag) {
7566      CALL_WaitSync(ctx->Exec, (sync, flags, timeout));
7567   }
7568}
7569
7570
7571/** GL_NV_conditional_render */
7572static void GLAPIENTRY
7573save_BeginConditionalRender(GLuint queryId, GLenum mode)
7574{
7575   GET_CURRENT_CONTEXT(ctx);
7576   Node *n;
7577   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7578   n = alloc_instruction(ctx, OPCODE_BEGIN_CONDITIONAL_RENDER, 2);
7579   if (n) {
7580      n[1].i = queryId;
7581      n[2].e = mode;
7582   }
7583   if (ctx->ExecuteFlag) {
7584      CALL_BeginConditionalRender(ctx->Exec, (queryId, mode));
7585   }
7586}
7587
7588static void GLAPIENTRY
7589save_EndConditionalRender(void)
7590{
7591   GET_CURRENT_CONTEXT(ctx);
7592   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7593   alloc_instruction(ctx, OPCODE_END_CONDITIONAL_RENDER, 0);
7594   if (ctx->ExecuteFlag) {
7595      CALL_EndConditionalRender(ctx->Exec, ());
7596   }
7597}
7598
7599static void GLAPIENTRY
7600save_UniformBlockBinding(GLuint prog, GLuint index, GLuint binding)
7601{
7602   GET_CURRENT_CONTEXT(ctx);
7603   Node *n;
7604   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
7605   n = alloc_instruction(ctx, OPCODE_UNIFORM_BLOCK_BINDING, 3);
7606   if (n) {
7607      n[1].ui = prog;
7608      n[2].ui = index;
7609      n[3].ui = binding;
7610   }
7611   if (ctx->ExecuteFlag) {
7612      CALL_UniformBlockBinding(ctx->Exec, (prog, index, binding));
7613   }
7614}
7615
7616
7617/**
7618 * Save an error-generating command into display list.
7619 *
7620 * KW: Will appear in the list before the vertex buffer containing the
7621 * command that provoked the error.  I don't see this as a problem.
7622 */
7623static void
7624save_error(struct gl_context *ctx, GLenum error, const char *s)
7625{
7626   Node *n;
7627   n = alloc_instruction(ctx, OPCODE_ERROR, 1 + POINTER_DWORDS);
7628   if (n) {
7629      n[1].e = error;
7630      save_pointer(&n[2], (void *) s);
7631      /* note: the data/string here doesn't have to be freed in
7632       * _mesa_delete_list() since the string is never dynamically
7633       * allocated.
7634       */
7635   }
7636}
7637
7638
7639/**
7640 * Compile an error into current display list.
7641 */
7642void
7643_mesa_compile_error(struct gl_context *ctx, GLenum error, const char *s)
7644{
7645   if (ctx->CompileFlag)
7646      save_error(ctx, error, s);
7647   if (ctx->ExecuteFlag)
7648      _mesa_error(ctx, error, "%s", s);
7649}
7650
7651
7652/**
7653 * Test if ID names a display list.
7654 */
7655static GLboolean
7656islist(struct gl_context *ctx, GLuint list)
7657{
7658   if (list > 0 && _mesa_lookup_list(ctx, list)) {
7659      return GL_TRUE;
7660   }
7661   else {
7662      return GL_FALSE;
7663   }
7664}
7665
7666
7667
7668/**********************************************************************/
7669/*                     Display list execution                         */
7670/**********************************************************************/
7671
7672
7673/*
7674 * Execute a display list.  Note that the ListBase offset must have already
7675 * been added before calling this function.  I.e. the list argument is
7676 * the absolute list number, not relative to ListBase.
7677 * \param list - display list number
7678 */
7679static void
7680execute_list(struct gl_context *ctx, GLuint list)
7681{
7682   struct gl_display_list *dlist;
7683   Node *n;
7684   GLboolean done;
7685
7686   if (list == 0 || !islist(ctx, list))
7687      return;
7688
7689   if (ctx->ListState.CallDepth == MAX_LIST_NESTING) {
7690      /* raise an error? */
7691      return;
7692   }
7693
7694   dlist = _mesa_lookup_list(ctx, list);
7695   if (!dlist)
7696      return;
7697
7698   ctx->ListState.CallDepth++;
7699
7700   if (ctx->Driver.BeginCallList)
7701      ctx->Driver.BeginCallList(ctx, dlist);
7702
7703   n = dlist->Head;
7704
7705   done = GL_FALSE;
7706   while (!done) {
7707      const OpCode opcode = n[0].opcode;
7708
7709      if (is_ext_opcode(opcode)) {
7710         n += ext_opcode_execute(ctx, n);
7711      }
7712      else {
7713         switch (opcode) {
7714         case OPCODE_ERROR:
7715            _mesa_error(ctx, n[1].e, "%s", (const char *) get_pointer(&n[2]));
7716            break;
7717         case OPCODE_ACCUM:
7718            CALL_Accum(ctx->Exec, (n[1].e, n[2].f));
7719            break;
7720         case OPCODE_ALPHA_FUNC:
7721            CALL_AlphaFunc(ctx->Exec, (n[1].e, n[2].f));
7722            break;
7723         case OPCODE_BIND_TEXTURE:
7724            CALL_BindTexture(ctx->Exec, (n[1].e, n[2].ui));
7725            break;
7726         case OPCODE_BITMAP:
7727            {
7728               const struct gl_pixelstore_attrib save = ctx->Unpack;
7729               ctx->Unpack = ctx->DefaultPacking;
7730               CALL_Bitmap(ctx->Exec, ((GLsizei) n[1].i, (GLsizei) n[2].i,
7731                                       n[3].f, n[4].f, n[5].f, n[6].f,
7732                                       get_pointer(&n[7])));
7733               ctx->Unpack = save;      /* restore */
7734            }
7735            break;
7736         case OPCODE_BLEND_COLOR:
7737            CALL_BlendColor(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
7738            break;
7739         case OPCODE_BLEND_EQUATION:
7740            CALL_BlendEquation(ctx->Exec, (n[1].e));
7741            break;
7742         case OPCODE_BLEND_EQUATION_SEPARATE:
7743            CALL_BlendEquationSeparate(ctx->Exec, (n[1].e, n[2].e));
7744            break;
7745         case OPCODE_BLEND_FUNC_SEPARATE:
7746            CALL_BlendFuncSeparate(ctx->Exec,
7747                                      (n[1].e, n[2].e, n[3].e, n[4].e));
7748            break;
7749
7750         case OPCODE_BLEND_FUNC_I:
7751            /* GL_ARB_draw_buffers_blend */
7752            CALL_BlendFunciARB(ctx->Exec, (n[1].ui, n[2].e, n[3].e));
7753            break;
7754         case OPCODE_BLEND_FUNC_SEPARATE_I:
7755            /* GL_ARB_draw_buffers_blend */
7756            CALL_BlendFuncSeparateiARB(ctx->Exec, (n[1].ui, n[2].e, n[3].e,
7757                                                   n[4].e, n[5].e));
7758            break;
7759         case OPCODE_BLEND_EQUATION_I:
7760            /* GL_ARB_draw_buffers_blend */
7761            CALL_BlendEquationiARB(ctx->Exec, (n[1].ui, n[2].e));
7762            break;
7763         case OPCODE_BLEND_EQUATION_SEPARATE_I:
7764            /* GL_ARB_draw_buffers_blend */
7765            CALL_BlendEquationSeparateiARB(ctx->Exec,
7766                                           (n[1].ui, n[2].e, n[3].e));
7767            break;
7768
7769         case OPCODE_CALL_LIST:
7770            /* Generated by glCallList(), don't add ListBase */
7771            if (ctx->ListState.CallDepth < MAX_LIST_NESTING) {
7772               execute_list(ctx, n[1].ui);
7773            }
7774            break;
7775         case OPCODE_CALL_LIST_OFFSET:
7776            /* Generated by glCallLists() so we must add ListBase */
7777            if (n[2].b) {
7778               /* user specified a bad data type at compile time */
7779               _mesa_error(ctx, GL_INVALID_ENUM, "glCallLists(type)");
7780            }
7781            else if (ctx->ListState.CallDepth < MAX_LIST_NESTING) {
7782               GLuint list = (GLuint) (ctx->List.ListBase + n[1].i);
7783               execute_list(ctx, list);
7784            }
7785            break;
7786         case OPCODE_CLEAR:
7787            CALL_Clear(ctx->Exec, (n[1].bf));
7788            break;
7789         case OPCODE_CLEAR_BUFFER_IV:
7790            {
7791               GLint value[4];
7792               value[0] = n[3].i;
7793               value[1] = n[4].i;
7794               value[2] = n[5].i;
7795               value[3] = n[6].i;
7796               CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));
7797            }
7798            break;
7799         case OPCODE_CLEAR_BUFFER_UIV:
7800            {
7801               GLuint value[4];
7802               value[0] = n[3].ui;
7803               value[1] = n[4].ui;
7804               value[2] = n[5].ui;
7805               value[3] = n[6].ui;
7806               CALL_ClearBufferuiv(ctx->Exec, (n[1].e, n[2].i, value));
7807            }
7808            break;
7809         case OPCODE_CLEAR_BUFFER_FV:
7810            {
7811               GLfloat value[4];
7812               value[0] = n[3].f;
7813               value[1] = n[4].f;
7814               value[2] = n[5].f;
7815               value[3] = n[6].f;
7816               CALL_ClearBufferfv(ctx->Exec, (n[1].e, n[2].i, value));
7817            }
7818            break;
7819         case OPCODE_CLEAR_BUFFER_FI:
7820            CALL_ClearBufferfi(ctx->Exec, (n[1].e, n[2].i, n[3].f, n[4].i));
7821            break;
7822         case OPCODE_CLEAR_COLOR:
7823            CALL_ClearColor(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
7824            break;
7825         case OPCODE_CLEAR_ACCUM:
7826            CALL_ClearAccum(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
7827            break;
7828         case OPCODE_CLEAR_DEPTH:
7829            CALL_ClearDepth(ctx->Exec, ((GLclampd) n[1].f));
7830            break;
7831         case OPCODE_CLEAR_INDEX:
7832            CALL_ClearIndex(ctx->Exec, ((GLfloat) n[1].ui));
7833            break;
7834         case OPCODE_CLEAR_STENCIL:
7835            CALL_ClearStencil(ctx->Exec, (n[1].i));
7836            break;
7837         case OPCODE_CLIP_PLANE:
7838            {
7839               GLdouble eq[4];
7840               eq[0] = n[2].f;
7841               eq[1] = n[3].f;
7842               eq[2] = n[4].f;
7843               eq[3] = n[5].f;
7844               CALL_ClipPlane(ctx->Exec, (n[1].e, eq));
7845            }
7846            break;
7847         case OPCODE_COLOR_MASK:
7848            CALL_ColorMask(ctx->Exec, (n[1].b, n[2].b, n[3].b, n[4].b));
7849            break;
7850         case OPCODE_COLOR_MASK_INDEXED:
7851            CALL_ColorMaski(ctx->Exec, (n[1].ui, n[2].b, n[3].b,
7852                                                 n[4].b, n[5].b));
7853            break;
7854         case OPCODE_COLOR_MATERIAL:
7855            CALL_ColorMaterial(ctx->Exec, (n[1].e, n[2].e));
7856            break;
7857         case OPCODE_COPY_PIXELS:
7858            CALL_CopyPixels(ctx->Exec, (n[1].i, n[2].i,
7859                                        (GLsizei) n[3].i, (GLsizei) n[4].i,
7860                                        n[5].e));
7861            break;
7862         case OPCODE_COPY_TEX_IMAGE1D:
7863            CALL_CopyTexImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].e, n[4].i,
7864                                            n[5].i, n[6].i, n[7].i));
7865            break;
7866         case OPCODE_COPY_TEX_IMAGE2D:
7867            CALL_CopyTexImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].e, n[4].i,
7868                                            n[5].i, n[6].i, n[7].i, n[8].i));
7869            break;
7870         case OPCODE_COPY_TEX_SUB_IMAGE1D:
7871            CALL_CopyTexSubImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
7872                                               n[4].i, n[5].i, n[6].i));
7873            break;
7874         case OPCODE_COPY_TEX_SUB_IMAGE2D:
7875            CALL_CopyTexSubImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
7876                                               n[4].i, n[5].i, n[6].i, n[7].i,
7877                                               n[8].i));
7878            break;
7879         case OPCODE_COPY_TEX_SUB_IMAGE3D:
7880            CALL_CopyTexSubImage3D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
7881                                               n[4].i, n[5].i, n[6].i, n[7].i,
7882                                               n[8].i, n[9].i));
7883            break;
7884         case OPCODE_CULL_FACE:
7885            CALL_CullFace(ctx->Exec, (n[1].e));
7886            break;
7887         case OPCODE_DEPTH_FUNC:
7888            CALL_DepthFunc(ctx->Exec, (n[1].e));
7889            break;
7890         case OPCODE_DEPTH_MASK:
7891            CALL_DepthMask(ctx->Exec, (n[1].b));
7892            break;
7893         case OPCODE_DEPTH_RANGE:
7894            CALL_DepthRange(ctx->Exec,
7895                            ((GLclampd) n[1].f, (GLclampd) n[2].f));
7896            break;
7897         case OPCODE_DISABLE:
7898            CALL_Disable(ctx->Exec, (n[1].e));
7899            break;
7900         case OPCODE_DISABLE_INDEXED:
7901            CALL_Disablei(ctx->Exec, (n[1].ui, n[2].e));
7902            break;
7903         case OPCODE_DRAW_BUFFER:
7904            CALL_DrawBuffer(ctx->Exec, (n[1].e));
7905            break;
7906         case OPCODE_DRAW_PIXELS:
7907            {
7908               const struct gl_pixelstore_attrib save = ctx->Unpack;
7909               ctx->Unpack = ctx->DefaultPacking;
7910               CALL_DrawPixels(ctx->Exec, (n[1].i, n[2].i, n[3].e, n[4].e,
7911                                           get_pointer(&n[5])));
7912               ctx->Unpack = save;      /* restore */
7913            }
7914            break;
7915         case OPCODE_ENABLE:
7916            CALL_Enable(ctx->Exec, (n[1].e));
7917            break;
7918         case OPCODE_ENABLE_INDEXED:
7919            CALL_Enablei(ctx->Exec, (n[1].ui, n[2].e));
7920            break;
7921         case OPCODE_EVALMESH1:
7922            CALL_EvalMesh1(ctx->Exec, (n[1].e, n[2].i, n[3].i));
7923            break;
7924         case OPCODE_EVALMESH2:
7925            CALL_EvalMesh2(ctx->Exec,
7926                           (n[1].e, n[2].i, n[3].i, n[4].i, n[5].i));
7927            break;
7928         case OPCODE_FOG:
7929            {
7930               GLfloat p[4];
7931               p[0] = n[2].f;
7932               p[1] = n[3].f;
7933               p[2] = n[4].f;
7934               p[3] = n[5].f;
7935               CALL_Fogfv(ctx->Exec, (n[1].e, p));
7936            }
7937            break;
7938         case OPCODE_FRONT_FACE:
7939            CALL_FrontFace(ctx->Exec, (n[1].e));
7940            break;
7941         case OPCODE_FRUSTUM:
7942            CALL_Frustum(ctx->Exec,
7943                         (n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f));
7944            break;
7945         case OPCODE_HINT:
7946            CALL_Hint(ctx->Exec, (n[1].e, n[2].e));
7947            break;
7948         case OPCODE_INDEX_MASK:
7949            CALL_IndexMask(ctx->Exec, (n[1].ui));
7950            break;
7951         case OPCODE_INIT_NAMES:
7952            CALL_InitNames(ctx->Exec, ());
7953            break;
7954         case OPCODE_LIGHT:
7955            {
7956               GLfloat p[4];
7957               p[0] = n[3].f;
7958               p[1] = n[4].f;
7959               p[2] = n[5].f;
7960               p[3] = n[6].f;
7961               CALL_Lightfv(ctx->Exec, (n[1].e, n[2].e, p));
7962            }
7963            break;
7964         case OPCODE_LIGHT_MODEL:
7965            {
7966               GLfloat p[4];
7967               p[0] = n[2].f;
7968               p[1] = n[3].f;
7969               p[2] = n[4].f;
7970               p[3] = n[5].f;
7971               CALL_LightModelfv(ctx->Exec, (n[1].e, p));
7972            }
7973            break;
7974         case OPCODE_LINE_STIPPLE:
7975            CALL_LineStipple(ctx->Exec, (n[1].i, n[2].us));
7976            break;
7977         case OPCODE_LINE_WIDTH:
7978            CALL_LineWidth(ctx->Exec, (n[1].f));
7979            break;
7980         case OPCODE_LIST_BASE:
7981            CALL_ListBase(ctx->Exec, (n[1].ui));
7982            break;
7983         case OPCODE_LOAD_IDENTITY:
7984            CALL_LoadIdentity(ctx->Exec, ());
7985            break;
7986         case OPCODE_LOAD_MATRIX:
7987            if (sizeof(Node) == sizeof(GLfloat)) {
7988               CALL_LoadMatrixf(ctx->Exec, (&n[1].f));
7989            }
7990            else {
7991               GLfloat m[16];
7992               GLuint i;
7993               for (i = 0; i < 16; i++) {
7994                  m[i] = n[1 + i].f;
7995               }
7996               CALL_LoadMatrixf(ctx->Exec, (m));
7997            }
7998            break;
7999         case OPCODE_LOAD_NAME:
8000            CALL_LoadName(ctx->Exec, (n[1].ui));
8001            break;
8002         case OPCODE_LOGIC_OP:
8003            CALL_LogicOp(ctx->Exec, (n[1].e));
8004            break;
8005         case OPCODE_MAP1:
8006            {
8007               GLenum target = n[1].e;
8008               GLint ustride = _mesa_evaluator_components(target);
8009               GLint uorder = n[5].i;
8010               GLfloat u1 = n[2].f;
8011               GLfloat u2 = n[3].f;
8012               CALL_Map1f(ctx->Exec, (target, u1, u2, ustride, uorder,
8013                                      (GLfloat *) get_pointer(&n[6])));
8014            }
8015            break;
8016         case OPCODE_MAP2:
8017            {
8018               GLenum target = n[1].e;
8019               GLfloat u1 = n[2].f;
8020               GLfloat u2 = n[3].f;
8021               GLfloat v1 = n[4].f;
8022               GLfloat v2 = n[5].f;
8023               GLint ustride = n[6].i;
8024               GLint vstride = n[7].i;
8025               GLint uorder = n[8].i;
8026               GLint vorder = n[9].i;
8027               CALL_Map2f(ctx->Exec, (target, u1, u2, ustride, uorder,
8028                                      v1, v2, vstride, vorder,
8029                                      (GLfloat *) get_pointer(&n[10])));
8030            }
8031            break;
8032         case OPCODE_MAPGRID1:
8033            CALL_MapGrid1f(ctx->Exec, (n[1].i, n[2].f, n[3].f));
8034            break;
8035         case OPCODE_MAPGRID2:
8036            CALL_MapGrid2f(ctx->Exec,
8037                           (n[1].i, n[2].f, n[3].f, n[4].i, n[5].f, n[6].f));
8038            break;
8039         case OPCODE_MATRIX_MODE:
8040            CALL_MatrixMode(ctx->Exec, (n[1].e));
8041            break;
8042         case OPCODE_MULT_MATRIX:
8043            if (sizeof(Node) == sizeof(GLfloat)) {
8044               CALL_MultMatrixf(ctx->Exec, (&n[1].f));
8045            }
8046            else {
8047               GLfloat m[16];
8048               GLuint i;
8049               for (i = 0; i < 16; i++) {
8050                  m[i] = n[1 + i].f;
8051               }
8052               CALL_MultMatrixf(ctx->Exec, (m));
8053            }
8054            break;
8055         case OPCODE_ORTHO:
8056            CALL_Ortho(ctx->Exec,
8057                       (n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f));
8058            break;
8059         case OPCODE_PASSTHROUGH:
8060            CALL_PassThrough(ctx->Exec, (n[1].f));
8061            break;
8062         case OPCODE_PIXEL_MAP:
8063            CALL_PixelMapfv(ctx->Exec,
8064                            (n[1].e, n[2].i, get_pointer(&n[3])));
8065            break;
8066         case OPCODE_PIXEL_TRANSFER:
8067            CALL_PixelTransferf(ctx->Exec, (n[1].e, n[2].f));
8068            break;
8069         case OPCODE_PIXEL_ZOOM:
8070            CALL_PixelZoom(ctx->Exec, (n[1].f, n[2].f));
8071            break;
8072         case OPCODE_POINT_SIZE:
8073            CALL_PointSize(ctx->Exec, (n[1].f));
8074            break;
8075         case OPCODE_POINT_PARAMETERS:
8076            {
8077               GLfloat params[3];
8078               params[0] = n[2].f;
8079               params[1] = n[3].f;
8080               params[2] = n[4].f;
8081               CALL_PointParameterfv(ctx->Exec, (n[1].e, params));
8082            }
8083            break;
8084         case OPCODE_POLYGON_MODE:
8085            CALL_PolygonMode(ctx->Exec, (n[1].e, n[2].e));
8086            break;
8087         case OPCODE_POLYGON_STIPPLE:
8088            {
8089               const struct gl_pixelstore_attrib save = ctx->Unpack;
8090               ctx->Unpack = ctx->DefaultPacking;
8091               CALL_PolygonStipple(ctx->Exec, (get_pointer(&n[1])));
8092               ctx->Unpack = save;      /* restore */
8093            }
8094            break;
8095         case OPCODE_POLYGON_OFFSET:
8096            CALL_PolygonOffset(ctx->Exec, (n[1].f, n[2].f));
8097            break;
8098         case OPCODE_POP_ATTRIB:
8099            CALL_PopAttrib(ctx->Exec, ());
8100            break;
8101         case OPCODE_POP_MATRIX:
8102            CALL_PopMatrix(ctx->Exec, ());
8103            break;
8104         case OPCODE_POP_NAME:
8105            CALL_PopName(ctx->Exec, ());
8106            break;
8107         case OPCODE_PRIORITIZE_TEXTURE:
8108            CALL_PrioritizeTextures(ctx->Exec, (1, &n[1].ui, &n[2].f));
8109            break;
8110         case OPCODE_PUSH_ATTRIB:
8111            CALL_PushAttrib(ctx->Exec, (n[1].bf));
8112            break;
8113         case OPCODE_PUSH_MATRIX:
8114            CALL_PushMatrix(ctx->Exec, ());
8115            break;
8116         case OPCODE_PUSH_NAME:
8117            CALL_PushName(ctx->Exec, (n[1].ui));
8118            break;
8119         case OPCODE_RASTER_POS:
8120            CALL_RasterPos4f(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
8121            break;
8122         case OPCODE_READ_BUFFER:
8123            CALL_ReadBuffer(ctx->Exec, (n[1].e));
8124            break;
8125         case OPCODE_ROTATE:
8126            CALL_Rotatef(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
8127            break;
8128         case OPCODE_SCALE:
8129            CALL_Scalef(ctx->Exec, (n[1].f, n[2].f, n[3].f));
8130            break;
8131         case OPCODE_SCISSOR:
8132            CALL_Scissor(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i));
8133            break;
8134         case OPCODE_SHADE_MODEL:
8135            CALL_ShadeModel(ctx->Exec, (n[1].e));
8136            break;
8137         case OPCODE_PROVOKING_VERTEX:
8138            CALL_ProvokingVertex(ctx->Exec, (n[1].e));
8139            break;
8140         case OPCODE_STENCIL_FUNC:
8141            CALL_StencilFunc(ctx->Exec, (n[1].e, n[2].i, n[3].ui));
8142            break;
8143         case OPCODE_STENCIL_MASK:
8144            CALL_StencilMask(ctx->Exec, (n[1].ui));
8145            break;
8146         case OPCODE_STENCIL_OP:
8147            CALL_StencilOp(ctx->Exec, (n[1].e, n[2].e, n[3].e));
8148            break;
8149         case OPCODE_STENCIL_FUNC_SEPARATE:
8150            CALL_StencilFuncSeparate(ctx->Exec,
8151                                     (n[1].e, n[2].e, n[3].i, n[4].ui));
8152            break;
8153         case OPCODE_STENCIL_MASK_SEPARATE:
8154            CALL_StencilMaskSeparate(ctx->Exec, (n[1].e, n[2].ui));
8155            break;
8156         case OPCODE_STENCIL_OP_SEPARATE:
8157            CALL_StencilOpSeparate(ctx->Exec,
8158                                   (n[1].e, n[2].e, n[3].e, n[4].e));
8159            break;
8160         case OPCODE_TEXENV:
8161            {
8162               GLfloat params[4];
8163               params[0] = n[3].f;
8164               params[1] = n[4].f;
8165               params[2] = n[5].f;
8166               params[3] = n[6].f;
8167               CALL_TexEnvfv(ctx->Exec, (n[1].e, n[2].e, params));
8168            }
8169            break;
8170         case OPCODE_TEXGEN:
8171            {
8172               GLfloat params[4];
8173               params[0] = n[3].f;
8174               params[1] = n[4].f;
8175               params[2] = n[5].f;
8176               params[3] = n[6].f;
8177               CALL_TexGenfv(ctx->Exec, (n[1].e, n[2].e, params));
8178            }
8179            break;
8180         case OPCODE_TEXPARAMETER:
8181            {
8182               GLfloat params[4];
8183               params[0] = n[3].f;
8184               params[1] = n[4].f;
8185               params[2] = n[5].f;
8186               params[3] = n[6].f;
8187               CALL_TexParameterfv(ctx->Exec, (n[1].e, n[2].e, params));
8188            }
8189            break;
8190         case OPCODE_TEX_IMAGE1D:
8191            {
8192               const struct gl_pixelstore_attrib save = ctx->Unpack;
8193               ctx->Unpack = ctx->DefaultPacking;
8194               CALL_TexImage1D(ctx->Exec, (n[1].e,      /* target */
8195                                           n[2].i,      /* level */
8196                                           n[3].i,      /* components */
8197                                           n[4].i,      /* width */
8198                                           n[5].e,      /* border */
8199                                           n[6].e,      /* format */
8200                                           n[7].e,      /* type */
8201                                           get_pointer(&n[8])));
8202               ctx->Unpack = save;      /* restore */
8203            }
8204            break;
8205         case OPCODE_TEX_IMAGE2D:
8206            {
8207               const struct gl_pixelstore_attrib save = ctx->Unpack;
8208               ctx->Unpack = ctx->DefaultPacking;
8209               CALL_TexImage2D(ctx->Exec, (n[1].e,      /* target */
8210                                           n[2].i,      /* level */
8211                                           n[3].i,      /* components */
8212                                           n[4].i,      /* width */
8213                                           n[5].i,      /* height */
8214                                           n[6].e,      /* border */
8215                                           n[7].e,      /* format */
8216                                           n[8].e,      /* type */
8217                                           get_pointer(&n[9])));
8218               ctx->Unpack = save;      /* restore */
8219            }
8220            break;
8221         case OPCODE_TEX_IMAGE3D:
8222            {
8223               const struct gl_pixelstore_attrib save = ctx->Unpack;
8224               ctx->Unpack = ctx->DefaultPacking;
8225               CALL_TexImage3D(ctx->Exec, (n[1].e,      /* target */
8226                                           n[2].i,      /* level */
8227                                           n[3].i,      /* components */
8228                                           n[4].i,      /* width */
8229                                           n[5].i,      /* height */
8230                                           n[6].i,      /* depth  */
8231                                           n[7].e,      /* border */
8232                                           n[8].e,      /* format */
8233                                           n[9].e,      /* type */
8234                                           get_pointer(&n[10])));
8235               ctx->Unpack = save;      /* restore */
8236            }
8237            break;
8238         case OPCODE_TEX_SUB_IMAGE1D:
8239            {
8240               const struct gl_pixelstore_attrib save = ctx->Unpack;
8241               ctx->Unpack = ctx->DefaultPacking;
8242               CALL_TexSubImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
8243                                              n[4].i, n[5].e,
8244                                              n[6].e, get_pointer(&n[7])));
8245               ctx->Unpack = save;      /* restore */
8246            }
8247            break;
8248         case OPCODE_TEX_SUB_IMAGE2D:
8249            {
8250               const struct gl_pixelstore_attrib save = ctx->Unpack;
8251               ctx->Unpack = ctx->DefaultPacking;
8252               CALL_TexSubImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
8253                                              n[4].i, n[5].e,
8254                                              n[6].i, n[7].e, n[8].e,
8255                                              get_pointer(&n[9])));
8256               ctx->Unpack = save;      /* restore */
8257            }
8258            break;
8259         case OPCODE_TEX_SUB_IMAGE3D:
8260            {
8261               const struct gl_pixelstore_attrib save = ctx->Unpack;
8262               ctx->Unpack = ctx->DefaultPacking;
8263               CALL_TexSubImage3D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
8264                                              n[4].i, n[5].i, n[6].i, n[7].i,
8265                                              n[8].i, n[9].e, n[10].e,
8266                                              get_pointer(&n[11])));
8267               ctx->Unpack = save;      /* restore */
8268            }
8269            break;
8270         case OPCODE_TRANSLATE:
8271            CALL_Translatef(ctx->Exec, (n[1].f, n[2].f, n[3].f));
8272            break;
8273         case OPCODE_VIEWPORT:
8274            CALL_Viewport(ctx->Exec, (n[1].i, n[2].i,
8275                                      (GLsizei) n[3].i, (GLsizei) n[4].i));
8276            break;
8277         case OPCODE_WINDOW_POS:
8278            CALL_WindowPos4fMESA(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
8279            break;
8280         case OPCODE_ACTIVE_TEXTURE:   /* GL_ARB_multitexture */
8281            CALL_ActiveTexture(ctx->Exec, (n[1].e));
8282            break;
8283         case OPCODE_COMPRESSED_TEX_IMAGE_1D:  /* GL_ARB_texture_compression */
8284            CALL_CompressedTexImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].e,
8285                                                  n[4].i, n[5].i, n[6].i,
8286                                                  get_pointer(&n[7])));
8287            break;
8288         case OPCODE_COMPRESSED_TEX_IMAGE_2D:  /* GL_ARB_texture_compression */
8289            CALL_CompressedTexImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].e,
8290                                                  n[4].i, n[5].i, n[6].i,
8291                                                  n[7].i, get_pointer(&n[8])));
8292            break;
8293         case OPCODE_COMPRESSED_TEX_IMAGE_3D:  /* GL_ARB_texture_compression */
8294            CALL_CompressedTexImage3D(ctx->Exec, (n[1].e, n[2].i, n[3].e,
8295                                                  n[4].i, n[5].i, n[6].i,
8296                                                  n[7].i, n[8].i,
8297                                                  get_pointer(&n[9])));
8298            break;
8299         case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D:      /* GL_ARB_texture_compress */
8300            CALL_CompressedTexSubImage1D(ctx->Exec,
8301                                            (n[1].e, n[2].i, n[3].i, n[4].i,
8302                                             n[5].e, n[6].i,
8303                                             get_pointer(&n[7])));
8304            break;
8305         case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D:      /* GL_ARB_texture_compress */
8306            CALL_CompressedTexSubImage2D(ctx->Exec,
8307                                            (n[1].e, n[2].i, n[3].i, n[4].i,
8308                                             n[5].i, n[6].i, n[7].e, n[8].i,
8309                                             get_pointer(&n[9])));
8310            break;
8311         case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D:      /* GL_ARB_texture_compress */
8312            CALL_CompressedTexSubImage3D(ctx->Exec,
8313                                            (n[1].e, n[2].i, n[3].i, n[4].i,
8314                                             n[5].i, n[6].i, n[7].i, n[8].i,
8315                                             n[9].e, n[10].i,
8316                                             get_pointer(&n[11])));
8317            break;
8318         case OPCODE_SAMPLE_COVERAGE:  /* GL_ARB_multisample */
8319            CALL_SampleCoverage(ctx->Exec, (n[1].f, n[2].b));
8320            break;
8321         case OPCODE_WINDOW_POS_ARB:   /* GL_ARB_window_pos */
8322            CALL_WindowPos3f(ctx->Exec, (n[1].f, n[2].f, n[3].f));
8323            break;
8324         case OPCODE_BIND_PROGRAM_NV:  /* GL_ARB_vertex_program */
8325            CALL_BindProgramARB(ctx->Exec, (n[1].e, n[2].ui));
8326            break;
8327         case OPCODE_PROGRAM_LOCAL_PARAMETER_ARB:
8328            CALL_ProgramLocalParameter4fARB(ctx->Exec,
8329                                            (n[1].e, n[2].ui, n[3].f, n[4].f,
8330                                             n[5].f, n[6].f));
8331            break;
8332         case OPCODE_ACTIVE_STENCIL_FACE_EXT:
8333            CALL_ActiveStencilFaceEXT(ctx->Exec, (n[1].e));
8334            break;
8335         case OPCODE_DEPTH_BOUNDS_EXT:
8336            CALL_DepthBoundsEXT(ctx->Exec, (n[1].f, n[2].f));
8337            break;
8338         case OPCODE_PROGRAM_STRING_ARB:
8339            CALL_ProgramStringARB(ctx->Exec,
8340                                  (n[1].e, n[2].e, n[3].i,
8341                                   get_pointer(&n[4])));
8342            break;
8343         case OPCODE_PROGRAM_ENV_PARAMETER_ARB:
8344            CALL_ProgramEnvParameter4fARB(ctx->Exec, (n[1].e, n[2].ui, n[3].f,
8345                                                      n[4].f, n[5].f,
8346                                                      n[6].f));
8347            break;
8348         case OPCODE_BEGIN_QUERY_ARB:
8349            CALL_BeginQuery(ctx->Exec, (n[1].e, n[2].ui));
8350            break;
8351         case OPCODE_END_QUERY_ARB:
8352            CALL_EndQuery(ctx->Exec, (n[1].e));
8353            break;
8354         case OPCODE_QUERY_COUNTER:
8355            CALL_QueryCounter(ctx->Exec, (n[1].ui, n[2].e));
8356            break;
8357         case OPCODE_BEGIN_QUERY_INDEXED:
8358            CALL_BeginQueryIndexed(ctx->Exec, (n[1].e, n[2].ui, n[3].ui));
8359            break;
8360         case OPCODE_END_QUERY_INDEXED:
8361            CALL_EndQueryIndexed(ctx->Exec, (n[1].e, n[2].ui));
8362            break;
8363         case OPCODE_DRAW_BUFFERS_ARB:
8364            {
8365               GLenum buffers[MAX_DRAW_BUFFERS];
8366               GLint i, count = MIN2(n[1].i, MAX_DRAW_BUFFERS);
8367               for (i = 0; i < count; i++)
8368                  buffers[i] = n[2 + i].e;
8369               CALL_DrawBuffers(ctx->Exec, (n[1].i, buffers));
8370            }
8371            break;
8372	 case OPCODE_BLIT_FRAMEBUFFER:
8373	    CALL_BlitFramebuffer(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i,
8374                                                n[5].i, n[6].i, n[7].i, n[8].i,
8375                                                n[9].i, n[10].e));
8376	    break;
8377	 case OPCODE_USE_PROGRAM:
8378	    CALL_UseProgram(ctx->Exec, (n[1].ui));
8379	    break;
8380	 case OPCODE_UNIFORM_1F:
8381	    CALL_Uniform1f(ctx->Exec, (n[1].i, n[2].f));
8382	    break;
8383	 case OPCODE_UNIFORM_2F:
8384	    CALL_Uniform2f(ctx->Exec, (n[1].i, n[2].f, n[3].f));
8385	    break;
8386	 case OPCODE_UNIFORM_3F:
8387	    CALL_Uniform3f(ctx->Exec, (n[1].i, n[2].f, n[3].f, n[4].f));
8388	    break;
8389	 case OPCODE_UNIFORM_4F:
8390	    CALL_Uniform4f(ctx->Exec,
8391                              (n[1].i, n[2].f, n[3].f, n[4].f, n[5].f));
8392	    break;
8393	 case OPCODE_UNIFORM_1FV:
8394	    CALL_Uniform1fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
8395	    break;
8396	 case OPCODE_UNIFORM_2FV:
8397	    CALL_Uniform2fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
8398	    break;
8399	 case OPCODE_UNIFORM_3FV:
8400	    CALL_Uniform3fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
8401	    break;
8402	 case OPCODE_UNIFORM_4FV:
8403	    CALL_Uniform4fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
8404	    break;
8405	 case OPCODE_UNIFORM_1I:
8406	    CALL_Uniform1i(ctx->Exec, (n[1].i, n[2].i));
8407	    break;
8408	 case OPCODE_UNIFORM_2I:
8409	    CALL_Uniform2i(ctx->Exec, (n[1].i, n[2].i, n[3].i));
8410	    break;
8411	 case OPCODE_UNIFORM_3I:
8412	    CALL_Uniform3i(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i));
8413	    break;
8414	 case OPCODE_UNIFORM_4I:
8415	    CALL_Uniform4i(ctx->Exec,
8416                              (n[1].i, n[2].i, n[3].i, n[4].i, n[5].i));
8417	    break;
8418	 case OPCODE_UNIFORM_1IV:
8419	    CALL_Uniform1iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
8420	    break;
8421	 case OPCODE_UNIFORM_2IV:
8422	    CALL_Uniform2iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
8423	    break;
8424	 case OPCODE_UNIFORM_3IV:
8425	    CALL_Uniform3iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
8426	    break;
8427	 case OPCODE_UNIFORM_4IV:
8428	    CALL_Uniform4iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
8429	    break;
8430	 case OPCODE_UNIFORM_1UI:
8431	    /*CALL_Uniform1uiARB(ctx->Exec, (n[1].i, n[2].i));*/
8432	    break;
8433	 case OPCODE_UNIFORM_2UI:
8434	    /*CALL_Uniform2uiARB(ctx->Exec, (n[1].i, n[2].i, n[3].i));*/
8435	    break;
8436	 case OPCODE_UNIFORM_3UI:
8437	    /*CALL_Uniform3uiARB(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i));*/
8438	    break;
8439	 case OPCODE_UNIFORM_4UI:
8440	    /*CALL_Uniform4uiARB(ctx->Exec,
8441                              (n[1].i, n[2].i, n[3].i, n[4].i, n[5].i));
8442            */
8443	    break;
8444	 case OPCODE_UNIFORM_1UIV:
8445	    /*CALL_Uniform1uivARB(ctx->Exec, (n[1].i, n[2].i,
8446                                              get_pointer(&n[3])));*/
8447	    break;
8448	 case OPCODE_UNIFORM_2UIV:
8449	    /*CALL_Uniform2uivARB(ctx->Exec, (n[1].i, n[2].i,
8450                                              get_pointer(&n[3])));*/
8451	    break;
8452	 case OPCODE_UNIFORM_3UIV:
8453	    /*CALL_Uniform3uivARB(ctx->Exec, (n[1].i, n[2].i,
8454                                              get_pointer(&n[3])));*/
8455	    break;
8456	 case OPCODE_UNIFORM_4UIV:
8457	    /*CALL_Uniform4uivARB(ctx->Exec, (n[1].i, n[2].i,
8458                                              get_pointer(&n[3])));*/
8459	    break;
8460	 case OPCODE_UNIFORM_MATRIX22:
8461	    CALL_UniformMatrix2fv(ctx->Exec,
8462                                  (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
8463	    break;
8464	 case OPCODE_UNIFORM_MATRIX33:
8465	    CALL_UniformMatrix3fv(ctx->Exec,
8466                                  (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
8467	    break;
8468	 case OPCODE_UNIFORM_MATRIX44:
8469	    CALL_UniformMatrix4fv(ctx->Exec,
8470                                  (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
8471	    break;
8472	 case OPCODE_UNIFORM_MATRIX23:
8473	    CALL_UniformMatrix2x3fv(ctx->Exec,
8474                                    (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
8475	    break;
8476	 case OPCODE_UNIFORM_MATRIX32:
8477	    CALL_UniformMatrix3x2fv(ctx->Exec,
8478                                    (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
8479	    break;
8480	 case OPCODE_UNIFORM_MATRIX24:
8481	    CALL_UniformMatrix2x4fv(ctx->Exec,
8482                                    (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
8483	    break;
8484	 case OPCODE_UNIFORM_MATRIX42:
8485	    CALL_UniformMatrix4x2fv(ctx->Exec,
8486                                    (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
8487	    break;
8488	 case OPCODE_UNIFORM_MATRIX34:
8489	    CALL_UniformMatrix3x4fv(ctx->Exec,
8490                                    (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
8491	    break;
8492	 case OPCODE_UNIFORM_MATRIX43:
8493	    CALL_UniformMatrix4x3fv(ctx->Exec,
8494                                    (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
8495	    break;
8496
8497	 case OPCODE_USE_PROGRAM_STAGES:
8498	    CALL_UseProgramStages(ctx->Exec, (n[1].ui, n[2].ui, n[3].ui));
8499	    break;
8500         case OPCODE_PROGRAM_UNIFORM_1F:
8501            CALL_ProgramUniform1f(ctx->Exec, (n[1].ui, n[2].i, n[3].f));
8502            break;
8503         case OPCODE_PROGRAM_UNIFORM_2F:
8504            CALL_ProgramUniform2f(ctx->Exec, (n[1].ui, n[2].i, n[3].f, n[4].f));
8505            break;
8506         case OPCODE_PROGRAM_UNIFORM_3F:
8507            CALL_ProgramUniform3f(ctx->Exec, (n[1].ui, n[2].i,
8508                                              n[3].f, n[4].f, n[5].f));
8509            break;
8510         case OPCODE_PROGRAM_UNIFORM_4F:
8511            CALL_ProgramUniform4f(ctx->Exec, (n[1].ui, n[2].i,
8512                                              n[3].f, n[4].f, n[5].f, n[6].f));
8513            break;
8514         case OPCODE_PROGRAM_UNIFORM_1FV:
8515            CALL_ProgramUniform1fv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
8516                                               get_pointer(&n[4])));
8517            break;
8518         case OPCODE_PROGRAM_UNIFORM_2FV:
8519            CALL_ProgramUniform2fv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
8520                                               get_pointer(&n[4])));
8521            break;
8522         case OPCODE_PROGRAM_UNIFORM_3FV:
8523            CALL_ProgramUniform3fv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
8524                                               get_pointer(&n[4])));
8525            break;
8526         case OPCODE_PROGRAM_UNIFORM_4FV:
8527            CALL_ProgramUniform4fv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
8528                                               get_pointer(&n[4])));
8529            break;
8530         case OPCODE_PROGRAM_UNIFORM_1I:
8531            CALL_ProgramUniform1i(ctx->Exec, (n[1].ui, n[2].i, n[3].i));
8532            break;
8533         case OPCODE_PROGRAM_UNIFORM_2I:
8534            CALL_ProgramUniform2i(ctx->Exec, (n[1].ui, n[2].i, n[3].i, n[4].i));
8535            break;
8536         case OPCODE_PROGRAM_UNIFORM_3I:
8537            CALL_ProgramUniform3i(ctx->Exec, (n[1].ui, n[2].i,
8538                                              n[3].i, n[4].i, n[5].i));
8539            break;
8540         case OPCODE_PROGRAM_UNIFORM_4I:
8541            CALL_ProgramUniform4i(ctx->Exec, (n[1].ui, n[2].i,
8542                                              n[3].i, n[4].i, n[5].i, n[6].i));
8543            break;
8544         case OPCODE_PROGRAM_UNIFORM_1IV:
8545            CALL_ProgramUniform1iv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
8546                                               get_pointer(&n[4])));
8547            break;
8548         case OPCODE_PROGRAM_UNIFORM_2IV:
8549            CALL_ProgramUniform2iv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
8550                                               get_pointer(&n[4])));
8551            break;
8552         case OPCODE_PROGRAM_UNIFORM_3IV:
8553            CALL_ProgramUniform3iv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
8554                                               get_pointer(&n[4])));
8555            break;
8556         case OPCODE_PROGRAM_UNIFORM_4IV:
8557            CALL_ProgramUniform4iv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
8558                                               get_pointer(&n[4])));
8559            break;
8560         case OPCODE_PROGRAM_UNIFORM_1UI:
8561            CALL_ProgramUniform1ui(ctx->Exec, (n[1].ui, n[2].i, n[3].ui));
8562            break;
8563         case OPCODE_PROGRAM_UNIFORM_2UI:
8564            CALL_ProgramUniform2ui(ctx->Exec, (n[1].ui, n[2].i,
8565                                               n[3].ui, n[4].ui));
8566            break;
8567         case OPCODE_PROGRAM_UNIFORM_3UI:
8568            CALL_ProgramUniform3ui(ctx->Exec, (n[1].ui, n[2].i,
8569                                               n[3].ui, n[4].ui, n[5].ui));
8570            break;
8571         case OPCODE_PROGRAM_UNIFORM_4UI:
8572            CALL_ProgramUniform4ui(ctx->Exec, (n[1].ui, n[2].i,
8573                                               n[3].ui,
8574                                               n[4].ui, n[5].ui, n[6].ui));
8575            break;
8576         case OPCODE_PROGRAM_UNIFORM_1UIV:
8577            CALL_ProgramUniform1uiv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
8578                                                get_pointer(&n[4])));
8579            break;
8580         case OPCODE_PROGRAM_UNIFORM_2UIV:
8581            CALL_ProgramUniform2uiv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
8582                                                get_pointer(&n[4])));
8583            break;
8584         case OPCODE_PROGRAM_UNIFORM_3UIV:
8585            CALL_ProgramUniform3uiv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
8586                                                get_pointer(&n[4])));
8587            break;
8588         case OPCODE_PROGRAM_UNIFORM_4UIV:
8589            CALL_ProgramUniform4uiv(ctx->Exec, (n[1].ui, n[2].i, n[3].i,
8590                                                get_pointer(&n[4])));
8591            break;
8592         case OPCODE_PROGRAM_UNIFORM_MATRIX22F:
8593            CALL_ProgramUniformMatrix2fv(ctx->Exec,
8594                                         (n[1].ui, n[2].i, n[3].i, n[4].b,
8595                                          get_pointer(&n[5])));
8596            break;
8597         case OPCODE_PROGRAM_UNIFORM_MATRIX23F:
8598            CALL_ProgramUniformMatrix2x3fv(ctx->Exec,
8599                                           (n[1].ui, n[2].i, n[3].i, n[4].b,
8600                                            get_pointer(&n[5])));
8601            break;
8602         case OPCODE_PROGRAM_UNIFORM_MATRIX24F:
8603            CALL_ProgramUniformMatrix2x4fv(ctx->Exec,
8604                                           (n[1].ui, n[2].i, n[3].i, n[4].b,
8605                                            get_pointer(&n[5])));
8606            break;
8607         case OPCODE_PROGRAM_UNIFORM_MATRIX32F:
8608            CALL_ProgramUniformMatrix3x2fv(ctx->Exec,
8609                                           (n[1].ui, n[2].i, n[3].i, n[4].b,
8610                                            get_pointer(&n[5])));
8611            break;
8612         case OPCODE_PROGRAM_UNIFORM_MATRIX33F:
8613            CALL_ProgramUniformMatrix3fv(ctx->Exec,
8614                                         (n[1].ui, n[2].i, n[3].i, n[4].b,
8615                                          get_pointer(&n[5])));
8616            break;
8617         case OPCODE_PROGRAM_UNIFORM_MATRIX34F:
8618            CALL_ProgramUniformMatrix3x4fv(ctx->Exec,
8619                                           (n[1].ui, n[2].i, n[3].i, n[4].b,
8620                                            get_pointer(&n[5])));
8621            break;
8622         case OPCODE_PROGRAM_UNIFORM_MATRIX42F:
8623            CALL_ProgramUniformMatrix4x2fv(ctx->Exec,
8624                                           (n[1].ui, n[2].i, n[3].i, n[4].b,
8625                                            get_pointer(&n[5])));
8626            break;
8627         case OPCODE_PROGRAM_UNIFORM_MATRIX43F:
8628            CALL_ProgramUniformMatrix4x3fv(ctx->Exec,
8629                                           (n[1].ui, n[2].i, n[3].i, n[4].b,
8630                                            get_pointer(&n[5])));
8631            break;
8632         case OPCODE_PROGRAM_UNIFORM_MATRIX44F:
8633            CALL_ProgramUniformMatrix4fv(ctx->Exec,
8634                                         (n[1].ui, n[2].i, n[3].i, n[4].b,
8635                                          get_pointer(&n[5])));
8636            break;
8637
8638         case OPCODE_CLAMP_COLOR:
8639            CALL_ClampColor(ctx->Exec, (n[1].e, n[2].e));
8640            break;
8641
8642         case OPCODE_BIND_FRAGMENT_SHADER_ATI:
8643            CALL_BindFragmentShaderATI(ctx->Exec, (n[1].i));
8644            break;
8645         case OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI:
8646            {
8647               GLfloat values[4];
8648               GLuint i, dst = n[1].ui;
8649
8650               for (i = 0; i < 4; i++)
8651                  values[i] = n[1 + i].f;
8652               CALL_SetFragmentShaderConstantATI(ctx->Exec, (dst, values));
8653            }
8654            break;
8655         case OPCODE_ATTR_1F_NV:
8656            CALL_VertexAttrib1fNV(ctx->Exec, (n[1].e, n[2].f));
8657            break;
8658         case OPCODE_ATTR_2F_NV:
8659            /* Really shouldn't have to do this - the Node structure
8660             * is convenient, but it would be better to store the data
8661             * packed appropriately so that it can be sent directly
8662             * on.  With x86_64 becoming common, this will start to
8663             * matter more.
8664             */
8665            if (sizeof(Node) == sizeof(GLfloat))
8666               CALL_VertexAttrib2fvNV(ctx->Exec, (n[1].e, &n[2].f));
8667            else
8668               CALL_VertexAttrib2fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f));
8669            break;
8670         case OPCODE_ATTR_3F_NV:
8671            if (sizeof(Node) == sizeof(GLfloat))
8672               CALL_VertexAttrib3fvNV(ctx->Exec, (n[1].e, &n[2].f));
8673            else
8674               CALL_VertexAttrib3fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f,
8675                                                 n[4].f));
8676            break;
8677         case OPCODE_ATTR_4F_NV:
8678            if (sizeof(Node) == sizeof(GLfloat))
8679               CALL_VertexAttrib4fvNV(ctx->Exec, (n[1].e, &n[2].f));
8680            else
8681               CALL_VertexAttrib4fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f,
8682                                                 n[4].f, n[5].f));
8683            break;
8684         case OPCODE_ATTR_1F_ARB:
8685            CALL_VertexAttrib1fARB(ctx->Exec, (n[1].e, n[2].f));
8686            break;
8687         case OPCODE_ATTR_2F_ARB:
8688            /* Really shouldn't have to do this - the Node structure
8689             * is convenient, but it would be better to store the data
8690             * packed appropriately so that it can be sent directly
8691             * on.  With x86_64 becoming common, this will start to
8692             * matter more.
8693             */
8694            if (sizeof(Node) == sizeof(GLfloat))
8695               CALL_VertexAttrib2fvARB(ctx->Exec, (n[1].e, &n[2].f));
8696            else
8697               CALL_VertexAttrib2fARB(ctx->Exec, (n[1].e, n[2].f, n[3].f));
8698            break;
8699         case OPCODE_ATTR_3F_ARB:
8700            if (sizeof(Node) == sizeof(GLfloat))
8701               CALL_VertexAttrib3fvARB(ctx->Exec, (n[1].e, &n[2].f));
8702            else
8703               CALL_VertexAttrib3fARB(ctx->Exec, (n[1].e, n[2].f, n[3].f,
8704                                                  n[4].f));
8705            break;
8706         case OPCODE_ATTR_4F_ARB:
8707            if (sizeof(Node) == sizeof(GLfloat))
8708               CALL_VertexAttrib4fvARB(ctx->Exec, (n[1].e, &n[2].f));
8709            else
8710               CALL_VertexAttrib4fARB(ctx->Exec, (n[1].e, n[2].f, n[3].f,
8711                                                  n[4].f, n[5].f));
8712            break;
8713         case OPCODE_MATERIAL:
8714            if (sizeof(Node) == sizeof(GLfloat))
8715               CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, &n[3].f));
8716            else {
8717               GLfloat f[4];
8718               f[0] = n[3].f;
8719               f[1] = n[4].f;
8720               f[2] = n[5].f;
8721               f[3] = n[6].f;
8722               CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, f));
8723            }
8724            break;
8725         case OPCODE_BEGIN:
8726            CALL_Begin(ctx->Exec, (n[1].e));
8727            break;
8728         case OPCODE_END:
8729            CALL_End(ctx->Exec, ());
8730            break;
8731         case OPCODE_RECTF:
8732            CALL_Rectf(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
8733            break;
8734         case OPCODE_EVAL_C1:
8735            CALL_EvalCoord1f(ctx->Exec, (n[1].f));
8736            break;
8737         case OPCODE_EVAL_C2:
8738            CALL_EvalCoord2f(ctx->Exec, (n[1].f, n[2].f));
8739            break;
8740         case OPCODE_EVAL_P1:
8741            CALL_EvalPoint1(ctx->Exec, (n[1].i));
8742            break;
8743         case OPCODE_EVAL_P2:
8744            CALL_EvalPoint2(ctx->Exec, (n[1].i, n[2].i));
8745            break;
8746
8747         /* GL_EXT_texture_integer */
8748         case OPCODE_CLEARCOLOR_I:
8749            CALL_ClearColorIiEXT(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i));
8750            break;
8751         case OPCODE_CLEARCOLOR_UI:
8752            CALL_ClearColorIuiEXT(ctx->Exec,
8753                                  (n[1].ui, n[2].ui, n[3].ui, n[4].ui));
8754            break;
8755         case OPCODE_TEXPARAMETER_I:
8756            {
8757               GLint params[4];
8758               params[0] = n[3].i;
8759               params[1] = n[4].i;
8760               params[2] = n[5].i;
8761               params[3] = n[6].i;
8762               CALL_TexParameterIiv(ctx->Exec, (n[1].e, n[2].e, params));
8763            }
8764            break;
8765         case OPCODE_TEXPARAMETER_UI:
8766            {
8767               GLuint params[4];
8768               params[0] = n[3].ui;
8769               params[1] = n[4].ui;
8770               params[2] = n[5].ui;
8771               params[3] = n[6].ui;
8772               CALL_TexParameterIuiv(ctx->Exec, (n[1].e, n[2].e, params));
8773            }
8774            break;
8775
8776         case OPCODE_VERTEX_ATTRIB_DIVISOR:
8777            /* GL_ARB_instanced_arrays */
8778            CALL_VertexAttribDivisor(ctx->Exec, (n[1].ui, n[2].ui));
8779            break;
8780
8781         case OPCODE_TEXTURE_BARRIER_NV:
8782            CALL_TextureBarrierNV(ctx->Exec, ());
8783            break;
8784
8785         /* GL_EXT/ARB_transform_feedback */
8786         case OPCODE_BEGIN_TRANSFORM_FEEDBACK:
8787            CALL_BeginTransformFeedback(ctx->Exec, (n[1].e));
8788            break;
8789         case OPCODE_END_TRANSFORM_FEEDBACK:
8790            CALL_EndTransformFeedback(ctx->Exec, ());
8791            break;
8792         case OPCODE_BIND_TRANSFORM_FEEDBACK:
8793            CALL_BindTransformFeedback(ctx->Exec, (n[1].e, n[2].ui));
8794            break;
8795         case OPCODE_PAUSE_TRANSFORM_FEEDBACK:
8796            CALL_PauseTransformFeedback(ctx->Exec, ());
8797            break;
8798         case OPCODE_RESUME_TRANSFORM_FEEDBACK:
8799            CALL_ResumeTransformFeedback(ctx->Exec, ());
8800            break;
8801         case OPCODE_DRAW_TRANSFORM_FEEDBACK:
8802            CALL_DrawTransformFeedback(ctx->Exec, (n[1].e, n[2].ui));
8803            break;
8804         case OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM:
8805            CALL_DrawTransformFeedbackStream(ctx->Exec,
8806                                             (n[1].e, n[2].ui, n[3].ui));
8807            break;
8808         case OPCODE_DRAW_TRANSFORM_FEEDBACK_INSTANCED:
8809            CALL_DrawTransformFeedbackInstanced(ctx->Exec,
8810                                                (n[1].e, n[2].ui, n[3].si));
8811            break;
8812         case OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM_INSTANCED:
8813            CALL_DrawTransformFeedbackStreamInstanced(ctx->Exec,
8814                                       (n[1].e, n[2].ui, n[3].ui, n[4].si));
8815            break;
8816
8817
8818         case OPCODE_BIND_SAMPLER:
8819            CALL_BindSampler(ctx->Exec, (n[1].ui, n[2].ui));
8820            break;
8821         case OPCODE_SAMPLER_PARAMETERIV:
8822            {
8823               GLint params[4];
8824               params[0] = n[3].i;
8825               params[1] = n[4].i;
8826               params[2] = n[5].i;
8827               params[3] = n[6].i;
8828               CALL_SamplerParameteriv(ctx->Exec, (n[1].ui, n[2].e, params));
8829            }
8830            break;
8831         case OPCODE_SAMPLER_PARAMETERFV:
8832            {
8833               GLfloat params[4];
8834               params[0] = n[3].f;
8835               params[1] = n[4].f;
8836               params[2] = n[5].f;
8837               params[3] = n[6].f;
8838               CALL_SamplerParameterfv(ctx->Exec, (n[1].ui, n[2].e, params));
8839            }
8840            break;
8841         case OPCODE_SAMPLER_PARAMETERIIV:
8842            {
8843               GLint params[4];
8844               params[0] = n[3].i;
8845               params[1] = n[4].i;
8846               params[2] = n[5].i;
8847               params[3] = n[6].i;
8848               CALL_SamplerParameterIiv(ctx->Exec, (n[1].ui, n[2].e, params));
8849            }
8850            break;
8851         case OPCODE_SAMPLER_PARAMETERUIV:
8852            {
8853               GLuint params[4];
8854               params[0] = n[3].ui;
8855               params[1] = n[4].ui;
8856               params[2] = n[5].ui;
8857               params[3] = n[6].ui;
8858               CALL_SamplerParameterIuiv(ctx->Exec, (n[1].ui, n[2].e, params));
8859            }
8860            break;
8861
8862         /* GL_ARB_geometry_shader4 */
8863         case OPCODE_PROGRAM_PARAMETERI:
8864            CALL_ProgramParameteri(ctx->Exec, (n[1].ui, n[2].e, n[3].i));
8865            break;
8866         case OPCODE_FRAMEBUFFER_TEXTURE:
8867            CALL_FramebufferTexture(ctx->Exec, (n[1].e, n[2].e,
8868                                                   n[3].ui, n[4].i));
8869            break;
8870         case OPCODE_FRAMEBUFFER_TEXTURE_FACE:
8871            CALL_FramebufferTextureFaceARB(ctx->Exec, (n[1].e, n[2].e,
8872                                                       n[3].ui, n[4].i, n[5].e));
8873            break;
8874
8875         /* GL_ARB_sync */
8876         case OPCODE_WAIT_SYNC:
8877            {
8878               union uint64_pair p;
8879               p.uint32[0] = n[2].ui;
8880               p.uint32[1] = n[3].ui;
8881               CALL_WaitSync(ctx->Exec,
8882                             (get_pointer(&n[4]), n[1].bf, p.uint64));
8883            }
8884            break;
8885
8886         /* GL_NV_conditional_render */
8887         case OPCODE_BEGIN_CONDITIONAL_RENDER:
8888            CALL_BeginConditionalRender(ctx->Exec, (n[1].i, n[2].e));
8889            break;
8890         case OPCODE_END_CONDITIONAL_RENDER:
8891            CALL_EndConditionalRender(ctx->Exec, ());
8892            break;
8893
8894         case OPCODE_UNIFORM_BLOCK_BINDING:
8895            CALL_UniformBlockBinding(ctx->Exec, (n[1].ui, n[2].ui, n[3].ui));
8896            break;
8897
8898         case OPCODE_CONTINUE:
8899            n = (Node *) get_pointer(&n[1]);
8900            break;
8901         case OPCODE_END_OF_LIST:
8902            done = GL_TRUE;
8903            break;
8904         default:
8905            {
8906               char msg[1000];
8907               _mesa_snprintf(msg, sizeof(msg), "Error in execute_list: opcode=%d",
8908                             (int) opcode);
8909               _mesa_problem(ctx, "%s", msg);
8910            }
8911            done = GL_TRUE;
8912         }
8913
8914         /* increment n to point to next compiled command */
8915         if (opcode != OPCODE_CONTINUE) {
8916            n += InstSize[opcode];
8917         }
8918      }
8919   }
8920
8921   if (ctx->Driver.EndCallList)
8922      ctx->Driver.EndCallList(ctx);
8923
8924   ctx->ListState.CallDepth--;
8925}
8926
8927
8928
8929/**********************************************************************/
8930/*                           GL functions                             */
8931/**********************************************************************/
8932
8933/**
8934 * Test if a display list number is valid.
8935 */
8936GLboolean GLAPIENTRY
8937_mesa_IsList(GLuint list)
8938{
8939   GET_CURRENT_CONTEXT(ctx);
8940   FLUSH_VERTICES(ctx, 0);      /* must be called before assert */
8941   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
8942   return islist(ctx, list);
8943}
8944
8945
8946/**
8947 * Delete a sequence of consecutive display lists.
8948 */
8949void GLAPIENTRY
8950_mesa_DeleteLists(GLuint list, GLsizei range)
8951{
8952   GET_CURRENT_CONTEXT(ctx);
8953   GLuint i;
8954   FLUSH_VERTICES(ctx, 0);      /* must be called before assert */
8955   ASSERT_OUTSIDE_BEGIN_END(ctx);
8956
8957   if (range < 0) {
8958      _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteLists");
8959      return;
8960   }
8961   for (i = list; i < list + range; i++) {
8962      destroy_list(ctx, i);
8963   }
8964}
8965
8966
8967/**
8968 * Return a display list number, n, such that lists n through n+range-1
8969 * are free.
8970 */
8971GLuint GLAPIENTRY
8972_mesa_GenLists(GLsizei range)
8973{
8974   GET_CURRENT_CONTEXT(ctx);
8975   GLuint base;
8976   FLUSH_VERTICES(ctx, 0);      /* must be called before assert */
8977   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
8978
8979   if (range < 0) {
8980      _mesa_error(ctx, GL_INVALID_VALUE, "glGenLists");
8981      return 0;
8982   }
8983   if (range == 0) {
8984      return 0;
8985   }
8986
8987   /*
8988    * Make this an atomic operation
8989    */
8990   mtx_lock(&ctx->Shared->Mutex);
8991
8992   base = _mesa_HashFindFreeKeyBlock(ctx->Shared->DisplayList, range);
8993   if (base) {
8994      /* reserve the list IDs by with empty/dummy lists */
8995      GLint i;
8996      for (i = 0; i < range; i++) {
8997         _mesa_HashInsert(ctx->Shared->DisplayList, base + i,
8998                          make_list(base + i, 1));
8999      }
9000   }
9001
9002   mtx_unlock(&ctx->Shared->Mutex);
9003
9004   return base;
9005}
9006
9007
9008/**
9009 * Begin a new display list.
9010 */
9011void GLAPIENTRY
9012_mesa_NewList(GLuint name, GLenum mode)
9013{
9014   GET_CURRENT_CONTEXT(ctx);
9015
9016   FLUSH_CURRENT(ctx, 0);       /* must be called before assert */
9017   ASSERT_OUTSIDE_BEGIN_END(ctx);
9018
9019   if (MESA_VERBOSE & VERBOSE_API)
9020      _mesa_debug(ctx, "glNewList %u %s\n", name,
9021                  _mesa_lookup_enum_by_nr(mode));
9022
9023   if (name == 0) {
9024      _mesa_error(ctx, GL_INVALID_VALUE, "glNewList");
9025      return;
9026   }
9027
9028   if (mode != GL_COMPILE && mode != GL_COMPILE_AND_EXECUTE) {
9029      _mesa_error(ctx, GL_INVALID_ENUM, "glNewList");
9030      return;
9031   }
9032
9033   if (ctx->ListState.CurrentList) {
9034      /* already compiling a display list */
9035      _mesa_error(ctx, GL_INVALID_OPERATION, "glNewList");
9036      return;
9037   }
9038
9039   ctx->CompileFlag = GL_TRUE;
9040   ctx->ExecuteFlag = (mode == GL_COMPILE_AND_EXECUTE);
9041
9042   /* Reset accumulated list state */
9043   invalidate_saved_current_state( ctx );
9044
9045   /* Allocate new display list */
9046   ctx->ListState.CurrentList = make_list(name, BLOCK_SIZE);
9047   ctx->ListState.CurrentBlock = ctx->ListState.CurrentList->Head;
9048   ctx->ListState.CurrentPos = 0;
9049
9050   ctx->Driver.NewList(ctx, name, mode);
9051
9052   ctx->CurrentDispatch = ctx->Save;
9053   _glapi_set_dispatch(ctx->CurrentDispatch);
9054}
9055
9056
9057/**
9058 * End definition of current display list.
9059 */
9060void GLAPIENTRY
9061_mesa_EndList(void)
9062{
9063   GET_CURRENT_CONTEXT(ctx);
9064   SAVE_FLUSH_VERTICES(ctx);
9065   FLUSH_VERTICES(ctx, 0);
9066
9067   if (MESA_VERBOSE & VERBOSE_API)
9068      _mesa_debug(ctx, "glEndList\n");
9069
9070   if (ctx->ExecuteFlag && _mesa_inside_dlist_begin_end(ctx)) {
9071      _mesa_error(ctx, GL_INVALID_OPERATION,
9072                  "glEndList() called inside glBegin/End");
9073   }
9074
9075   /* Check that a list is under construction */
9076   if (!ctx->ListState.CurrentList) {
9077      _mesa_error(ctx, GL_INVALID_OPERATION, "glEndList");
9078      return;
9079   }
9080
9081   /* Call before emitting END_OF_LIST, in case the driver wants to
9082    * emit opcodes itself.
9083    */
9084   ctx->Driver.EndList(ctx);
9085
9086   (void) alloc_instruction(ctx, OPCODE_END_OF_LIST, 0);
9087
9088   trim_list(ctx);
9089
9090   /* Destroy old list, if any */
9091   destroy_list(ctx, ctx->ListState.CurrentList->Name);
9092
9093   /* Install the new list */
9094   _mesa_HashInsert(ctx->Shared->DisplayList,
9095                    ctx->ListState.CurrentList->Name,
9096                    ctx->ListState.CurrentList);
9097
9098
9099   if (MESA_VERBOSE & VERBOSE_DISPLAY_LIST)
9100      mesa_print_display_list(ctx->ListState.CurrentList->Name);
9101
9102   ctx->ListState.CurrentList = NULL;
9103   ctx->ListState.CurrentBlock = NULL;
9104   ctx->ListState.CurrentPos = 0;
9105   ctx->ExecuteFlag = GL_TRUE;
9106   ctx->CompileFlag = GL_FALSE;
9107
9108   ctx->CurrentDispatch = ctx->Exec;
9109   _glapi_set_dispatch(ctx->CurrentDispatch);
9110}
9111
9112
9113void GLAPIENTRY
9114_mesa_CallList(GLuint list)
9115{
9116   GLboolean save_compile_flag;
9117   GET_CURRENT_CONTEXT(ctx);
9118   FLUSH_CURRENT(ctx, 0);
9119
9120   if (MESA_VERBOSE & VERBOSE_API)
9121      _mesa_debug(ctx, "glCallList %d\n", list);
9122
9123   if (list == 0) {
9124      _mesa_error(ctx, GL_INVALID_VALUE, "glCallList(list==0)");
9125      return;
9126   }
9127
9128   if (0)
9129      mesa_print_display_list( list );
9130
9131   /* VERY IMPORTANT:  Save the CompileFlag status, turn it off,
9132    * execute the display list, and restore the CompileFlag.
9133    */
9134   save_compile_flag = ctx->CompileFlag;
9135   if (save_compile_flag) {
9136      ctx->CompileFlag = GL_FALSE;
9137   }
9138
9139   execute_list(ctx, list);
9140   ctx->CompileFlag = save_compile_flag;
9141
9142   /* also restore API function pointers to point to "save" versions */
9143   if (save_compile_flag) {
9144      ctx->CurrentDispatch = ctx->Save;
9145      _glapi_set_dispatch(ctx->CurrentDispatch);
9146   }
9147}
9148
9149
9150/**
9151 * Execute glCallLists:  call multiple display lists.
9152 */
9153void GLAPIENTRY
9154_mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
9155{
9156   GET_CURRENT_CONTEXT(ctx);
9157   GLint i;
9158   GLboolean save_compile_flag;
9159
9160   if (MESA_VERBOSE & VERBOSE_API)
9161      _mesa_debug(ctx, "glCallLists %d\n", n);
9162
9163   switch (type) {
9164   case GL_BYTE:
9165   case GL_UNSIGNED_BYTE:
9166   case GL_SHORT:
9167   case GL_UNSIGNED_SHORT:
9168   case GL_INT:
9169   case GL_UNSIGNED_INT:
9170   case GL_FLOAT:
9171   case GL_2_BYTES:
9172   case GL_3_BYTES:
9173   case GL_4_BYTES:
9174      /* OK */
9175      break;
9176   default:
9177      _mesa_error(ctx, GL_INVALID_ENUM, "glCallLists(type)");
9178      return;
9179   }
9180
9181   /* Save the CompileFlag status, turn it off, execute display list,
9182    * and restore the CompileFlag.
9183    */
9184   save_compile_flag = ctx->CompileFlag;
9185   ctx->CompileFlag = GL_FALSE;
9186
9187   for (i = 0; i < n; i++) {
9188      GLuint list = (GLuint) (ctx->List.ListBase + translate_id(i, type, lists));
9189      execute_list(ctx, list);
9190   }
9191
9192   ctx->CompileFlag = save_compile_flag;
9193
9194   /* also restore API function pointers to point to "save" versions */
9195   if (save_compile_flag) {
9196      ctx->CurrentDispatch = ctx->Save;
9197      _glapi_set_dispatch(ctx->CurrentDispatch);
9198   }
9199}
9200
9201
9202/**
9203 * Set the offset added to list numbers in glCallLists.
9204 */
9205void GLAPIENTRY
9206_mesa_ListBase(GLuint base)
9207{
9208   GET_CURRENT_CONTEXT(ctx);
9209   FLUSH_VERTICES(ctx, 0);      /* must be called before assert */
9210   ASSERT_OUTSIDE_BEGIN_END(ctx);
9211   ctx->List.ListBase = base;
9212}
9213
9214/**
9215 * Setup the given dispatch table to point to Mesa's display list
9216 * building functions.
9217 *
9218 * This does not include any of the tnl functions - they are
9219 * initialized from _mesa_init_api_defaults and from the active vtxfmt
9220 * struct.
9221 */
9222void
9223_mesa_initialize_save_table(const struct gl_context *ctx)
9224{
9225   struct _glapi_table *table = ctx->Save;
9226   int numEntries = MAX2(_gloffset_COUNT, _glapi_get_dispatch_table_size());
9227
9228   /* Initially populate the dispatch table with the contents of the
9229    * normal-execution dispatch table.  This lets us skip populating functions
9230    * that should be called directly instead of compiled into display lists.
9231    */
9232   memcpy(table, ctx->Exec, numEntries * sizeof(_glapi_proc));
9233
9234   _mesa_loopback_init_api_table(ctx, table);
9235
9236   /* VBO functions */
9237   vbo_initialize_save_dispatch(ctx, table);
9238
9239   /* GL 1.0 */
9240   SET_Accum(table, save_Accum);
9241   SET_AlphaFunc(table, save_AlphaFunc);
9242   SET_Bitmap(table, save_Bitmap);
9243   SET_BlendFunc(table, save_BlendFunc);
9244   SET_CallList(table, save_CallList);
9245   SET_CallLists(table, save_CallLists);
9246   SET_Clear(table, save_Clear);
9247   SET_ClearAccum(table, save_ClearAccum);
9248   SET_ClearColor(table, save_ClearColor);
9249   SET_ClearDepth(table, save_ClearDepth);
9250   SET_ClearIndex(table, save_ClearIndex);
9251   SET_ClearStencil(table, save_ClearStencil);
9252   SET_ClipPlane(table, save_ClipPlane);
9253   SET_ColorMask(table, save_ColorMask);
9254   SET_ColorMaski(table, save_ColorMaskIndexed);
9255   SET_ColorMaterial(table, save_ColorMaterial);
9256   SET_CopyPixels(table, save_CopyPixels);
9257   SET_CullFace(table, save_CullFace);
9258   SET_DepthFunc(table, save_DepthFunc);
9259   SET_DepthMask(table, save_DepthMask);
9260   SET_DepthRange(table, save_DepthRange);
9261   SET_Disable(table, save_Disable);
9262   SET_Disablei(table, save_DisableIndexed);
9263   SET_DrawBuffer(table, save_DrawBuffer);
9264   SET_DrawPixels(table, save_DrawPixels);
9265   SET_Enable(table, save_Enable);
9266   SET_Enablei(table, save_EnableIndexed);
9267   SET_EvalMesh1(table, save_EvalMesh1);
9268   SET_EvalMesh2(table, save_EvalMesh2);
9269   SET_Fogf(table, save_Fogf);
9270   SET_Fogfv(table, save_Fogfv);
9271   SET_Fogi(table, save_Fogi);
9272   SET_Fogiv(table, save_Fogiv);
9273   SET_FrontFace(table, save_FrontFace);
9274   SET_Frustum(table, save_Frustum);
9275   SET_Hint(table, save_Hint);
9276   SET_IndexMask(table, save_IndexMask);
9277   SET_InitNames(table, save_InitNames);
9278   SET_LightModelf(table, save_LightModelf);
9279   SET_LightModelfv(table, save_LightModelfv);
9280   SET_LightModeli(table, save_LightModeli);
9281   SET_LightModeliv(table, save_LightModeliv);
9282   SET_Lightf(table, save_Lightf);
9283   SET_Lightfv(table, save_Lightfv);
9284   SET_Lighti(table, save_Lighti);
9285   SET_Lightiv(table, save_Lightiv);
9286   SET_LineStipple(table, save_LineStipple);
9287   SET_LineWidth(table, save_LineWidth);
9288   SET_ListBase(table, save_ListBase);
9289   SET_LoadIdentity(table, save_LoadIdentity);
9290   SET_LoadMatrixd(table, save_LoadMatrixd);
9291   SET_LoadMatrixf(table, save_LoadMatrixf);
9292   SET_LoadName(table, save_LoadName);
9293   SET_LogicOp(table, save_LogicOp);
9294   SET_Map1d(table, save_Map1d);
9295   SET_Map1f(table, save_Map1f);
9296   SET_Map2d(table, save_Map2d);
9297   SET_Map2f(table, save_Map2f);
9298   SET_MapGrid1d(table, save_MapGrid1d);
9299   SET_MapGrid1f(table, save_MapGrid1f);
9300   SET_MapGrid2d(table, save_MapGrid2d);
9301   SET_MapGrid2f(table, save_MapGrid2f);
9302   SET_MatrixMode(table, save_MatrixMode);
9303   SET_MultMatrixd(table, save_MultMatrixd);
9304   SET_MultMatrixf(table, save_MultMatrixf);
9305   SET_NewList(table, save_NewList);
9306   SET_Ortho(table, save_Ortho);
9307   SET_PassThrough(table, save_PassThrough);
9308   SET_PixelMapfv(table, save_PixelMapfv);
9309   SET_PixelMapuiv(table, save_PixelMapuiv);
9310   SET_PixelMapusv(table, save_PixelMapusv);
9311   SET_PixelTransferf(table, save_PixelTransferf);
9312   SET_PixelTransferi(table, save_PixelTransferi);
9313   SET_PixelZoom(table, save_PixelZoom);
9314   SET_PointSize(table, save_PointSize);
9315   SET_PolygonMode(table, save_PolygonMode);
9316   SET_PolygonOffset(table, save_PolygonOffset);
9317   SET_PolygonStipple(table, save_PolygonStipple);
9318   SET_PopAttrib(table, save_PopAttrib);
9319   SET_PopMatrix(table, save_PopMatrix);
9320   SET_PopName(table, save_PopName);
9321   SET_PushAttrib(table, save_PushAttrib);
9322   SET_PushMatrix(table, save_PushMatrix);
9323   SET_PushName(table, save_PushName);
9324   SET_RasterPos2d(table, save_RasterPos2d);
9325   SET_RasterPos2dv(table, save_RasterPos2dv);
9326   SET_RasterPos2f(table, save_RasterPos2f);
9327   SET_RasterPos2fv(table, save_RasterPos2fv);
9328   SET_RasterPos2i(table, save_RasterPos2i);
9329   SET_RasterPos2iv(table, save_RasterPos2iv);
9330   SET_RasterPos2s(table, save_RasterPos2s);
9331   SET_RasterPos2sv(table, save_RasterPos2sv);
9332   SET_RasterPos3d(table, save_RasterPos3d);
9333   SET_RasterPos3dv(table, save_RasterPos3dv);
9334   SET_RasterPos3f(table, save_RasterPos3f);
9335   SET_RasterPos3fv(table, save_RasterPos3fv);
9336   SET_RasterPos3i(table, save_RasterPos3i);
9337   SET_RasterPos3iv(table, save_RasterPos3iv);
9338   SET_RasterPos3s(table, save_RasterPos3s);
9339   SET_RasterPos3sv(table, save_RasterPos3sv);
9340   SET_RasterPos4d(table, save_RasterPos4d);
9341   SET_RasterPos4dv(table, save_RasterPos4dv);
9342   SET_RasterPos4f(table, save_RasterPos4f);
9343   SET_RasterPos4fv(table, save_RasterPos4fv);
9344   SET_RasterPos4i(table, save_RasterPos4i);
9345   SET_RasterPos4iv(table, save_RasterPos4iv);
9346   SET_RasterPos4s(table, save_RasterPos4s);
9347   SET_RasterPos4sv(table, save_RasterPos4sv);
9348   SET_ReadBuffer(table, save_ReadBuffer);
9349   SET_Rectf(table, save_Rectf);
9350   SET_Rotated(table, save_Rotated);
9351   SET_Rotatef(table, save_Rotatef);
9352   SET_Scaled(table, save_Scaled);
9353   SET_Scalef(table, save_Scalef);
9354   SET_Scissor(table, save_Scissor);
9355   SET_ShadeModel(table, save_ShadeModel);
9356   SET_StencilFunc(table, save_StencilFunc);
9357   SET_StencilMask(table, save_StencilMask);
9358   SET_StencilOp(table, save_StencilOp);
9359   SET_TexEnvf(table, save_TexEnvf);
9360   SET_TexEnvfv(table, save_TexEnvfv);
9361   SET_TexEnvi(table, save_TexEnvi);
9362   SET_TexEnviv(table, save_TexEnviv);
9363   SET_TexGend(table, save_TexGend);
9364   SET_TexGendv(table, save_TexGendv);
9365   SET_TexGenf(table, save_TexGenf);
9366   SET_TexGenfv(table, save_TexGenfv);
9367   SET_TexGeni(table, save_TexGeni);
9368   SET_TexGeniv(table, save_TexGeniv);
9369   SET_TexImage1D(table, save_TexImage1D);
9370   SET_TexImage2D(table, save_TexImage2D);
9371   SET_TexParameterf(table, save_TexParameterf);
9372   SET_TexParameterfv(table, save_TexParameterfv);
9373   SET_TexParameteri(table, save_TexParameteri);
9374   SET_TexParameteriv(table, save_TexParameteriv);
9375   SET_Translated(table, save_Translated);
9376   SET_Translatef(table, save_Translatef);
9377   SET_Viewport(table, save_Viewport);
9378
9379   /* GL 1.1 */
9380   SET_BindTexture(table, save_BindTexture);
9381   SET_CopyTexImage1D(table, save_CopyTexImage1D);
9382   SET_CopyTexImage2D(table, save_CopyTexImage2D);
9383   SET_CopyTexSubImage1D(table, save_CopyTexSubImage1D);
9384   SET_CopyTexSubImage2D(table, save_CopyTexSubImage2D);
9385   SET_PrioritizeTextures(table, save_PrioritizeTextures);
9386   SET_TexSubImage1D(table, save_TexSubImage1D);
9387   SET_TexSubImage2D(table, save_TexSubImage2D);
9388
9389   /* GL 1.2 */
9390   SET_CopyTexSubImage3D(table, save_CopyTexSubImage3D);
9391   SET_TexImage3D(table, save_TexImage3D);
9392   SET_TexSubImage3D(table, save_TexSubImage3D);
9393
9394   /* GL 2.0 */
9395   SET_StencilFuncSeparate(table, save_StencilFuncSeparate);
9396   SET_StencilMaskSeparate(table, save_StencilMaskSeparate);
9397   SET_StencilOpSeparate(table, save_StencilOpSeparate);
9398
9399   /* ATI_separate_stencil */
9400   SET_StencilFuncSeparateATI(table, save_StencilFuncSeparateATI);
9401
9402   /* GL_ARB_imaging */
9403   /* Not all are supported */
9404   SET_BlendColor(table, save_BlendColor);
9405   SET_BlendEquation(table, save_BlendEquation);
9406
9407   /* 2. GL_EXT_blend_color */
9408#if 0
9409   SET_BlendColorEXT(table, save_BlendColorEXT);
9410#endif
9411
9412   /* 3. GL_EXT_polygon_offset */
9413   SET_PolygonOffsetEXT(table, save_PolygonOffsetEXT);
9414
9415   /* 6. GL_EXT_texture3d */
9416#if 0
9417   SET_CopyTexSubImage3DEXT(table, save_CopyTexSubImage3D);
9418   SET_TexImage3DEXT(table, save_TexImage3DEXT);
9419   SET_TexSubImage3DEXT(table, save_TexSubImage3D);
9420#endif
9421
9422   /* 37. GL_EXT_blend_minmax */
9423#if 0
9424   SET_BlendEquationEXT(table, save_BlendEquationEXT);
9425#endif
9426
9427   /* 54. GL_EXT_point_parameters */
9428   SET_PointParameterf(table, save_PointParameterfEXT);
9429   SET_PointParameterfv(table, save_PointParameterfvEXT);
9430
9431   /* 173. GL_EXT_blend_func_separate */
9432   SET_BlendFuncSeparate(table, save_BlendFuncSeparateEXT);
9433
9434   /* 197. GL_MESA_window_pos */
9435   SET_WindowPos2d(table, save_WindowPos2dMESA);
9436   SET_WindowPos2dv(table, save_WindowPos2dvMESA);
9437   SET_WindowPos2f(table, save_WindowPos2fMESA);
9438   SET_WindowPos2fv(table, save_WindowPos2fvMESA);
9439   SET_WindowPos2i(table, save_WindowPos2iMESA);
9440   SET_WindowPos2iv(table, save_WindowPos2ivMESA);
9441   SET_WindowPos2s(table, save_WindowPos2sMESA);
9442   SET_WindowPos2sv(table, save_WindowPos2svMESA);
9443   SET_WindowPos3d(table, save_WindowPos3dMESA);
9444   SET_WindowPos3dv(table, save_WindowPos3dvMESA);
9445   SET_WindowPos3f(table, save_WindowPos3fMESA);
9446   SET_WindowPos3fv(table, save_WindowPos3fvMESA);
9447   SET_WindowPos3i(table, save_WindowPos3iMESA);
9448   SET_WindowPos3iv(table, save_WindowPos3ivMESA);
9449   SET_WindowPos3s(table, save_WindowPos3sMESA);
9450   SET_WindowPos3sv(table, save_WindowPos3svMESA);
9451   SET_WindowPos4dMESA(table, save_WindowPos4dMESA);
9452   SET_WindowPos4dvMESA(table, save_WindowPos4dvMESA);
9453   SET_WindowPos4fMESA(table, save_WindowPos4fMESA);
9454   SET_WindowPos4fvMESA(table, save_WindowPos4fvMESA);
9455   SET_WindowPos4iMESA(table, save_WindowPos4iMESA);
9456   SET_WindowPos4ivMESA(table, save_WindowPos4ivMESA);
9457   SET_WindowPos4sMESA(table, save_WindowPos4sMESA);
9458   SET_WindowPos4svMESA(table, save_WindowPos4svMESA);
9459
9460   /* 233. GL_NV_vertex_program */
9461   /* The following commands DO NOT go into display lists:
9462    * AreProgramsResidentNV, IsProgramNV, GenProgramsNV, DeleteProgramsNV,
9463    * VertexAttribPointerNV, GetProgram*, GetVertexAttrib*
9464    */
9465   SET_BindProgramARB(table, save_BindProgramNV);
9466
9467   /* 245. GL_ATI_fragment_shader */
9468   SET_BindFragmentShaderATI(table, save_BindFragmentShaderATI);
9469   SET_SetFragmentShaderConstantATI(table, save_SetFragmentShaderConstantATI);
9470
9471   /* 262. GL_NV_point_sprite */
9472   SET_PointParameteri(table, save_PointParameteriNV);
9473   SET_PointParameteriv(table, save_PointParameterivNV);
9474
9475   /* 268. GL_EXT_stencil_two_side */
9476   SET_ActiveStencilFaceEXT(table, save_ActiveStencilFaceEXT);
9477
9478   /* ???. GL_EXT_depth_bounds_test */
9479   SET_DepthBoundsEXT(table, save_DepthBoundsEXT);
9480
9481   /* ARB 1. GL_ARB_multitexture */
9482   SET_ActiveTexture(table, save_ActiveTextureARB);
9483
9484   /* ARB 3. GL_ARB_transpose_matrix */
9485   SET_LoadTransposeMatrixd(table, save_LoadTransposeMatrixdARB);
9486   SET_LoadTransposeMatrixf(table, save_LoadTransposeMatrixfARB);
9487   SET_MultTransposeMatrixd(table, save_MultTransposeMatrixdARB);
9488   SET_MultTransposeMatrixf(table, save_MultTransposeMatrixfARB);
9489
9490   /* ARB 5. GL_ARB_multisample */
9491   SET_SampleCoverage(table, save_SampleCoverageARB);
9492
9493   /* ARB 12. GL_ARB_texture_compression */
9494   SET_CompressedTexImage3D(table, save_CompressedTexImage3DARB);
9495   SET_CompressedTexImage2D(table, save_CompressedTexImage2DARB);
9496   SET_CompressedTexImage1D(table, save_CompressedTexImage1DARB);
9497   SET_CompressedTexSubImage3D(table, save_CompressedTexSubImage3DARB);
9498   SET_CompressedTexSubImage2D(table, save_CompressedTexSubImage2DARB);
9499   SET_CompressedTexSubImage1D(table, save_CompressedTexSubImage1DARB);
9500
9501   /* ARB 14. GL_ARB_point_parameters */
9502   /* aliased with EXT_point_parameters functions */
9503
9504   /* ARB 25. GL_ARB_window_pos */
9505   /* aliased with MESA_window_pos functions */
9506
9507   /* ARB 26. GL_ARB_vertex_program */
9508   /* ARB 27. GL_ARB_fragment_program */
9509   /* glVertexAttrib* functions alias the NV ones, handled elsewhere */
9510   SET_ProgramStringARB(table, save_ProgramStringARB);
9511   SET_BindProgramARB(table, save_BindProgramNV);
9512   SET_ProgramEnvParameter4dARB(table, save_ProgramEnvParameter4dARB);
9513   SET_ProgramEnvParameter4dvARB(table, save_ProgramEnvParameter4dvARB);
9514   SET_ProgramEnvParameter4fARB(table, save_ProgramEnvParameter4fARB);
9515   SET_ProgramEnvParameter4fvARB(table, save_ProgramEnvParameter4fvARB);
9516   SET_ProgramLocalParameter4dARB(table, save_ProgramLocalParameter4dARB);
9517   SET_ProgramLocalParameter4dvARB(table, save_ProgramLocalParameter4dvARB);
9518   SET_ProgramLocalParameter4fARB(table, save_ProgramLocalParameter4fARB);
9519   SET_ProgramLocalParameter4fvARB(table, save_ProgramLocalParameter4fvARB);
9520
9521   SET_BeginQuery(table, save_BeginQueryARB);
9522   SET_EndQuery(table, save_EndQueryARB);
9523   SET_QueryCounter(table, save_QueryCounter);
9524
9525   SET_DrawBuffers(table, save_DrawBuffersARB);
9526
9527   SET_BlitFramebuffer(table, save_BlitFramebufferEXT);
9528
9529   SET_UseProgram(table, save_UseProgramObjectARB);
9530   SET_Uniform1f(table, save_Uniform1fARB);
9531   SET_Uniform2f(table, save_Uniform2fARB);
9532   SET_Uniform3f(table, save_Uniform3fARB);
9533   SET_Uniform4f(table, save_Uniform4fARB);
9534   SET_Uniform1fv(table, save_Uniform1fvARB);
9535   SET_Uniform2fv(table, save_Uniform2fvARB);
9536   SET_Uniform3fv(table, save_Uniform3fvARB);
9537   SET_Uniform4fv(table, save_Uniform4fvARB);
9538   SET_Uniform1i(table, save_Uniform1iARB);
9539   SET_Uniform2i(table, save_Uniform2iARB);
9540   SET_Uniform3i(table, save_Uniform3iARB);
9541   SET_Uniform4i(table, save_Uniform4iARB);
9542   SET_Uniform1iv(table, save_Uniform1ivARB);
9543   SET_Uniform2iv(table, save_Uniform2ivARB);
9544   SET_Uniform3iv(table, save_Uniform3ivARB);
9545   SET_Uniform4iv(table, save_Uniform4ivARB);
9546   SET_UniformMatrix2fv(table, save_UniformMatrix2fvARB);
9547   SET_UniformMatrix3fv(table, save_UniformMatrix3fvARB);
9548   SET_UniformMatrix4fv(table, save_UniformMatrix4fvARB);
9549   SET_UniformMatrix2x3fv(table, save_UniformMatrix2x3fv);
9550   SET_UniformMatrix3x2fv(table, save_UniformMatrix3x2fv);
9551   SET_UniformMatrix2x4fv(table, save_UniformMatrix2x4fv);
9552   SET_UniformMatrix4x2fv(table, save_UniformMatrix4x2fv);
9553   SET_UniformMatrix3x4fv(table, save_UniformMatrix3x4fv);
9554   SET_UniformMatrix4x3fv(table, save_UniformMatrix4x3fv);
9555
9556   /* 299. GL_EXT_blend_equation_separate */
9557   SET_BlendEquationSeparate(table, save_BlendEquationSeparateEXT);
9558
9559   /* GL_EXT_gpu_program_parameters */
9560   SET_ProgramEnvParameters4fvEXT(table, save_ProgramEnvParameters4fvEXT);
9561   SET_ProgramLocalParameters4fvEXT(table, save_ProgramLocalParameters4fvEXT);
9562
9563   /* 364. GL_EXT_provoking_vertex */
9564   SET_ProvokingVertex(table, save_ProvokingVertexEXT);
9565
9566   /* GL_EXT_texture_integer */
9567   SET_ClearColorIiEXT(table, save_ClearColorIi);
9568   SET_ClearColorIuiEXT(table, save_ClearColorIui);
9569   SET_TexParameterIiv(table, save_TexParameterIiv);
9570   SET_TexParameterIuiv(table, save_TexParameterIuiv);
9571
9572   /* GL_ARB_color_buffer_float */
9573   SET_ClampColor(table, save_ClampColorARB);
9574
9575   /* GL 3.0 */
9576   SET_ClearBufferiv(table, save_ClearBufferiv);
9577   SET_ClearBufferuiv(table, save_ClearBufferuiv);
9578   SET_ClearBufferfv(table, save_ClearBufferfv);
9579   SET_ClearBufferfi(table, save_ClearBufferfi);
9580#if 0
9581   SET_Uniform1ui(table, save_Uniform1ui);
9582   SET_Uniform2ui(table, save_Uniform2ui);
9583   SET_Uniform3ui(table, save_Uniform3ui);
9584   SET_Uniform4ui(table, save_Uniform4ui);
9585   SET_Uniform1uiv(table, save_Uniform1uiv);
9586   SET_Uniform2uiv(table, save_Uniform2uiv);
9587   SET_Uniform3uiv(table, save_Uniform3uiv);
9588   SET_Uniform4uiv(table, save_Uniform4uiv);
9589#else
9590   (void) save_Uniform1ui;
9591   (void) save_Uniform2ui;
9592   (void) save_Uniform3ui;
9593   (void) save_Uniform4ui;
9594   (void) save_Uniform1uiv;
9595   (void) save_Uniform2uiv;
9596   (void) save_Uniform3uiv;
9597   (void) save_Uniform4uiv;
9598#endif
9599
9600   /* These are: */
9601   SET_BeginTransformFeedback(table, save_BeginTransformFeedback);
9602   SET_EndTransformFeedback(table, save_EndTransformFeedback);
9603   SET_BindTransformFeedback(table, save_BindTransformFeedback);
9604   SET_PauseTransformFeedback(table, save_PauseTransformFeedback);
9605   SET_ResumeTransformFeedback(table, save_ResumeTransformFeedback);
9606   SET_DrawTransformFeedback(table, save_DrawTransformFeedback);
9607   SET_DrawTransformFeedbackStream(table, save_DrawTransformFeedbackStream);
9608   SET_DrawTransformFeedbackInstanced(table,
9609                                      save_DrawTransformFeedbackInstanced);
9610   SET_DrawTransformFeedbackStreamInstanced(table,
9611                                save_DrawTransformFeedbackStreamInstanced);
9612   SET_BeginQueryIndexed(table, save_BeginQueryIndexed);
9613   SET_EndQueryIndexed(table, save_EndQueryIndexed);
9614
9615   /* GL_ARB_instanced_arrays */
9616   SET_VertexAttribDivisor(table, save_VertexAttribDivisor);
9617
9618   /* GL_NV_texture_barrier */
9619   SET_TextureBarrierNV(table, save_TextureBarrierNV);
9620
9621   SET_BindSampler(table, save_BindSampler);
9622   SET_SamplerParameteri(table, save_SamplerParameteri);
9623   SET_SamplerParameterf(table, save_SamplerParameterf);
9624   SET_SamplerParameteriv(table, save_SamplerParameteriv);
9625   SET_SamplerParameterfv(table, save_SamplerParameterfv);
9626   SET_SamplerParameterIiv(table, save_SamplerParameterIiv);
9627   SET_SamplerParameterIuiv(table, save_SamplerParameterIuiv);
9628
9629   /* GL_ARB_draw_buffer_blend */
9630   SET_BlendFunciARB(table, save_BlendFunci);
9631   SET_BlendFuncSeparateiARB(table, save_BlendFuncSeparatei);
9632   SET_BlendEquationiARB(table, save_BlendEquationi);
9633   SET_BlendEquationSeparateiARB(table, save_BlendEquationSeparatei);
9634
9635   /* GL_ARB_geometry_shader4 */
9636   SET_ProgramParameteri(table, save_ProgramParameteri);
9637   SET_FramebufferTexture(table, save_FramebufferTexture);
9638   SET_FramebufferTextureFaceARB(table, save_FramebufferTextureFace);
9639
9640   /* GL_NV_conditional_render */
9641   SET_BeginConditionalRender(table, save_BeginConditionalRender);
9642   SET_EndConditionalRender(table, save_EndConditionalRender);
9643
9644   /* GL_ARB_sync */
9645   SET_WaitSync(table, save_WaitSync);
9646
9647   /* GL_ARB_uniform_buffer_object */
9648   SET_UniformBlockBinding(table, save_UniformBlockBinding);
9649
9650   /* GL_ARB_draw_instanced */
9651   SET_DrawArraysInstancedARB(table, save_DrawArraysInstancedARB);
9652   SET_DrawElementsInstancedARB(table, save_DrawElementsInstancedARB);
9653
9654   /* GL_ARB_draw_elements_base_vertex */
9655   SET_DrawElementsInstancedBaseVertex(table, save_DrawElementsInstancedBaseVertexARB);
9656
9657   /* GL_ARB_base_instance */
9658   SET_DrawArraysInstancedBaseInstance(table, save_DrawArraysInstancedBaseInstance);
9659   SET_DrawElementsInstancedBaseInstance(table, save_DrawElementsInstancedBaseInstance);
9660   SET_DrawElementsInstancedBaseVertexBaseInstance(table, save_DrawElementsInstancedBaseVertexBaseInstance);
9661
9662   /* OpenGL 4.2 / GL_ARB_separate_shader_objects */
9663   SET_UseProgramStages(table, save_UseProgramStages);
9664   SET_ProgramUniform1f(table, save_ProgramUniform1f);
9665   SET_ProgramUniform2f(table, save_ProgramUniform2f);
9666   SET_ProgramUniform3f(table, save_ProgramUniform3f);
9667   SET_ProgramUniform4f(table, save_ProgramUniform4f);
9668   SET_ProgramUniform1fv(table, save_ProgramUniform1fv);
9669   SET_ProgramUniform2fv(table, save_ProgramUniform2fv);
9670   SET_ProgramUniform3fv(table, save_ProgramUniform3fv);
9671   SET_ProgramUniform4fv(table, save_ProgramUniform4fv);
9672   SET_ProgramUniform1i(table, save_ProgramUniform1i);
9673   SET_ProgramUniform2i(table, save_ProgramUniform2i);
9674   SET_ProgramUniform3i(table, save_ProgramUniform3i);
9675   SET_ProgramUniform4i(table, save_ProgramUniform4i);
9676   SET_ProgramUniform1iv(table, save_ProgramUniform1iv);
9677   SET_ProgramUniform2iv(table, save_ProgramUniform2iv);
9678   SET_ProgramUniform3iv(table, save_ProgramUniform3iv);
9679   SET_ProgramUniform4iv(table, save_ProgramUniform4iv);
9680   SET_ProgramUniform1ui(table, save_ProgramUniform1ui);
9681   SET_ProgramUniform2ui(table, save_ProgramUniform2ui);
9682   SET_ProgramUniform3ui(table, save_ProgramUniform3ui);
9683   SET_ProgramUniform4ui(table, save_ProgramUniform4ui);
9684   SET_ProgramUniform1uiv(table, save_ProgramUniform1uiv);
9685   SET_ProgramUniform2uiv(table, save_ProgramUniform2uiv);
9686   SET_ProgramUniform3uiv(table, save_ProgramUniform3uiv);
9687   SET_ProgramUniform4uiv(table, save_ProgramUniform4uiv);
9688   SET_ProgramUniformMatrix2fv(table, save_ProgramUniformMatrix2fv);
9689   SET_ProgramUniformMatrix3fv(table, save_ProgramUniformMatrix3fv);
9690   SET_ProgramUniformMatrix4fv(table, save_ProgramUniformMatrix4fv);
9691   SET_ProgramUniformMatrix2x3fv(table, save_ProgramUniformMatrix2x3fv);
9692   SET_ProgramUniformMatrix3x2fv(table, save_ProgramUniformMatrix3x2fv);
9693   SET_ProgramUniformMatrix2x4fv(table, save_ProgramUniformMatrix2x4fv);
9694   SET_ProgramUniformMatrix4x2fv(table, save_ProgramUniformMatrix4x2fv);
9695   SET_ProgramUniformMatrix3x4fv(table, save_ProgramUniformMatrix3x4fv);
9696   SET_ProgramUniformMatrix4x3fv(table, save_ProgramUniformMatrix4x3fv);
9697}
9698
9699
9700
9701static const char *
9702enum_string(GLenum k)
9703{
9704   return _mesa_lookup_enum_by_nr(k);
9705}
9706
9707
9708/**
9709 * Print the commands in a display list.  For debugging only.
9710 * TODO: many commands aren't handled yet.
9711 */
9712static void GLAPIENTRY
9713print_list(struct gl_context *ctx, GLuint list)
9714{
9715   struct gl_display_list *dlist;
9716   Node *n;
9717   GLboolean done;
9718
9719   if (!islist(ctx, list)) {
9720      printf("%u is not a display list ID\n", list);
9721      return;
9722   }
9723
9724   dlist = _mesa_lookup_list(ctx, list);
9725   if (!dlist)
9726      return;
9727
9728   n = dlist->Head;
9729
9730   printf("START-LIST %u, address %p\n", list, (void *) n);
9731
9732   done = n ? GL_FALSE : GL_TRUE;
9733   while (!done) {
9734      const OpCode opcode = n[0].opcode;
9735
9736      if (is_ext_opcode(opcode)) {
9737         n += ext_opcode_print(ctx, n);
9738      }
9739      else {
9740         switch (opcode) {
9741         case OPCODE_ACCUM:
9742            printf("Accum %s %g\n", enum_string(n[1].e), n[2].f);
9743            break;
9744         case OPCODE_BITMAP:
9745            printf("Bitmap %d %d %g %g %g %g %p\n", n[1].i, n[2].i,
9746                   n[3].f, n[4].f, n[5].f, n[6].f,
9747                   get_pointer(&n[7]));
9748            break;
9749         case OPCODE_CALL_LIST:
9750            printf("CallList %d\n", (int) n[1].ui);
9751            break;
9752         case OPCODE_CALL_LIST_OFFSET:
9753            printf("CallList %d + offset %u = %u\n", (int) n[1].ui,
9754                         ctx->List.ListBase, ctx->List.ListBase + n[1].ui);
9755            break;
9756         case OPCODE_DISABLE:
9757            printf("Disable %s\n", enum_string(n[1].e));
9758            break;
9759         case OPCODE_ENABLE:
9760            printf("Enable %s\n", enum_string(n[1].e));
9761            break;
9762         case OPCODE_FRUSTUM:
9763            printf("Frustum %g %g %g %g %g %g\n",
9764                         n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f);
9765            break;
9766         case OPCODE_LINE_STIPPLE:
9767            printf("LineStipple %d %x\n", n[1].i, (int) n[2].us);
9768            break;
9769         case OPCODE_LOAD_IDENTITY:
9770            printf("LoadIdentity\n");
9771            break;
9772         case OPCODE_LOAD_MATRIX:
9773            printf("LoadMatrix\n");
9774            printf("  %8f %8f %8f %8f\n",
9775                         n[1].f, n[5].f, n[9].f, n[13].f);
9776            printf("  %8f %8f %8f %8f\n",
9777                         n[2].f, n[6].f, n[10].f, n[14].f);
9778            printf("  %8f %8f %8f %8f\n",
9779                         n[3].f, n[7].f, n[11].f, n[15].f);
9780            printf("  %8f %8f %8f %8f\n",
9781                         n[4].f, n[8].f, n[12].f, n[16].f);
9782            break;
9783         case OPCODE_MULT_MATRIX:
9784            printf("MultMatrix (or Rotate)\n");
9785            printf("  %8f %8f %8f %8f\n",
9786                         n[1].f, n[5].f, n[9].f, n[13].f);
9787            printf("  %8f %8f %8f %8f\n",
9788                         n[2].f, n[6].f, n[10].f, n[14].f);
9789            printf("  %8f %8f %8f %8f\n",
9790                         n[3].f, n[7].f, n[11].f, n[15].f);
9791            printf("  %8f %8f %8f %8f\n",
9792                         n[4].f, n[8].f, n[12].f, n[16].f);
9793            break;
9794         case OPCODE_ORTHO:
9795            printf("Ortho %g %g %g %g %g %g\n",
9796                         n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f);
9797            break;
9798         case OPCODE_POP_ATTRIB:
9799            printf("PopAttrib\n");
9800            break;
9801         case OPCODE_POP_MATRIX:
9802            printf("PopMatrix\n");
9803            break;
9804         case OPCODE_POP_NAME:
9805            printf("PopName\n");
9806            break;
9807         case OPCODE_PUSH_ATTRIB:
9808            printf("PushAttrib %x\n", n[1].bf);
9809            break;
9810         case OPCODE_PUSH_MATRIX:
9811            printf("PushMatrix\n");
9812            break;
9813         case OPCODE_PUSH_NAME:
9814            printf("PushName %d\n", (int) n[1].ui);
9815            break;
9816         case OPCODE_RASTER_POS:
9817            printf("RasterPos %g %g %g %g\n",
9818                         n[1].f, n[2].f, n[3].f, n[4].f);
9819            break;
9820         case OPCODE_ROTATE:
9821            printf("Rotate %g %g %g %g\n",
9822                         n[1].f, n[2].f, n[3].f, n[4].f);
9823            break;
9824         case OPCODE_SCALE:
9825            printf("Scale %g %g %g\n", n[1].f, n[2].f, n[3].f);
9826            break;
9827         case OPCODE_TRANSLATE:
9828            printf("Translate %g %g %g\n", n[1].f, n[2].f, n[3].f);
9829            break;
9830         case OPCODE_BIND_TEXTURE:
9831            printf("BindTexture %s %d\n",
9832                         _mesa_lookup_enum_by_nr(n[1].ui), n[2].ui);
9833            break;
9834         case OPCODE_SHADE_MODEL:
9835            printf("ShadeModel %s\n", _mesa_lookup_enum_by_nr(n[1].ui));
9836            break;
9837         case OPCODE_MAP1:
9838            printf("Map1 %s %.3f %.3f %d %d\n",
9839                         _mesa_lookup_enum_by_nr(n[1].ui),
9840                         n[2].f, n[3].f, n[4].i, n[5].i);
9841            break;
9842         case OPCODE_MAP2:
9843            printf("Map2 %s %.3f %.3f %.3f %.3f %d %d %d %d\n",
9844                         _mesa_lookup_enum_by_nr(n[1].ui),
9845                         n[2].f, n[3].f, n[4].f, n[5].f,
9846                         n[6].i, n[7].i, n[8].i, n[9].i);
9847            break;
9848         case OPCODE_MAPGRID1:
9849            printf("MapGrid1 %d %.3f %.3f\n", n[1].i, n[2].f, n[3].f);
9850            break;
9851         case OPCODE_MAPGRID2:
9852            printf("MapGrid2 %d %.3f %.3f, %d %.3f %.3f\n",
9853                         n[1].i, n[2].f, n[3].f, n[4].i, n[5].f, n[6].f);
9854            break;
9855         case OPCODE_EVALMESH1:
9856            printf("EvalMesh1 %d %d\n", n[1].i, n[2].i);
9857            break;
9858         case OPCODE_EVALMESH2:
9859            printf("EvalMesh2 %d %d %d %d\n",
9860                         n[1].i, n[2].i, n[3].i, n[4].i);
9861            break;
9862
9863         case OPCODE_ATTR_1F_NV:
9864            printf("ATTR_1F_NV attr %d: %f\n", n[1].i, n[2].f);
9865            break;
9866         case OPCODE_ATTR_2F_NV:
9867            printf("ATTR_2F_NV attr %d: %f %f\n",
9868                         n[1].i, n[2].f, n[3].f);
9869            break;
9870         case OPCODE_ATTR_3F_NV:
9871            printf("ATTR_3F_NV attr %d: %f %f %f\n",
9872                         n[1].i, n[2].f, n[3].f, n[4].f);
9873            break;
9874         case OPCODE_ATTR_4F_NV:
9875            printf("ATTR_4F_NV attr %d: %f %f %f %f\n",
9876                         n[1].i, n[2].f, n[3].f, n[4].f, n[5].f);
9877            break;
9878         case OPCODE_ATTR_1F_ARB:
9879            printf("ATTR_1F_ARB attr %d: %f\n", n[1].i, n[2].f);
9880            break;
9881         case OPCODE_ATTR_2F_ARB:
9882            printf("ATTR_2F_ARB attr %d: %f %f\n",
9883                         n[1].i, n[2].f, n[3].f);
9884            break;
9885         case OPCODE_ATTR_3F_ARB:
9886            printf("ATTR_3F_ARB attr %d: %f %f %f\n",
9887                         n[1].i, n[2].f, n[3].f, n[4].f);
9888            break;
9889         case OPCODE_ATTR_4F_ARB:
9890            printf("ATTR_4F_ARB attr %d: %f %f %f %f\n",
9891                         n[1].i, n[2].f, n[3].f, n[4].f, n[5].f);
9892            break;
9893
9894         case OPCODE_MATERIAL:
9895            printf("MATERIAL %x %x: %f %f %f %f\n",
9896                         n[1].i, n[2].i, n[3].f, n[4].f, n[5].f, n[6].f);
9897            break;
9898         case OPCODE_BEGIN:
9899            printf("BEGIN %x\n", n[1].i);
9900            break;
9901         case OPCODE_END:
9902            printf("END\n");
9903            break;
9904         case OPCODE_RECTF:
9905            printf("RECTF %f %f %f %f\n", n[1].f, n[2].f, n[3].f,
9906                         n[4].f);
9907            break;
9908         case OPCODE_EVAL_C1:
9909            printf("EVAL_C1 %f\n", n[1].f);
9910            break;
9911         case OPCODE_EVAL_C2:
9912            printf("EVAL_C2 %f %f\n", n[1].f, n[2].f);
9913            break;
9914         case OPCODE_EVAL_P1:
9915            printf("EVAL_P1 %d\n", n[1].i);
9916            break;
9917         case OPCODE_EVAL_P2:
9918            printf("EVAL_P2 %d %d\n", n[1].i, n[2].i);
9919            break;
9920
9921         case OPCODE_PROVOKING_VERTEX:
9922            printf("ProvokingVertex %s\n",
9923                         _mesa_lookup_enum_by_nr(n[1].ui));
9924            break;
9925
9926            /*
9927             * meta opcodes/commands
9928             */
9929         case OPCODE_ERROR:
9930            printf("Error: %s %s\n", enum_string(n[1].e),
9931                   (const char *) get_pointer(&n[2]));
9932            break;
9933         case OPCODE_CONTINUE:
9934            printf("DISPLAY-LIST-CONTINUE\n");
9935            n = (Node *) get_pointer(&n[1]);
9936            break;
9937         case OPCODE_END_OF_LIST:
9938            printf("END-LIST %u\n", list);
9939            done = GL_TRUE;
9940            break;
9941         default:
9942            if (opcode < 0 || opcode > OPCODE_END_OF_LIST) {
9943               printf
9944                  ("ERROR IN DISPLAY LIST: opcode = %d, address = %p\n",
9945                   opcode, (void *) n);
9946               return;
9947            }
9948            else {
9949               printf("command %d, %u operands\n", opcode,
9950                            InstSize[opcode]);
9951            }
9952         }
9953         /* increment n to point to next compiled command */
9954         if (opcode != OPCODE_CONTINUE) {
9955            n += InstSize[opcode];
9956         }
9957      }
9958   }
9959}
9960
9961
9962
9963/**
9964 * Clients may call this function to help debug display list problems.
9965 * This function is _ONLY_FOR_DEBUGGING_PURPOSES_.  It may be removed,
9966 * changed, or break in the future without notice.
9967 */
9968void
9969mesa_print_display_list(GLuint list)
9970{
9971   GET_CURRENT_CONTEXT(ctx);
9972   print_list(ctx, list);
9973}
9974
9975
9976/**********************************************************************/
9977/*****                      Initialization                        *****/
9978/**********************************************************************/
9979
9980static void
9981save_vtxfmt_init(GLvertexformat * vfmt)
9982{
9983   vfmt->ArrayElement = _ae_ArrayElement;
9984
9985   vfmt->Begin = save_Begin;
9986
9987   vfmt->CallList = save_CallList;
9988   vfmt->CallLists = save_CallLists;
9989
9990   vfmt->Color3f = save_Color3f;
9991   vfmt->Color3fv = save_Color3fv;
9992   vfmt->Color4f = save_Color4f;
9993   vfmt->Color4fv = save_Color4fv;
9994   vfmt->EdgeFlag = save_EdgeFlag;
9995   vfmt->End = save_End;
9996
9997   vfmt->EvalCoord1f = save_EvalCoord1f;
9998   vfmt->EvalCoord1fv = save_EvalCoord1fv;
9999   vfmt->EvalCoord2f = save_EvalCoord2f;
10000   vfmt->EvalCoord2fv = save_EvalCoord2fv;
10001   vfmt->EvalPoint1 = save_EvalPoint1;
10002   vfmt->EvalPoint2 = save_EvalPoint2;
10003
10004   vfmt->FogCoordfEXT = save_FogCoordfEXT;
10005   vfmt->FogCoordfvEXT = save_FogCoordfvEXT;
10006   vfmt->Indexf = save_Indexf;
10007   vfmt->Indexfv = save_Indexfv;
10008   vfmt->Materialfv = save_Materialfv;
10009   vfmt->MultiTexCoord1fARB = save_MultiTexCoord1f;
10010   vfmt->MultiTexCoord1fvARB = save_MultiTexCoord1fv;
10011   vfmt->MultiTexCoord2fARB = save_MultiTexCoord2f;
10012   vfmt->MultiTexCoord2fvARB = save_MultiTexCoord2fv;
10013   vfmt->MultiTexCoord3fARB = save_MultiTexCoord3f;
10014   vfmt->MultiTexCoord3fvARB = save_MultiTexCoord3fv;
10015   vfmt->MultiTexCoord4fARB = save_MultiTexCoord4f;
10016   vfmt->MultiTexCoord4fvARB = save_MultiTexCoord4fv;
10017   vfmt->Normal3f = save_Normal3f;
10018   vfmt->Normal3fv = save_Normal3fv;
10019   vfmt->SecondaryColor3fEXT = save_SecondaryColor3fEXT;
10020   vfmt->SecondaryColor3fvEXT = save_SecondaryColor3fvEXT;
10021   vfmt->TexCoord1f = save_TexCoord1f;
10022   vfmt->TexCoord1fv = save_TexCoord1fv;
10023   vfmt->TexCoord2f = save_TexCoord2f;
10024   vfmt->TexCoord2fv = save_TexCoord2fv;
10025   vfmt->TexCoord3f = save_TexCoord3f;
10026   vfmt->TexCoord3fv = save_TexCoord3fv;
10027   vfmt->TexCoord4f = save_TexCoord4f;
10028   vfmt->TexCoord4fv = save_TexCoord4fv;
10029   vfmt->Vertex2f = save_Vertex2f;
10030   vfmt->Vertex2fv = save_Vertex2fv;
10031   vfmt->Vertex3f = save_Vertex3f;
10032   vfmt->Vertex3fv = save_Vertex3fv;
10033   vfmt->Vertex4f = save_Vertex4f;
10034   vfmt->Vertex4fv = save_Vertex4fv;
10035   vfmt->VertexAttrib1fARB = save_VertexAttrib1fARB;
10036   vfmt->VertexAttrib1fvARB = save_VertexAttrib1fvARB;
10037   vfmt->VertexAttrib2fARB = save_VertexAttrib2fARB;
10038   vfmt->VertexAttrib2fvARB = save_VertexAttrib2fvARB;
10039   vfmt->VertexAttrib3fARB = save_VertexAttrib3fARB;
10040   vfmt->VertexAttrib3fvARB = save_VertexAttrib3fvARB;
10041   vfmt->VertexAttrib4fARB = save_VertexAttrib4fARB;
10042   vfmt->VertexAttrib4fvARB = save_VertexAttrib4fvARB;
10043}
10044
10045
10046void
10047_mesa_install_dlist_vtxfmt(struct _glapi_table *disp,
10048                           const GLvertexformat *vfmt)
10049{
10050   SET_CallList(disp, vfmt->CallList);
10051   SET_CallLists(disp, vfmt->CallLists);
10052}
10053
10054
10055/**
10056 * Initialize display list state for given context.
10057 */
10058void
10059_mesa_init_display_list(struct gl_context *ctx)
10060{
10061   static GLboolean tableInitialized = GL_FALSE;
10062
10063   /* zero-out the instruction size table, just once */
10064   if (!tableInitialized) {
10065      memset(InstSize, 0, sizeof(InstSize));
10066      tableInitialized = GL_TRUE;
10067   }
10068
10069   /* extension info */
10070   ctx->ListExt = CALLOC_STRUCT(gl_list_extensions);
10071
10072   /* Display list */
10073   ctx->ListState.CallDepth = 0;
10074   ctx->ExecuteFlag = GL_TRUE;
10075   ctx->CompileFlag = GL_FALSE;
10076   ctx->ListState.CurrentBlock = NULL;
10077   ctx->ListState.CurrentPos = 0;
10078
10079   /* Display List group */
10080   ctx->List.ListBase = 0;
10081
10082   save_vtxfmt_init(&ctx->ListState.ListVtxfmt);
10083}
10084
10085
10086void
10087_mesa_free_display_list_data(struct gl_context *ctx)
10088{
10089   free(ctx->ListExt);
10090   ctx->ListExt = NULL;
10091}
10092