3177df2ad3a52903005e41cc9598a4bf4a29369c
[reactos.git] / reactos / dll / opengl / mesa / src / mesa / main / dlist.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.7
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR 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 "config.h"
39 #include "mfeatures.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 #if FEATURE_EXT_framebuffer_object
47 #include "fbobject.h"
48 #endif
49 #include "framebuffer.h"
50 #include "glapi/glapi.h"
51 #include "hash.h"
52 #include "image.h"
53 #include "light.h"
54 #include "macros.h"
55 #include "pack.h"
56 #include "pbo.h"
57 #include "shaderapi.h"
58 #include "teximage.h"
59 #include "texstorage.h"
60 #include "mtypes.h"
61 #include "varray.h"
62 #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
63 #include "arbprogram.h"
64 #endif
65 #if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
66 #include "nvprogram.h"
67 #endif
68
69 #include "math/m_matrix.h"
70
71 #include "main/dispatch.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 */
79 struct 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 */
93 struct 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) \
111 do { \
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) \
125 do { \
126 if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON || \
127 ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \
128 _mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \
129 return retval; \
130 } \
131 } while (0)
132
133 /**
134 * Macro to assert that the API call was made outside the
135 * glBegin()/glEnd() pair.
136 *
137 * \param ctx GL context.
138 */
139 #define ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx) \
140 do { \
141 if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON || \
142 ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \
143 _mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \
144 return; \
145 } \
146 } while (0)
147
148 /**
149 * Macro to assert that the API call was made outside the
150 * glBegin()/glEnd() pair and flush the vertices.
151 *
152 * \param ctx GL context.
153 */
154 #define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx) \
155 do { \
156 ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx); \
157 SAVE_FLUSH_VERTICES(ctx); \
158 } while (0)
159
160 /**
161 * Macro to assert that the API call was made outside the
162 * glBegin()/glEnd() pair and flush the vertices, with return value.
163 *
164 * \param ctx GL context.
165 * \param retval value to return value in case the assertion fails.
166 */
167 #define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, retval)\
168 do { \
169 ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval); \
170 SAVE_FLUSH_VERTICES(ctx); \
171 } while (0)
172
173
174
175 /**
176 * Display list opcodes.
177 *
178 * The fact that these identifiers are assigned consecutive
179 * integer values starting at 0 is very important, see InstSize array usage)
180 */
181 typedef enum
182 {
183 OPCODE_INVALID = -1, /* Force signed enum */
184 OPCODE_ACCUM,
185 OPCODE_ALPHA_FUNC,
186 OPCODE_BIND_TEXTURE,
187 OPCODE_BITMAP,
188 OPCODE_BLEND_COLOR,
189 OPCODE_BLEND_EQUATION,
190 OPCODE_BLEND_EQUATION_SEPARATE,
191 OPCODE_BLEND_FUNC_SEPARATE,
192
193 OPCODE_BLEND_EQUATION_I,
194 OPCODE_BLEND_EQUATION_SEPARATE_I,
195 OPCODE_BLEND_FUNC_I,
196 OPCODE_BLEND_FUNC_SEPARATE_I,
197
198 OPCODE_CALL_LIST,
199 OPCODE_CALL_LIST_OFFSET,
200 OPCODE_CLEAR,
201 OPCODE_CLEAR_ACCUM,
202 OPCODE_CLEAR_COLOR,
203 OPCODE_CLEAR_DEPTH,
204 OPCODE_CLEAR_INDEX,
205 OPCODE_CLEAR_STENCIL,
206 OPCODE_CLEAR_BUFFER_IV,
207 OPCODE_CLEAR_BUFFER_UIV,
208 OPCODE_CLEAR_BUFFER_FV,
209 OPCODE_CLEAR_BUFFER_FI,
210 OPCODE_CLIP_PLANE,
211 OPCODE_COLOR_MASK,
212 OPCODE_COLOR_MATERIAL,
213 OPCODE_COLOR_TABLE,
214 OPCODE_COLOR_TABLE_PARAMETER_FV,
215 OPCODE_COLOR_TABLE_PARAMETER_IV,
216 OPCODE_COLOR_SUB_TABLE,
217 OPCODE_CONVOLUTION_FILTER_1D,
218 OPCODE_CONVOLUTION_FILTER_2D,
219 OPCODE_CONVOLUTION_PARAMETER_I,
220 OPCODE_CONVOLUTION_PARAMETER_IV,
221 OPCODE_CONVOLUTION_PARAMETER_F,
222 OPCODE_CONVOLUTION_PARAMETER_FV,
223 OPCODE_COPY_COLOR_SUB_TABLE,
224 OPCODE_COPY_COLOR_TABLE,
225 OPCODE_COPY_PIXELS,
226 OPCODE_COPY_TEX_IMAGE1D,
227 OPCODE_COPY_TEX_IMAGE2D,
228 OPCODE_COPY_TEX_SUB_IMAGE1D,
229 OPCODE_COPY_TEX_SUB_IMAGE2D,
230 OPCODE_COPY_TEX_SUB_IMAGE3D,
231 OPCODE_CULL_FACE,
232 OPCODE_DEPTH_FUNC,
233 OPCODE_DEPTH_MASK,
234 OPCODE_DEPTH_RANGE,
235 OPCODE_DISABLE,
236 OPCODE_DRAW_BUFFER,
237 OPCODE_DRAW_PIXELS,
238 OPCODE_ENABLE,
239 OPCODE_EVALMESH1,
240 OPCODE_EVALMESH2,
241 OPCODE_FOG,
242 OPCODE_FRONT_FACE,
243 OPCODE_FRUSTUM,
244 OPCODE_HINT,
245 OPCODE_HISTOGRAM,
246 OPCODE_INDEX_MASK,
247 OPCODE_INIT_NAMES,
248 OPCODE_LIGHT,
249 OPCODE_LIGHT_MODEL,
250 OPCODE_LINE_STIPPLE,
251 OPCODE_LINE_WIDTH,
252 OPCODE_LIST_BASE,
253 OPCODE_LOAD_IDENTITY,
254 OPCODE_LOAD_MATRIX,
255 OPCODE_LOAD_NAME,
256 OPCODE_LOGIC_OP,
257 OPCODE_MAP1,
258 OPCODE_MAP2,
259 OPCODE_MAPGRID1,
260 OPCODE_MAPGRID2,
261 OPCODE_MATRIX_MODE,
262 OPCODE_MIN_MAX,
263 OPCODE_MULT_MATRIX,
264 OPCODE_ORTHO,
265 OPCODE_PASSTHROUGH,
266 OPCODE_PIXEL_MAP,
267 OPCODE_PIXEL_TRANSFER,
268 OPCODE_PIXEL_ZOOM,
269 OPCODE_POINT_SIZE,
270 OPCODE_POINT_PARAMETERS,
271 OPCODE_POLYGON_MODE,
272 OPCODE_POLYGON_STIPPLE,
273 OPCODE_POLYGON_OFFSET,
274 OPCODE_POP_ATTRIB,
275 OPCODE_POP_MATRIX,
276 OPCODE_POP_NAME,
277 OPCODE_PRIORITIZE_TEXTURE,
278 OPCODE_PUSH_ATTRIB,
279 OPCODE_PUSH_MATRIX,
280 OPCODE_PUSH_NAME,
281 OPCODE_RASTER_POS,
282 OPCODE_READ_BUFFER,
283 OPCODE_RESET_HISTOGRAM,
284 OPCODE_RESET_MIN_MAX,
285 OPCODE_ROTATE,
286 OPCODE_SCALE,
287 OPCODE_SCISSOR,
288 OPCODE_SELECT_TEXTURE_SGIS,
289 OPCODE_SELECT_TEXTURE_COORD_SET,
290 OPCODE_SHADE_MODEL,
291 OPCODE_STENCIL_FUNC,
292 OPCODE_STENCIL_MASK,
293 OPCODE_STENCIL_OP,
294 OPCODE_TEXENV,
295 OPCODE_TEXGEN,
296 OPCODE_TEXPARAMETER,
297 OPCODE_TEX_IMAGE1D,
298 OPCODE_TEX_IMAGE2D,
299 OPCODE_TEX_IMAGE3D,
300 OPCODE_TEX_SUB_IMAGE1D,
301 OPCODE_TEX_SUB_IMAGE2D,
302 OPCODE_TEX_SUB_IMAGE3D,
303 OPCODE_TRANSLATE,
304 OPCODE_VIEWPORT,
305 OPCODE_WINDOW_POS,
306 /* GL_ARB_multitexture */
307 OPCODE_ACTIVE_TEXTURE,
308 /* GL_ARB_texture_compression */
309 OPCODE_COMPRESSED_TEX_IMAGE_1D,
310 OPCODE_COMPRESSED_TEX_IMAGE_2D,
311 OPCODE_COMPRESSED_TEX_IMAGE_3D,
312 OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D,
313 OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D,
314 OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D,
315 /* GL_ARB_multisample */
316 OPCODE_SAMPLE_COVERAGE,
317 /* GL_ARB_window_pos */
318 OPCODE_WINDOW_POS_ARB,
319 /* GL_NV_vertex_program */
320 OPCODE_BIND_PROGRAM_NV,
321 OPCODE_EXECUTE_PROGRAM_NV,
322 OPCODE_REQUEST_RESIDENT_PROGRAMS_NV,
323 OPCODE_LOAD_PROGRAM_NV,
324 OPCODE_TRACK_MATRIX_NV,
325 /* GL_NV_fragment_program */
326 OPCODE_PROGRAM_LOCAL_PARAMETER_ARB,
327 OPCODE_PROGRAM_NAMED_PARAMETER_NV,
328 /* GL_EXT_stencil_two_side */
329 OPCODE_ACTIVE_STENCIL_FACE_EXT,
330 /* GL_EXT_depth_bounds_test */
331 OPCODE_DEPTH_BOUNDS_EXT,
332 /* GL_ARB_vertex/fragment_program */
333 OPCODE_PROGRAM_STRING_ARB,
334 OPCODE_PROGRAM_ENV_PARAMETER_ARB,
335 /* GL_ARB_draw_buffers */
336 OPCODE_DRAW_BUFFERS_ARB,
337 /* GL_ATI_fragment_shader */
338 OPCODE_TEX_BUMP_PARAMETER_ATI,
339 /* OpenGL 2.0 */
340 OPCODE_STENCIL_FUNC_SEPARATE,
341 OPCODE_STENCIL_OP_SEPARATE,
342 OPCODE_STENCIL_MASK_SEPARATE,
343
344 /* GL_ARB_shader_objects */
345 OPCODE_USE_PROGRAM,
346 OPCODE_UNIFORM_1F,
347 OPCODE_UNIFORM_2F,
348 OPCODE_UNIFORM_3F,
349 OPCODE_UNIFORM_4F,
350 OPCODE_UNIFORM_1FV,
351 OPCODE_UNIFORM_2FV,
352 OPCODE_UNIFORM_3FV,
353 OPCODE_UNIFORM_4FV,
354 OPCODE_UNIFORM_1I,
355 OPCODE_UNIFORM_2I,
356 OPCODE_UNIFORM_3I,
357 OPCODE_UNIFORM_4I,
358 OPCODE_UNIFORM_1IV,
359 OPCODE_UNIFORM_2IV,
360 OPCODE_UNIFORM_3IV,
361 OPCODE_UNIFORM_4IV,
362 OPCODE_UNIFORM_MATRIX22,
363 OPCODE_UNIFORM_MATRIX33,
364 OPCODE_UNIFORM_MATRIX44,
365 OPCODE_UNIFORM_MATRIX23,
366 OPCODE_UNIFORM_MATRIX32,
367 OPCODE_UNIFORM_MATRIX24,
368 OPCODE_UNIFORM_MATRIX42,
369 OPCODE_UNIFORM_MATRIX34,
370 OPCODE_UNIFORM_MATRIX43,
371
372 /* OpenGL 3.0 */
373 OPCODE_UNIFORM_1UI,
374 OPCODE_UNIFORM_2UI,
375 OPCODE_UNIFORM_3UI,
376 OPCODE_UNIFORM_4UI,
377 OPCODE_UNIFORM_1UIV,
378 OPCODE_UNIFORM_2UIV,
379 OPCODE_UNIFORM_3UIV,
380 OPCODE_UNIFORM_4UIV,
381
382 /* GL_ARB_color_buffer_float */
383 OPCODE_CLAMP_COLOR,
384
385 /* GL_EXT_framebuffer_blit */
386 OPCODE_BLIT_FRAMEBUFFER,
387
388 /* Vertex attributes -- fallback for when optimized display
389 * list build isn't active.
390 */
391 OPCODE_ATTR_1F_NV,
392 OPCODE_ATTR_2F_NV,
393 OPCODE_ATTR_3F_NV,
394 OPCODE_ATTR_4F_NV,
395 OPCODE_ATTR_1F_ARB,
396 OPCODE_ATTR_2F_ARB,
397 OPCODE_ATTR_3F_ARB,
398 OPCODE_ATTR_4F_ARB,
399 OPCODE_MATERIAL,
400 OPCODE_BEGIN,
401 OPCODE_END,
402 OPCODE_RECTF,
403 OPCODE_EVAL_C1,
404 OPCODE_EVAL_C2,
405 OPCODE_EVAL_P1,
406 OPCODE_EVAL_P2,
407
408 /* GL_EXT_provoking_vertex */
409 OPCODE_PROVOKING_VERTEX,
410
411 /* GL_EXT_texture_integer */
412 OPCODE_CLEARCOLOR_I,
413 OPCODE_CLEARCOLOR_UI,
414 OPCODE_TEXPARAMETER_I,
415 OPCODE_TEXPARAMETER_UI,
416
417 /* GL_EXT_separate_shader_objects */
418 OPCODE_ACTIVE_PROGRAM_EXT,
419 OPCODE_USE_SHADER_PROGRAM_EXT,
420
421 /* GL_NV_texture_barrier */
422 OPCODE_TEXTURE_BARRIER_NV,
423
424 /* GL_ARB_geometry_shader4 */
425 OPCODE_PROGRAM_PARAMETERI,
426 OPCODE_FRAMEBUFFER_TEXTURE,
427 OPCODE_FRAMEBUFFER_TEXTURE_FACE,
428
429 /* The following three are meta instructions */
430 OPCODE_ERROR, /* raise compiled-in error */
431 OPCODE_CONTINUE,
432 OPCODE_END_OF_LIST,
433 OPCODE_EXT_0
434 } OpCode;
435
436
437
438 /**
439 * Display list node.
440 *
441 * Display list instructions are stored as sequences of "nodes". Nodes
442 * are allocated in blocks. Each block has BLOCK_SIZE nodes. Blocks
443 * are linked together with a pointer.
444 *
445 * Each instruction in the display list is stored as a sequence of
446 * contiguous nodes in memory.
447 * Each node is the union of a variety of data types.
448 */
449 union gl_dlist_node
450 {
451 OpCode opcode;
452 GLboolean b;
453 GLbitfield bf;
454 GLubyte ub;
455 GLshort s;
456 GLushort us;
457 GLint i;
458 GLuint ui;
459 GLenum e;
460 GLfloat f;
461 GLvoid *data;
462 void *next; /* If prev node's opcode==OPCODE_CONTINUE */
463 };
464
465
466 typedef union gl_dlist_node Node;
467
468
469 /**
470 * Used to store a 64-bit uint in a pair of "Nodes" for the sake of 32-bit
471 * environment. In 64-bit env, sizeof(Node)==8 anyway.
472 */
473 union uint64_pair
474 {
475 GLuint64 uint64;
476 GLuint uint32[2];
477 };
478
479
480 /**
481 * How many nodes to allocate at a time.
482 *
483 * \note Reduced now that we hold vertices etc. elsewhere.
484 */
485 #define BLOCK_SIZE 256
486
487
488
489 /**
490 * Number of nodes of storage needed for each instruction.
491 * Sizes for dynamically allocated opcodes are stored in the context struct.
492 */
493 static GLuint InstSize[OPCODE_END_OF_LIST + 1];
494
495
496 #if FEATURE_dlist
497
498
499 void mesa_print_display_list(GLuint list);
500
501
502 /**********************************************************************/
503 /***** Private *****/
504 /**********************************************************************/
505
506
507 /**
508 * Make an empty display list. This is used by glGenLists() to
509 * reserve display list IDs.
510 */
511 static struct gl_display_list *
512 make_list(GLuint name, GLuint count)
513 {
514 struct gl_display_list *dlist = CALLOC_STRUCT(gl_display_list);
515 dlist->Name = name;
516 dlist->Head = (Node *) malloc(sizeof(Node) * count);
517 dlist->Head[0].opcode = OPCODE_END_OF_LIST;
518 return dlist;
519 }
520
521
522 /**
523 * Lookup function to just encapsulate casting.
524 */
525 static inline struct gl_display_list *
526 lookup_list(struct gl_context *ctx, GLuint list)
527 {
528 return (struct gl_display_list *)
529 _mesa_HashLookup(ctx->Shared->DisplayList, list);
530 }
531
532
533 /** Is the given opcode an extension code? */
534 static inline GLboolean
535 is_ext_opcode(OpCode opcode)
536 {
537 return (opcode >= OPCODE_EXT_0);
538 }
539
540
541 /** Destroy an extended opcode instruction */
542 static GLint
543 ext_opcode_destroy(struct gl_context *ctx, Node *node)
544 {
545 const GLint i = node[0].opcode - OPCODE_EXT_0;
546 GLint step;
547 ctx->ListExt->Opcode[i].Destroy(ctx, &node[1]);
548 step = ctx->ListExt->Opcode[i].Size;
549 return step;
550 }
551
552
553 /** Execute an extended opcode instruction */
554 static GLint
555 ext_opcode_execute(struct gl_context *ctx, Node *node)
556 {
557 const GLint i = node[0].opcode - OPCODE_EXT_0;
558 GLint step;
559 ctx->ListExt->Opcode[i].Execute(ctx, &node[1]);
560 step = ctx->ListExt->Opcode[i].Size;
561 return step;
562 }
563
564
565 /** Print an extended opcode instruction */
566 static GLint
567 ext_opcode_print(struct gl_context *ctx, Node *node)
568 {
569 const GLint i = node[0].opcode - OPCODE_EXT_0;
570 GLint step;
571 ctx->ListExt->Opcode[i].Print(ctx, &node[1]);
572 step = ctx->ListExt->Opcode[i].Size;
573 return step;
574 }
575
576
577 /**
578 * Delete the named display list, but don't remove from hash table.
579 * \param dlist - display list pointer
580 */
581 void
582 _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
583 {
584 Node *n, *block;
585 GLboolean done;
586
587 n = block = dlist->Head;
588
589 done = block ? GL_FALSE : GL_TRUE;
590 while (!done) {
591 const OpCode opcode = n[0].opcode;
592
593 /* check for extension opcodes first */
594 if (is_ext_opcode(opcode)) {
595 n += ext_opcode_destroy(ctx, n);
596 }
597 else {
598 switch (opcode) {
599 /* for some commands, we need to free malloc'd memory */
600 case OPCODE_MAP1:
601 free(n[6].data);
602 n += InstSize[n[0].opcode];
603 break;
604 case OPCODE_MAP2:
605 free(n[10].data);
606 n += InstSize[n[0].opcode];
607 break;
608 case OPCODE_DRAW_PIXELS:
609 free(n[5].data);
610 n += InstSize[n[0].opcode];
611 break;
612 case OPCODE_BITMAP:
613 free(n[7].data);
614 n += InstSize[n[0].opcode];
615 break;
616 case OPCODE_COLOR_TABLE:
617 free(n[6].data);
618 n += InstSize[n[0].opcode];
619 break;
620 case OPCODE_COLOR_SUB_TABLE:
621 free(n[6].data);
622 n += InstSize[n[0].opcode];
623 break;
624 case OPCODE_CONVOLUTION_FILTER_1D:
625 free(n[6].data);
626 n += InstSize[n[0].opcode];
627 break;
628 case OPCODE_CONVOLUTION_FILTER_2D:
629 free(n[7].data);
630 n += InstSize[n[0].opcode];
631 break;
632 case OPCODE_POLYGON_STIPPLE:
633 free(n[1].data);
634 n += InstSize[n[0].opcode];
635 break;
636 case OPCODE_TEX_IMAGE1D:
637 free(n[8].data);
638 n += InstSize[n[0].opcode];
639 break;
640 case OPCODE_TEX_IMAGE2D:
641 free(n[9].data);
642 n += InstSize[n[0].opcode];
643 break;
644 case OPCODE_TEX_IMAGE3D:
645 free(n[10].data);
646 n += InstSize[n[0].opcode];
647 break;
648 case OPCODE_TEX_SUB_IMAGE1D:
649 free(n[7].data);
650 n += InstSize[n[0].opcode];
651 break;
652 case OPCODE_TEX_SUB_IMAGE2D:
653 free(n[9].data);
654 n += InstSize[n[0].opcode];
655 break;
656 case OPCODE_TEX_SUB_IMAGE3D:
657 free(n[11].data);
658 n += InstSize[n[0].opcode];
659 break;
660 case OPCODE_COMPRESSED_TEX_IMAGE_1D:
661 free(n[7].data);
662 n += InstSize[n[0].opcode];
663 break;
664 case OPCODE_COMPRESSED_TEX_IMAGE_2D:
665 free(n[8].data);
666 n += InstSize[n[0].opcode];
667 break;
668 case OPCODE_COMPRESSED_TEX_IMAGE_3D:
669 free(n[9].data);
670 n += InstSize[n[0].opcode];
671 break;
672 case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D:
673 free(n[7].data);
674 n += InstSize[n[0].opcode];
675 break;
676 case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D:
677 free(n[9].data);
678 n += InstSize[n[0].opcode];
679 break;
680 case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D:
681 free(n[11].data);
682 n += InstSize[n[0].opcode];
683 break;
684 #if FEATURE_NV_vertex_program
685 case OPCODE_LOAD_PROGRAM_NV:
686 free(n[4].data); /* program string */
687 n += InstSize[n[0].opcode];
688 break;
689 case OPCODE_REQUEST_RESIDENT_PROGRAMS_NV:
690 free(n[2].data); /* array of program ids */
691 n += InstSize[n[0].opcode];
692 break;
693 #endif
694 #if FEATURE_NV_fragment_program
695 case OPCODE_PROGRAM_NAMED_PARAMETER_NV:
696 free(n[3].data); /* parameter name */
697 n += InstSize[n[0].opcode];
698 break;
699 #endif
700 #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
701 case OPCODE_PROGRAM_STRING_ARB:
702 free(n[4].data); /* program string */
703 n += InstSize[n[0].opcode];
704 break;
705 #endif
706 case OPCODE_UNIFORM_1FV:
707 case OPCODE_UNIFORM_2FV:
708 case OPCODE_UNIFORM_3FV:
709 case OPCODE_UNIFORM_4FV:
710 case OPCODE_UNIFORM_1IV:
711 case OPCODE_UNIFORM_2IV:
712 case OPCODE_UNIFORM_3IV:
713 case OPCODE_UNIFORM_4IV:
714 case OPCODE_UNIFORM_1UIV:
715 case OPCODE_UNIFORM_2UIV:
716 case OPCODE_UNIFORM_3UIV:
717 case OPCODE_UNIFORM_4UIV:
718 free(n[3].data);
719 n += InstSize[n[0].opcode];
720 break;
721 case OPCODE_UNIFORM_MATRIX22:
722 case OPCODE_UNIFORM_MATRIX33:
723 case OPCODE_UNIFORM_MATRIX44:
724 case OPCODE_UNIFORM_MATRIX24:
725 case OPCODE_UNIFORM_MATRIX42:
726 case OPCODE_UNIFORM_MATRIX23:
727 case OPCODE_UNIFORM_MATRIX32:
728 case OPCODE_UNIFORM_MATRIX34:
729 case OPCODE_UNIFORM_MATRIX43:
730 free(n[4].data);
731 n += InstSize[n[0].opcode];
732 break;
733
734 case OPCODE_CONTINUE:
735 n = (Node *) n[1].next;
736 free(block);
737 block = n;
738 break;
739 case OPCODE_END_OF_LIST:
740 free(block);
741 done = GL_TRUE;
742 break;
743 default:
744 /* Most frequent case */
745 n += InstSize[n[0].opcode];
746 break;
747 }
748 }
749 }
750
751 free(dlist);
752 }
753
754
755 /**
756 * Destroy a display list and remove from hash table.
757 * \param list - display list number
758 */
759 static void
760 destroy_list(struct gl_context *ctx, GLuint list)
761 {
762 struct gl_display_list *dlist;
763
764 if (list == 0)
765 return;
766
767 dlist = lookup_list(ctx, list);
768 if (!dlist)
769 return;
770
771 _mesa_delete_list(ctx, dlist);
772 _mesa_HashRemove(ctx->Shared->DisplayList, list);
773 }
774
775
776 /*
777 * Translate the nth element of list from <type> to GLint.
778 */
779 static GLint
780 translate_id(GLsizei n, GLenum type, const GLvoid * list)
781 {
782 GLbyte *bptr;
783 GLubyte *ubptr;
784 GLshort *sptr;
785 GLushort *usptr;
786 GLint *iptr;
787 GLuint *uiptr;
788 GLfloat *fptr;
789
790 switch (type) {
791 case GL_BYTE:
792 bptr = (GLbyte *) list;
793 return (GLint) bptr[n];
794 case GL_UNSIGNED_BYTE:
795 ubptr = (GLubyte *) list;
796 return (GLint) ubptr[n];
797 case GL_SHORT:
798 sptr = (GLshort *) list;
799 return (GLint) sptr[n];
800 case GL_UNSIGNED_SHORT:
801 usptr = (GLushort *) list;
802 return (GLint) usptr[n];
803 case GL_INT:
804 iptr = (GLint *) list;
805 return iptr[n];
806 case GL_UNSIGNED_INT:
807 uiptr = (GLuint *) list;
808 return (GLint) uiptr[n];
809 case GL_FLOAT:
810 fptr = (GLfloat *) list;
811 return (GLint) FLOORF(fptr[n]);
812 case GL_2_BYTES:
813 ubptr = ((GLubyte *) list) + 2 * n;
814 return (GLint) ubptr[0] * 256
815 + (GLint) ubptr[1];
816 case GL_3_BYTES:
817 ubptr = ((GLubyte *) list) + 3 * n;
818 return (GLint) ubptr[0] * 65536
819 + (GLint) ubptr[1] * 256
820 + (GLint) ubptr[2];
821 case GL_4_BYTES:
822 ubptr = ((GLubyte *) list) + 4 * n;
823 return (GLint) ubptr[0] * 16777216
824 + (GLint) ubptr[1] * 65536
825 + (GLint) ubptr[2] * 256
826 + (GLint) ubptr[3];
827 default:
828 return 0;
829 }
830 }
831
832
833
834
835 /**********************************************************************/
836 /***** Public *****/
837 /**********************************************************************/
838
839 /**
840 * Wrapper for _mesa_unpack_image/bitmap() that handles pixel buffer objects.
841 * If width < 0 or height < 0 or format or type are invalid we'll just
842 * return NULL. We will not generate an error since OpenGL command
843 * arguments aren't error-checked until the command is actually executed
844 * (not when they're compiled).
845 * But if we run out of memory, GL_OUT_OF_MEMORY will be recorded.
846 */
847 static GLvoid *
848 unpack_image(struct gl_context *ctx, GLuint dimensions,
849 GLsizei width, GLsizei height, GLsizei depth,
850 GLenum format, GLenum type, const GLvoid * pixels,
851 const struct gl_pixelstore_attrib *unpack)
852 {
853 if (width <= 0 || height <= 0) {
854 return NULL;
855 }
856
857 if (_mesa_bytes_per_pixel(format, type) < 0) {
858 /* bad format and/or type */
859 return NULL;
860 }
861
862 if (!_mesa_is_bufferobj(unpack->BufferObj)) {
863 /* no PBO */
864 GLvoid *image;
865
866 if (type == GL_BITMAP)
867 image = _mesa_unpack_bitmap(width, height, pixels, unpack);
868 else
869 image = _mesa_unpack_image(dimensions, width, height, depth,
870 format, type, pixels, unpack);
871 if (pixels && !image) {
872 _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
873 }
874 return image;
875 }
876 else if (_mesa_validate_pbo_access(dimensions, unpack, width, height,
877 depth, format, type, INT_MAX, pixels)) {
878 const GLubyte *map, *src;
879 GLvoid *image;
880
881 map = (GLubyte *)
882 ctx->Driver.MapBufferRange(ctx, 0, unpack->BufferObj->Size,
883 GL_MAP_READ_BIT, unpack->BufferObj);
884 if (!map) {
885 /* unable to map src buffer! */
886 _mesa_error(ctx, GL_INVALID_OPERATION, "unable to map PBO");
887 return NULL;
888 }
889
890 src = ADD_POINTERS(map, pixels);
891 if (type == GL_BITMAP)
892 image = _mesa_unpack_bitmap(width, height, src, unpack);
893 else
894 image = _mesa_unpack_image(dimensions, width, height, depth,
895 format, type, src, unpack);
896
897 ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj);
898
899 if (!image) {
900 _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
901 }
902 return image;
903 }
904
905 /* bad access! */
906 _mesa_error(ctx, GL_INVALID_OPERATION, "invalid PBO access");
907 return NULL;
908 }
909
910 /**
911 * Allocate space for a display list instruction (opcode + payload space).
912 * \param opcode the instruction opcode (OPCODE_* value)
913 * \param bytes instruction payload size (not counting opcode)
914 * \return pointer to allocated memory (the opcode space)
915 */
916 static Node *
917 dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes)
918 {
919 const GLuint numNodes = 1 + (bytes + sizeof(Node) - 1) / sizeof(Node);
920 Node *n;
921
922 if (opcode < (GLuint) OPCODE_EXT_0) {
923 if (InstSize[opcode] == 0) {
924 /* save instruction size now */
925 InstSize[opcode] = numNodes;
926 }
927 else {
928 /* make sure instruction size agrees */
929 ASSERT(numNodes == InstSize[opcode]);
930 }
931 }
932
933 if (ctx->ListState.CurrentPos + numNodes + 2 > BLOCK_SIZE) {
934 /* This block is full. Allocate a new block and chain to it */
935 Node *newblock;
936 n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos;
937 n[0].opcode = OPCODE_CONTINUE;
938 newblock = (Node *) malloc(sizeof(Node) * BLOCK_SIZE);
939 if (!newblock) {
940 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Building display list");
941 return NULL;
942 }
943 n[1].next = (Node *) newblock;
944 ctx->ListState.CurrentBlock = newblock;
945 ctx->ListState.CurrentPos = 0;
946 }
947
948 n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos;
949 ctx->ListState.CurrentPos += numNodes;
950
951 n[0].opcode = opcode;
952
953 return n;
954 }
955
956
957
958 /**
959 * Allocate space for a display list instruction. Used by callers outside
960 * this file for things like VBO vertex data.
961 *
962 * \param opcode the instruction opcode (OPCODE_* value)
963 * \param bytes instruction size in bytes, not counting opcode.
964 * \return pointer to the usable data area (not including the internal
965 * opcode).
966 */
967 void *
968 _mesa_dlist_alloc(struct gl_context *ctx, GLuint opcode, GLuint bytes)
969 {
970 Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes);
971 if (n)
972 return n + 1; /* return pointer to payload area, after opcode */
973 else
974 return NULL;
975 }
976
977
978 /**
979 * This function allows modules and drivers to get their own opcodes
980 * for extending display list functionality.
981 * \param ctx the rendering context
982 * \param size number of bytes for storing the new display list command
983 * \param execute function to execute the new display list command
984 * \param destroy function to destroy the new display list command
985 * \param print function to print the new display list command
986 * \return the new opcode number or -1 if error
987 */
988 GLint
989 _mesa_dlist_alloc_opcode(struct gl_context *ctx,
990 GLuint size,
991 void (*execute) (struct gl_context *, void *),
992 void (*destroy) (struct gl_context *, void *),
993 void (*print) (struct gl_context *, void *))
994 {
995 if (ctx->ListExt->NumOpcodes < MAX_DLIST_EXT_OPCODES) {
996 const GLuint i = ctx->ListExt->NumOpcodes++;
997 ctx->ListExt->Opcode[i].Size =
998 1 + (size + sizeof(Node) - 1) / sizeof(Node);
999 ctx->ListExt->Opcode[i].Execute = execute;
1000 ctx->ListExt->Opcode[i].Destroy = destroy;
1001 ctx->ListExt->Opcode[i].Print = print;
1002 return i + OPCODE_EXT_0;
1003 }
1004 return -1;
1005 }
1006
1007
1008 /**
1009 * Allocate space for a display list instruction. The space is basically
1010 * an array of Nodes where node[0] holds the opcode, node[1] is the first
1011 * function parameter, node[2] is the second parameter, etc.
1012 *
1013 * \param opcode one of OPCODE_x
1014 * \param nparams number of function parameters
1015 * \return pointer to start of instruction space
1016 */
1017 static inline Node *
1018 alloc_instruction(struct gl_context *ctx, OpCode opcode, GLuint nparams)
1019 {
1020 return dlist_alloc(ctx, opcode, nparams * sizeof(Node));
1021 }
1022
1023
1024
1025 /*
1026 * Display List compilation functions
1027 */
1028 static void GLAPIENTRY
1029 save_Accum(GLenum op, GLfloat value)
1030 {
1031 GET_CURRENT_CONTEXT(ctx);
1032 Node *n;
1033 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1034 n = alloc_instruction(ctx, OPCODE_ACCUM, 2);
1035 if (n) {
1036 n[1].e = op;
1037 n[2].f = value;
1038 }
1039 if (ctx->ExecuteFlag) {
1040 CALL_Accum(ctx->Exec, (op, value));
1041 }
1042 }
1043
1044
1045 static void GLAPIENTRY
1046 save_AlphaFunc(GLenum func, GLclampf ref)
1047 {
1048 GET_CURRENT_CONTEXT(ctx);
1049 Node *n;
1050 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1051 n = alloc_instruction(ctx, OPCODE_ALPHA_FUNC, 2);
1052 if (n) {
1053 n[1].e = func;
1054 n[2].f = (GLfloat) ref;
1055 }
1056 if (ctx->ExecuteFlag) {
1057 CALL_AlphaFunc(ctx->Exec, (func, ref));
1058 }
1059 }
1060
1061
1062 static void GLAPIENTRY
1063 save_BindTexture(GLenum target, GLuint texture)
1064 {
1065 GET_CURRENT_CONTEXT(ctx);
1066 Node *n;
1067 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1068 n = alloc_instruction(ctx, OPCODE_BIND_TEXTURE, 2);
1069 if (n) {
1070 n[1].e = target;
1071 n[2].ui = texture;
1072 }
1073 if (ctx->ExecuteFlag) {
1074 CALL_BindTexture(ctx->Exec, (target, texture));
1075 }
1076 }
1077
1078
1079 static void GLAPIENTRY
1080 save_Bitmap(GLsizei width, GLsizei height,
1081 GLfloat xorig, GLfloat yorig,
1082 GLfloat xmove, GLfloat ymove, const GLubyte * pixels)
1083 {
1084 GET_CURRENT_CONTEXT(ctx);
1085 Node *n;
1086 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1087 n = alloc_instruction(ctx, OPCODE_BITMAP, 7);
1088 if (n) {
1089 n[1].i = (GLint) width;
1090 n[2].i = (GLint) height;
1091 n[3].f = xorig;
1092 n[4].f = yorig;
1093 n[5].f = xmove;
1094 n[6].f = ymove;
1095 n[7].data = unpack_image(ctx, 2, width, height, 1, GL_COLOR_INDEX,
1096 GL_BITMAP, pixels, &ctx->Unpack);
1097 }
1098 if (ctx->ExecuteFlag) {
1099 CALL_Bitmap(ctx->Exec, (width, height,
1100 xorig, yorig, xmove, ymove, pixels));
1101 }
1102 }
1103
1104
1105 static void GLAPIENTRY
1106 save_BlendEquation(GLenum mode)
1107 {
1108 GET_CURRENT_CONTEXT(ctx);
1109 Node *n;
1110 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1111 n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION, 1);
1112 if (n) {
1113 n[1].e = mode;
1114 }
1115 if (ctx->ExecuteFlag) {
1116 CALL_BlendEquation(ctx->Exec, (mode));
1117 }
1118 }
1119
1120
1121 static void GLAPIENTRY
1122 save_BlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA)
1123 {
1124 GET_CURRENT_CONTEXT(ctx);
1125 Node *n;
1126 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1127 n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION_SEPARATE, 2);
1128 if (n) {
1129 n[1].e = modeRGB;
1130 n[2].e = modeA;
1131 }
1132 if (ctx->ExecuteFlag) {
1133 CALL_BlendEquationSeparateEXT(ctx->Exec, (modeRGB, modeA));
1134 }
1135 }
1136
1137
1138 static void GLAPIENTRY
1139 save_BlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB,
1140 GLenum sfactorA, GLenum dfactorA)
1141 {
1142 GET_CURRENT_CONTEXT(ctx);
1143 Node *n;
1144 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1145 n = alloc_instruction(ctx, OPCODE_BLEND_FUNC_SEPARATE, 4);
1146 if (n) {
1147 n[1].e = sfactorRGB;
1148 n[2].e = dfactorRGB;
1149 n[3].e = sfactorA;
1150 n[4].e = dfactorA;
1151 }
1152 if (ctx->ExecuteFlag) {
1153 CALL_BlendFuncSeparateEXT(ctx->Exec,
1154 (sfactorRGB, dfactorRGB, sfactorA, dfactorA));
1155 }
1156 }
1157
1158
1159 static void GLAPIENTRY
1160 save_BlendFunc(GLenum srcfactor, GLenum dstfactor)
1161 {
1162 save_BlendFuncSeparateEXT(srcfactor, dstfactor, srcfactor, dstfactor);
1163 }
1164
1165
1166 static void GLAPIENTRY
1167 save_BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
1168 {
1169 GET_CURRENT_CONTEXT(ctx);
1170 Node *n;
1171 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1172 n = alloc_instruction(ctx, OPCODE_BLEND_COLOR, 4);
1173 if (n) {
1174 n[1].f = red;
1175 n[2].f = green;
1176 n[3].f = blue;
1177 n[4].f = alpha;
1178 }
1179 if (ctx->ExecuteFlag) {
1180 CALL_BlendColor(ctx->Exec, (red, green, blue, alpha));
1181 }
1182 }
1183
1184 /* GL_ARB_draw_buffers_blend */
1185 static void GLAPIENTRY
1186 save_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB,
1187 GLenum sfactorA, GLenum dfactorA)
1188 {
1189 GET_CURRENT_CONTEXT(ctx);
1190 Node *n;
1191 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1192 n = alloc_instruction(ctx, OPCODE_BLEND_FUNC_SEPARATE_I, 5);
1193 if (n) {
1194 n[1].ui = buf;
1195 n[2].e = sfactorRGB;
1196 n[3].e = dfactorRGB;
1197 n[4].e = sfactorA;
1198 n[5].e = dfactorA;
1199 }
1200 if (ctx->ExecuteFlag) {
1201 CALL_BlendFuncSeparateiARB(ctx->Exec, (buf, sfactorRGB, dfactorRGB,
1202 sfactorA, dfactorA));
1203 }
1204 }
1205
1206 /* GL_ARB_draw_buffers_blend */
1207 static void GLAPIENTRY
1208 save_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor)
1209 {
1210 GET_CURRENT_CONTEXT(ctx);
1211 Node *n;
1212 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1213 n = alloc_instruction(ctx, OPCODE_BLEND_FUNC_SEPARATE_I, 3);
1214 if (n) {
1215 n[1].ui = buf;
1216 n[2].e = sfactor;
1217 n[3].e = dfactor;
1218 }
1219 if (ctx->ExecuteFlag) {
1220 CALL_BlendFunciARB(ctx->Exec, (buf, sfactor, dfactor));
1221 }
1222 }
1223
1224 /* GL_ARB_draw_buffers_blend */
1225 static void GLAPIENTRY
1226 save_BlendEquationi(GLuint buf, GLenum mode)
1227 {
1228 GET_CURRENT_CONTEXT(ctx);
1229 Node *n;
1230 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1231 n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION_I, 2);
1232 if (n) {
1233 n[1].ui = buf;
1234 n[2].e = mode;
1235 }
1236 if (ctx->ExecuteFlag) {
1237 CALL_BlendEquationiARB(ctx->Exec, (buf, mode));
1238 }
1239 }
1240
1241 /* GL_ARB_draw_buffers_blend */
1242 static void GLAPIENTRY
1243 save_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA)
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_SEPARATE_I, 3);
1249 if (n) {
1250 n[1].ui = buf;
1251 n[2].e = modeRGB;
1252 n[3].e = modeA;
1253 }
1254 if (ctx->ExecuteFlag) {
1255 CALL_BlendEquationSeparateiARB(ctx->Exec, (buf, modeRGB, modeA));
1256 }
1257 }
1258
1259
1260 /* GL_ARB_draw_instanced. */
1261 static void GLAPIENTRY
1262 save_DrawArraysInstancedARB(GLenum mode,
1263 GLint first,
1264 GLsizei count,
1265 GLsizei primcount)
1266 {
1267 GET_CURRENT_CONTEXT(ctx);
1268 _mesa_error(ctx, GL_INVALID_OPERATION,
1269 "glDrawArraysInstanced() during display list compile");
1270 }
1271
1272 static void GLAPIENTRY
1273 save_DrawElementsInstancedARB(GLenum mode,
1274 GLsizei count,
1275 GLenum type,
1276 const GLvoid *indices,
1277 GLsizei primcount)
1278 {
1279 GET_CURRENT_CONTEXT(ctx);
1280 _mesa_error(ctx, GL_INVALID_OPERATION,
1281 "glDrawElementsInstanced() during display list compile");
1282 }
1283
1284 static void GLAPIENTRY
1285 save_DrawElementsInstancedBaseVertexARB(GLenum mode,
1286 GLsizei count,
1287 GLenum type,
1288 const GLvoid *indices,
1289 GLsizei primcount,
1290 GLint basevertex)
1291 {
1292 GET_CURRENT_CONTEXT(ctx);
1293 _mesa_error(ctx, GL_INVALID_OPERATION,
1294 "glDrawElementsInstancedBaseVertex() during display list compile");
1295 }
1296
1297 static void invalidate_saved_current_state( struct gl_context *ctx )
1298 {
1299 GLint i;
1300
1301 for (i = 0; i < VERT_ATTRIB_MAX; i++)
1302 ctx->ListState.ActiveAttribSize[i] = 0;
1303
1304 for (i = 0; i < MAT_ATTRIB_MAX; i++)
1305 ctx->ListState.ActiveMaterialSize[i] = 0;
1306
1307 memset(&ctx->ListState.Current, 0, sizeof ctx->ListState.Current);
1308
1309 ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
1310 }
1311
1312 static void GLAPIENTRY
1313 save_CallList(GLuint list)
1314 {
1315 GET_CURRENT_CONTEXT(ctx);
1316 Node *n;
1317 SAVE_FLUSH_VERTICES(ctx);
1318
1319 n = alloc_instruction(ctx, OPCODE_CALL_LIST, 1);
1320 if (n) {
1321 n[1].ui = list;
1322 }
1323
1324 /* After this, we don't know what state we're in. Invalidate all
1325 * cached information previously gathered:
1326 */
1327 invalidate_saved_current_state( ctx );
1328
1329 if (ctx->ExecuteFlag) {
1330 _mesa_CallList(list);
1331 }
1332 }
1333
1334
1335 static void GLAPIENTRY
1336 save_CallLists(GLsizei num, GLenum type, const GLvoid * lists)
1337 {
1338 GET_CURRENT_CONTEXT(ctx);
1339 GLint i;
1340 GLboolean typeErrorFlag;
1341
1342 SAVE_FLUSH_VERTICES(ctx);
1343
1344 switch (type) {
1345 case GL_BYTE:
1346 case GL_UNSIGNED_BYTE:
1347 case GL_SHORT:
1348 case GL_UNSIGNED_SHORT:
1349 case GL_INT:
1350 case GL_UNSIGNED_INT:
1351 case GL_FLOAT:
1352 case GL_2_BYTES:
1353 case GL_3_BYTES:
1354 case GL_4_BYTES:
1355 typeErrorFlag = GL_FALSE;
1356 break;
1357 default:
1358 typeErrorFlag = GL_TRUE;
1359 }
1360
1361 for (i = 0; i < num; i++) {
1362 GLint list = translate_id(i, type, lists);
1363 Node *n = alloc_instruction(ctx, OPCODE_CALL_LIST_OFFSET, 2);
1364 if (n) {
1365 n[1].i = list;
1366 n[2].b = typeErrorFlag;
1367 }
1368 }
1369
1370 /* After this, we don't know what state we're in. Invalidate all
1371 * cached information previously gathered:
1372 */
1373 invalidate_saved_current_state( ctx );
1374
1375 if (ctx->ExecuteFlag) {
1376 CALL_CallLists(ctx->Exec, (num, type, lists));
1377 }
1378 }
1379
1380
1381 static void GLAPIENTRY
1382 save_Clear(GLbitfield mask)
1383 {
1384 GET_CURRENT_CONTEXT(ctx);
1385 Node *n;
1386 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1387 n = alloc_instruction(ctx, OPCODE_CLEAR, 1);
1388 if (n) {
1389 n[1].bf = mask;
1390 }
1391 if (ctx->ExecuteFlag) {
1392 CALL_Clear(ctx->Exec, (mask));
1393 }
1394 }
1395
1396
1397 static void GLAPIENTRY
1398 save_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
1399 {
1400 GET_CURRENT_CONTEXT(ctx);
1401 Node *n;
1402 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1403 n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_IV, 6);
1404 if (n) {
1405 n[1].e = buffer;
1406 n[2].i = drawbuffer;
1407 n[3].i = value[0];
1408 if (buffer == GL_COLOR) {
1409 n[4].i = value[1];
1410 n[5].i = value[2];
1411 n[6].i = value[3];
1412 }
1413 else {
1414 n[4].i = 0;
1415 n[5].i = 0;
1416 n[6].i = 0;
1417 }
1418 }
1419 if (ctx->ExecuteFlag) {
1420 CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value));
1421 }
1422 }
1423
1424
1425 static void GLAPIENTRY
1426 save_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
1427 {
1428 GET_CURRENT_CONTEXT(ctx);
1429 Node *n;
1430 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1431 n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_UIV, 6);
1432 if (n) {
1433 n[1].e = buffer;
1434 n[2].i = drawbuffer;
1435 n[3].ui = value[0];
1436 if (buffer == GL_COLOR) {
1437 n[4].ui = value[1];
1438 n[5].ui = value[2];
1439 n[6].ui = value[3];
1440 }
1441 else {
1442 n[4].ui = 0;
1443 n[5].ui = 0;
1444 n[6].ui = 0;
1445 }
1446 }
1447 if (ctx->ExecuteFlag) {
1448 CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));
1449 }
1450 }
1451
1452
1453 static void GLAPIENTRY
1454 save_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
1455 {
1456 GET_CURRENT_CONTEXT(ctx);
1457 Node *n;
1458 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1459 n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_FV, 6);
1460 if (n) {
1461 n[1].e = buffer;
1462 n[2].i = drawbuffer;
1463 n[3].f = value[0];
1464 if (buffer == GL_COLOR) {
1465 n[4].f = value[1];
1466 n[5].f = value[2];
1467 n[6].f = value[3];
1468 }
1469 else {
1470 n[4].f = 0.0F;
1471 n[5].f = 0.0F;
1472 n[6].f = 0.0F;
1473 }
1474 }
1475 if (ctx->ExecuteFlag) {
1476 CALL_ClearBufferfv(ctx->Exec, (buffer, drawbuffer, value));
1477 }
1478 }
1479
1480
1481 static void GLAPIENTRY
1482 save_ClearBufferfi(GLenum buffer, GLint drawbuffer,
1483 GLfloat depth, GLint stencil)
1484 {
1485 GET_CURRENT_CONTEXT(ctx);
1486 Node *n;
1487 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1488 n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_FI, 4);
1489 if (n) {
1490 n[1].e = buffer;
1491 n[2].i = drawbuffer;
1492 n[3].f = depth;
1493 n[4].i = stencil;
1494 }
1495 if (ctx->ExecuteFlag) {
1496 CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil));
1497 }
1498 }
1499
1500
1501 static void GLAPIENTRY
1502 save_ClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
1503 {
1504 GET_CURRENT_CONTEXT(ctx);
1505 Node *n;
1506 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1507 n = alloc_instruction(ctx, OPCODE_CLEAR_ACCUM, 4);
1508 if (n) {
1509 n[1].f = red;
1510 n[2].f = green;
1511 n[3].f = blue;
1512 n[4].f = alpha;
1513 }
1514 if (ctx->ExecuteFlag) {
1515 CALL_ClearAccum(ctx->Exec, (red, green, blue, alpha));
1516 }
1517 }
1518
1519
1520 static void GLAPIENTRY
1521 save_ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
1522 {
1523 GET_CURRENT_CONTEXT(ctx);
1524 Node *n;
1525 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1526 n = alloc_instruction(ctx, OPCODE_CLEAR_COLOR, 4);
1527 if (n) {
1528 n[1].f = red;
1529 n[2].f = green;
1530 n[3].f = blue;
1531 n[4].f = alpha;
1532 }
1533 if (ctx->ExecuteFlag) {
1534 CALL_ClearColor(ctx->Exec, (red, green, blue, alpha));
1535 }
1536 }
1537
1538
1539 static void GLAPIENTRY
1540 save_ClearDepth(GLclampd depth)
1541 {
1542 GET_CURRENT_CONTEXT(ctx);
1543 Node *n;
1544 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1545 n = alloc_instruction(ctx, OPCODE_CLEAR_DEPTH, 1);
1546 if (n) {
1547 n[1].f = (GLfloat) depth;
1548 }
1549 if (ctx->ExecuteFlag) {
1550 CALL_ClearDepth(ctx->Exec, (depth));
1551 }
1552 }
1553
1554
1555 static void GLAPIENTRY
1556 save_ClearIndex(GLfloat c)
1557 {
1558 GET_CURRENT_CONTEXT(ctx);
1559 Node *n;
1560 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1561 n = alloc_instruction(ctx, OPCODE_CLEAR_INDEX, 1);
1562 if (n) {
1563 n[1].f = c;
1564 }
1565 if (ctx->ExecuteFlag) {
1566 CALL_ClearIndex(ctx->Exec, (c));
1567 }
1568 }
1569
1570
1571 static void GLAPIENTRY
1572 save_ClearStencil(GLint s)
1573 {
1574 GET_CURRENT_CONTEXT(ctx);
1575 Node *n;
1576 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1577 n = alloc_instruction(ctx, OPCODE_CLEAR_STENCIL, 1);
1578 if (n) {
1579 n[1].i = s;
1580 }
1581 if (ctx->ExecuteFlag) {
1582 CALL_ClearStencil(ctx->Exec, (s));
1583 }
1584 }
1585
1586
1587 static void GLAPIENTRY
1588 save_ClipPlane(GLenum plane, const GLdouble * equ)
1589 {
1590 GET_CURRENT_CONTEXT(ctx);
1591 Node *n;
1592 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1593 n = alloc_instruction(ctx, OPCODE_CLIP_PLANE, 5);
1594 if (n) {
1595 n[1].e = plane;
1596 n[2].f = (GLfloat) equ[0];
1597 n[3].f = (GLfloat) equ[1];
1598 n[4].f = (GLfloat) equ[2];
1599 n[5].f = (GLfloat) equ[3];
1600 }
1601 if (ctx->ExecuteFlag) {
1602 CALL_ClipPlane(ctx->Exec, (plane, equ));
1603 }
1604 }
1605
1606
1607
1608 static void GLAPIENTRY
1609 save_ColorMask(GLboolean red, GLboolean green,
1610 GLboolean blue, GLboolean alpha)
1611 {
1612 GET_CURRENT_CONTEXT(ctx);
1613 Node *n;
1614 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1615 n = alloc_instruction(ctx, OPCODE_COLOR_MASK, 4);
1616 if (n) {
1617 n[1].b = red;
1618 n[2].b = green;
1619 n[3].b = blue;
1620 n[4].b = alpha;
1621 }
1622 if (ctx->ExecuteFlag) {
1623 CALL_ColorMask(ctx->Exec, (red, green, blue, alpha));
1624 }
1625 }
1626
1627
1628 static void GLAPIENTRY
1629 save_ColorMaterial(GLenum face, GLenum mode)
1630 {
1631 GET_CURRENT_CONTEXT(ctx);
1632 Node *n;
1633 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1634
1635 n = alloc_instruction(ctx, OPCODE_COLOR_MATERIAL, 2);
1636 if (n) {
1637 n[1].e = face;
1638 n[2].e = mode;
1639 }
1640 if (ctx->ExecuteFlag) {
1641 CALL_ColorMaterial(ctx->Exec, (face, mode));
1642 }
1643 }
1644
1645
1646 static void GLAPIENTRY
1647 save_ColorTable(GLenum target, GLenum internalFormat,
1648 GLsizei width, GLenum format, GLenum type,
1649 const GLvoid * table)
1650 {
1651 GET_CURRENT_CONTEXT(ctx);
1652 if (_mesa_is_proxy_texture(target)) {
1653 /* execute immediately */
1654 CALL_ColorTable(ctx->Exec, (target, internalFormat, width,
1655 format, type, table));
1656 }
1657 else {
1658 Node *n;
1659 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1660 n = alloc_instruction(ctx, OPCODE_COLOR_TABLE, 6);
1661 if (n) {
1662 n[1].e = target;
1663 n[2].e = internalFormat;
1664 n[3].i = width;
1665 n[4].e = format;
1666 n[5].e = type;
1667 n[6].data = unpack_image(ctx, 1, width, 1, 1, format, type, table,
1668 &ctx->Unpack);
1669 }
1670 if (ctx->ExecuteFlag) {
1671 CALL_ColorTable(ctx->Exec, (target, internalFormat, width,
1672 format, type, table));
1673 }
1674 }
1675 }
1676
1677
1678
1679 static void GLAPIENTRY
1680 save_ColorTableParameterfv(GLenum target, GLenum pname,
1681 const GLfloat *params)
1682 {
1683 GET_CURRENT_CONTEXT(ctx);
1684 Node *n;
1685
1686 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1687
1688 n = alloc_instruction(ctx, OPCODE_COLOR_TABLE_PARAMETER_FV, 6);
1689 if (n) {
1690 n[1].e = target;
1691 n[2].e = pname;
1692 n[3].f = params[0];
1693 if (pname == GL_COLOR_TABLE_SGI ||
1694 pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI ||
1695 pname == GL_TEXTURE_COLOR_TABLE_SGI) {
1696 n[4].f = params[1];
1697 n[5].f = params[2];
1698 n[6].f = params[3];
1699 }
1700 }
1701
1702 if (ctx->ExecuteFlag) {
1703 CALL_ColorTableParameterfv(ctx->Exec, (target, pname, params));
1704 }
1705 }
1706
1707
1708 static void GLAPIENTRY
1709 save_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params)
1710 {
1711 GET_CURRENT_CONTEXT(ctx);
1712 Node *n;
1713
1714 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1715
1716 n = alloc_instruction(ctx, OPCODE_COLOR_TABLE_PARAMETER_IV, 6);
1717 if (n) {
1718 n[1].e = target;
1719 n[2].e = pname;
1720 n[3].i = params[0];
1721 if (pname == GL_COLOR_TABLE_SGI ||
1722 pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI ||
1723 pname == GL_TEXTURE_COLOR_TABLE_SGI) {
1724 n[4].i = params[1];
1725 n[5].i = params[2];
1726 n[6].i = params[3];
1727 }
1728 }
1729
1730 if (ctx->ExecuteFlag) {
1731 CALL_ColorTableParameteriv(ctx->Exec, (target, pname, params));
1732 }
1733 }
1734
1735
1736
1737 static void GLAPIENTRY
1738 save_ColorSubTable(GLenum target, GLsizei start, GLsizei count,
1739 GLenum format, GLenum type, const GLvoid * table)
1740 {
1741 GET_CURRENT_CONTEXT(ctx);
1742 Node *n;
1743 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1744 n = alloc_instruction(ctx, OPCODE_COLOR_SUB_TABLE, 6);
1745 if (n) {
1746 n[1].e = target;
1747 n[2].i = start;
1748 n[3].i = count;
1749 n[4].e = format;
1750 n[5].e = type;
1751 n[6].data = unpack_image(ctx, 1, count, 1, 1, format, type, table,
1752 &ctx->Unpack);
1753 }
1754 if (ctx->ExecuteFlag) {
1755 CALL_ColorSubTable(ctx->Exec,
1756 (target, start, count, format, type, table));
1757 }
1758 }
1759
1760
1761 static void GLAPIENTRY
1762 save_CopyColorSubTable(GLenum target, GLsizei start,
1763 GLint x, GLint y, GLsizei width)
1764 {
1765 GET_CURRENT_CONTEXT(ctx);
1766 Node *n;
1767
1768 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1769 n = alloc_instruction(ctx, OPCODE_COPY_COLOR_SUB_TABLE, 5);
1770 if (n) {
1771 n[1].e = target;
1772 n[2].i = start;
1773 n[3].i = x;
1774 n[4].i = y;
1775 n[5].i = width;
1776 }
1777 if (ctx->ExecuteFlag) {
1778 CALL_CopyColorSubTable(ctx->Exec, (target, start, x, y, width));
1779 }
1780 }
1781
1782
1783 static void GLAPIENTRY
1784 save_CopyColorTable(GLenum target, GLenum internalformat,
1785 GLint x, GLint y, GLsizei width)
1786 {
1787 GET_CURRENT_CONTEXT(ctx);
1788 Node *n;
1789
1790 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1791 n = alloc_instruction(ctx, OPCODE_COPY_COLOR_TABLE, 5);
1792 if (n) {
1793 n[1].e = target;
1794 n[2].e = internalformat;
1795 n[3].i = x;
1796 n[4].i = y;
1797 n[5].i = width;
1798 }
1799 if (ctx->ExecuteFlag) {
1800 CALL_CopyColorTable(ctx->Exec, (target, internalformat, x, y, width));
1801 }
1802 }
1803
1804
1805 static void GLAPIENTRY
1806 save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width,
1807 GLenum format, GLenum type, const GLvoid * filter)
1808 {
1809 GET_CURRENT_CONTEXT(ctx);
1810 Node *n;
1811
1812 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1813
1814 n = alloc_instruction(ctx, OPCODE_CONVOLUTION_FILTER_1D, 6);
1815 if (n) {
1816 n[1].e = target;
1817 n[2].e = internalFormat;
1818 n[3].i = width;
1819 n[4].e = format;
1820 n[5].e = type;
1821 n[6].data = unpack_image(ctx, 1, width, 1, 1, format, type, filter,
1822 &ctx->Unpack);
1823 }
1824 if (ctx->ExecuteFlag) {
1825 CALL_ConvolutionFilter1D(ctx->Exec, (target, internalFormat, width,
1826 format, type, filter));
1827 }
1828 }
1829
1830
1831 static void GLAPIENTRY
1832 save_ConvolutionFilter2D(GLenum target, GLenum internalFormat,
1833 GLsizei width, GLsizei height, GLenum format,
1834 GLenum type, const GLvoid * filter)
1835 {
1836 GET_CURRENT_CONTEXT(ctx);
1837 Node *n;
1838
1839 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1840
1841 n = alloc_instruction(ctx, OPCODE_CONVOLUTION_FILTER_2D, 7);
1842 if (n) {
1843 n[1].e = target;
1844 n[2].e = internalFormat;
1845 n[3].i = width;
1846 n[4].i = height;
1847 n[5].e = format;
1848 n[6].e = type;
1849 n[7].data = unpack_image(ctx, 2, width, height, 1, format, type, filter,
1850 &ctx->Unpack);
1851 }
1852 if (ctx->ExecuteFlag) {
1853 CALL_ConvolutionFilter2D(ctx->Exec,
1854 (target, internalFormat, width, height, format,
1855 type, filter));
1856 }
1857 }
1858
1859
1860 static void GLAPIENTRY
1861 save_ConvolutionParameteri(GLenum target, GLenum pname, GLint param)
1862 {
1863 GET_CURRENT_CONTEXT(ctx);
1864 Node *n;
1865 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1866 n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_I, 3);
1867 if (n) {
1868 n[1].e = target;
1869 n[2].e = pname;
1870 n[3].i = param;
1871 }
1872 if (ctx->ExecuteFlag) {
1873 CALL_ConvolutionParameteri(ctx->Exec, (target, pname, param));
1874 }
1875 }
1876
1877
1878 static void GLAPIENTRY
1879 save_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params)
1880 {
1881 GET_CURRENT_CONTEXT(ctx);
1882 Node *n;
1883 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1884 n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_IV, 6);
1885 if (n) {
1886 n[1].e = target;
1887 n[2].e = pname;
1888 n[3].i = params[0];
1889 if (pname == GL_CONVOLUTION_BORDER_COLOR ||
1890 pname == GL_CONVOLUTION_FILTER_SCALE ||
1891 pname == GL_CONVOLUTION_FILTER_BIAS) {
1892 n[4].i = params[1];
1893 n[5].i = params[2];
1894 n[6].i = params[3];
1895 }
1896 else {
1897 n[4].i = n[5].i = n[6].i = 0;
1898 }
1899 }
1900 if (ctx->ExecuteFlag) {
1901 CALL_ConvolutionParameteriv(ctx->Exec, (target, pname, params));
1902 }
1903 }
1904
1905
1906 static void GLAPIENTRY
1907 save_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param)
1908 {
1909 GET_CURRENT_CONTEXT(ctx);
1910 Node *n;
1911 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1912 n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_F, 3);
1913 if (n) {
1914 n[1].e = target;
1915 n[2].e = pname;
1916 n[3].f = param;
1917 }
1918 if (ctx->ExecuteFlag) {
1919 CALL_ConvolutionParameterf(ctx->Exec, (target, pname, param));
1920 }
1921 }
1922
1923
1924 static void GLAPIENTRY
1925 save_ConvolutionParameterfv(GLenum target, GLenum pname,
1926 const GLfloat *params)
1927 {
1928 GET_CURRENT_CONTEXT(ctx);
1929 Node *n;
1930 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1931 n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_FV, 6);
1932 if (n) {
1933 n[1].e = target;
1934 n[2].e = pname;
1935 n[3].f = params[0];
1936 if (pname == GL_CONVOLUTION_BORDER_COLOR ||
1937 pname == GL_CONVOLUTION_FILTER_SCALE ||
1938 pname == GL_CONVOLUTION_FILTER_BIAS) {
1939 n[4].f = params[1];
1940 n[5].f = params[2];
1941 n[6].f = params[3];
1942 }
1943 else {
1944 n[4].f = n[5].f = n[6].f = 0.0F;
1945 }
1946 }
1947 if (ctx->ExecuteFlag) {
1948 CALL_ConvolutionParameterfv(ctx->Exec, (target, pname, params));
1949 }
1950 }
1951
1952
1953 static void GLAPIENTRY
1954 save_CopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
1955 {
1956 GET_CURRENT_CONTEXT(ctx);
1957 Node *n;
1958 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1959 n = alloc_instruction(ctx, OPCODE_COPY_PIXELS, 5);
1960 if (n) {
1961 n[1].i = x;
1962 n[2].i = y;
1963 n[3].i = (GLint) width;
1964 n[4].i = (GLint) height;
1965 n[5].e = type;
1966 }
1967 if (ctx->ExecuteFlag) {
1968 CALL_CopyPixels(ctx->Exec, (x, y, width, height, type));
1969 }
1970 }
1971
1972
1973
1974 static void GLAPIENTRY
1975 save_CopyTexImage1D(GLenum target, GLint level, GLenum internalformat,
1976 GLint x, GLint y, GLsizei width, GLint border)
1977 {
1978 GET_CURRENT_CONTEXT(ctx);
1979 Node *n;
1980 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1981 n = alloc_instruction(ctx, OPCODE_COPY_TEX_IMAGE1D, 7);
1982 if (n) {
1983 n[1].e = target;
1984 n[2].i = level;
1985 n[3].e = internalformat;
1986 n[4].i = x;
1987 n[5].i = y;
1988 n[6].i = width;
1989 n[7].i = border;
1990 }
1991 if (ctx->ExecuteFlag) {
1992 CALL_CopyTexImage1D(ctx->Exec, (target, level, internalformat,
1993 x, y, width, border));
1994 }
1995 }
1996
1997
1998 static void GLAPIENTRY
1999 save_CopyTexImage2D(GLenum target, GLint level,
2000 GLenum internalformat,
2001 GLint x, GLint y, GLsizei width,
2002 GLsizei height, GLint border)
2003 {
2004 GET_CURRENT_CONTEXT(ctx);
2005 Node *n;
2006 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2007 n = alloc_instruction(ctx, OPCODE_COPY_TEX_IMAGE2D, 8);
2008 if (n) {
2009 n[1].e = target;
2010 n[2].i = level;
2011 n[3].e = internalformat;
2012 n[4].i = x;
2013 n[5].i = y;
2014 n[6].i = width;
2015 n[7].i = height;
2016 n[8].i = border;
2017 }
2018 if (ctx->ExecuteFlag) {
2019 CALL_CopyTexImage2D(ctx->Exec, (target, level, internalformat,
2020 x, y, width, height, border));
2021 }
2022 }
2023
2024
2025
2026 static void GLAPIENTRY
2027 save_CopyTexSubImage1D(GLenum target, GLint level,
2028 GLint xoffset, GLint x, GLint y, GLsizei width)
2029 {
2030 GET_CURRENT_CONTEXT(ctx);
2031 Node *n;
2032 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2033 n = alloc_instruction(ctx, OPCODE_COPY_TEX_SUB_IMAGE1D, 6);
2034 if (n) {
2035 n[1].e = target;
2036 n[2].i = level;
2037 n[3].i = xoffset;
2038 n[4].i = x;
2039 n[5].i = y;
2040 n[6].i = width;
2041 }
2042 if (ctx->ExecuteFlag) {
2043 CALL_CopyTexSubImage1D(ctx->Exec,
2044 (target, level, xoffset, x, y, width));
2045 }
2046 }
2047
2048
2049 static void GLAPIENTRY
2050 save_CopyTexSubImage2D(GLenum target, GLint level,
2051 GLint xoffset, GLint yoffset,
2052 GLint x, GLint y, GLsizei width, GLint height)
2053 {
2054 GET_CURRENT_CONTEXT(ctx);
2055 Node *n;
2056 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2057 n = alloc_instruction(ctx, OPCODE_COPY_TEX_SUB_IMAGE2D, 8);
2058 if (n) {
2059 n[1].e = target;
2060 n[2].i = level;
2061 n[3].i = xoffset;
2062 n[4].i = yoffset;
2063 n[5].i = x;
2064 n[6].i = y;
2065 n[7].i = width;
2066 n[8].i = height;
2067 }
2068 if (ctx->ExecuteFlag) {
2069 CALL_CopyTexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset,
2070 x, y, width, height));
2071 }
2072 }
2073
2074
2075 static void GLAPIENTRY
2076 save_CopyTexSubImage3D(GLenum target, GLint level,
2077 GLint xoffset, GLint yoffset, GLint zoffset,
2078 GLint x, GLint y, GLsizei width, GLint height)
2079 {
2080 GET_CURRENT_CONTEXT(ctx);
2081 Node *n;
2082 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2083 n = alloc_instruction(ctx, OPCODE_COPY_TEX_SUB_IMAGE3D, 9);
2084 if (n) {
2085 n[1].e = target;
2086 n[2].i = level;
2087 n[3].i = xoffset;
2088 n[4].i = yoffset;
2089 n[5].i = zoffset;
2090 n[6].i = x;
2091 n[7].i = y;
2092 n[8].i = width;
2093 n[9].i = height;
2094 }
2095 if (ctx->ExecuteFlag) {
2096 CALL_CopyTexSubImage3D(ctx->Exec, (target, level,
2097 xoffset, yoffset, zoffset,
2098 x, y, width, height));
2099 }
2100 }
2101
2102
2103 static void GLAPIENTRY
2104 save_CullFace(GLenum mode)
2105 {
2106 GET_CURRENT_CONTEXT(ctx);
2107 Node *n;
2108 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2109 n = alloc_instruction(ctx, OPCODE_CULL_FACE, 1);
2110 if (n) {
2111 n[1].e = mode;
2112 }
2113 if (ctx->ExecuteFlag) {
2114 CALL_CullFace(ctx->Exec, (mode));
2115 }
2116 }
2117
2118
2119 static void GLAPIENTRY
2120 save_DepthFunc(GLenum func)
2121 {
2122 GET_CURRENT_CONTEXT(ctx);
2123 Node *n;
2124 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2125 n = alloc_instruction(ctx, OPCODE_DEPTH_FUNC, 1);
2126 if (n) {
2127 n[1].e = func;
2128 }
2129 if (ctx->ExecuteFlag) {
2130 CALL_DepthFunc(ctx->Exec, (func));
2131 }
2132 }
2133
2134
2135 static void GLAPIENTRY
2136 save_DepthMask(GLboolean mask)
2137 {
2138 GET_CURRENT_CONTEXT(ctx);
2139 Node *n;
2140 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2141 n = alloc_instruction(ctx, OPCODE_DEPTH_MASK, 1);
2142 if (n) {
2143 n[1].b = mask;
2144 }
2145 if (ctx->ExecuteFlag) {
2146 CALL_DepthMask(ctx->Exec, (mask));
2147 }
2148 }
2149
2150
2151 static void GLAPIENTRY
2152 save_DepthRange(GLclampd nearval, GLclampd farval)
2153 {
2154 GET_CURRENT_CONTEXT(ctx);
2155 Node *n;
2156 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2157 n = alloc_instruction(ctx, OPCODE_DEPTH_RANGE, 2);
2158 if (n) {
2159 n[1].f = (GLfloat) nearval;
2160 n[2].f = (GLfloat) farval;
2161 }
2162 if (ctx->ExecuteFlag) {
2163 CALL_DepthRange(ctx->Exec, (nearval, farval));
2164 }
2165 }
2166
2167
2168 static void GLAPIENTRY
2169 save_Disable(GLenum cap)
2170 {
2171 GET_CURRENT_CONTEXT(ctx);
2172 Node *n;
2173 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2174 n = alloc_instruction(ctx, OPCODE_DISABLE, 1);
2175 if (n) {
2176 n[1].e = cap;
2177 }
2178 if (ctx->ExecuteFlag) {
2179 CALL_Disable(ctx->Exec, (cap));
2180 }
2181 }
2182
2183
2184 static void GLAPIENTRY
2185 save_DrawBuffer(GLenum mode)
2186 {
2187 GET_CURRENT_CONTEXT(ctx);
2188 Node *n;
2189 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2190 n = alloc_instruction(ctx, OPCODE_DRAW_BUFFER, 1);
2191 if (n) {
2192 n[1].e = mode;
2193 }
2194 if (ctx->ExecuteFlag) {
2195 CALL_DrawBuffer(ctx->Exec, (mode));
2196 }
2197 }
2198
2199
2200 static void GLAPIENTRY
2201 save_DrawPixels(GLsizei width, GLsizei height,
2202 GLenum format, GLenum type, const GLvoid * pixels)
2203 {
2204 GET_CURRENT_CONTEXT(ctx);
2205 Node *n;
2206
2207 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2208
2209 n = alloc_instruction(ctx, OPCODE_DRAW_PIXELS, 5);
2210 if (n) {
2211 n[1].i = width;
2212 n[2].i = height;
2213 n[3].e = format;
2214 n[4].e = type;
2215 n[5].data = unpack_image(ctx, 2, width, height, 1, format, type,
2216 pixels, &ctx->Unpack);
2217 }
2218 if (ctx->ExecuteFlag) {
2219 CALL_DrawPixels(ctx->Exec, (width, height, format, type, pixels));
2220 }
2221 }
2222
2223
2224
2225 static void GLAPIENTRY
2226 save_Enable(GLenum cap)
2227 {
2228 GET_CURRENT_CONTEXT(ctx);
2229 Node *n;
2230 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2231 n = alloc_instruction(ctx, OPCODE_ENABLE, 1);
2232 if (n) {
2233 n[1].e = cap;
2234 }
2235 if (ctx->ExecuteFlag) {
2236 CALL_Enable(ctx->Exec, (cap));
2237 }
2238 }
2239
2240
2241
2242 static void GLAPIENTRY
2243 save_EvalMesh1(GLenum mode, GLint i1, GLint i2)
2244 {
2245 GET_CURRENT_CONTEXT(ctx);
2246 Node *n;
2247 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2248 n = alloc_instruction(ctx, OPCODE_EVALMESH1, 3);
2249 if (n) {
2250 n[1].e = mode;
2251 n[2].i = i1;
2252 n[3].i = i2;
2253 }
2254 if (ctx->ExecuteFlag) {
2255 CALL_EvalMesh1(ctx->Exec, (mode, i1, i2));
2256 }
2257 }
2258
2259
2260 static void GLAPIENTRY
2261 save_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
2262 {
2263 GET_CURRENT_CONTEXT(ctx);
2264 Node *n;
2265 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2266 n = alloc_instruction(ctx, OPCODE_EVALMESH2, 5);
2267 if (n) {
2268 n[1].e = mode;
2269 n[2].i = i1;
2270 n[3].i = i2;
2271 n[4].i = j1;
2272 n[5].i = j2;
2273 }
2274 if (ctx->ExecuteFlag) {
2275 CALL_EvalMesh2(ctx->Exec, (mode, i1, i2, j1, j2));
2276 }
2277 }
2278
2279
2280
2281
2282 static void GLAPIENTRY
2283 save_Fogfv(GLenum pname, const GLfloat *params)
2284 {
2285 GET_CURRENT_CONTEXT(ctx);
2286 Node *n;
2287 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2288 n = alloc_instruction(ctx, OPCODE_FOG, 5);
2289 if (n) {
2290 n[1].e = pname;
2291 n[2].f = params[0];
2292 n[3].f = params[1];
2293 n[4].f = params[2];
2294 n[5].f = params[3];
2295 }
2296 if (ctx->ExecuteFlag) {
2297 CALL_Fogfv(ctx->Exec, (pname, params));
2298 }
2299 }
2300
2301
2302 static void GLAPIENTRY
2303 save_Fogf(GLenum pname, GLfloat param)
2304 {
2305 GLfloat parray[4];
2306 parray[0] = param;
2307 parray[1] = parray[2] = parray[3] = 0.0F;
2308 save_Fogfv(pname, parray);
2309 }
2310
2311
2312 static void GLAPIENTRY
2313 save_Fogiv(GLenum pname, const GLint *params)
2314 {
2315 GLfloat p[4];
2316 switch (pname) {
2317 case GL_FOG_MODE:
2318 case GL_FOG_DENSITY:
2319 case GL_FOG_START:
2320 case GL_FOG_END:
2321 case GL_FOG_INDEX:
2322 p[0] = (GLfloat) *params;
2323 p[1] = 0.0f;
2324 p[2] = 0.0f;
2325 p[3] = 0.0f;
2326 break;
2327 case GL_FOG_COLOR:
2328 p[0] = INT_TO_FLOAT(params[0]);
2329 p[1] = INT_TO_FLOAT(params[1]);
2330 p[2] = INT_TO_FLOAT(params[2]);
2331 p[3] = INT_TO_FLOAT(params[3]);
2332 break;
2333 default:
2334 /* Error will be caught later in gl_Fogfv */
2335 ASSIGN_4V(p, 0.0F, 0.0F, 0.0F, 0.0F);
2336 }
2337 save_Fogfv(pname, p);
2338 }
2339
2340
2341 static void GLAPIENTRY
2342 save_Fogi(GLenum pname, GLint param)
2343 {
2344 GLint parray[4];
2345 parray[0] = param;
2346 parray[1] = parray[2] = parray[3] = 0;
2347 save_Fogiv(pname, parray);
2348 }
2349
2350
2351 static void GLAPIENTRY
2352 save_FrontFace(GLenum mode)
2353 {
2354 GET_CURRENT_CONTEXT(ctx);
2355 Node *n;
2356 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2357 n = alloc_instruction(ctx, OPCODE_FRONT_FACE, 1);
2358 if (n) {
2359 n[1].e = mode;
2360 }
2361 if (ctx->ExecuteFlag) {
2362 CALL_FrontFace(ctx->Exec, (mode));
2363 }
2364 }
2365
2366
2367 static void GLAPIENTRY
2368 save_Frustum(GLdouble left, GLdouble right,
2369 GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval)
2370 {
2371 GET_CURRENT_CONTEXT(ctx);
2372 Node *n;
2373 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2374 n = alloc_instruction(ctx, OPCODE_FRUSTUM, 6);
2375 if (n) {
2376 n[1].f = (GLfloat) left;
2377 n[2].f = (GLfloat) right;
2378 n[3].f = (GLfloat) bottom;
2379 n[4].f = (GLfloat) top;
2380 n[5].f = (GLfloat) nearval;
2381 n[6].f = (GLfloat) farval;
2382 }
2383 if (ctx->ExecuteFlag) {
2384 CALL_Frustum(ctx->Exec, (left, right, bottom, top, nearval, farval));
2385 }
2386 }
2387
2388
2389 static void GLAPIENTRY
2390 save_Hint(GLenum target, GLenum mode)
2391 {
2392 GET_CURRENT_CONTEXT(ctx);
2393 Node *n;
2394 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2395 n = alloc_instruction(ctx, OPCODE_HINT, 2);
2396 if (n) {
2397 n[1].e = target;
2398 n[2].e = mode;
2399 }
2400 if (ctx->ExecuteFlag) {
2401 CALL_Hint(ctx->Exec, (target, mode));
2402 }
2403 }
2404
2405
2406 static void GLAPIENTRY
2407 save_Histogram(GLenum target, GLsizei width, GLenum internalFormat,
2408 GLboolean sink)
2409 {
2410 GET_CURRENT_CONTEXT(ctx);
2411 Node *n;
2412
2413 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2414 n = alloc_instruction(ctx, OPCODE_HISTOGRAM, 4);
2415 if (n) {
2416 n[1].e = target;
2417 n[2].i = width;
2418 n[3].e = internalFormat;
2419 n[4].b = sink;
2420 }
2421 if (ctx->ExecuteFlag) {
2422 CALL_Histogram(ctx->Exec, (target, width, internalFormat, sink));
2423 }
2424 }
2425
2426
2427 static void GLAPIENTRY
2428 save_IndexMask(GLuint mask)
2429 {
2430 GET_CURRENT_CONTEXT(ctx);
2431 Node *n;
2432 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2433 n = alloc_instruction(ctx, OPCODE_INDEX_MASK, 1);
2434 if (n) {
2435 n[1].ui = mask;
2436 }
2437 if (ctx->ExecuteFlag) {
2438 CALL_IndexMask(ctx->Exec, (mask));
2439 }
2440 }
2441
2442
2443 static void GLAPIENTRY
2444 save_InitNames(void)
2445 {
2446 GET_CURRENT_CONTEXT(ctx);
2447 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2448 (void) alloc_instruction(ctx, OPCODE_INIT_NAMES, 0);
2449 if (ctx->ExecuteFlag) {
2450 CALL_InitNames(ctx->Exec, ());
2451 }
2452 }
2453
2454
2455 static void GLAPIENTRY
2456 save_Lightfv(GLenum light, GLenum pname, const GLfloat *params)
2457 {
2458 GET_CURRENT_CONTEXT(ctx);
2459 Node *n;
2460 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2461 n = alloc_instruction(ctx, OPCODE_LIGHT, 6);
2462 if (n) {
2463 GLint i, nParams;
2464 n[1].e = light;
2465 n[2].e = pname;
2466 switch (pname) {
2467 case GL_AMBIENT:
2468 nParams = 4;
2469 break;
2470 case GL_DIFFUSE:
2471 nParams = 4;
2472 break;
2473 case GL_SPECULAR:
2474 nParams = 4;
2475 break;
2476 case GL_POSITION:
2477 nParams = 4;
2478 break;
2479 case GL_SPOT_DIRECTION:
2480 nParams = 3;
2481 break;
2482 case GL_SPOT_EXPONENT:
2483 nParams = 1;
2484 break;
2485 case GL_SPOT_CUTOFF:
2486 nParams = 1;
2487 break;
2488 case GL_CONSTANT_ATTENUATION:
2489 nParams = 1;
2490 break;
2491 case GL_LINEAR_ATTENUATION:
2492 nParams = 1;
2493 break;
2494 case GL_QUADRATIC_ATTENUATION:
2495 nParams = 1;
2496 break;
2497 default:
2498 nParams = 0;
2499 }
2500 for (i = 0; i < nParams; i++) {
2501 n[3 + i].f = params[i];
2502 }
2503 }
2504 if (ctx->ExecuteFlag) {
2505 CALL_Lightfv(ctx->Exec, (light, pname, params));
2506 }
2507 }
2508
2509
2510 static void GLAPIENTRY
2511 save_Lightf(GLenum light, GLenum pname, GLfloat param)
2512 {
2513 GLfloat parray[4];
2514 parray[0] = param;
2515 parray[1] = parray[2] = parray[3] = 0.0F;
2516 save_Lightfv(light, pname, parray);
2517 }
2518
2519
2520 static void GLAPIENTRY
2521 save_Lightiv(GLenum light, GLenum pname, const GLint *params)
2522 {
2523 GLfloat fparam[4];
2524 switch (pname) {
2525 case GL_AMBIENT:
2526 case GL_DIFFUSE:
2527 case GL_SPECULAR:
2528 fparam[0] = INT_TO_FLOAT(params[0]);
2529 fparam[1] = INT_TO_FLOAT(params[1]);
2530 fparam[2] = INT_TO_FLOAT(params[2]);
2531 fparam[3] = INT_TO_FLOAT(params[3]);
2532 break;
2533 case GL_POSITION:
2534 fparam[0] = (GLfloat) params[0];
2535 fparam[1] = (GLfloat) params[1];
2536 fparam[2] = (GLfloat) params[2];
2537 fparam[3] = (GLfloat) params[3];
2538 break;
2539 case GL_SPOT_DIRECTION:
2540 fparam[0] = (GLfloat) params[0];
2541 fparam[1] = (GLfloat) params[1];
2542 fparam[2] = (GLfloat) params[2];
2543 break;
2544 case GL_SPOT_EXPONENT:
2545 case GL_SPOT_CUTOFF:
2546 case GL_CONSTANT_ATTENUATION:
2547 case GL_LINEAR_ATTENUATION:
2548 case GL_QUADRATIC_ATTENUATION:
2549 fparam[0] = (GLfloat) params[0];
2550 break;
2551 default:
2552 /* error will be caught later in gl_Lightfv */
2553 ;
2554 }
2555 save_Lightfv(light, pname, fparam);
2556 }
2557
2558
2559 static void GLAPIENTRY
2560 save_Lighti(GLenum light, GLenum pname, GLint param)
2561 {
2562 GLint parray[4];
2563 parray[0] = param;
2564 parray[1] = parray[2] = parray[3] = 0;
2565 save_Lightiv(light, pname, parray);
2566 }
2567
2568
2569 static void GLAPIENTRY
2570 save_LightModelfv(GLenum pname, const GLfloat *params)
2571 {
2572 GET_CURRENT_CONTEXT(ctx);
2573 Node *n;
2574 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2575 n = alloc_instruction(ctx, OPCODE_LIGHT_MODEL, 5);
2576 if (n) {
2577 n[1].e = pname;
2578 n[2].f = params[0];
2579 n[3].f = params[1];
2580 n[4].f = params[2];
2581 n[5].f = params[3];
2582 }
2583 if (ctx->ExecuteFlag) {
2584 CALL_LightModelfv(ctx->Exec, (pname, params));
2585 }
2586 }
2587
2588
2589 static void GLAPIENTRY
2590 save_LightModelf(GLenum pname, GLfloat param)
2591 {
2592 GLfloat parray[4];
2593 parray[0] = param;
2594 parray[1] = parray[2] = parray[3] = 0.0F;
2595 save_LightModelfv(pname, parray);
2596 }
2597
2598
2599 static void GLAPIENTRY
2600 save_LightModeliv(GLenum pname, const GLint *params)
2601 {
2602 GLfloat fparam[4];
2603 switch (pname) {
2604 case GL_LIGHT_MODEL_AMBIENT:
2605 fparam[0] = INT_TO_FLOAT(params[0]);
2606 fparam[1] = INT_TO_FLOAT(params[1]);
2607 fparam[2] = INT_TO_FLOAT(params[2]);
2608 fparam[3] = INT_TO_FLOAT(params[3]);
2609 break;
2610 case GL_LIGHT_MODEL_LOCAL_VIEWER:
2611 case GL_LIGHT_MODEL_TWO_SIDE:
2612 case GL_LIGHT_MODEL_COLOR_CONTROL:
2613 fparam[0] = (GLfloat) params[0];
2614 fparam[1] = 0.0F;
2615 fparam[2] = 0.0F;
2616 fparam[3] = 0.0F;
2617 break;
2618 default:
2619 /* Error will be caught later in gl_LightModelfv */
2620 ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F);
2621 }
2622 save_LightModelfv(pname, fparam);
2623 }
2624
2625
2626 static void GLAPIENTRY
2627 save_LightModeli(GLenum pname, GLint param)
2628 {
2629 GLint parray[4];
2630 parray[0] = param;
2631 parray[1] = parray[2] = parray[3] = 0;
2632 save_LightModeliv(pname, parray);
2633 }
2634
2635
2636 static void GLAPIENTRY
2637 save_LineStipple(GLint factor, GLushort pattern)
2638 {
2639 GET_CURRENT_CONTEXT(ctx);
2640 Node *n;
2641 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2642 n = alloc_instruction(ctx, OPCODE_LINE_STIPPLE, 2);
2643 if (n) {
2644 n[1].i = factor;
2645 n[2].us = pattern;
2646 }
2647 if (ctx->ExecuteFlag) {
2648 CALL_LineStipple(ctx->Exec, (factor, pattern));
2649 }
2650 }
2651
2652
2653 static void GLAPIENTRY
2654 save_LineWidth(GLfloat width)
2655 {
2656 GET_CURRENT_CONTEXT(ctx);
2657 Node *n;
2658 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2659 n = alloc_instruction(ctx, OPCODE_LINE_WIDTH, 1);
2660 if (n) {
2661 n[1].f = width;
2662 }
2663 if (ctx->ExecuteFlag) {
2664 CALL_LineWidth(ctx->Exec, (width));
2665 }
2666 }
2667
2668
2669 static void GLAPIENTRY
2670 save_ListBase(GLuint base)
2671 {
2672 GET_CURRENT_CONTEXT(ctx);
2673 Node *n;
2674 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2675 n = alloc_instruction(ctx, OPCODE_LIST_BASE, 1);
2676 if (n) {
2677 n[1].ui = base;
2678 }
2679 if (ctx->ExecuteFlag) {
2680 CALL_ListBase(ctx->Exec, (base));
2681 }
2682 }
2683
2684
2685 static void GLAPIENTRY
2686 save_LoadIdentity(void)
2687 {
2688 GET_CURRENT_CONTEXT(ctx);
2689 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2690 (void) alloc_instruction(ctx, OPCODE_LOAD_IDENTITY, 0);
2691 if (ctx->ExecuteFlag) {
2692 CALL_LoadIdentity(ctx->Exec, ());
2693 }
2694 }
2695
2696
2697 static void GLAPIENTRY
2698 save_LoadMatrixf(const GLfloat * m)
2699 {
2700 GET_CURRENT_CONTEXT(ctx);
2701 Node *n;
2702 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2703 n = alloc_instruction(ctx, OPCODE_LOAD_MATRIX, 16);
2704 if (n) {
2705 GLuint i;
2706 for (i = 0; i < 16; i++) {
2707 n[1 + i].f = m[i];
2708 }
2709 }
2710 if (ctx->ExecuteFlag) {
2711 CALL_LoadMatrixf(ctx->Exec, (m));
2712 }
2713 }
2714
2715
2716 static void GLAPIENTRY
2717 save_LoadMatrixd(const GLdouble * m)
2718 {
2719 GLfloat f[16];
2720 GLint i;
2721 for (i = 0; i < 16; i++) {
2722 f[i] = (GLfloat) m[i];
2723 }
2724 save_LoadMatrixf(f);
2725 }
2726
2727
2728 static void GLAPIENTRY
2729 save_LoadName(GLuint name)
2730 {
2731 GET_CURRENT_CONTEXT(ctx);
2732 Node *n;
2733 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2734 n = alloc_instruction(ctx, OPCODE_LOAD_NAME, 1);
2735 if (n) {
2736 n[1].ui = name;
2737 }
2738 if (ctx->ExecuteFlag) {
2739 CALL_LoadName(ctx->Exec, (name));
2740 }
2741 }
2742
2743
2744 static void GLAPIENTRY
2745 save_LogicOp(GLenum opcode)
2746 {
2747 GET_CURRENT_CONTEXT(ctx);
2748 Node *n;
2749 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2750 n = alloc_instruction(ctx, OPCODE_LOGIC_OP, 1);
2751 if (n) {
2752 n[1].e = opcode;
2753 }
2754 if (ctx->ExecuteFlag) {
2755 CALL_LogicOp(ctx->Exec, (opcode));
2756 }
2757 }
2758
2759
2760 static void GLAPIENTRY
2761 save_Map1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride,
2762 GLint order, const GLdouble * points)
2763 {
2764 GET_CURRENT_CONTEXT(ctx);
2765 Node *n;
2766 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2767 n = alloc_instruction(ctx, OPCODE_MAP1, 6);
2768 if (n) {
2769 GLfloat *pnts = _mesa_copy_map_points1d(target, stride, order, points);
2770 n[1].e = target;
2771 n[2].f = (GLfloat) u1;
2772 n[3].f = (GLfloat) u2;
2773 n[4].i = _mesa_evaluator_components(target); /* stride */
2774 n[5].i = order;
2775 n[6].data = (void *) pnts;
2776 }
2777 if (ctx->ExecuteFlag) {
2778 CALL_Map1d(ctx->Exec, (target, u1, u2, stride, order, points));
2779 }
2780 }
2781
2782 static void GLAPIENTRY
2783 save_Map1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
2784 GLint order, const GLfloat * points)
2785 {
2786 GET_CURRENT_CONTEXT(ctx);
2787 Node *n;
2788 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2789 n = alloc_instruction(ctx, OPCODE_MAP1, 6);
2790 if (n) {
2791 GLfloat *pnts = _mesa_copy_map_points1f(target, stride, order, points);
2792 n[1].e = target;
2793 n[2].f = u1;
2794 n[3].f = u2;
2795 n[4].i = _mesa_evaluator_components(target); /* stride */
2796 n[5].i = order;
2797 n[6].data = (void *) pnts;
2798 }
2799 if (ctx->ExecuteFlag) {
2800 CALL_Map1f(ctx->Exec, (target, u1, u2, stride, order, points));
2801 }
2802 }
2803
2804
2805 static void GLAPIENTRY
2806 save_Map2d(GLenum target,
2807 GLdouble u1, GLdouble u2, GLint ustride, GLint uorder,
2808 GLdouble v1, GLdouble v2, GLint vstride, GLint vorder,
2809 const GLdouble * points)
2810 {
2811 GET_CURRENT_CONTEXT(ctx);
2812 Node *n;
2813 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2814 n = alloc_instruction(ctx, OPCODE_MAP2, 10);
2815 if (n) {
2816 GLfloat *pnts = _mesa_copy_map_points2d(target, ustride, uorder,
2817 vstride, vorder, points);
2818 n[1].e = target;
2819 n[2].f = (GLfloat) u1;
2820 n[3].f = (GLfloat) u2;
2821 n[4].f = (GLfloat) v1;
2822 n[5].f = (GLfloat) v2;
2823 /* XXX verify these strides are correct */
2824 n[6].i = _mesa_evaluator_components(target) * vorder; /*ustride */
2825 n[7].i = _mesa_evaluator_components(target); /*vstride */
2826 n[8].i = uorder;
2827 n[9].i = vorder;
2828 n[10].data = (void *) pnts;
2829 }
2830 if (ctx->ExecuteFlag) {
2831 CALL_Map2d(ctx->Exec, (target,
2832 u1, u2, ustride, uorder,
2833 v1, v2, vstride, vorder, points));
2834 }
2835 }
2836
2837
2838 static void GLAPIENTRY
2839 save_Map2f(GLenum target,
2840 GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
2841 GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
2842 const GLfloat * points)
2843 {
2844 GET_CURRENT_CONTEXT(ctx);
2845 Node *n;
2846 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2847 n = alloc_instruction(ctx, OPCODE_MAP2, 10);
2848 if (n) {
2849 GLfloat *pnts = _mesa_copy_map_points2f(target, ustride, uorder,
2850 vstride, vorder, points);
2851 n[1].e = target;
2852 n[2].f = u1;
2853 n[3].f = u2;
2854 n[4].f = v1;
2855 n[5].f = v2;
2856 /* XXX verify these strides are correct */
2857 n[6].i = _mesa_evaluator_components(target) * vorder; /*ustride */
2858 n[7].i = _mesa_evaluator_components(target); /*vstride */
2859 n[8].i = uorder;
2860 n[9].i = vorder;
2861 n[10].data = (void *) pnts;
2862 }
2863 if (ctx->ExecuteFlag) {
2864 CALL_Map2f(ctx->Exec, (target, u1, u2, ustride, uorder,
2865 v1, v2, vstride, vorder, points));
2866 }
2867 }
2868
2869
2870 static void GLAPIENTRY
2871 save_MapGrid1f(GLint un, GLfloat u1, GLfloat u2)
2872 {
2873 GET_CURRENT_CONTEXT(ctx);
2874 Node *n;
2875 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2876 n = alloc_instruction(ctx, OPCODE_MAPGRID1, 3);
2877 if (n) {
2878 n[1].i = un;
2879 n[2].f = u1;
2880 n[3].f = u2;
2881 }
2882 if (ctx->ExecuteFlag) {
2883 CALL_MapGrid1f(ctx->Exec, (un, u1, u2));
2884 }
2885 }
2886
2887
2888 static void GLAPIENTRY
2889 save_MapGrid1d(GLint un, GLdouble u1, GLdouble u2)
2890 {
2891 save_MapGrid1f(un, (GLfloat) u1, (GLfloat) u2);
2892 }
2893
2894
2895 static void GLAPIENTRY
2896 save_MapGrid2f(GLint un, GLfloat u1, GLfloat u2,
2897 GLint vn, GLfloat v1, GLfloat v2)
2898 {
2899 GET_CURRENT_CONTEXT(ctx);
2900 Node *n;
2901 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2902 n = alloc_instruction(ctx, OPCODE_MAPGRID2, 6);
2903 if (n) {
2904 n[1].i = un;
2905 n[2].f = u1;
2906 n[3].f = u2;
2907 n[4].i = vn;
2908 n[5].f = v1;
2909 n[6].f = v2;
2910 }
2911 if (ctx->ExecuteFlag) {
2912 CALL_MapGrid2f(ctx->Exec, (un, u1, u2, vn, v1, v2));
2913 }
2914 }
2915
2916
2917
2918 static void GLAPIENTRY
2919 save_MapGrid2d(GLint un, GLdouble u1, GLdouble u2,
2920 GLint vn, GLdouble v1, GLdouble v2)
2921 {
2922 save_MapGrid2f(un, (GLfloat) u1, (GLfloat) u2,
2923 vn, (GLfloat) v1, (GLfloat) v2);
2924 }
2925
2926
2927 static void GLAPIENTRY
2928 save_MatrixMode(GLenum mode)
2929 {
2930 GET_CURRENT_CONTEXT(ctx);
2931 Node *n;
2932 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2933 n = alloc_instruction(ctx, OPCODE_MATRIX_MODE, 1);
2934 if (n) {
2935 n[1].e = mode;
2936 }
2937 if (ctx->ExecuteFlag) {
2938 CALL_MatrixMode(ctx->Exec, (mode));
2939 }
2940 }
2941
2942
2943 static void GLAPIENTRY
2944 save_Minmax(GLenum target, GLenum internalFormat, GLboolean sink)
2945 {
2946 GET_CURRENT_CONTEXT(ctx);
2947 Node *n;
2948
2949 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2950 n = alloc_instruction(ctx, OPCODE_MIN_MAX, 3);
2951 if (n) {
2952 n[1].e = target;
2953 n[2].e = internalFormat;
2954 n[3].b = sink;
2955 }
2956 if (ctx->ExecuteFlag) {
2957 CALL_Minmax(ctx->Exec, (target, internalFormat, sink));
2958 }
2959 }
2960
2961
2962 static void GLAPIENTRY
2963 save_MultMatrixf(const GLfloat * m)
2964 {
2965 GET_CURRENT_CONTEXT(ctx);
2966 Node *n;
2967 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2968 n = alloc_instruction(ctx, OPCODE_MULT_MATRIX, 16);
2969 if (n) {
2970 GLuint i;
2971 for (i = 0; i < 16; i++) {
2972 n[1 + i].f = m[i];
2973 }
2974 }
2975 if (ctx->ExecuteFlag) {
2976 CALL_MultMatrixf(ctx->Exec, (m));
2977 }
2978 }
2979
2980
2981 static void GLAPIENTRY
2982 save_MultMatrixd(const GLdouble * m)
2983 {
2984 GLfloat f[16];
2985 GLint i;
2986 for (i = 0; i < 16; i++) {
2987 f[i] = (GLfloat) m[i];
2988 }
2989 save_MultMatrixf(f);
2990 }
2991
2992
2993 static void GLAPIENTRY
2994 save_NewList(GLuint name, GLenum mode)
2995 {
2996 GET_CURRENT_CONTEXT(ctx);
2997 /* It's an error to call this function while building a display list */
2998 _mesa_error(ctx, GL_INVALID_OPERATION, "glNewList");
2999 (void) name;
3000 (void) mode;
3001 }
3002
3003
3004
3005 static void GLAPIENTRY
3006 save_Ortho(GLdouble left, GLdouble right,
3007 GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval)
3008 {
3009 GET_CURRENT_CONTEXT(ctx);
3010 Node *n;
3011 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3012 n = alloc_instruction(ctx, OPCODE_ORTHO, 6);
3013 if (n) {
3014 n[1].f = (GLfloat) left;
3015 n[2].f = (GLfloat) right;
3016 n[3].f = (GLfloat) bottom;
3017 n[4].f = (GLfloat) top;
3018 n[5].f = (GLfloat) nearval;
3019 n[6].f = (GLfloat) farval;
3020 }
3021 if (ctx->ExecuteFlag) {
3022 CALL_Ortho(ctx->Exec, (left, right, bottom, top, nearval, farval));
3023 }
3024 }
3025
3026
3027 static void GLAPIENTRY
3028 save_PixelMapfv(GLenum map, GLint mapsize, const GLfloat *values)
3029 {
3030 GET_CURRENT_CONTEXT(ctx);
3031 Node *n;
3032 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3033 n = alloc_instruction(ctx, OPCODE_PIXEL_MAP, 3);
3034 if (n) {
3035 n[1].e = map;
3036 n[2].i = mapsize;
3037 n[3].data = (void *) malloc(mapsize * sizeof(GLfloat));
3038 memcpy(n[3].data, (void *) values, mapsize * sizeof(GLfloat));
3039 }
3040 if (ctx->ExecuteFlag) {
3041 CALL_PixelMapfv(ctx->Exec, (map, mapsize, values));
3042 }
3043 }
3044
3045
3046 static void GLAPIENTRY
3047 save_PixelMapuiv(GLenum map, GLint mapsize, const GLuint *values)
3048 {
3049 GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
3050 GLint i;
3051 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
3052 for (i = 0; i < mapsize; i++) {
3053 fvalues[i] = (GLfloat) values[i];
3054 }
3055 }
3056 else {
3057 for (i = 0; i < mapsize; i++) {
3058 fvalues[i] = UINT_TO_FLOAT(values[i]);
3059 }
3060 }
3061 save_PixelMapfv(map, mapsize, fvalues);
3062 }
3063
3064
3065 static void GLAPIENTRY
3066 save_PixelMapusv(GLenum map, GLint mapsize, const GLushort *values)
3067 {
3068 GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
3069 GLint i;
3070 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
3071 for (i = 0; i < mapsize; i++) {
3072 fvalues[i] = (GLfloat) values[i];
3073 }
3074 }
3075 else {
3076 for (i = 0; i < mapsize; i++) {
3077 fvalues[i] = USHORT_TO_FLOAT(values[i]);
3078 }
3079 }
3080 save_PixelMapfv(map, mapsize, fvalues);
3081 }
3082
3083
3084 static void GLAPIENTRY
3085 save_PixelTransferf(GLenum pname, GLfloat param)
3086 {
3087 GET_CURRENT_CONTEXT(ctx);
3088 Node *n;
3089 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3090 n = alloc_instruction(ctx, OPCODE_PIXEL_TRANSFER, 2);
3091 if (n) {
3092 n[1].e = pname;
3093 n[2].f = param;
3094 }
3095 if (ctx->ExecuteFlag) {
3096 CALL_PixelTransferf(ctx->Exec, (pname, param));
3097 }
3098 }
3099
3100
3101 static void GLAPIENTRY
3102 save_PixelTransferi(GLenum pname, GLint param)
3103 {
3104 save_PixelTransferf(pname, (GLfloat) param);
3105 }
3106
3107
3108 static void GLAPIENTRY
3109 save_PixelZoom(GLfloat xfactor, GLfloat yfactor)
3110 {
3111 GET_CURRENT_CONTEXT(ctx);
3112 Node *n;
3113 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3114 n = alloc_instruction(ctx, OPCODE_PIXEL_ZOOM, 2);
3115 if (n) {
3116 n[1].f = xfactor;
3117 n[2].f = yfactor;
3118 }
3119 if (ctx->ExecuteFlag) {
3120 CALL_PixelZoom(ctx->Exec, (xfactor, yfactor));
3121 }
3122 }
3123
3124
3125 static void GLAPIENTRY
3126 save_PointParameterfvEXT(GLenum pname, const GLfloat *params)
3127 {
3128 GET_CURRENT_CONTEXT(ctx);
3129 Node *n;
3130 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3131 n = alloc_instruction(ctx, OPCODE_POINT_PARAMETERS, 4);
3132 if (n) {
3133 n[1].e = pname;
3134 n[2].f = params[0];
3135 n[3].f = params[1];
3136 n[4].f = params[2];
3137 }
3138 if (ctx->ExecuteFlag) {
3139 CALL_PointParameterfvEXT(ctx->Exec, (pname, params));
3140 }
3141 }
3142
3143
3144 static void GLAPIENTRY
3145 save_PointParameterfEXT(GLenum pname, GLfloat param)
3146 {
3147 GLfloat parray[3];
3148 parray[0] = param;
3149 parray[1] = parray[2] = 0.0F;
3150 save_PointParameterfvEXT(pname, parray);
3151 }
3152
3153 static void GLAPIENTRY
3154 save_PointParameteriNV(GLenum pname, GLint param)
3155 {
3156 GLfloat parray[3];
3157 parray[0] = (GLfloat) param;
3158 parray[1] = parray[2] = 0.0F;
3159 save_PointParameterfvEXT(pname, parray);
3160 }
3161
3162 static void GLAPIENTRY
3163 save_PointParameterivNV(GLenum pname, const GLint * param)
3164 {
3165 GLfloat parray[3];
3166 parray[0] = (GLfloat) param[0];
3167 parray[1] = parray[2] = 0.0F;
3168 save_PointParameterfvEXT(pname, parray);
3169 }
3170
3171
3172 static void GLAPIENTRY
3173 save_PointSize(GLfloat size)
3174 {
3175 GET_CURRENT_CONTEXT(ctx);
3176 Node *n;
3177 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3178 n = alloc_instruction(ctx, OPCODE_POINT_SIZE, 1);
3179 if (n) {
3180 n[1].f = size;
3181 }
3182 if (ctx->ExecuteFlag) {
3183 CALL_PointSize(ctx->Exec, (size));
3184 }
3185 }
3186
3187
3188 static void GLAPIENTRY
3189 save_PolygonMode(GLenum face, GLenum mode)
3190 {
3191 GET_CURRENT_CONTEXT(ctx);
3192 Node *n;
3193 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3194 n = alloc_instruction(ctx, OPCODE_POLYGON_MODE, 2);
3195 if (n) {
3196 n[1].e = face;
3197 n[2].e = mode;
3198 }
3199 if (ctx->ExecuteFlag) {
3200 CALL_PolygonMode(ctx->Exec, (face, mode));
3201 }
3202 }
3203
3204
3205 static void GLAPIENTRY
3206 save_PolygonStipple(const GLubyte * pattern)
3207 {
3208 GET_CURRENT_CONTEXT(ctx);
3209 Node *n;
3210
3211 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3212
3213 n = alloc_instruction(ctx, OPCODE_POLYGON_STIPPLE, 1);
3214 if (n) {
3215 n[1].data = unpack_image(ctx, 2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP,
3216 pattern, &ctx->Unpack);
3217 }
3218 if (ctx->ExecuteFlag) {
3219 CALL_PolygonStipple(ctx->Exec, ((GLubyte *) pattern));
3220 }
3221 }
3222
3223
3224 static void GLAPIENTRY
3225 save_PolygonOffset(GLfloat factor, GLfloat units)
3226 {
3227 GET_CURRENT_CONTEXT(ctx);
3228 Node *n;
3229 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3230 n = alloc_instruction(ctx, OPCODE_POLYGON_OFFSET, 2);
3231 if (n) {
3232 n[1].f = factor;
3233 n[2].f = units;
3234 }
3235 if (ctx->ExecuteFlag) {
3236 CALL_PolygonOffset(ctx->Exec, (factor, units));
3237 }
3238 }
3239
3240
3241 static void GLAPIENTRY
3242 save_PolygonOffsetEXT(GLfloat factor, GLfloat bias)
3243 {
3244 GET_CURRENT_CONTEXT(ctx);
3245 /* XXX mult by DepthMaxF here??? */
3246 save_PolygonOffset(factor, ctx->DrawBuffer->_DepthMaxF * bias);
3247 }
3248
3249
3250 static void GLAPIENTRY
3251 save_PopAttrib(void)
3252 {
3253 GET_CURRENT_CONTEXT(ctx);
3254 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3255 (void) alloc_instruction(ctx, OPCODE_POP_ATTRIB, 0);
3256 if (ctx->ExecuteFlag) {
3257 CALL_PopAttrib(ctx->Exec, ());
3258 }
3259 }
3260
3261
3262 static void GLAPIENTRY
3263 save_PopMatrix(void)
3264 {
3265 GET_CURRENT_CONTEXT(ctx);
3266 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3267 (void) alloc_instruction(ctx, OPCODE_POP_MATRIX, 0);
3268 if (ctx->ExecuteFlag) {
3269 CALL_PopMatrix(ctx->Exec, ());
3270 }
3271 }
3272
3273
3274 static void GLAPIENTRY
3275 save_PopName(void)
3276 {
3277 GET_CURRENT_CONTEXT(ctx);
3278 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3279 (void) alloc_instruction(ctx, OPCODE_POP_NAME, 0);
3280 if (ctx->ExecuteFlag) {
3281 CALL_PopName(ctx->Exec, ());
3282 }
3283 }
3284
3285
3286 static void GLAPIENTRY
3287 save_PrioritizeTextures(GLsizei num, const GLuint * textures,
3288 const GLclampf * priorities)
3289 {
3290 GET_CURRENT_CONTEXT(ctx);
3291 GLint i;
3292 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3293
3294 for (i = 0; i < num; i++) {
3295 Node *n;
3296 n = alloc_instruction(ctx, OPCODE_PRIORITIZE_TEXTURE, 2);
3297 if (n) {
3298 n[1].ui = textures[i];
3299 n[2].f = priorities[i];
3300 }
3301 }
3302 if (ctx->ExecuteFlag) {
3303 CALL_PrioritizeTextures(ctx->Exec, (num, textures, priorities));
3304 }
3305 }
3306
3307
3308 static void GLAPIENTRY
3309 save_PushAttrib(GLbitfield mask)
3310 {
3311 GET_CURRENT_CONTEXT(ctx);
3312 Node *n;
3313 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3314 n = alloc_instruction(ctx, OPCODE_PUSH_ATTRIB, 1);
3315 if (n) {
3316 n[1].bf = mask;
3317 }
3318 if (ctx->ExecuteFlag) {
3319 CALL_PushAttrib(ctx->Exec, (mask));
3320 }
3321 }
3322
3323
3324 static void GLAPIENTRY
3325 save_PushMatrix(void)
3326 {
3327 GET_CURRENT_CONTEXT(ctx);
3328 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3329 (void) alloc_instruction(ctx, OPCODE_PUSH_MATRIX, 0);
3330 if (ctx->ExecuteFlag) {
3331 CALL_PushMatrix(ctx->Exec, ());
3332 }
3333 }
3334
3335
3336 static void GLAPIENTRY
3337 save_PushName(GLuint name)
3338 {
3339 GET_CURRENT_CONTEXT(ctx);
3340 Node *n;
3341 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3342 n = alloc_instruction(ctx, OPCODE_PUSH_NAME, 1);
3343 if (n) {
3344 n[1].ui = name;
3345 }
3346 if (ctx->ExecuteFlag) {
3347 CALL_PushName(ctx->Exec, (name));
3348 }
3349 }
3350
3351
3352 static void GLAPIENTRY
3353 save_RasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3354 {
3355 GET_CURRENT_CONTEXT(ctx);
3356 Node *n;
3357 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3358 n = alloc_instruction(ctx, OPCODE_RASTER_POS, 4);
3359 if (n) {
3360 n[1].f = x;
3361 n[2].f = y;
3362 n[3].f = z;
3363 n[4].f = w;
3364 }
3365 if (ctx->ExecuteFlag) {
3366 CALL_RasterPos4f(ctx->Exec, (x, y, z, w));
3367 }
3368 }
3369
3370 static void GLAPIENTRY
3371 save_RasterPos2d(GLdouble x, GLdouble y)
3372 {
3373 save_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
3374 }
3375
3376 static void GLAPIENTRY
3377 save_RasterPos2f(GLfloat x, GLfloat y)
3378 {
3379 save_RasterPos4f(x, y, 0.0F, 1.0F);
3380 }
3381
3382 static void GLAPIENTRY
3383 save_RasterPos2i(GLint x, GLint y)
3384 {
3385 save_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
3386 }
3387
3388 static void GLAPIENTRY
3389 save_RasterPos2s(GLshort x, GLshort y)
3390 {
3391 save_RasterPos4f(x, y, 0.0F, 1.0F);
3392 }
3393
3394 static void GLAPIENTRY
3395 save_RasterPos3d(GLdouble x, GLdouble y, GLdouble z)
3396 {
3397 save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
3398 }
3399
3400 static void GLAPIENTRY
3401 save_RasterPos3f(GLfloat x, GLfloat y, GLfloat z)
3402 {
3403 save_RasterPos4f(x, y, z, 1.0F);
3404 }
3405
3406 static void GLAPIENTRY
3407 save_RasterPos3i(GLint x, GLint y, GLint z)
3408 {
3409 save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
3410 }
3411
3412 static void GLAPIENTRY
3413 save_RasterPos3s(GLshort x, GLshort y, GLshort z)
3414 {
3415 save_RasterPos4f(x, y, z, 1.0F);
3416 }
3417
3418 static void GLAPIENTRY
3419 save_RasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
3420 {
3421 save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
3422 }
3423
3424 static void GLAPIENTRY
3425 save_RasterPos4i(GLint x, GLint y, GLint z, GLint w)
3426 {
3427 save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
3428 }
3429
3430 static void GLAPIENTRY
3431 save_RasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
3432 {
3433 save_RasterPos4f(x, y, z, w);
3434 }
3435
3436 static void GLAPIENTRY
3437 save_RasterPos2dv(const GLdouble * v)
3438 {
3439 save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
3440 }
3441
3442 static void GLAPIENTRY
3443 save_RasterPos2fv(const GLfloat * v)
3444 {
3445 save_RasterPos4f(v[0], v[1], 0.0F, 1.0F);
3446 }
3447
3448 static void GLAPIENTRY
3449 save_RasterPos2iv(const GLint * v)
3450 {
3451 save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
3452 }
3453
3454 static void GLAPIENTRY
3455 save_RasterPos2sv(const GLshort * v)
3456 {
3457 save_RasterPos4f(v[0], v[1], 0.0F, 1.0F);
3458 }
3459
3460 static void GLAPIENTRY
3461 save_RasterPos3dv(const GLdouble * v)
3462 {
3463 save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
3464 }
3465
3466 static void GLAPIENTRY
3467 save_RasterPos3fv(const GLfloat * v)
3468 {
3469 save_RasterPos4f(v[0], v[1], v[2], 1.0F);
3470 }
3471
3472 static void GLAPIENTRY
3473 save_RasterPos3iv(const GLint * v)
3474 {
3475 save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
3476 }
3477
3478 static void GLAPIENTRY
3479 save_RasterPos3sv(const GLshort * v)
3480 {
3481 save_RasterPos4f(v[0], v[1], v[2], 1.0F);
3482 }
3483
3484 static void GLAPIENTRY
3485 save_RasterPos4dv(const GLdouble * v)
3486 {
3487 save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1],
3488 (GLfloat) v[2], (GLfloat) v[3]);
3489 }
3490
3491 static void GLAPIENTRY
3492 save_RasterPos4fv(const GLfloat * v)
3493 {
3494 save_RasterPos4f(v[0], v[1], v[2], v[3]);
3495 }
3496
3497 static void GLAPIENTRY
3498 save_RasterPos4iv(const GLint * v)
3499 {
3500 save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1],
3501 (GLfloat) v[2], (GLfloat) v[3]);
3502 }
3503
3504 static void GLAPIENTRY
3505 save_RasterPos4sv(const GLshort * v)
3506 {
3507 save_RasterPos4f(v[0], v[1], v[2], v[3]);
3508 }
3509
3510
3511 static void GLAPIENTRY
3512 save_PassThrough(GLfloat token)
3513 {
3514 GET_CURRENT_CONTEXT(ctx);
3515 Node *n;
3516 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3517 n = alloc_instruction(ctx, OPCODE_PASSTHROUGH, 1);
3518 if (n) {
3519 n[1].f = token;
3520 }
3521 if (ctx->ExecuteFlag) {
3522 CALL_PassThrough(ctx->Exec, (token));
3523 }
3524 }
3525
3526
3527 static void GLAPIENTRY
3528 save_ReadBuffer(GLenum mode)
3529 {
3530 GET_CURRENT_CONTEXT(ctx);
3531 Node *n;
3532 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3533 n = alloc_instruction(ctx, OPCODE_READ_BUFFER, 1);
3534 if (n) {
3535 n[1].e = mode;
3536 }
3537 if (ctx->ExecuteFlag) {
3538 CALL_ReadBuffer(ctx->Exec, (mode));
3539 }
3540 }
3541
3542
3543 static void GLAPIENTRY
3544 save_ResetHistogram(GLenum target)
3545 {
3546 GET_CURRENT_CONTEXT(ctx);
3547 Node *n;
3548 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3549 n = alloc_instruction(ctx, OPCODE_RESET_HISTOGRAM, 1);
3550 if (n) {
3551 n[1].e = target;
3552 }
3553 if (ctx->ExecuteFlag) {
3554 CALL_ResetHistogram(ctx->Exec, (target));
3555 }
3556 }
3557
3558
3559 static void GLAPIENTRY
3560 save_ResetMinmax(GLenum target)
3561 {
3562 GET_CURRENT_CONTEXT(ctx);
3563 Node *n;
3564 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3565 n = alloc_instruction(ctx, OPCODE_RESET_MIN_MAX, 1);
3566 if (n) {
3567 n[1].e = target;
3568 }
3569 if (ctx->ExecuteFlag) {
3570 CALL_ResetMinmax(ctx->Exec, (target));
3571 }
3572 }
3573
3574
3575 static void GLAPIENTRY
3576 save_Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
3577 {
3578 GET_CURRENT_CONTEXT(ctx);
3579 Node *n;
3580 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3581 n = alloc_instruction(ctx, OPCODE_ROTATE, 4);
3582 if (n) {
3583 n[1].f = angle;
3584 n[2].f = x;
3585 n[3].f = y;
3586 n[4].f = z;
3587 }
3588 if (ctx->ExecuteFlag) {
3589 CALL_Rotatef(ctx->Exec, (angle, x, y, z));
3590 }
3591 }
3592
3593
3594 static void GLAPIENTRY
3595 save_Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
3596 {
3597 save_Rotatef((GLfloat) angle, (GLfloat) x, (GLfloat) y, (GLfloat) z);
3598 }
3599
3600
3601 static void GLAPIENTRY
3602 save_Scalef(GLfloat x, GLfloat y, GLfloat z)
3603 {
3604 GET_CURRENT_CONTEXT(ctx);
3605 Node *n;
3606 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3607 n = alloc_instruction(ctx, OPCODE_SCALE, 3);
3608 if (n) {
3609 n[