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