[[MESA]
[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_texture_integer */
409 OPCODE_CLEARCOLOR_I,
410 OPCODE_CLEARCOLOR_UI,
411 OPCODE_TEXPARAMETER_I,
412 OPCODE_TEXPARAMETER_UI,
413
414 /* GL_EXT_separate_shader_objects */
415 OPCODE_ACTIVE_PROGRAM_EXT,
416 OPCODE_USE_SHADER_PROGRAM_EXT,
417
418 /* GL_NV_texture_barrier */
419 OPCODE_TEXTURE_BARRIER_NV,
420
421 /* The following three are meta instructions */
422 OPCODE_ERROR, /* raise compiled-in error */
423 OPCODE_CONTINUE,
424 OPCODE_END_OF_LIST,
425 OPCODE_EXT_0
426 } OpCode;
427
428
429
430 /**
431 * Display list node.
432 *
433 * Display list instructions are stored as sequences of "nodes". Nodes
434 * are allocated in blocks. Each block has BLOCK_SIZE nodes. Blocks
435 * are linked together with a pointer.
436 *
437 * Each instruction in the display list is stored as a sequence of
438 * contiguous nodes in memory.
439 * Each node is the union of a variety of data types.
440 */
441 union gl_dlist_node
442 {
443 OpCode opcode;
444 GLboolean b;
445 GLbitfield bf;
446 GLubyte ub;
447 GLshort s;
448 GLushort us;
449 GLint i;
450 GLuint ui;
451 GLenum e;
452 GLfloat f;
453 GLvoid *data;
454 void *next; /* If prev node's opcode==OPCODE_CONTINUE */
455 };
456
457
458 typedef union gl_dlist_node Node;
459
460
461 /**
462 * Used to store a 64-bit uint in a pair of "Nodes" for the sake of 32-bit
463 * environment. In 64-bit env, sizeof(Node)==8 anyway.
464 */
465 union uint64_pair
466 {
467 GLuint64 uint64;
468 GLuint uint32[2];
469 };
470
471
472 /**
473 * How many nodes to allocate at a time.
474 *
475 * \note Reduced now that we hold vertices etc. elsewhere.
476 */
477 #define BLOCK_SIZE 256
478
479
480
481 /**
482 * Number of nodes of storage needed for each instruction.
483 * Sizes for dynamically allocated opcodes are stored in the context struct.
484 */
485 static GLuint InstSize[OPCODE_END_OF_LIST + 1];
486
487
488 #if FEATURE_dlist
489
490
491 void mesa_print_display_list(GLuint list);
492
493
494 /**********************************************************************/
495 /***** Private *****/
496 /**********************************************************************/
497
498
499 /**
500 * Make an empty display list. This is used by glGenLists() to
501 * reserve display list IDs.
502 */
503 static struct gl_display_list *
504 make_list(GLuint name, GLuint count)
505 {
506 struct gl_display_list *dlist = CALLOC_STRUCT(gl_display_list);
507 dlist->Name = name;
508 dlist->Head = (Node *) malloc(sizeof(Node) * count);
509 dlist->Head[0].opcode = OPCODE_END_OF_LIST;
510 return dlist;
511 }
512
513
514 /**
515 * Lookup function to just encapsulate casting.
516 */
517 static inline struct gl_display_list *
518 lookup_list(struct gl_context *ctx, GLuint list)
519 {
520 return (struct gl_display_list *)
521 _mesa_HashLookup(ctx->Shared->DisplayList, list);
522 }
523
524
525 /** Is the given opcode an extension code? */
526 static inline GLboolean
527 is_ext_opcode(OpCode opcode)
528 {
529 return (opcode >= OPCODE_EXT_0);
530 }
531
532
533 /** Destroy an extended opcode instruction */
534 static GLint
535 ext_opcode_destroy(struct gl_context *ctx, Node *node)
536 {
537 const GLint i = node[0].opcode - OPCODE_EXT_0;
538 GLint step;
539 ctx->ListExt->Opcode[i].Destroy(ctx, &node[1]);
540 step = ctx->ListExt->Opcode[i].Size;
541 return step;
542 }
543
544
545 /** Execute an extended opcode instruction */
546 static GLint
547 ext_opcode_execute(struct gl_context *ctx, Node *node)
548 {
549 const GLint i = node[0].opcode - OPCODE_EXT_0;
550 GLint step;
551 ctx->ListExt->Opcode[i].Execute(ctx, &node[1]);
552 step = ctx->ListExt->Opcode[i].Size;
553 return step;
554 }
555
556
557 /** Print an extended opcode instruction */
558 static GLint
559 ext_opcode_print(struct gl_context *ctx, Node *node)
560 {
561 const GLint i = node[0].opcode - OPCODE_EXT_0;
562 GLint step;
563 ctx->ListExt->Opcode[i].Print(ctx, &node[1]);
564 step = ctx->ListExt->Opcode[i].Size;
565 return step;
566 }
567
568
569 /**
570 * Delete the named display list, but don't remove from hash table.
571 * \param dlist - display list pointer
572 */
573 void
574 _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
575 {
576 Node *n, *block;
577 GLboolean done;
578
579 n = block = dlist->Head;
580
581 done = block ? GL_FALSE : GL_TRUE;
582 while (!done) {
583 const OpCode opcode = n[0].opcode;
584
585 /* check for extension opcodes first */
586 if (is_ext_opcode(opcode)) {
587 n += ext_opcode_destroy(ctx, n);
588 }
589 else {
590 switch (opcode) {
591 /* for some commands, we need to free malloc'd memory */
592 case OPCODE_MAP1:
593 free(n[6].data);
594 n += InstSize[n[0].opcode];
595 break;
596 case OPCODE_MAP2:
597 free(n[10].data);
598 n += InstSize[n[0].opcode];
599 break;
600 case OPCODE_DRAW_PIXELS:
601 free(n[5].data);
602 n += InstSize[n[0].opcode];
603 break;
604 case OPCODE_BITMAP:
605 free(n[7].data);
606 n += InstSize[n[0].opcode];
607 break;
608 case OPCODE_COLOR_TABLE:
609 free(n[6].data);
610 n += InstSize[n[0].opcode];
611 break;
612 case OPCODE_COLOR_SUB_TABLE:
613 free(n[6].data);
614 n += InstSize[n[0].opcode];
615 break;
616 case OPCODE_CONVOLUTION_FILTER_1D:
617 free(n[6].data);
618 n += InstSize[n[0].opcode];
619 break;
620 case OPCODE_CONVOLUTION_FILTER_2D:
621 free(n[7].data);
622 n += InstSize[n[0].opcode];
623 break;
624 case OPCODE_POLYGON_STIPPLE:
625 free(n[1].data);
626 n += InstSize[n[0].opcode];
627 break;
628 case OPCODE_TEX_IMAGE1D:
629 free(n[8].data);
630 n += InstSize[n[0].opcode];
631 break;
632 case OPCODE_TEX_IMAGE2D:
633 free(n[9].data);
634 n += InstSize[n[0].opcode];
635 break;
636 case OPCODE_TEX_IMAGE3D:
637 free(n[10].data);
638 n += InstSize[n[0].opcode];
639 break;
640 case OPCODE_TEX_SUB_IMAGE1D:
641 free(n[7].data);
642 n += InstSize[n[0].opcode];
643 break;
644 case OPCODE_TEX_SUB_IMAGE2D:
645 free(n[9].data);
646 n += InstSize[n[0].opcode];
647 break;
648 case OPCODE_TEX_SUB_IMAGE3D:
649 free(n[11].data);
650 n += InstSize[n[0].opcode];
651 break;
652 case OPCODE_COMPRESSED_TEX_IMAGE_1D:
653 free(n[7].data);
654 n += InstSize[n[0].opcode];
655 break;
656 case OPCODE_COMPRESSED_TEX_IMAGE_2D:
657 free(n[8].data);
658 n += InstSize[n[0].opcode];
659 break;
660 case OPCODE_COMPRESSED_TEX_IMAGE_3D:
661 free(n[9].data);
662 n += InstSize[n[0].opcode];
663 break;
664 case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D:
665 free(n[7].data);
666 n += InstSize[n[0].opcode];
667 break;
668 case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D:
669 free(n[9].data);
670 n += InstSize[n[0].opcode];
671 break;
672 case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D:
673 free(n[11].data);
674 n += InstSize[n[0].opcode];
675 break;
676 #if FEATURE_NV_vertex_program
677 case OPCODE_LOAD_PROGRAM_NV:
678 free(n[4].data); /* program string */
679 n += InstSize[n[0].opcode];
680 break;
681 case OPCODE_REQUEST_RESIDENT_PROGRAMS_NV:
682 free(n[2].data); /* array of program ids */
683 n += InstSize[n[0].opcode];
684 break;
685 #endif
686 #if FEATURE_NV_fragment_program
687 case OPCODE_PROGRAM_NAMED_PARAMETER_NV:
688 free(n[3].data); /* parameter name */
689 n += InstSize[n[0].opcode];
690 break;
691 #endif
692 #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
693 case OPCODE_PROGRAM_STRING_ARB:
694 free(n[4].data); /* program string */
695 n += InstSize[n[0].opcode];
696 break;
697 #endif
698 case OPCODE_UNIFORM_1FV:
699 case OPCODE_UNIFORM_2FV:
700 case OPCODE_UNIFORM_3FV:
701 case OPCODE_UNIFORM_4FV:
702 case OPCODE_UNIFORM_1IV:
703 case OPCODE_UNIFORM_2IV:
704 case OPCODE_UNIFORM_3IV:
705 case OPCODE_UNIFORM_4IV:
706 case OPCODE_UNIFORM_1UIV:
707 case OPCODE_UNIFORM_2UIV:
708 case OPCODE_UNIFORM_3UIV:
709 case OPCODE_UNIFORM_4UIV:
710 free(n[3].data);
711 n += InstSize[n[0].opcode];
712 break;
713 case OPCODE_UNIFORM_MATRIX22:
714 case OPCODE_UNIFORM_MATRIX33:
715 case OPCODE_UNIFORM_MATRIX44:
716 case OPCODE_UNIFORM_MATRIX24:
717 case OPCODE_UNIFORM_MATRIX42:
718 case OPCODE_UNIFORM_MATRIX23:
719 case OPCODE_UNIFORM_MATRIX32:
720 case OPCODE_UNIFORM_MATRIX34:
721 case OPCODE_UNIFORM_MATRIX43:
722 free(n[4].data);
723 n += InstSize[n[0].opcode];
724 break;
725
726 case OPCODE_CONTINUE:
727 n = (Node *) n[1].next;
728 free(block);
729 block = n;
730 break;
731 case OPCODE_END_OF_LIST:
732 free(block);
733 done = GL_TRUE;
734 break;
735 default:
736 /* Most frequent case */
737 n += InstSize[n[0].opcode];
738 break;
739 }
740 }
741 }
742
743 free(dlist);
744 }
745
746
747 /**
748 * Destroy a display list and remove from hash table.
749 * \param list - display list number
750 */
751 static void
752 destroy_list(struct gl_context *ctx, GLuint list)
753 {
754 struct gl_display_list *dlist;
755
756 if (list == 0)
757 return;
758
759 dlist = lookup_list(ctx, list);
760 if (!dlist)
761 return;
762
763 _mesa_delete_list(ctx, dlist);
764 _mesa_HashRemove(ctx->Shared->DisplayList, list);
765 }
766
767
768 /*
769 * Translate the nth element of list from <type> to GLint.
770 */
771 static GLint
772 translate_id(GLsizei n, GLenum type, const GLvoid * list)
773 {
774 GLbyte *bptr;
775 GLubyte *ubptr;
776 GLshort *sptr;
777 GLushort *usptr;
778 GLint *iptr;
779 GLuint *uiptr;
780 GLfloat *fptr;
781
782 switch (type) {
783 case GL_BYTE:
784 bptr = (GLbyte *) list;
785 return (GLint) bptr[n];
786 case GL_UNSIGNED_BYTE:
787 ubptr = (GLubyte *) list;
788 return (GLint) ubptr[n];
789 case GL_SHORT:
790 sptr = (GLshort *) list;
791 return (GLint) sptr[n];
792 case GL_UNSIGNED_SHORT:
793 usptr = (GLushort *) list;
794 return (GLint) usptr[n];
795 case GL_INT:
796 iptr = (GLint *) list;
797 return iptr[n];
798 case GL_UNSIGNED_INT:
799 uiptr = (GLuint *) list;
800 return (GLint) uiptr[n];
801 case GL_FLOAT:
802 fptr = (GLfloat *) list;
803 return (GLint) FLOORF(fptr[n]);
804 case GL_2_BYTES:
805 ubptr = ((GLubyte *) list) + 2 * n;
806 return (GLint) ubptr[0] * 256
807 + (GLint) ubptr[1];
808 case GL_3_BYTES:
809 ubptr = ((GLubyte *) list) + 3 * n;
810 return (GLint) ubptr[0] * 65536
811 + (GLint) ubptr[1] * 256
812 + (GLint) ubptr[2];
813 case GL_4_BYTES:
814 ubptr = ((GLubyte *) list) + 4 * n;
815 return (GLint) ubptr[0] * 16777216
816 + (GLint) ubptr[1] * 65536
817 + (GLint) ubptr[2] * 256
818 + (GLint) ubptr[3];
819 default:
820 return 0;
821 }
822 }
823
824
825
826
827 /**********************************************************************/
828 /***** Public *****/
829 /**********************************************************************/
830
831 /**
832 * Wrapper for _mesa_unpack_image/bitmap() that handles pixel buffer objects.
833 * If width < 0 or height < 0 or format or type are invalid we'll just
834 * return NULL. We will not generate an error since OpenGL command
835 * arguments aren't error-checked until the command is actually executed
836 * (not when they're compiled).
837 * But if we run out of memory, GL_OUT_OF_MEMORY will be recorded.
838 */
839 static GLvoid *
840 unpack_image(struct gl_context *ctx, GLuint dimensions,
841 GLsizei width, GLsizei height, GLsizei depth,
842 GLenum format, GLenum type, const GLvoid * pixels,
843 const struct gl_pixelstore_attrib *unpack)
844 {
845 if (width <= 0 || height <= 0) {
846 return NULL;
847 }
848
849 if (_mesa_bytes_per_pixel(format, type) < 0) {
850 /* bad format and/or type */
851 return NULL;
852 }
853
854 if (!_mesa_is_bufferobj(unpack->BufferObj)) {
855 /* no PBO */
856 GLvoid *image;
857
858 if (type == GL_BITMAP)
859 image = _mesa_unpack_bitmap(width, height, pixels, unpack);
860 else
861 image = _mesa_unpack_image(dimensions, width, height, depth,
862 format, type, pixels, unpack);
863 if (pixels && !image) {
864 _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
865 }
866 return image;
867 }
868 else if (_mesa_validate_pbo_access(dimensions, unpack, width, height,
869 depth, format, type, INT_MAX, pixels)) {
870 const GLubyte *map, *src;
871 GLvoid *image;
872
873 map = (GLubyte *)
874 ctx->Driver.MapBufferRange(ctx, 0, unpack->BufferObj->Size,
875 GL_MAP_READ_BIT, unpack->BufferObj);
876 if (!map) {
877 /* unable to map src buffer! */
878 _mesa_error(ctx, GL_INVALID_OPERATION, "unable to map PBO");
879 return NULL;
880 }
881
882 src = ADD_POINTERS(map, pixels);
883 if (type == GL_BITMAP)
884 image = _mesa_unpack_bitmap(width, height, src, unpack);
885 else
886 image = _mesa_unpack_image(dimensions, width, height, depth,
887 format, type, src, unpack);
888
889 ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj);
890
891 if (!image) {
892 _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
893 }
894 return image;
895 }
896
897 /* bad access! */
898 _mesa_error(ctx, GL_INVALID_OPERATION, "invalid PBO access");
899 return NULL;
900 }
901
902 /**
903 * Allocate space for a display list instruction (opcode + payload space).
904 * \param opcode the instruction opcode (OPCODE_* value)
905 * \param bytes instruction payload size (not counting opcode)
906 * \return pointer to allocated memory (the opcode space)
907 */
908 static Node *
909 dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes)
910 {
911 const GLuint numNodes = 1 + (bytes + sizeof(Node) - 1) / sizeof(Node);
912 Node *n;
913
914 if (opcode < (GLuint) OPCODE_EXT_0) {
915 if (InstSize[opcode] == 0) {
916 /* save instruction size now */
917 InstSize[opcode] = numNodes;
918 }
919 else {
920 /* make sure instruction size agrees */
921 ASSERT(numNodes == InstSize[opcode]);
922 }
923 }
924
925 if (ctx->ListState.CurrentPos + numNodes + 2 > BLOCK_SIZE) {
926 /* This block is full. Allocate a new block and chain to it */
927 Node *newblock;
928 n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos;
929 n[0].opcode = OPCODE_CONTINUE;
930 newblock = (Node *) malloc(sizeof(Node) * BLOCK_SIZE);
931 if (!newblock) {
932 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Building display list");
933 return NULL;
934 }
935 n[1].next = (Node *) newblock;
936 ctx->ListState.CurrentBlock = newblock;
937 ctx->ListState.CurrentPos = 0;
938 }
939
940 n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos;
941 ctx->ListState.CurrentPos += numNodes;
942
943 n[0].opcode = opcode;
944
945 return n;
946 }
947
948
949
950 /**
951 * Allocate space for a display list instruction. Used by callers outside
952 * this file for things like VBO vertex data.
953 *
954 * \param opcode the instruction opcode (OPCODE_* value)
955 * \param bytes instruction size in bytes, not counting opcode.
956 * \return pointer to the usable data area (not including the internal
957 * opcode).
958 */
959 void *
960 _mesa_dlist_alloc(struct gl_context *ctx, GLuint opcode, GLuint bytes)
961 {
962 Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes);
963 if (n)
964 return n + 1; /* return pointer to payload area, after opcode */
965 else
966 return NULL;
967 }
968
969
970 /**
971 * This function allows modules and drivers to get their own opcodes
972 * for extending display list functionality.
973 * \param ctx the rendering context
974 * \param size number of bytes for storing the new display list command
975 * \param execute function to execute the new display list command
976 * \param destroy function to destroy the new display list command
977 * \param print function to print the new display list command
978 * \return the new opcode number or -1 if error
979 */
980 GLint
981 _mesa_dlist_alloc_opcode(struct gl_context *ctx,
982 GLuint size,
983 void (*execute) (struct gl_context *, void *),
984 void (*destroy) (struct gl_context *, void *),
985 void (*print) (struct gl_context *, void *))
986 {
987 if (ctx->ListExt->NumOpcodes < MAX_DLIST_EXT_OPCODES) {
988 const GLuint i = ctx->ListExt->NumOpcodes++;
989 ctx->ListExt->Opcode[i].Size =
990 1 + (size + sizeof(Node) - 1) / sizeof(Node);
991 ctx->ListExt->Opcode[i].Execute = execute;
992 ctx->ListExt->Opcode[i].Destroy = destroy;
993 ctx->ListExt->Opcode[i].Print = print;
994 return i + OPCODE_EXT_0;
995 }
996 return -1;
997 }
998
999
1000 /**
1001 * Allocate space for a display list instruction. The space is basically
1002 * an array of Nodes where node[0] holds the opcode, node[1] is the first
1003 * function parameter, node[2] is the second parameter, etc.
1004 *
1005 * \param opcode one of OPCODE_x
1006 * \param nparams number of function parameters
1007 * \return pointer to start of instruction space
1008 */
1009 static inline Node *
1010 alloc_instruction(struct gl_context *ctx, OpCode opcode, GLuint nparams)
1011 {
1012 return dlist_alloc(ctx, opcode, nparams * sizeof(Node));
1013 }
1014
1015
1016
1017 /*
1018 * Display List compilation functions
1019 */
1020 static void GLAPIENTRY
1021 save_Accum(GLenum op, GLfloat value)
1022 {
1023 GET_CURRENT_CONTEXT(ctx);
1024 Node *n;
1025 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1026 n = alloc_instruction(ctx, OPCODE_ACCUM, 2);
1027 if (n) {
1028 n[1].e = op;
1029 n[2].f = value;
1030 }
1031 if (ctx->ExecuteFlag) {
1032 CALL_Accum(ctx->Exec, (op, value));
1033 }
1034 }
1035
1036
1037 static void GLAPIENTRY
1038 save_AlphaFunc(GLenum func, GLclampf ref)
1039 {
1040 GET_CURRENT_CONTEXT(ctx);
1041 Node *n;
1042 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1043 n = alloc_instruction(ctx, OPCODE_ALPHA_FUNC, 2);
1044 if (n) {
1045 n[1].e = func;
1046 n[2].f = (GLfloat) ref;
1047 }
1048 if (ctx->ExecuteFlag) {
1049 CALL_AlphaFunc(ctx->Exec, (func, ref));
1050 }
1051 }
1052
1053
1054 static void GLAPIENTRY
1055 save_BindTexture(GLenum target, GLuint texture)
1056 {
1057 GET_CURRENT_CONTEXT(ctx);
1058 Node *n;
1059 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1060 n = alloc_instruction(ctx, OPCODE_BIND_TEXTURE, 2);
1061 if (n) {
1062 n[1].e = target;
1063 n[2].ui = texture;
1064 }
1065 if (ctx->ExecuteFlag) {
1066 CALL_BindTexture(ctx->Exec, (target, texture));
1067 }
1068 }
1069
1070
1071 static void GLAPIENTRY
1072 save_Bitmap(GLsizei width, GLsizei height,
1073 GLfloat xorig, GLfloat yorig,
1074 GLfloat xmove, GLfloat ymove, const GLubyte * pixels)
1075 {
1076 GET_CURRENT_CONTEXT(ctx);
1077 Node *n;
1078 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1079 n = alloc_instruction(ctx, OPCODE_BITMAP, 7);
1080 if (n) {
1081 n[1].i = (GLint) width;
1082 n[2].i = (GLint) height;
1083 n[3].f = xorig;
1084 n[4].f = yorig;
1085 n[5].f = xmove;
1086 n[6].f = ymove;
1087 n[7].data = unpack_image(ctx, 2, width, height, 1, GL_COLOR_INDEX,
1088 GL_BITMAP, pixels, &ctx->Unpack);
1089 }
1090 if (ctx->ExecuteFlag) {
1091 CALL_Bitmap(ctx->Exec, (width, height,
1092 xorig, yorig, xmove, ymove, pixels));
1093 }
1094 }
1095
1096
1097 static void GLAPIENTRY
1098 save_BlendEquation(GLenum mode)
1099 {
1100 GET_CURRENT_CONTEXT(ctx);
1101 Node *n;
1102 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1103 n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION, 1);
1104 if (n) {
1105 n[1].e = mode;
1106 }
1107 if (ctx->ExecuteFlag) {
1108 CALL_BlendEquation(ctx->Exec, (mode));
1109 }
1110 }
1111
1112
1113 static void GLAPIENTRY
1114 save_BlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA)
1115 {
1116 GET_CURRENT_CONTEXT(ctx);
1117 Node *n;
1118 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1119 n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION_SEPARATE, 2);
1120 if (n) {
1121 n[1].e = modeRGB;
1122 n[2].e = modeA;
1123 }
1124 if (ctx->ExecuteFlag) {
1125 CALL_BlendEquationSeparateEXT(ctx->Exec, (modeRGB, modeA));
1126 }
1127 }
1128
1129
1130 static void GLAPIENTRY
1131 save_BlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB,
1132 GLenum sfactorA, GLenum dfactorA)
1133 {
1134 GET_CURRENT_CONTEXT(ctx);
1135 Node *n;
1136 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1137 n = alloc_instruction(ctx, OPCODE_BLEND_FUNC_SEPARATE, 4);
1138 if (n) {
1139 n[1].e = sfactorRGB;
1140 n[2].e = dfactorRGB;
1141 n[3].e = sfactorA;
1142 n[4].e = dfactorA;
1143 }
1144 if (ctx->ExecuteFlag) {
1145 CALL_BlendFuncSeparateEXT(ctx->Exec,
1146 (sfactorRGB, dfactorRGB, sfactorA, dfactorA));
1147 }
1148 }
1149
1150
1151 static void GLAPIENTRY
1152 save_BlendFunc(GLenum srcfactor, GLenum dstfactor)
1153 {
1154 save_BlendFuncSeparateEXT(srcfactor, dstfactor, srcfactor, dstfactor);
1155 }
1156
1157
1158 static void GLAPIENTRY
1159 save_BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
1160 {
1161 GET_CURRENT_CONTEXT(ctx);
1162 Node *n;
1163 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1164 n = alloc_instruction(ctx, OPCODE_BLEND_COLOR, 4);
1165 if (n) {
1166 n[1].f = red;
1167 n[2].f = green;
1168 n[3].f = blue;
1169 n[4].f = alpha;
1170 }
1171 if (ctx->ExecuteFlag) {
1172 CALL_BlendColor(ctx->Exec, (red, green, blue, alpha));
1173 }
1174 }
1175
1176 /* GL_ARB_draw_buffers_blend */
1177 static void GLAPIENTRY
1178 save_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB,
1179 GLenum sfactorA, GLenum dfactorA)
1180 {
1181 GET_CURRENT_CONTEXT(ctx);
1182 Node *n;
1183 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1184 n = alloc_instruction(ctx, OPCODE_BLEND_FUNC_SEPARATE_I, 5);
1185 if (n) {
1186 n[1].ui = buf;
1187 n[2].e = sfactorRGB;
1188 n[3].e = dfactorRGB;
1189 n[4].e = sfactorA;
1190 n[5].e = dfactorA;
1191 }
1192 if (ctx->ExecuteFlag) {
1193 CALL_BlendFuncSeparateiARB(ctx->Exec, (buf, sfactorRGB, dfactorRGB,
1194 sfactorA, dfactorA));
1195 }
1196 }
1197
1198 /* GL_ARB_draw_buffers_blend */
1199 static void GLAPIENTRY
1200 save_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor)
1201 {
1202 GET_CURRENT_CONTEXT(ctx);
1203 Node *n;
1204 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1205 n = alloc_instruction(ctx, OPCODE_BLEND_FUNC_SEPARATE_I, 3);
1206 if (n) {
1207 n[1].ui = buf;
1208 n[2].e = sfactor;
1209 n[3].e = dfactor;
1210 }
1211 if (ctx->ExecuteFlag) {
1212 CALL_BlendFunciARB(ctx->Exec, (buf, sfactor, dfactor));
1213 }
1214 }
1215
1216 /* GL_ARB_draw_buffers_blend */
1217 static void GLAPIENTRY
1218 save_BlendEquationi(GLuint buf, GLenum mode)
1219 {
1220 GET_CURRENT_CONTEXT(ctx);
1221 Node *n;
1222 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1223 n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION_I, 2);
1224 if (n) {
1225 n[1].ui = buf;
1226 n[2].e = mode;
1227 }
1228 if (ctx->ExecuteFlag) {
1229 CALL_BlendEquationiARB(ctx->Exec, (buf, mode));
1230 }
1231 }
1232
1233 /* GL_ARB_draw_buffers_blend */
1234 static void GLAPIENTRY
1235 save_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA)
1236 {
1237 GET_CURRENT_CONTEXT(ctx);
1238 Node *n;
1239 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1240 n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION_SEPARATE_I, 3);
1241 if (n) {
1242 n[1].ui = buf;
1243 n[2].e = modeRGB;
1244 n[3].e = modeA;
1245 }
1246 if (ctx->ExecuteFlag) {
1247 CALL_BlendEquationSeparateiARB(ctx->Exec, (buf, modeRGB, modeA));
1248 }
1249 }
1250
1251
1252 /* GL_ARB_draw_instanced. */
1253 static void GLAPIENTRY
1254 save_DrawArraysInstancedARB(GLenum mode,
1255 GLint first,
1256 GLsizei count,
1257 GLsizei primcount)
1258 {
1259 GET_CURRENT_CONTEXT(ctx);
1260 _mesa_error(ctx, GL_INVALID_OPERATION,
1261 "glDrawArraysInstanced() during display list compile");
1262 }
1263
1264 static void GLAPIENTRY
1265 save_DrawElementsInstancedARB(GLenum mode,
1266 GLsizei count,
1267 GLenum type,
1268 const GLvoid *indices,
1269 GLsizei primcount)
1270 {
1271 GET_CURRENT_CONTEXT(ctx);
1272 _mesa_error(ctx, GL_INVALID_OPERATION,
1273 "glDrawElementsInstanced() during display list compile");
1274 }
1275
1276 static void GLAPIENTRY
1277 save_DrawElementsInstancedBaseVertexARB(GLenum mode,
1278 GLsizei count,
1279 GLenum type,
1280 const GLvoid *indices,
1281 GLsizei primcount,
1282 GLint basevertex)
1283 {
1284 GET_CURRENT_CONTEXT(ctx);
1285 _mesa_error(ctx, GL_INVALID_OPERATION,
1286 "glDrawElementsInstancedBaseVertex() during display list compile");
1287 }
1288
1289 static void invalidate_saved_current_state( struct gl_context *ctx )
1290 {
1291 GLint i;
1292
1293 for (i = 0; i < VERT_ATTRIB_MAX; i++)
1294 ctx->ListState.ActiveAttribSize[i] = 0;
1295
1296 for (i = 0; i < MAT_ATTRIB_MAX; i++)
1297 ctx->ListState.ActiveMaterialSize[i] = 0;
1298
1299 memset(&ctx->ListState.Current, 0, sizeof ctx->ListState.Current);
1300
1301 ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
1302 }
1303
1304 static void GLAPIENTRY
1305 save_CallList(GLuint list)
1306 {
1307 GET_CURRENT_CONTEXT(ctx);
1308 Node *n;
1309 SAVE_FLUSH_VERTICES(ctx);
1310
1311 n = alloc_instruction(ctx, OPCODE_CALL_LIST, 1);
1312 if (n) {
1313 n[1].ui = list;
1314 }
1315
1316 /* After this, we don't know what state we're in. Invalidate all
1317 * cached information previously gathered:
1318 */
1319 invalidate_saved_current_state( ctx );
1320
1321 if (ctx->ExecuteFlag) {
1322 _mesa_CallList(list);
1323 }
1324 }
1325
1326
1327 static void GLAPIENTRY
1328 save_CallLists(GLsizei num, GLenum type, const GLvoid * lists)
1329 {
1330 GET_CURRENT_CONTEXT(ctx);
1331 GLint i;
1332 GLboolean typeErrorFlag;
1333
1334 SAVE_FLUSH_VERTICES(ctx);
1335
1336 switch (type) {
1337 case GL_BYTE:
1338 case GL_UNSIGNED_BYTE:
1339 case GL_SHORT:
1340 case GL_UNSIGNED_SHORT:
1341 case GL_INT:
1342 case GL_UNSIGNED_INT:
1343 case GL_FLOAT:
1344 case GL_2_BYTES:
1345 case GL_3_BYTES:
1346 case GL_4_BYTES:
1347 typeErrorFlag = GL_FALSE;
1348 break;
1349 default:
1350 typeErrorFlag = GL_TRUE;
1351 }
1352
1353 for (i = 0; i < num; i++) {
1354 GLint list = translate_id(i, type, lists);
1355 Node *n = alloc_instruction(ctx, OPCODE_CALL_LIST_OFFSET, 2);
1356 if (n) {
1357 n[1].i = list;
1358 n[2].b = typeErrorFlag;
1359 }
1360 }
1361
1362 /* After this, we don't know what state we're in. Invalidate all
1363 * cached information previously gathered:
1364 */
1365 invalidate_saved_current_state( ctx );
1366
1367 if (ctx->ExecuteFlag) {
1368 CALL_CallLists(ctx->Exec, (num, type, lists));
1369 }
1370 }
1371
1372
1373 static void GLAPIENTRY
1374 save_Clear(GLbitfield mask)
1375 {
1376 GET_CURRENT_CONTEXT(ctx);
1377 Node *n;
1378 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1379 n = alloc_instruction(ctx, OPCODE_CLEAR, 1);
1380 if (n) {
1381 n[1].bf = mask;
1382 }
1383 if (ctx->ExecuteFlag) {
1384 CALL_Clear(ctx->Exec, (mask));
1385 }
1386 }
1387
1388
1389 static void GLAPIENTRY
1390 save_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
1391 {
1392 GET_CURRENT_CONTEXT(ctx);
1393 Node *n;
1394 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1395 n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_IV, 6);
1396 if (n) {
1397 n[1].e = buffer;
1398 n[2].i = drawbuffer;
1399 n[3].i = value[0];
1400 if (buffer == GL_COLOR) {
1401 n[4].i = value[1];
1402 n[5].i = value[2];
1403 n[6].i = value[3];
1404 }
1405 else {
1406 n[4].i = 0;
1407 n[5].i = 0;
1408 n[6].i = 0;
1409 }
1410 }
1411 if (ctx->ExecuteFlag) {
1412 CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value));
1413 }
1414 }
1415
1416
1417 static void GLAPIENTRY
1418 save_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
1419 {
1420 GET_CURRENT_CONTEXT(ctx);
1421 Node *n;
1422 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1423 n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_UIV, 6);
1424 if (n) {
1425 n[1].e = buffer;
1426 n[2].i = drawbuffer;
1427 n[3].ui = value[0];
1428 if (buffer == GL_COLOR) {
1429 n[4].ui = value[1];
1430 n[5].ui = value[2];
1431 n[6].ui = value[3];
1432 }
1433 else {
1434 n[4].ui = 0;
1435 n[5].ui = 0;
1436 n[6].ui = 0;
1437 }
1438 }
1439 if (ctx->ExecuteFlag) {
1440 CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));
1441 }
1442 }
1443
1444
1445 static void GLAPIENTRY
1446 save_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
1447 {
1448 GET_CURRENT_CONTEXT(ctx);
1449 Node *n;
1450 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1451 n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_FV, 6);
1452 if (n) {
1453 n[1].e = buffer;
1454 n[2].i = drawbuffer;
1455 n[3].f = value[0];
1456 if (buffer == GL_COLOR) {
1457 n[4].f = value[1];
1458 n[5].f = value[2];
1459 n[6].f = value[3];
1460 }
1461 else {
1462 n[4].f = 0.0F;
1463 n[5].f = 0.0F;
1464 n[6].f = 0.0F;
1465 }
1466 }
1467 if (ctx->ExecuteFlag) {
1468 CALL_ClearBufferfv(ctx->Exec, (buffer, drawbuffer, value));
1469 }
1470 }
1471
1472
1473 static void GLAPIENTRY
1474 save_ClearBufferfi(GLenum buffer, GLint drawbuffer,
1475 GLfloat depth, GLint stencil)
1476 {
1477 GET_CURRENT_CONTEXT(ctx);
1478 Node *n;
1479 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1480 n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_FI, 4);
1481 if (n) {
1482 n[1].e = buffer;
1483 n[2].i = drawbuffer;
1484 n[3].f = depth;
1485 n[4].i = stencil;
1486 }
1487 if (ctx->ExecuteFlag) {
1488 CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil));
1489 }
1490 }
1491
1492
1493 static void GLAPIENTRY
1494 save_ClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
1495 {
1496 GET_CURRENT_CONTEXT(ctx);
1497 Node *n;
1498 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1499 n = alloc_instruction(ctx, OPCODE_CLEAR_ACCUM, 4);
1500 if (n) {
1501 n[1].f = red;
1502 n[2].f = green;
1503 n[3].f = blue;
1504 n[4].f = alpha;
1505 }
1506 if (ctx->ExecuteFlag) {
1507 CALL_ClearAccum(ctx->Exec, (red, green, blue, alpha));
1508 }
1509 }
1510
1511
1512 static void GLAPIENTRY
1513 save_ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
1514 {
1515 GET_CURRENT_CONTEXT(ctx);
1516 Node *n;
1517 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1518 n = alloc_instruction(ctx, OPCODE_CLEAR_COLOR, 4);
1519 if (n) {
1520 n[1].f = red;
1521 n[2].f = green;
1522 n[3].f = blue;
1523 n[4].f = alpha;
1524 }
1525 if (ctx->ExecuteFlag) {
1526 CALL_ClearColor(ctx->Exec, (red, green, blue, alpha));
1527 }
1528 }
1529
1530
1531 static void GLAPIENTRY
1532 save_ClearDepth(GLclampd depth)
1533 {
1534 GET_CURRENT_CONTEXT(ctx);
1535 Node *n;
1536 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1537 n = alloc_instruction(ctx, OPCODE_CLEAR_DEPTH, 1);
1538 if (n) {
1539 n[1].f = (GLfloat) depth;
1540 }
1541 if (ctx->ExecuteFlag) {
1542 CALL_ClearDepth(ctx->Exec, (depth));
1543 }
1544 }
1545
1546
1547 static void GLAPIENTRY
1548 save_ClearIndex(GLfloat c)
1549 {
1550 GET_CURRENT_CONTEXT(ctx);
1551 Node *n;
1552 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1553 n = alloc_instruction(ctx, OPCODE_CLEAR_INDEX, 1);
1554 if (n) {
1555 n[1].f = c;
1556 }
1557 if (ctx->ExecuteFlag) {
1558 CALL_ClearIndex(ctx->Exec, (c));
1559 }
1560 }
1561
1562
1563 static void GLAPIENTRY
1564 save_ClearStencil(GLint s)
1565 {
1566 GET_CURRENT_CONTEXT(ctx);
1567 Node *n;
1568 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1569 n = alloc_instruction(ctx, OPCODE_CLEAR_STENCIL, 1);
1570 if (n) {
1571 n[1].i = s;
1572 }
1573 if (ctx->ExecuteFlag) {
1574 CALL_ClearStencil(ctx->Exec, (s));
1575 }
1576 }
1577
1578
1579 static void GLAPIENTRY
1580 save_ClipPlane(GLenum plane, const GLdouble * equ)
1581 {
1582 GET_CURRENT_CONTEXT(ctx);
1583 Node *n;
1584 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1585 n = alloc_instruction(ctx, OPCODE_CLIP_PLANE, 5);
1586 if (n) {
1587 n[1].e = plane;
1588 n[2].f = (GLfloat) equ[0];
1589 n[3].f = (GLfloat) equ[1];
1590 n[4].f = (GLfloat) equ[2];
1591 n[5].f = (GLfloat) equ[3];
1592 }
1593 if (ctx->ExecuteFlag) {
1594 CALL_ClipPlane(ctx->Exec, (plane, equ));
1595 }
1596 }
1597
1598
1599
1600 static void GLAPIENTRY
1601 save_ColorMask(GLboolean red, GLboolean green,
1602 GLboolean blue, GLboolean alpha)
1603 {
1604 GET_CURRENT_CONTEXT(ctx);
1605 Node *n;
1606 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1607 n = alloc_instruction(ctx, OPCODE_COLOR_MASK, 4);
1608 if (n) {
1609 n[1].b = red;
1610 n[2].b = green;
1611 n[3].b = blue;
1612 n[4].b = alpha;
1613 }
1614 if (ctx->ExecuteFlag) {
1615 CALL_ColorMask(ctx->Exec, (red, green, blue, alpha));
1616 }
1617 }
1618
1619
1620 static void GLAPIENTRY
1621 save_ColorMaterial(GLenum face, GLenum mode)
1622 {
1623 GET_CURRENT_CONTEXT(ctx);
1624 Node *n;
1625 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1626
1627 n = alloc_instruction(ctx, OPCODE_COLOR_MATERIAL, 2);
1628 if (n) {
1629 n[1].e = face;
1630 n[2].e = mode;
1631 }
1632 if (ctx->ExecuteFlag) {
1633 CALL_ColorMaterial(ctx->Exec, (face, mode));
1634 }
1635 }
1636
1637
1638 static void GLAPIENTRY
1639 save_ColorTable(GLenum target, GLenum internalFormat,
1640 GLsizei width, GLenum format, GLenum type,
1641 const GLvoid * table)
1642 {
1643 GET_CURRENT_CONTEXT(ctx);
1644 if (_mesa_is_proxy_texture(target)) {
1645 /* execute immediately */
1646 CALL_ColorTable(ctx->Exec, (target, internalFormat, width,
1647 format, type, table));
1648 }
1649 else {
1650 Node *n;
1651 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1652 n = alloc_instruction(ctx, OPCODE_COLOR_TABLE, 6);
1653 if (n) {
1654 n[1].e = target;
1655 n[2].e = internalFormat;
1656 n[3].i = width;
1657 n[4].e = format;
1658 n[5].e = type;
1659 n[6].data = unpack_image(ctx, 1, width, 1, 1, format, type, table,
1660 &ctx->Unpack);
1661 }
1662 if (ctx->ExecuteFlag) {
1663 CALL_ColorTable(ctx->Exec, (target, internalFormat, width,
1664 format, type, table));
1665 }
1666 }
1667 }
1668
1669
1670
1671 static void GLAPIENTRY
1672 save_ColorTableParameterfv(GLenum target, GLenum pname,
1673 const GLfloat *params)
1674 {
1675 GET_CURRENT_CONTEXT(ctx);
1676 Node *n;
1677
1678 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1679
1680 n = alloc_instruction(ctx, OPCODE_COLOR_TABLE_PARAMETER_FV, 6);
1681 if (n) {
1682 n[1].e = target;
1683 n[2].e = pname;
1684 n[3].f = params[0];
1685 if (pname == GL_COLOR_TABLE_SGI ||
1686 pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI ||
1687 pname == GL_TEXTURE_COLOR_TABLE_SGI) {
1688 n[4].f = params[1];
1689 n[5].f = params[2];
1690 n[6].f = params[3];
1691 }
1692 }
1693
1694 if (ctx->ExecuteFlag) {
1695 CALL_ColorTableParameterfv(ctx->Exec, (target, pname, params));
1696 }
1697 }
1698
1699
1700 static void GLAPIENTRY
1701 save_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params)
1702 {
1703 GET_CURRENT_CONTEXT(ctx);
1704 Node *n;
1705
1706 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1707
1708 n = alloc_instruction(ctx, OPCODE_COLOR_TABLE_PARAMETER_IV, 6);
1709 if (n) {
1710 n[1].e = target;
1711 n[2].e = pname;
1712 n[3].i = params[0];
1713 if (pname == GL_COLOR_TABLE_SGI ||
1714 pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI ||
1715 pname == GL_TEXTURE_COLOR_TABLE_SGI) {
1716 n[4].i = params[1];
1717 n[5].i = params[2];
1718 n[6].i = params[3];
1719 }
1720 }
1721
1722 if (ctx->ExecuteFlag) {
1723 CALL_ColorTableParameteriv(ctx->Exec, (target, pname, params));
1724 }
1725 }
1726
1727
1728
1729 static void GLAPIENTRY
1730 save_ColorSubTable(GLenum target, GLsizei start, GLsizei count,
1731 GLenum format, GLenum type, const GLvoid * table)
1732 {
1733 GET_CURRENT_CONTEXT(ctx);
1734 Node *n;
1735 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1736 n = alloc_instruction(ctx, OPCODE_COLOR_SUB_TABLE, 6);
1737 if (n) {
1738 n[1].e = target;
1739 n[2].i = start;
1740 n[3].i = count;
1741 n[4].e = format;
1742 n[5].e = type;
1743 n[6].data = unpack_image(ctx, 1, count, 1, 1, format, type, table,
1744 &ctx->Unpack);
1745 }
1746 if (ctx->ExecuteFlag) {
1747 CALL_ColorSubTable(ctx->Exec,
1748 (target, start, count, format, type, table));
1749 }
1750 }
1751
1752
1753 static void GLAPIENTRY
1754 save_CopyColorSubTable(GLenum target, GLsizei start,
1755 GLint x, GLint y, GLsizei width)
1756 {
1757 GET_CURRENT_CONTEXT(ctx);
1758 Node *n;
1759
1760 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1761 n = alloc_instruction(ctx, OPCODE_COPY_COLOR_SUB_TABLE, 5);
1762 if (n) {
1763 n[1].e = target;
1764 n[2].i = start;
1765 n[3].i = x;
1766 n[4].i = y;
1767 n[5].i = width;
1768 }
1769 if (ctx->ExecuteFlag) {
1770 CALL_CopyColorSubTable(ctx->Exec, (target, start, x, y, width));
1771 }
1772 }
1773
1774
1775 static void GLAPIENTRY
1776 save_CopyColorTable(GLenum target, GLenum internalformat,
1777 GLint x, GLint y, GLsizei width)
1778 {
1779 GET_CURRENT_CONTEXT(ctx);
1780 Node *n;
1781
1782 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1783 n = alloc_instruction(ctx, OPCODE_COPY_COLOR_TABLE, 5);
1784 if (n) {
1785 n[1].e = target;
1786 n[2].e = internalformat;
1787 n[3].i = x;
1788 n[4].i = y;
1789 n[5].i = width;
1790 }
1791 if (ctx->ExecuteFlag) {
1792 CALL_CopyColorTable(ctx->Exec, (target, internalformat, x, y, width));
1793 }
1794 }
1795
1796
1797 static void GLAPIENTRY
1798 save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width,
1799 GLenum format, GLenum type, const GLvoid * filter)
1800 {
1801 GET_CURRENT_CONTEXT(ctx);
1802 Node *n;
1803
1804 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1805
1806 n = alloc_instruction(ctx, OPCODE_CONVOLUTION_FILTER_1D, 6);
1807 if (n) {
1808 n[1].e = target;
1809 n[2].e = internalFormat;
1810 n[3].i = width;
1811 n[4].e = format;
1812 n[5].e = type;
1813 n[6].data = unpack_image(ctx, 1, width, 1, 1, format, type, filter,
1814 &ctx->Unpack);
1815 }
1816 if (ctx->ExecuteFlag) {
1817 CALL_ConvolutionFilter1D(ctx->Exec, (target, internalFormat, width,
1818 format, type, filter));
1819 }
1820 }
1821
1822
1823 static void GLAPIENTRY
1824 save_ConvolutionFilter2D(GLenum target, GLenum internalFormat,
1825 GLsizei width, GLsizei height, GLenum format,
1826 GLenum type, const GLvoid * filter)
1827 {
1828 GET_CURRENT_CONTEXT(ctx);
1829 Node *n;
1830
1831 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1832
1833 n = alloc_instruction(ctx, OPCODE_CONVOLUTION_FILTER_2D, 7);
1834 if (n) {
1835 n[1].e = target;
1836 n[2].e = internalFormat;
1837 n[3].i = width;
1838 n[4].i = height;
1839 n[5].e = format;
1840 n[6].e = type;
1841 n[7].data = unpack_image(ctx, 2, width, height, 1, format, type, filter,
1842 &ctx->Unpack);
1843 }
1844 if (ctx->ExecuteFlag) {
1845 CALL_ConvolutionFilter2D(ctx->Exec,
1846 (target, internalFormat, width, height, format,
1847 type, filter));
1848 }
1849 }
1850
1851
1852 static void GLAPIENTRY
1853 save_ConvolutionParameteri(GLenum target, GLenum pname, GLint param)
1854 {
1855 GET_CURRENT_CONTEXT(ctx);
1856 Node *n;
1857 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1858 n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_I, 3);
1859 if (n) {
1860 n[1].e = target;
1861 n[2].e = pname;
1862 n[3].i = param;
1863 }
1864 if (ctx->ExecuteFlag) {
1865 CALL_ConvolutionParameteri(ctx->Exec, (target, pname, param));
1866 }
1867 }
1868
1869
1870 static void GLAPIENTRY
1871 save_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params)
1872 {
1873 GET_CURRENT_CONTEXT(ctx);
1874 Node *n;
1875 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1876 n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_IV, 6);
1877 if (n) {
1878 n[1].e = target;
1879 n[2].e = pname;
1880 n[3].i = params[0];
1881 if (pname == GL_CONVOLUTION_BORDER_COLOR ||
1882 pname == GL_CONVOLUTION_FILTER_SCALE ||
1883 pname == GL_CONVOLUTION_FILTER_BIAS) {
1884 n[4].i = params[1];
1885 n[5].i = params[2];
1886 n[6].i = params[3];
1887 }
1888 else {
1889 n[4].i = n[5].i = n[6].i = 0;
1890 }
1891 }
1892 if (ctx->ExecuteFlag) {
1893 CALL_ConvolutionParameteriv(ctx->Exec, (target, pname, params));
1894 }
1895 }
1896
1897
1898 static void GLAPIENTRY
1899 save_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param)
1900 {
1901 GET_CURRENT_CONTEXT(ctx);
1902 Node *n;
1903 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1904 n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_F, 3);
1905 if (n) {
1906 n[1].e = target;
1907 n[2].e = pname;
1908 n[3].f = param;
1909 }
1910 if (ctx->ExecuteFlag) {
1911 CALL_ConvolutionParameterf(ctx->Exec, (target, pname, param));
1912 }
1913 }
1914
1915
1916 static void GLAPIENTRY
1917 save_ConvolutionParameterfv(GLenum target, GLenum pname,
1918 const GLfloat *params)
1919 {
1920 GET_CURRENT_CONTEXT(ctx);
1921 Node *n;
1922 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1923 n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_FV, 6);
1924 if (n) {
1925 n[1].e = target;
1926 n[2].e = pname;
1927 n[3].f = params[0];
1928 if (pname == GL_CONVOLUTION_BORDER_COLOR ||
1929 pname == GL_CONVOLUTION_FILTER_SCALE ||
1930 pname == GL_CONVOLUTION_FILTER_BIAS) {
1931 n[4].f = params[1];
1932 n[5].f = params[2];
1933 n[6].f = params[3];
1934 }
1935 else {
1936 n[4].f = n[5].f = n[6].f = 0.0F;
1937 }
1938 }
1939 if (ctx->ExecuteFlag) {
1940 CALL_ConvolutionParameterfv(ctx->Exec, (target, pname, params));
1941 }
1942 }
1943
1944
1945 static void GLAPIENTRY
1946 save_CopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
1947 {
1948 GET_CURRENT_CONTEXT(ctx);
1949 Node *n;
1950 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1951 n = alloc_instruction(ctx, OPCODE_COPY_PIXELS, 5);
1952 if (n) {
1953 n[1].i = x;
1954 n[2].i = y;
1955 n[3].i = (GLint) width;
1956 n[4].i = (GLint) height;
1957 n[5].e = type;
1958 }
1959 if (ctx->ExecuteFlag) {
1960 CALL_CopyPixels(ctx->Exec, (x, y, width, height, type));
1961 }
1962 }
1963
1964
1965
1966 static void GLAPIENTRY
1967 save_CopyTexImage1D(GLenum target, GLint level, GLenum internalformat,
1968 GLint x, GLint y, GLsizei width, GLint border)
1969 {
1970 GET_CURRENT_CONTEXT(ctx);
1971 Node *n;
1972 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1973 n = alloc_instruction(ctx, OPCODE_COPY_TEX_IMAGE1D, 7);
1974 if (n) {
1975 n[1].e = target;
1976 n[2].i = level;
1977 n[3].e = internalformat;
1978 n[4].i = x;
1979 n[5].i = y;
1980 n[6].i = width;
1981 n[7].i = border;
1982 }
1983 if (ctx->ExecuteFlag) {
1984 CALL_CopyTexImage1D(ctx->Exec, (target, level, internalformat,
1985 x, y, width, border));
1986 }
1987 }
1988
1989
1990 static void GLAPIENTRY
1991 save_CopyTexImage2D(GLenum target, GLint level,
1992 GLenum internalformat,
1993 GLint x, GLint y, GLsizei width,
1994 GLsizei height, GLint border)
1995 {
1996 GET_CURRENT_CONTEXT(ctx);
1997 Node *n;
1998 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
1999 n = alloc_instruction(ctx, OPCODE_COPY_TEX_IMAGE2D, 8);
2000 if (n) {
2001 n[1].e = target;
2002 n[2].i = level;
2003 n[3].e = internalformat;
2004 n[4].i = x;
2005 n[5].i = y;
2006 n[6].i = width;
2007 n[7].i = height;
2008 n[8].i = border;
2009 }
2010 if (ctx->ExecuteFlag) {
2011 CALL_CopyTexImage2D(ctx->Exec, (target, level, internalformat,
2012 x, y, width, height, border));
2013 }
2014 }
2015
2016
2017
2018 static void GLAPIENTRY
2019 save_CopyTexSubImage1D(GLenum target, GLint level,
2020 GLint xoffset, GLint x, GLint y, GLsizei width)
2021 {
2022 GET_CURRENT_CONTEXT(ctx);
2023 Node *n;
2024 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2025 n = alloc_instruction(ctx, OPCODE_COPY_TEX_SUB_IMAGE1D, 6);
2026 if (n) {
2027 n[1].e = target;
2028 n[2].i = level;
2029 n[3].i = xoffset;
2030 n[4].i = x;
2031 n[5].i = y;
2032 n[6].i = width;
2033 }
2034 if (ctx->ExecuteFlag) {
2035 CALL_CopyTexSubImage1D(ctx->Exec,
2036 (target, level, xoffset, x, y, width));
2037 }
2038 }
2039
2040
2041 static void GLAPIENTRY
2042 save_CopyTexSubImage2D(GLenum target, GLint level,
2043 GLint xoffset, GLint yoffset,
2044 GLint x, GLint y, GLsizei width, GLint height)
2045 {
2046 GET_CURRENT_CONTEXT(ctx);
2047 Node *n;
2048 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2049 n = alloc_instruction(ctx, OPCODE_COPY_TEX_SUB_IMAGE2D, 8);
2050 if (n) {
2051 n[1].e = target;
2052 n[2].i = level;
2053 n[3].i = xoffset;
2054 n[4].i = yoffset;
2055 n[5].i = x;
2056 n[6].i = y;
2057 n[7].i = width;
2058 n[8].i = height;
2059 }
2060 if (ctx->ExecuteFlag) {
2061 CALL_CopyTexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset,
2062 x, y, width, height));
2063 }
2064 }
2065
2066
2067 static void GLAPIENTRY
2068 save_CopyTexSubImage3D(GLenum target, GLint level,
2069 GLint xoffset, GLint yoffset, GLint zoffset,
2070 GLint x, GLint y, GLsizei width, GLint height)
2071 {
2072 GET_CURRENT_CONTEXT(ctx);
2073 Node *n;
2074 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2075 n = alloc_instruction(ctx, OPCODE_COPY_TEX_SUB_IMAGE3D, 9);
2076 if (n) {
2077 n[1].e = target;
2078 n[2].i = level;
2079 n[3].i = xoffset;
2080 n[4].i = yoffset;
2081 n[5].i = zoffset;
2082 n[6].i = x;
2083 n[7].i = y;
2084 n[8].i = width;
2085 n[9].i = height;
2086 }
2087 if (ctx->ExecuteFlag) {
2088 CALL_CopyTexSubImage3D(ctx->Exec, (target, level,
2089 xoffset, yoffset, zoffset,
2090 x, y, width, height));
2091 }
2092 }
2093
2094
2095 static void GLAPIENTRY
2096 save_CullFace(GLenum mode)
2097 {
2098 GET_CURRENT_CONTEXT(ctx);
2099 Node *n;
2100 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2101 n = alloc_instruction(ctx, OPCODE_CULL_FACE, 1);
2102 if (n) {
2103 n[1].e = mode;
2104 }
2105 if (ctx->ExecuteFlag) {
2106 CALL_CullFace(ctx->Exec, (mode));
2107 }
2108 }
2109
2110
2111 static void GLAPIENTRY
2112 save_DepthFunc(GLenum func)
2113 {
2114 GET_CURRENT_CONTEXT(ctx);
2115 Node *n;
2116 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2117 n = alloc_instruction(ctx, OPCODE_DEPTH_FUNC, 1);
2118 if (n) {
2119 n[1].e = func;
2120 }
2121 if (ctx->ExecuteFlag) {
2122 CALL_DepthFunc(ctx->Exec, (func));
2123 }
2124 }
2125
2126
2127 static void GLAPIENTRY
2128 save_DepthMask(GLboolean mask)
2129 {
2130 GET_CURRENT_CONTEXT(ctx);
2131 Node *n;
2132 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2133 n = alloc_instruction(ctx, OPCODE_DEPTH_MASK, 1);
2134 if (n) {
2135 n[1].b = mask;
2136 }
2137 if (ctx->ExecuteFlag) {
2138 CALL_DepthMask(ctx->Exec, (mask));
2139 }
2140 }
2141
2142
2143 static void GLAPIENTRY
2144 save_DepthRange(GLclampd nearval, GLclampd farval)
2145 {
2146 GET_CURRENT_CONTEXT(ctx);
2147 Node *n;
2148 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2149 n = alloc_instruction(ctx, OPCODE_DEPTH_RANGE, 2);
2150 if (n) {
2151 n[1].f = (GLfloat) nearval;
2152 n[2].f = (GLfloat) farval;
2153 }
2154 if (ctx->ExecuteFlag) {
2155 CALL_DepthRange(ctx->Exec, (nearval, farval));
2156 }
2157 }
2158
2159
2160 static void GLAPIENTRY
2161 save_Disable(GLenum cap)
2162 {
2163 GET_CURRENT_CONTEXT(ctx);
2164 Node *n;
2165 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2166 n = alloc_instruction(ctx, OPCODE_DISABLE, 1);
2167 if (n) {
2168 n[1].e = cap;
2169 }
2170 if (ctx->ExecuteFlag) {
2171 CALL_Disable(ctx->Exec, (cap));
2172 }
2173 }
2174
2175
2176 static void GLAPIENTRY
2177 save_DrawBuffer(GLenum mode)
2178 {
2179 GET_CURRENT_CONTEXT(ctx);
2180 Node *n;
2181 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2182 n = alloc_instruction(ctx, OPCODE_DRAW_BUFFER, 1);
2183 if (n) {
2184 n[1].e = mode;
2185 }
2186 if (ctx->ExecuteFlag) {
2187 CALL_DrawBuffer(ctx->Exec, (mode));
2188 }
2189 }
2190
2191
2192 static void GLAPIENTRY
2193 save_DrawPixels(GLsizei width, GLsizei height,
2194 GLenum format, GLenum type, const GLvoid * pixels)
2195 {
2196 GET_CURRENT_CONTEXT(ctx);
2197 Node *n;
2198
2199 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2200
2201 n = alloc_instruction(ctx, OPCODE_DRAW_PIXELS, 5);
2202 if (n) {
2203 n[1].i = width;
2204 n[2].i = height;
2205 n[3].e = format;
2206 n[4].e = type;
2207 n[5].data = unpack_image(ctx, 2, width, height, 1, format, type,
2208 pixels, &ctx->Unpack);
2209 }
2210 if (ctx->ExecuteFlag) {
2211 CALL_DrawPixels(ctx->Exec, (width, height, format, type, pixels));
2212 }
2213 }
2214
2215
2216
2217 static void GLAPIENTRY
2218 save_Enable(GLenum cap)
2219 {
2220 GET_CURRENT_CONTEXT(ctx);
2221 Node *n;
2222 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2223 n = alloc_instruction(ctx, OPCODE_ENABLE, 1);
2224 if (n) {
2225 n[1].e = cap;
2226 }
2227 if (ctx->ExecuteFlag) {
2228 CALL_Enable(ctx->Exec, (cap));
2229 }
2230 }
2231
2232
2233
2234 static void GLAPIENTRY
2235 save_EvalMesh1(GLenum mode, GLint i1, GLint i2)
2236 {
2237 GET_CURRENT_CONTEXT(ctx);
2238 Node *n;
2239 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2240 n = alloc_instruction(ctx, OPCODE_EVALMESH1, 3);
2241 if (n) {
2242 n[1].e = mode;
2243 n[2].i = i1;
2244 n[3].i = i2;
2245 }
2246 if (ctx->ExecuteFlag) {
2247 CALL_EvalMesh1(ctx->Exec, (mode, i1, i2));
2248 }
2249 }
2250
2251
2252 static void GLAPIENTRY
2253 save_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
2254 {
2255 GET_CURRENT_CONTEXT(ctx);
2256 Node *n;
2257 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2258 n = alloc_instruction(ctx, OPCODE_EVALMESH2, 5);
2259 if (n) {
2260 n[1].e = mode;
2261 n[2].i = i1;
2262 n[3].i = i2;
2263 n[4].i = j1;
2264 n[5].i = j2;
2265 }
2266 if (ctx->ExecuteFlag) {
2267 CALL_EvalMesh2(ctx->Exec, (mode, i1, i2, j1, j2));
2268 }
2269 }
2270
2271
2272
2273
2274 static void GLAPIENTRY
2275 save_Fogfv(GLenum pname, const GLfloat *params)
2276 {
2277 GET_CURRENT_CONTEXT(ctx);
2278 Node *n;
2279 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2280 n = alloc_instruction(ctx, OPCODE_FOG, 5);
2281 if (n) {
2282 n[1].e = pname;
2283 n[2].f = params[0];
2284 n[3].f = params[1];
2285 n[4].f = params[2];
2286 n[5].f = params[3];
2287 }
2288 if (ctx->ExecuteFlag) {
2289 CALL_Fogfv(ctx->Exec, (pname, params));
2290 }
2291 }
2292
2293
2294 static void GLAPIENTRY
2295 save_Fogf(GLenum pname, GLfloat param)
2296 {
2297 GLfloat parray[4];
2298 parray[0] = param;
2299 parray[1] = parray[2] = parray[3] = 0.0F;
2300 save_Fogfv(pname, parray);
2301 }
2302
2303
2304 static void GLAPIENTRY
2305 save_Fogiv(GLenum pname, const GLint *params)
2306 {
2307 GLfloat p[4];
2308 switch (pname) {
2309 case GL_FOG_MODE:
2310 case GL_FOG_DENSITY:
2311 case GL_FOG_START:
2312 case GL_FOG_END:
2313 case GL_FOG_INDEX:
2314 p[0] = (GLfloat) *params;
2315 p[1] = 0.0f;
2316 p[2] = 0.0f;
2317 p[3] = 0.0f;
2318 break;
2319 case GL_FOG_COLOR:
2320 p[0] = INT_TO_FLOAT(params[0]);
2321 p[1] = INT_TO_FLOAT(params[1]);
2322 p[2] = INT_TO_FLOAT(params[2]);
2323 p[3] = INT_TO_FLOAT(params[3]);
2324 break;
2325 default:
2326 /* Error will be caught later in gl_Fogfv */
2327 ASSIGN_4V(p, 0.0F, 0.0F, 0.0F, 0.0F);
2328 }
2329 save_Fogfv(pname, p);
2330 }
2331
2332
2333 static void GLAPIENTRY
2334 save_Fogi(GLenum pname, GLint param)
2335 {
2336 GLint parray[4];
2337 parray[0] = param;
2338 parray[1] = parray[2] = parray[3] = 0;
2339 save_Fogiv(pname, parray);
2340 }
2341
2342
2343 static void GLAPIENTRY
2344 save_FrontFace(GLenum mode)
2345 {
2346 GET_CURRENT_CONTEXT(ctx);
2347 Node *n;
2348 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2349 n = alloc_instruction(ctx, OPCODE_FRONT_FACE, 1);
2350 if (n) {
2351 n[1].e = mode;
2352 }
2353 if (ctx->ExecuteFlag) {
2354 CALL_FrontFace(ctx->Exec, (mode));
2355 }
2356 }
2357
2358
2359 static void GLAPIENTRY
2360 save_Frustum(GLdouble left, GLdouble right,
2361 GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval)
2362 {
2363 GET_CURRENT_CONTEXT(ctx);
2364 Node *n;
2365 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2366 n = alloc_instruction(ctx, OPCODE_FRUSTUM, 6);
2367 if (n) {
2368 n[1].f = (GLfloat) left;
2369 n[2].f = (GLfloat) right;
2370 n[3].f = (GLfloat) bottom;
2371 n[4].f = (GLfloat) top;
2372 n[5].f = (GLfloat) nearval;
2373 n[6].f = (GLfloat) farval;
2374 }
2375 if (ctx->ExecuteFlag) {
2376 CALL_Frustum(ctx->Exec, (left, right, bottom, top, nearval, farval));
2377 }
2378 }
2379
2380
2381 static void GLAPIENTRY
2382 save_Hint(GLenum target, GLenum mode)
2383 {
2384 GET_CURRENT_CONTEXT(ctx);
2385 Node *n;
2386 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2387 n = alloc_instruction(ctx, OPCODE_HINT, 2);
2388 if (n) {
2389 n[1].e = target;
2390 n[2].e = mode;
2391 }
2392 if (ctx->ExecuteFlag) {
2393 CALL_Hint(ctx->Exec, (target, mode));
2394 }
2395 }
2396
2397
2398 static void GLAPIENTRY
2399 save_Histogram(GLenum target, GLsizei width, GLenum internalFormat,
2400 GLboolean sink)
2401 {
2402 GET_CURRENT_CONTEXT(ctx);
2403 Node *n;
2404
2405 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2406 n = alloc_instruction(ctx, OPCODE_HISTOGRAM, 4);
2407 if (n) {
2408 n[1].e = target;
2409 n[2].i = width;
2410 n[3].e = internalFormat;
2411 n[4].b = sink;
2412 }
2413 if (ctx->ExecuteFlag) {
2414 CALL_Histogram(ctx->Exec, (target, width, internalFormat, sink));
2415 }
2416 }
2417
2418
2419 static void GLAPIENTRY
2420 save_IndexMask(GLuint mask)
2421 {
2422 GET_CURRENT_CONTEXT(ctx);
2423 Node *n;
2424 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2425 n = alloc_instruction(ctx, OPCODE_INDEX_MASK, 1);
2426 if (n) {
2427 n[1].ui = mask;
2428 }
2429 if (ctx->ExecuteFlag) {
2430 CALL_IndexMask(ctx->Exec, (mask));
2431 }
2432 }
2433
2434
2435 static void GLAPIENTRY
2436 save_InitNames(void)
2437 {
2438 GET_CURRENT_CONTEXT(ctx);
2439 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2440 (void) alloc_instruction(ctx, OPCODE_INIT_NAMES, 0);
2441 if (ctx->ExecuteFlag) {
2442 CALL_InitNames(ctx->Exec, ());
2443 }
2444 }
2445
2446
2447 static void GLAPIENTRY
2448 save_Lightfv(GLenum light, GLenum pname, const GLfloat *params)
2449 {
2450 GET_CURRENT_CONTEXT(ctx);
2451 Node *n;
2452 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2453 n = alloc_instruction(ctx, OPCODE_LIGHT, 6);
2454 if (n) {
2455 GLint i, nParams;
2456 n[1].e = light;
2457 n[2].e = pname;
2458 switch (pname) {
2459 case GL_AMBIENT:
2460 nParams = 4;
2461 break;
2462 case GL_DIFFUSE:
2463 nParams = 4;
2464 break;
2465 case GL_SPECULAR:
2466 nParams = 4;
2467 break;
2468 case GL_POSITION:
2469 nParams = 4;
2470 break;
2471 case GL_SPOT_DIRECTION:
2472 nParams = 3;
2473 break;
2474 case GL_SPOT_EXPONENT:
2475 nParams = 1;
2476 break;
2477 case GL_SPOT_CUTOFF:
2478 nParams = 1;
2479 break;
2480 case GL_CONSTANT_ATTENUATION:
2481 nParams = 1;
2482 break;
2483 case GL_LINEAR_ATTENUATION:
2484 nParams = 1;
2485 break;
2486 case GL_QUADRATIC_ATTENUATION:
2487 nParams = 1;
2488 break;
2489 default:
2490 nParams = 0;
2491 }
2492 for (i = 0; i < nParams; i++) {
2493 n[3 + i].f = params[i];
2494 }
2495 }
2496 if (ctx->ExecuteFlag) {
2497 CALL_Lightfv(ctx->Exec, (light, pname, params));
2498 }
2499 }
2500
2501
2502 static void GLAPIENTRY
2503 save_Lightf(GLenum light, GLenum pname, GLfloat param)
2504 {
2505 GLfloat parray[4];
2506 parray[0] = param;
2507 parray[1] = parray[2] = parray[3] = 0.0F;
2508 save_Lightfv(light, pname, parray);
2509 }
2510
2511
2512 static void GLAPIENTRY
2513 save_Lightiv(GLenum light, GLenum pname, const GLint *params)
2514 {
2515 GLfloat fparam[4];
2516 switch (pname) {
2517 case GL_AMBIENT:
2518 case GL_DIFFUSE:
2519 case GL_SPECULAR:
2520 fparam[0] = INT_TO_FLOAT(params[0]);
2521 fparam[1] = INT_TO_FLOAT(params[1]);
2522 fparam[2] = INT_TO_FLOAT(params[2]);
2523 fparam[3] = INT_TO_FLOAT(params[3]);
2524 break;
2525 case GL_POSITION:
2526 fparam[0] = (GLfloat) params[0];
2527 fparam[1] = (GLfloat) params[1];
2528 fparam[2] = (GLfloat) params[2];
2529 fparam[3] = (GLfloat) params[3];
2530 break;
2531 case GL_SPOT_DIRECTION:
2532 fparam[0] = (GLfloat) params[0];
2533 fparam[1] = (GLfloat) params[1];
2534 fparam[2] = (GLfloat) params[2];
2535 break;
2536 case GL_SPOT_EXPONENT:
2537 case GL_SPOT_CUTOFF:
2538 case GL_CONSTANT_ATTENUATION:
2539 case GL_LINEAR_ATTENUATION:
2540 case GL_QUADRATIC_ATTENUATION:
2541 fparam[0] = (GLfloat) params[0];
2542 break;
2543 default:
2544 /* error will be caught later in gl_Lightfv */
2545 ;
2546 }
2547 save_Lightfv(light, pname, fparam);
2548 }
2549
2550
2551 static void GLAPIENTRY
2552 save_Lighti(GLenum light, GLenum pname, GLint param)
2553 {
2554 GLint parray[4];
2555 parray[0] = param;
2556 parray[1] = parray[2] = parray[3] = 0;
2557 save_Lightiv(light, pname, parray);
2558 }
2559
2560
2561 static void GLAPIENTRY
2562 save_LightModelfv(GLenum pname, const GLfloat *params)
2563 {
2564 GET_CURRENT_CONTEXT(ctx);
2565 Node *n;
2566 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2567 n = alloc_instruction(ctx, OPCODE_LIGHT_MODEL, 5);
2568 if (n) {
2569 n[1].e = pname;
2570 n[2].f = params[0];
2571 n[3].f = params[1];
2572 n[4].f = params[2];
2573 n[5].f = params[3];
2574 }
2575 if (ctx->ExecuteFlag) {
2576 CALL_LightModelfv(ctx->Exec, (pname, params));
2577 }
2578 }
2579
2580
2581 static void GLAPIENTRY
2582 save_LightModelf(GLenum pname, GLfloat param)
2583 {
2584 GLfloat parray[4];
2585 parray[0] = param;
2586 parray[1] = parray[2] = parray[3] = 0.0F;
2587 save_LightModelfv(pname, parray);
2588 }
2589
2590
2591 static void GLAPIENTRY
2592 save_LightModeliv(GLenum pname, const GLint *params)
2593 {
2594 GLfloat fparam[4];
2595 switch (pname) {
2596 case GL_LIGHT_MODEL_AMBIENT:
2597 fparam[0] = INT_TO_FLOAT(params[0]);
2598 fparam[1] = INT_TO_FLOAT(params[1]);
2599 fparam[2] = INT_TO_FLOAT(params[2]);
2600 fparam[3] = INT_TO_FLOAT(params[3]);
2601 break;
2602 case GL_LIGHT_MODEL_LOCAL_VIEWER:
2603 case GL_LIGHT_MODEL_TWO_SIDE:
2604 case GL_LIGHT_MODEL_COLOR_CONTROL:
2605 fparam[0] = (GLfloat) params[0];
2606 fparam[1] = 0.0F;
2607 fparam[2] = 0.0F;
2608 fparam[3] = 0.0F;
2609 break;
2610 default:
2611 /* Error will be caught later in gl_LightModelfv */
2612 ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F);
2613 }
2614 save_LightModelfv(pname, fparam);
2615 }
2616
2617
2618 static void GLAPIENTRY
2619 save_LightModeli(GLenum pname, GLint param)
2620 {
2621 GLint parray[4];
2622 parray[0] = param;
2623 parray[1] = parray[2] = parray[3] = 0;
2624 save_LightModeliv(pname, parray);
2625 }
2626
2627
2628 static void GLAPIENTRY
2629 save_LineStipple(GLint factor, GLushort pattern)
2630 {
2631 GET_CURRENT_CONTEXT(ctx);
2632 Node *n;
2633 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2634 n = alloc_instruction(ctx, OPCODE_LINE_STIPPLE, 2);
2635 if (n) {
2636 n[1].i = factor;
2637 n[2].us = pattern;
2638 }
2639 if (ctx->ExecuteFlag) {
2640 CALL_LineStipple(ctx->Exec, (factor, pattern));
2641 }
2642 }
2643
2644
2645 static void GLAPIENTRY
2646 save_LineWidth(GLfloat width)
2647 {
2648 GET_CURRENT_CONTEXT(ctx);
2649 Node *n;
2650 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2651 n = alloc_instruction(ctx, OPCODE_LINE_WIDTH, 1);
2652 if (n) {
2653 n[1].f = width;
2654 }
2655 if (ctx->ExecuteFlag) {
2656 CALL_LineWidth(ctx->Exec, (width));
2657 }
2658 }
2659
2660
2661 static void GLAPIENTRY
2662 save_ListBase(GLuint base)
2663 {
2664 GET_CURRENT_CONTEXT(ctx);
2665 Node *n;
2666 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2667 n = alloc_instruction(ctx, OPCODE_LIST_BASE, 1);
2668 if (n) {
2669 n[1].ui = base;
2670 }
2671 if (ctx->ExecuteFlag) {
2672 CALL_ListBase(ctx->Exec, (base));
2673 }
2674 }
2675
2676
2677 static void GLAPIENTRY
2678 save_LoadIdentity(void)
2679 {
2680 GET_CURRENT_CONTEXT(ctx);
2681 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2682 (void) alloc_instruction(ctx, OPCODE_LOAD_IDENTITY, 0);
2683 if (ctx->ExecuteFlag) {
2684 CALL_LoadIdentity(ctx->Exec, ());
2685 }
2686 }
2687
2688
2689 static void GLAPIENTRY
2690 save_LoadMatrixf(const GLfloat * m)
2691 {
2692 GET_CURRENT_CONTEXT(ctx);
2693 Node *n;
2694 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2695 n = alloc_instruction(ctx, OPCODE_LOAD_MATRIX, 16);
2696 if (n) {
2697 GLuint i;
2698 for (i = 0; i < 16; i++) {
2699 n[1 + i].f = m[i];
2700 }
2701 }
2702 if (ctx->ExecuteFlag) {
2703 CALL_LoadMatrixf(ctx->Exec, (m));
2704 }
2705 }
2706
2707
2708 static void GLAPIENTRY
2709 save_LoadMatrixd(const GLdouble * m)
2710 {
2711 GLfloat f[16];
2712 GLint i;
2713 for (i = 0; i < 16; i++) {
2714 f[i] = (GLfloat) m[i];
2715 }
2716 save_LoadMatrixf(f);
2717 }
2718
2719
2720 static void GLAPIENTRY
2721 save_LoadName(GLuint name)
2722 {
2723 GET_CURRENT_CONTEXT(ctx);
2724 Node *n;
2725 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2726 n = alloc_instruction(ctx, OPCODE_LOAD_NAME, 1);
2727 if (n) {
2728 n[1].ui = name;
2729 }
2730 if (ctx->ExecuteFlag) {
2731 CALL_LoadName(ctx->Exec, (name));
2732 }
2733 }
2734
2735
2736 static void GLAPIENTRY
2737 save_LogicOp(GLenum opcode)
2738 {
2739 GET_CURRENT_CONTEXT(ctx);
2740 Node *n;
2741 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2742 n = alloc_instruction(ctx, OPCODE_LOGIC_OP, 1);
2743 if (n) {
2744 n[1].e = opcode;
2745 }
2746 if (ctx->ExecuteFlag) {
2747 CALL_LogicOp(ctx->Exec, (opcode));
2748 }
2749 }
2750
2751
2752 static void GLAPIENTRY
2753 save_Map1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride,
2754 GLint order, const GLdouble * points)
2755 {
2756 GET_CURRENT_CONTEXT(ctx);
2757 Node *n;
2758 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2759 n = alloc_instruction(ctx, OPCODE_MAP1, 6);
2760 if (n) {
2761 GLfloat *pnts = _mesa_copy_map_points1d(target, stride, order, points);
2762 n[1].e = target;
2763 n[2].f = (GLfloat) u1;
2764 n[3].f = (GLfloat) u2;
2765 n[4].i = _mesa_evaluator_components(target); /* stride */
2766 n[5].i = order;
2767 n[6].data = (void *) pnts;
2768 }
2769 if (ctx->ExecuteFlag) {
2770 CALL_Map1d(ctx->Exec, (target, u1, u2, stride, order, points));
2771 }
2772 }
2773
2774 static void GLAPIENTRY
2775 save_Map1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
2776 GLint order, const GLfloat * points)
2777 {
2778 GET_CURRENT_CONTEXT(ctx);
2779 Node *n;
2780 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2781 n = alloc_instruction(ctx, OPCODE_MAP1, 6);
2782 if (n) {
2783 GLfloat *pnts = _mesa_copy_map_points1f(target, stride, order, points);
2784 n[1].e = target;
2785 n[2].f = u1;
2786 n[3].f = u2;
2787 n[4].i = _mesa_evaluator_components(target); /* stride */
2788 n[5].i = order;
2789 n[6].data = (void *) pnts;
2790 }
2791 if (ctx->ExecuteFlag) {
2792 CALL_Map1f(ctx->Exec, (target, u1, u2, stride, order, points));
2793 }
2794 }
2795
2796
2797 static void GLAPIENTRY
2798 save_Map2d(GLenum target,
2799 GLdouble u1, GLdouble u2, GLint ustride, GLint uorder,
2800 GLdouble v1, GLdouble v2, GLint vstride, GLint vorder,
2801 const GLdouble * points)
2802 {
2803 GET_CURRENT_CONTEXT(ctx);
2804 Node *n;
2805 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2806 n = alloc_instruction(ctx, OPCODE_MAP2, 10);
2807 if (n) {
2808 GLfloat *pnts = _mesa_copy_map_points2d(target, ustride, uorder,
2809 vstride, vorder, points);
2810 n[1].e = target;
2811 n[2].f = (GLfloat) u1;
2812 n[3].f = (GLfloat) u2;
2813 n[4].f = (GLfloat) v1;
2814 n[5].f = (GLfloat) v2;
2815 /* XXX verify these strides are correct */
2816 n[6].i = _mesa_evaluator_components(target) * vorder; /*ustride */
2817 n[7].i = _mesa_evaluator_components(target); /*vstride */
2818 n[8].i = uorder;
2819 n[9].i = vorder;
2820 n[10].data = (void *) pnts;
2821 }
2822 if (ctx->ExecuteFlag) {
2823 CALL_Map2d(ctx->Exec, (target,
2824 u1, u2, ustride, uorder,
2825 v1, v2, vstride, vorder, points));
2826 }
2827 }
2828
2829
2830 static void GLAPIENTRY
2831 save_Map2f(GLenum target,
2832 GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
2833 GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
2834 const GLfloat * points)
2835 {
2836 GET_CURRENT_CONTEXT(ctx);
2837 Node *n;
2838 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2839 n = alloc_instruction(ctx, OPCODE_MAP2, 10);
2840 if (n) {
2841 GLfloat *pnts = _mesa_copy_map_points2f(target, ustride, uorder,
2842 vstride, vorder, points);
2843 n[1].e = target;
2844 n[2].f = u1;
2845 n[3].f = u2;
2846 n[4].f = v1;
2847 n[5].f = v2;
2848 /* XXX verify these strides are correct */
2849 n[6].i = _mesa_evaluator_components(target) * vorder; /*ustride */
2850 n[7].i = _mesa_evaluator_components(target); /*vstride */
2851 n[8].i = uorder;
2852 n[9].i = vorder;
2853 n[10].data = (void *) pnts;
2854 }
2855 if (ctx->ExecuteFlag) {
2856 CALL_Map2f(ctx->Exec, (target, u1, u2, ustride, uorder,
2857 v1, v2, vstride, vorder, points));
2858 }
2859 }
2860
2861
2862 static void GLAPIENTRY
2863 save_MapGrid1f(GLint un, GLfloat u1, GLfloat u2)
2864 {
2865 GET_CURRENT_CONTEXT(ctx);
2866 Node *n;
2867 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2868 n = alloc_instruction(ctx, OPCODE_MAPGRID1, 3);
2869 if (n) {
2870 n[1].i = un;
2871 n[2].f = u1;
2872 n[3].f = u2;
2873 }
2874 if (ctx->ExecuteFlag) {
2875 CALL_MapGrid1f(ctx->Exec, (un, u1, u2));
2876 }
2877 }
2878
2879
2880 static void GLAPIENTRY
2881 save_MapGrid1d(GLint un, GLdouble u1, GLdouble u2)
2882 {
2883 save_MapGrid1f(un, (GLfloat) u1, (GLfloat) u2);
2884 }
2885
2886
2887 static void GLAPIENTRY
2888 save_MapGrid2f(GLint un, GLfloat u1, GLfloat u2,
2889 GLint vn, GLfloat v1, GLfloat v2)
2890 {
2891 GET_CURRENT_CONTEXT(ctx);
2892 Node *n;
2893 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2894 n = alloc_instruction(ctx, OPCODE_MAPGRID2, 6);
2895 if (n) {
2896 n[1].i = un;
2897 n[2].f = u1;
2898 n[3].f = u2;
2899 n[4].i = vn;
2900 n[5].f = v1;
2901 n[6].f = v2;
2902 }
2903 if (ctx->ExecuteFlag) {
2904 CALL_MapGrid2f(ctx->Exec, (un, u1, u2, vn, v1, v2));
2905 }
2906 }
2907
2908
2909
2910 static void GLAPIENTRY
2911 save_MapGrid2d(GLint un, GLdouble u1, GLdouble u2,
2912 GLint vn, GLdouble v1, GLdouble v2)
2913 {
2914 save_MapGrid2f(un, (GLfloat) u1, (GLfloat) u2,
2915 vn, (GLfloat) v1, (GLfloat) v2);
2916 }
2917
2918
2919 static void GLAPIENTRY
2920 save_MatrixMode(GLenum mode)
2921 {
2922 GET_CURRENT_CONTEXT(ctx);
2923 Node *n;
2924 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2925 n = alloc_instruction(ctx, OPCODE_MATRIX_MODE, 1);
2926 if (n) {
2927 n[1].e = mode;
2928 }
2929 if (ctx->ExecuteFlag) {
2930 CALL_MatrixMode(ctx->Exec, (mode));
2931 }
2932 }
2933
2934
2935 static void GLAPIENTRY
2936 save_Minmax(GLenum target, GLenum internalFormat, GLboolean sink)
2937 {
2938 GET_CURRENT_CONTEXT(ctx);
2939 Node *n;
2940
2941 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2942 n = alloc_instruction(ctx, OPCODE_MIN_MAX, 3);
2943 if (n) {
2944 n[1].e = target;
2945 n[2].e = internalFormat;
2946 n[3].b = sink;
2947 }
2948 if (ctx->ExecuteFlag) {
2949 CALL_Minmax(ctx->Exec, (target, internalFormat, sink));
2950 }
2951 }
2952
2953
2954 static void GLAPIENTRY
2955 save_MultMatrixf(const GLfloat * m)
2956 {
2957 GET_CURRENT_CONTEXT(ctx);
2958 Node *n;
2959 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
2960 n = alloc_instruction(ctx, OPCODE_MULT_MATRIX, 16);
2961 if (n) {
2962 GLuint i;
2963 for (i = 0; i < 16; i++) {
2964 n[1 + i].f = m[i];
2965 }
2966 }
2967 if (ctx->ExecuteFlag) {
2968 CALL_MultMatrixf(ctx->Exec, (m));
2969 }
2970 }
2971
2972
2973 static void GLAPIENTRY
2974 save_MultMatrixd(const GLdouble * m)
2975 {
2976 GLfloat f[16];
2977 GLint i;
2978 for (i = 0; i < 16; i++) {
2979 f[i] = (GLfloat) m[i];
2980 }
2981 save_MultMatrixf(f);
2982 }
2983
2984
2985 static void GLAPIENTRY
2986 save_NewList(GLuint name, GLenum mode)
2987 {
2988 GET_CURRENT_CONTEXT(ctx);
2989 /* It's an error to call this function while building a display list */
2990 _mesa_error(ctx, GL_INVALID_OPERATION, "glNewList");
2991 (void) name;
2992 (void) mode;
2993 }
2994
2995
2996
2997 static void GLAPIENTRY
2998 save_Ortho(GLdouble left, GLdouble right,
2999 GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval)
3000 {
3001 GET_CURRENT_CONTEXT(ctx);
3002 Node *n;
3003 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3004 n = alloc_instruction(ctx, OPCODE_ORTHO, 6);
3005 if (n) {
3006 n[1].f = (GLfloat) left;
3007 n[2].f = (GLfloat) right;
3008 n[3].f = (GLfloat) bottom;
3009 n[4].f = (GLfloat) top;
3010 n[5].f = (GLfloat) nearval;
3011 n[6].f = (GLfloat) farval;
3012 }
3013 if (ctx->ExecuteFlag) {
3014 CALL_Ortho(ctx->Exec, (left, right, bottom, top, nearval, farval));
3015 }
3016 }
3017
3018
3019 static void GLAPIENTRY
3020 save_PixelMapfv(GLenum map, GLint mapsize, const GLfloat *values)
3021 {
3022 GET_CURRENT_CONTEXT(ctx);
3023 Node *n;
3024 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3025 n = alloc_instruction(ctx, OPCODE_PIXEL_MAP, 3);
3026 if (n) {
3027 n[1].e = map;
3028 n[2].i = mapsize;
3029 n[3].data = (void *) malloc(mapsize * sizeof(GLfloat));
3030 memcpy(n[3].data, (void *) values, mapsize * sizeof(GLfloat));
3031 }
3032 if (ctx->ExecuteFlag) {
3033 CALL_PixelMapfv(ctx->Exec, (map, mapsize, values));
3034 }
3035 }
3036
3037
3038 static void GLAPIENTRY
3039 save_PixelMapuiv(GLenum map, GLint mapsize, const GLuint *values)
3040 {
3041 GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
3042 GLint i;
3043 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
3044 for (i = 0; i < mapsize; i++) {
3045 fvalues[i] = (GLfloat) values[i];
3046 }
3047 }
3048 else {
3049 for (i = 0; i < mapsize; i++) {
3050 fvalues[i] = UINT_TO_FLOAT(values[i]);
3051 }
3052 }
3053 save_PixelMapfv(map, mapsize, fvalues);
3054 }
3055
3056
3057 static void GLAPIENTRY
3058 save_PixelMapusv(GLenum map, GLint mapsize, const GLushort *values)
3059 {
3060 GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
3061 GLint i;
3062 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
3063 for (i = 0; i < mapsize; i++) {
3064 fvalues[i] = (GLfloat) values[i];
3065 }
3066 }
3067 else {
3068 for (i = 0; i < mapsize; i++) {
3069 fvalues[i] = USHORT_TO_FLOAT(values[i]);
3070 }
3071 }
3072 save_PixelMapfv(map, mapsize, fvalues);
3073 }
3074
3075
3076 static void GLAPIENTRY
3077 save_PixelTransferf(GLenum pname, GLfloat param)
3078 {
3079 GET_CURRENT_CONTEXT(ctx);
3080 Node *n;
3081 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3082 n = alloc_instruction(ctx, OPCODE_PIXEL_TRANSFER, 2);
3083 if (n) {
3084 n[1].e = pname;
3085 n[2].f = param;
3086 }
3087 if (ctx->ExecuteFlag) {
3088 CALL_PixelTransferf(ctx->Exec, (pname, param));
3089 }
3090 }
3091
3092
3093 static void GLAPIENTRY
3094 save_PixelTransferi(GLenum pname, GLint param)
3095 {
3096 save_PixelTransferf(pname, (GLfloat) param);
3097 }
3098
3099
3100 static void GLAPIENTRY
3101 save_PixelZoom(GLfloat xfactor, GLfloat yfactor)
3102 {
3103 GET_CURRENT_CONTEXT(ctx);
3104 Node *n;
3105 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3106 n = alloc_instruction(ctx, OPCODE_PIXEL_ZOOM, 2);
3107 if (n) {
3108 n[1].f = xfactor;
3109 n[2].f = yfactor;
3110 }
3111 if (ctx->ExecuteFlag) {
3112 CALL_PixelZoom(ctx->Exec, (xfactor, yfactor));
3113 }
3114 }
3115
3116
3117 static void GLAPIENTRY
3118 save_PointParameterfvEXT(GLenum pname, const GLfloat *params)
3119 {
3120 GET_CURRENT_CONTEXT(ctx);
3121 Node *n;
3122 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
3123 n = alloc_instruction(ctx, OPCODE_POINT_PARAMETERS, 4);
3124 if (n) {
3125 n[1].e = pname;
3126 n[2].f = params[0];
3127 n[3].f = params[1];
3128 n[4].f = params[2];