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