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