ReactOS  r73918
dlist.c
Go to the documentation of this file.
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 
32 #include <precomp.h>
33 
34 #include "config.h"
35 
41 {
43  void (*Execute)( struct gl_context *ctx, void *data );
44  void (*Destroy)( struct gl_context *ctx, void *data );
45  void (*Print)( struct gl_context *ctx, void *data );
46 };
47 
48 
49 #define MAX_DLIST_EXT_OPCODES 16
50 
55 {
58 };
59 
60 
61 
71 #define SAVE_FLUSH_VERTICES(ctx) \
72 do { \
73  if (ctx->Driver.SaveNeedFlush) \
74  ctx->Driver.SaveFlushVertices(ctx); \
75 } while (0)
76 
77 
85 #define ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval) \
86 do { \
87  if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON || \
88  ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \
89  _mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \
90  return retval; \
91  } \
92 } while (0)
93 
100 #define ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx) \
101 do { \
102  if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON || \
103  ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \
104  _mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \
105  return; \
106  } \
107 } while (0)
108 
115 #define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx) \
116 do { \
117  ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx); \
118  SAVE_FLUSH_VERTICES(ctx); \
119 } while (0)
120 
128 #define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, retval)\
129 do { \
130  ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval); \
131  SAVE_FLUSH_VERTICES(ctx); \
132 } while (0)
133 
134 
135 
142 typedef enum
143 {
144  OPCODE_INVALID = -1, /* Force signed enum */
150 
236  /* GL_ARB_multisample */
238  /* GL_ARB_window_pos */
240  /* GL_EXT_depth_bounds_test */
242 
243  /* Vertex attributes -- fallback for when optimized display
244  * list build isn't active.
245  */
258 
259  /* GL_EXT_texture_integer */
264 
265  /* The following three are meta instructions */
266  OPCODE_ERROR, /* raise compiled-in error */
270 } OpCode;
271 
272 
273 
286 {
298  void *next; /* If prev node's opcode==OPCODE_CONTINUE */
299 };
300 
301 
302 typedef union gl_dlist_node Node;
303 
304 
310 {
313 };
314 
315 
321 #define BLOCK_SIZE 256
322 
323 
324 
330 
331 
332 #if FEATURE_dlist
333 
334 
335 void mesa_print_display_list(GLuint list);
336 
337 
338 /**********************************************************************/
339 /***** Private *****/
340 /**********************************************************************/
341 
342 
347 static struct gl_display_list *
349 {
351  dlist->Name = name;
352  dlist->Head = (Node *) malloc(sizeof(Node) * count);
353  dlist->Head[0].opcode = OPCODE_END_OF_LIST;
354  return dlist;
355 }
356 
357 
361 static inline struct gl_display_list *
362 lookup_list(struct gl_context *ctx, GLuint list)
363 {
364  return (struct gl_display_list *)
365  _mesa_HashLookup(ctx->Shared->DisplayList, list);
366 }
367 
368 
370 static inline GLboolean
371 is_ext_opcode(OpCode opcode)
372 {
373  return (opcode >= OPCODE_EXT_0);
374 }
375 
376 
378 static GLint
379 ext_opcode_destroy(struct gl_context *ctx, Node *node)
380 {
381  const GLint i = node[0].opcode - OPCODE_EXT_0;
382  GLint step;
383  ctx->ListExt->Opcode[i].Destroy(ctx, &node[1]);
384  step = ctx->ListExt->Opcode[i].Size;
385  return step;
386 }
387 
388 
390 static GLint
391 ext_opcode_execute(struct gl_context *ctx, Node *node)
392 {
393  const GLint i = node[0].opcode - OPCODE_EXT_0;
394  GLint step;
395  ctx->ListExt->Opcode[i].Execute(ctx, &node[1]);
396  step = ctx->ListExt->Opcode[i].Size;
397  return step;
398 }
399 
400 
402 static GLint
403 ext_opcode_print(struct gl_context *ctx, Node *node)
404 {
405  const GLint i = node[0].opcode - OPCODE_EXT_0;
406  GLint step;
407  ctx->ListExt->Opcode[i].Print(ctx, &node[1]);
408  step = ctx->ListExt->Opcode[i].Size;
409  return step;
410 }
411 
412 
417 void
418 _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
419 {
420  Node *n, *block;
421  GLboolean done;
422 
423  n = block = dlist->Head;
424 
425  done = block ? GL_FALSE : GL_TRUE;
426  while (!done) {
427  const OpCode opcode = n[0].opcode;
428 
429  /* check for extension opcodes first */
430  if (is_ext_opcode(opcode)) {
431  n += ext_opcode_destroy(ctx, n);
432  }
433  else {
434  switch (opcode) {
435  /* for some commands, we need to free malloc'd memory */
436  case OPCODE_MAP1:
437  free(n[6].data);
438  n += InstSize[n[0].opcode];
439  break;
440  case OPCODE_MAP2:
441  free(n[10].data);
442  n += InstSize[n[0].opcode];
443  break;
444  case OPCODE_DRAW_PIXELS:
445  free(n[5].data);
446  n += InstSize[n[0].opcode];
447  break;
448  case OPCODE_BITMAP:
449  free(n[7].data);
450  n += InstSize[n[0].opcode];
451  break;
453  free(n[1].data);
454  n += InstSize[n[0].opcode];
455  break;
456  case OPCODE_TEX_IMAGE1D:
457  free(n[8].data);
458  n += InstSize[n[0].opcode];
459  break;
460  case OPCODE_TEX_IMAGE2D:
461  free(n[9].data);
462  n += InstSize[n[0].opcode];
463  break;
465  free(n[7].data);
466  n += InstSize[n[0].opcode];
467  break;
469  free(n[9].data);
470  n += InstSize[n[0].opcode];
471  break;
472  case OPCODE_CONTINUE:
473  n = (Node *) n[1].next;
474  free(block);
475  block = n;
476  break;
477  case OPCODE_END_OF_LIST:
478  free(block);
479  done = GL_TRUE;
480  break;
481  default:
482  /* Most frequent case */
483  n += InstSize[n[0].opcode];
484  break;
485  }
486  }
487  }
488 
489  free(dlist);
490 }
491 
492 
497 static void
498 destroy_list(struct gl_context *ctx, GLuint list)
499 {
500  struct gl_display_list *dlist;
501 
502  if (list == 0)
503  return;
504 
505  dlist = lookup_list(ctx, list);
506  if (!dlist)
507  return;
508 
509  _mesa_delete_list(ctx, dlist);
510  _mesa_HashRemove(ctx->Shared->DisplayList, list);
511 }
512 
513 
514 /*
515  * Translate the nth element of list from <type> to GLint.
516  */
517 static GLint
518 translate_id(GLsizei n, GLenum type, const GLvoid * list)
519 {
520  GLbyte *bptr;
521  GLubyte *ubptr;
522  GLshort *sptr;
523  GLushort *usptr;
524  GLint *iptr;
525  GLuint *uiptr;
526  GLfloat *fptr;
527 
528  switch (type) {
529  case GL_BYTE:
530  bptr = (GLbyte *) list;
531  return (GLint) bptr[n];
532  case GL_UNSIGNED_BYTE:
533  ubptr = (GLubyte *) list;
534  return (GLint) ubptr[n];
535  case GL_SHORT:
536  sptr = (GLshort *) list;
537  return (GLint) sptr[n];
538  case GL_UNSIGNED_SHORT:
539  usptr = (GLushort *) list;
540  return (GLint) usptr[n];
541  case GL_INT:
542  iptr = (GLint *) list;
543  return iptr[n];
544  case GL_UNSIGNED_INT:
545  uiptr = (GLuint *) list;
546  return (GLint) uiptr[n];
547  case GL_FLOAT:
548  fptr = (GLfloat *) list;
549  return (GLint) FLOORF(fptr[n]);
550  case GL_2_BYTES:
551  ubptr = ((GLubyte *) list) + 2 * n;
552  return (GLint) ubptr[0] * 256
553  + (GLint) ubptr[1];
554  case GL_3_BYTES:
555  ubptr = ((GLubyte *) list) + 3 * n;
556  return (GLint) ubptr[0] * 65536
557  + (GLint) ubptr[1] * 256
558  + (GLint) ubptr[2];
559  case GL_4_BYTES:
560  ubptr = ((GLubyte *) list) + 4 * n;
561  return (GLint) ubptr[0] * 16777216
562  + (GLint) ubptr[1] * 65536
563  + (GLint) ubptr[2] * 256
564  + (GLint) ubptr[3];
565  default:
566  return 0;
567  }
568 }
569 
570 
571 
572 
573 /**********************************************************************/
574 /***** Public *****/
575 /**********************************************************************/
576 
585 static GLvoid *
586 unpack_image(struct gl_context *ctx, GLuint dimensions,
590 {
591  GLvoid *image;
592 
593  if (width <= 0 || height <= 0) {
594  return NULL;
595  }
596 
597  if (_mesa_bytes_per_pixel(format, type) < 0) {
598  /* bad format and/or type */
599  return NULL;
600  }
601 
602  if (type == GL_BITMAP)
603  image = _mesa_unpack_bitmap(width, height, pixels, unpack);
604  else
605  image = _mesa_unpack_image(dimensions, width, height, depth,
606  format, type, pixels, unpack);
607  if (pixels && !image) {
608  _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
609  }
610  return image;
611 }
612 
619 static Node *
620 dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes)
621 {
622  const GLuint numNodes = 1 + (bytes + sizeof(Node) - 1) / sizeof(Node);
623  Node *n;
624 
625  if (opcode < (GLuint) OPCODE_EXT_0) {
626  if (InstSize[opcode] == 0) {
627  /* save instruction size now */
628  InstSize[opcode] = numNodes;
629  }
630  else {
631  /* make sure instruction size agrees */
632  ASSERT(numNodes == InstSize[opcode]);
633  }
634  }
635 
636  if (ctx->ListState.CurrentPos + numNodes + 2 > BLOCK_SIZE) {
637  /* This block is full. Allocate a new block and chain to it */
638  Node *newblock;
639  n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos;
640  n[0].opcode = OPCODE_CONTINUE;
641  newblock = (Node *) malloc(sizeof(Node) * BLOCK_SIZE);
642  if (!newblock) {
643  _mesa_error(ctx, GL_OUT_OF_MEMORY, "Building display list");
644  return NULL;
645  }
646  n[1].next = (Node *) newblock;
647  ctx->ListState.CurrentBlock = newblock;
648  ctx->ListState.CurrentPos = 0;
649  }
650 
651  n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos;
652  ctx->ListState.CurrentPos += numNodes;
653 
654  n[0].opcode = opcode;
655 
656  return n;
657 }
658 
659 
660 
670 void *
671 _mesa_dlist_alloc(struct gl_context *ctx, GLuint opcode, GLuint bytes)
672 {
673  Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes);
674  if (n)
675  return n + 1; /* return pointer to payload area, after opcode */
676  else
677  return NULL;
678 }
679 
680 
691 GLint
692 _mesa_dlist_alloc_opcode(struct gl_context *ctx,
693  GLuint size,
694  void (*execute) (struct gl_context *, void *),
695  void (*destroy) (struct gl_context *, void *),
696  void (*print) (struct gl_context *, void *))
697 {
698  if (ctx->ListExt->NumOpcodes < MAX_DLIST_EXT_OPCODES) {
699  const GLuint i = ctx->ListExt->NumOpcodes++;
700  ctx->ListExt->Opcode[i].Size =
701  1 + (size + sizeof(Node) - 1) / sizeof(Node);
702  ctx->ListExt->Opcode[i].Execute = execute;
703  ctx->ListExt->Opcode[i].Destroy = destroy;
704  ctx->ListExt->Opcode[i].Print = print;
705  return i + OPCODE_EXT_0;
706  }
707  return -1;
708 }
709 
710 
720 static inline Node *
721 alloc_instruction(struct gl_context *ctx, OpCode opcode, GLuint nparams)
722 {
723  return dlist_alloc(ctx, opcode, nparams * sizeof(Node));
724 }
725 
726 
727 
728 /*
729  * Display List compilation functions
730  */
731 static void GLAPIENTRY
732 save_Accum(GLenum op, GLfloat value)
733 {
734  GET_CURRENT_CONTEXT(ctx);
735  Node *n;
737  n = alloc_instruction(ctx, OPCODE_ACCUM, 2);
738  if (n) {
739  n[1].e = op;
740  n[2].f = value;
741  }
742  if (ctx->ExecuteFlag) {
743  CALL_Accum(ctx->Exec, (op, value));
744  }
745 }
746 
747 
748 static void GLAPIENTRY
749 save_AlphaFunc(GLenum func, GLclampf ref)
750 {
751  GET_CURRENT_CONTEXT(ctx);
752  Node *n;
754  n = alloc_instruction(ctx, OPCODE_ALPHA_FUNC, 2);
755  if (n) {
756  n[1].e = func;
757  n[2].f = (GLfloat) ref;
758  }
759  if (ctx->ExecuteFlag) {
760  CALL_AlphaFunc(ctx->Exec, (func, ref));
761  }
762 }
763 
764 
765 static void GLAPIENTRY
766 save_BindTexture(GLenum target, GLuint texture)
767 {
768  GET_CURRENT_CONTEXT(ctx);
769  Node *n;
771  n = alloc_instruction(ctx, OPCODE_BIND_TEXTURE, 2);
772  if (n) {
773  n[1].e = target;
774  n[2].ui = texture;
775  }
776  if (ctx->ExecuteFlag) {
777  CALL_BindTexture(ctx->Exec, (target, texture));
778  }
779 }
780 
781 
782 static void GLAPIENTRY
783 save_Bitmap(GLsizei width, GLsizei height,
784  GLfloat xorig, GLfloat yorig,
785  GLfloat xmove, GLfloat ymove, const GLubyte * pixels)
786 {
787  GET_CURRENT_CONTEXT(ctx);
788  Node *n;
790  n = alloc_instruction(ctx, OPCODE_BITMAP, 7);
791  if (n) {
792  n[1].i = (GLint) width;
793  n[2].i = (GLint) height;
794  n[3].f = xorig;
795  n[4].f = yorig;
796  n[5].f = xmove;
797  n[6].f = ymove;
798  n[7].data = unpack_image(ctx, 2, width, height, 1, GL_COLOR_INDEX,
799  GL_BITMAP, pixels, &ctx->Unpack);
800  }
801  if (ctx->ExecuteFlag) {
802  CALL_Bitmap(ctx->Exec, (width, height,
803  xorig, yorig, xmove, ymove, pixels));
804  }
805 }
806 
807 
808 static void GLAPIENTRY
809 save_BlendFunc(GLenum srcfactor, GLenum dstfactor)
810 {
811  GET_CURRENT_CONTEXT(ctx);
812  Node *n;
814  n = alloc_instruction(ctx, OPCODE_BLEND_FUNC, 2);
815  if (n) {
816  n[1].e = srcfactor;
817  n[2].e = dstfactor;
818  }
819  if (ctx->ExecuteFlag) {
820  CALL_BlendFunc(ctx->Exec, (srcfactor, dstfactor));
821  }
822 }
823 
824 
825 static void invalidate_saved_current_state( struct gl_context *ctx )
826 {
827  GLint i;
828 
829  for (i = 0; i < VERT_ATTRIB_MAX; i++)
830  ctx->ListState.ActiveAttribSize[i] = 0;
831 
832  for (i = 0; i < MAT_ATTRIB_MAX; i++)
833  ctx->ListState.ActiveMaterialSize[i] = 0;
834 
835  memset(&ctx->ListState.Current, 0, sizeof ctx->ListState.Current);
836 
837  ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
838 }
839 
840 static void GLAPIENTRY
841 save_CallList(GLuint list)
842 {
843  GET_CURRENT_CONTEXT(ctx);
844  Node *n;
845  SAVE_FLUSH_VERTICES(ctx);
846 
847  n = alloc_instruction(ctx, OPCODE_CALL_LIST, 1);
848  if (n) {
849  n[1].ui = list;
850  }
851 
852  /* After this, we don't know what state we're in. Invalidate all
853  * cached information previously gathered:
854  */
855  invalidate_saved_current_state( ctx );
856 
857  if (ctx->ExecuteFlag) {
858  _mesa_CallList(list);
859  }
860 }
861 
862 
863 static void GLAPIENTRY
864 save_CallLists(GLsizei num, GLenum type, const GLvoid * lists)
865 {
866  GET_CURRENT_CONTEXT(ctx);
867  GLint i;
868  GLboolean typeErrorFlag;
869 
870  SAVE_FLUSH_VERTICES(ctx);
871 
872  switch (type) {
873  case GL_BYTE:
874  case GL_UNSIGNED_BYTE:
875  case GL_SHORT:
876  case GL_UNSIGNED_SHORT:
877  case GL_INT:
878  case GL_UNSIGNED_INT:
879  case GL_FLOAT:
880  case GL_2_BYTES:
881  case GL_3_BYTES:
882  case GL_4_BYTES:
883  typeErrorFlag = GL_FALSE;
884  break;
885  default:
886  typeErrorFlag = GL_TRUE;
887  }
888 
889  for (i = 0; i < num; i++) {
890  GLint list = translate_id(i, type, lists);
891  Node *n = alloc_instruction(ctx, OPCODE_CALL_LIST_OFFSET, 2);
892  if (n) {
893  n[1].i = list;
894  n[2].b = typeErrorFlag;
895  }
896  }
897 
898  /* After this, we don't know what state we're in. Invalidate all
899  * cached information previously gathered:
900  */
901  invalidate_saved_current_state( ctx );
902 
903  if (ctx->ExecuteFlag) {
904  CALL_CallLists(ctx->Exec, (num, type, lists));
905  }
906 }
907 
908 
909 static void GLAPIENTRY
910 save_Clear(GLbitfield mask)
911 {
912  GET_CURRENT_CONTEXT(ctx);
913  Node *n;
915  n = alloc_instruction(ctx, OPCODE_CLEAR, 1);
916  if (n) {
917  n[1].bf = mask;
918  }
919  if (ctx->ExecuteFlag) {
920  CALL_Clear(ctx->Exec, (mask));
921  }
922 }
923 
924 
925 static void GLAPIENTRY
926 save_ClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
927 {
928  GET_CURRENT_CONTEXT(ctx);
929  Node *n;
931  n = alloc_instruction(ctx, OPCODE_CLEAR_ACCUM, 4);
932  if (n) {
933  n[1].f = red;
934  n[2].f = green;
935  n[3].f = blue;
936  n[4].f = alpha;
937  }
938  if (ctx->ExecuteFlag) {
939  CALL_ClearAccum(ctx->Exec, (red, green, blue, alpha));
940  }
941 }
942 
943 
944 static void GLAPIENTRY
945 save_ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
946 {
947  GET_CURRENT_CONTEXT(ctx);
948  Node *n;
950  n = alloc_instruction(ctx, OPCODE_CLEAR_COLOR, 4);
951  if (n) {
952  n[1].f = red;
953  n[2].f = green;
954  n[3].f = blue;
955  n[4].f = alpha;
956  }
957  if (ctx->ExecuteFlag) {
958  CALL_ClearColor(ctx->Exec, (red, green, blue, alpha));
959  }
960 }
961 
962 
963 static void GLAPIENTRY
964 save_ClearDepth(GLclampd depth)
965 {
966  GET_CURRENT_CONTEXT(ctx);
967  Node *n;
969  n = alloc_instruction(ctx, OPCODE_CLEAR_DEPTH, 1);
970  if (n) {
971  n[1].f = (GLfloat) depth;
972  }
973  if (ctx->ExecuteFlag) {
974  CALL_ClearDepth(ctx->Exec, (depth));
975  }
976 }
977 
978 
979 static void GLAPIENTRY
980 save_ClearIndex(GLfloat c)
981 {
982  GET_CURRENT_CONTEXT(ctx);
983  Node *n;
985  n = alloc_instruction(ctx, OPCODE_CLEAR_INDEX, 1);
986  if (n) {
987  n[1].f = c;
988  }
989  if (ctx->ExecuteFlag) {
990  CALL_ClearIndex(ctx->Exec, (c));
991  }
992 }
993 
994 
995 static void GLAPIENTRY
996 save_ClearStencil(GLint s)
997 {
998  GET_CURRENT_CONTEXT(ctx);
999  Node *n;
1001  n = alloc_instruction(ctx, OPCODE_CLEAR_STENCIL, 1);
1002  if (n) {
1003  n[1].i = s;
1004  }
1005  if (ctx->ExecuteFlag) {
1006  CALL_ClearStencil(ctx->Exec, (s));
1007  }
1008 }
1009 
1010 
1011 static void GLAPIENTRY
1012 save_ClipPlane(GLenum plane, const GLdouble * equ)
1013 {
1014  GET_CURRENT_CONTEXT(ctx);
1015  Node *n;
1017  n = alloc_instruction(ctx, OPCODE_CLIP_PLANE, 5);
1018  if (n) {
1019  n[1].e = plane;
1020  n[2].f = (GLfloat) equ[0];
1021  n[3].f = (GLfloat) equ[1];
1022  n[4].f = (GLfloat) equ[2];
1023  n[5].f = (GLfloat) equ[3];
1024  }
1025  if (ctx->ExecuteFlag) {
1026  CALL_ClipPlane(ctx->Exec, (plane, equ));
1027  }
1028 }
1029 
1030 
1031 
1032 static void GLAPIENTRY
1033 save_ColorMask(GLboolean red, GLboolean green,
1034  GLboolean blue, GLboolean alpha)
1035 {
1036  GET_CURRENT_CONTEXT(ctx);
1037  Node *n;
1039  n = alloc_instruction(ctx, OPCODE_COLOR_MASK, 4);
1040  if (n) {
1041  n[1].b = red;
1042  n[2].b = green;
1043  n[3].b = blue;
1044  n[4].b = alpha;
1045  }
1046  if (ctx->ExecuteFlag) {
1047  CALL_ColorMask(ctx->Exec, (red, green, blue, alpha));
1048  }
1049 }
1050 
1051 
1052 static void GLAPIENTRY
1053 save_ColorMaterial(GLenum face, GLenum mode)
1054 {
1055  GET_CURRENT_CONTEXT(ctx);
1056  Node *n;
1058 
1059  n = alloc_instruction(ctx, OPCODE_COLOR_MATERIAL, 2);
1060  if (n) {
1061  n[1].e = face;
1062  n[2].e = mode;
1063  }
1064  if (ctx->ExecuteFlag) {
1065  CALL_ColorMaterial(ctx->Exec, (face, mode));
1066  }
1067 }
1068 
1069 
1070 static void GLAPIENTRY
1071 save_CopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
1072 {
1073  GET_CURRENT_CONTEXT(ctx);
1074  Node *n;
1076  n = alloc_instruction(ctx, OPCODE_COPY_PIXELS, 5);
1077  if (n) {
1078  n[1].i = x;
1079  n[2].i = y;
1080  n[3].i = (GLint) width;
1081  n[4].i = (GLint) height;
1082  n[5].e = type;
1083  }
1084  if (ctx->ExecuteFlag) {
1085  CALL_CopyPixels(ctx->Exec, (x, y, width, height, type));
1086  }
1087 }
1088 
1089 
1090 
1091 static void GLAPIENTRY
1092 save_CopyTexImage1D(GLenum target, GLint level, GLenum internalformat,
1093  GLint x, GLint y, GLsizei width, GLint border)
1094 {
1095  GET_CURRENT_CONTEXT(ctx);
1096  Node *n;
1098  n = alloc_instruction(ctx, OPCODE_COPY_TEX_IMAGE1D, 7);
1099  if (n) {
1100  n[1].e = target;
1101  n[2].i = level;
1102  n[3].e = internalformat;
1103  n[4].i = x;
1104  n[5].i = y;
1105  n[6].i = width;
1106  n[7].i = border;
1107  }
1108  if (ctx->ExecuteFlag) {
1109  CALL_CopyTexImage1D(ctx->Exec, (target, level, internalformat,
1110  x, y, width, border));
1111  }
1112 }
1113 
1114 
1115 static void GLAPIENTRY
1116 save_CopyTexImage2D(GLenum target, GLint level,
1117  GLenum internalformat,
1118  GLint x, GLint y, GLsizei width,
1119  GLsizei height, GLint border)
1120 {
1121  GET_CURRENT_CONTEXT(ctx);
1122  Node *n;
1124  n = alloc_instruction(ctx, OPCODE_COPY_TEX_IMAGE2D, 8);
1125  if (n) {
1126  n[1].e = target;
1127  n[2].i = level;
1128  n[3].e = internalformat;
1129  n[4].i = x;
1130  n[5].i = y;
1131  n[6].i = width;
1132  n[7].i = height;
1133  n[8].i = border;
1134  }
1135  if (ctx->ExecuteFlag) {
1136  CALL_CopyTexImage2D(ctx->Exec, (target, level, internalformat,
1137  x, y, width, height, border));
1138  }
1139 }
1140 
1141 
1142 
1143 static void GLAPIENTRY
1144 save_CopyTexSubImage1D(GLenum target, GLint level,
1145  GLint xoffset, GLint x, GLint y, GLsizei width)
1146 {
1147  GET_CURRENT_CONTEXT(ctx);
1148  Node *n;
1150  n = alloc_instruction(ctx, OPCODE_COPY_TEX_SUB_IMAGE1D, 6);
1151  if (n) {
1152  n[1].e = target;
1153  n[2].i = level;
1154  n[3].i = xoffset;
1155  n[4].i = x;
1156  n[5].i = y;
1157  n[6].i = width;
1158  }
1159  if (ctx->ExecuteFlag) {
1161  (target, level, xoffset, x, y, width));
1162  }
1163 }
1164 
1165 
1166 static void GLAPIENTRY
1167 save_CopyTexSubImage2D(GLenum target, GLint level,
1168  GLint xoffset, GLint yoffset,
1169  GLint x, GLint y, GLsizei width, GLint height)
1170 {
1171  GET_CURRENT_CONTEXT(ctx);
1172  Node *n;
1174  n = alloc_instruction(ctx, OPCODE_COPY_TEX_SUB_IMAGE2D, 8);
1175  if (n) {
1176  n[1].e = target;
1177  n[2].i = level;
1178  n[3].i = xoffset;
1179  n[4].i = yoffset;
1180  n[5].i = x;
1181  n[6].i = y;
1182  n[7].i = width;
1183  n[8].i = height;
1184  }
1185  if (ctx->ExecuteFlag) {
1186  CALL_CopyTexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset,
1187  x, y, width, height));
1188  }
1189 }
1190 
1191 
1192 static void GLAPIENTRY
1193 save_CullFace(GLenum mode)
1194 {
1195  GET_CURRENT_CONTEXT(ctx);
1196  Node *n;
1198  n = alloc_instruction(ctx, OPCODE_CULL_FACE, 1);
1199  if (n) {
1200  n[1].e = mode;
1201  }
1202  if (ctx->ExecuteFlag) {
1203  CALL_CullFace(ctx->Exec, (mode));
1204  }
1205 }
1206 
1207 
1208 static void GLAPIENTRY
1209 save_DepthFunc(GLenum func)
1210 {
1211  GET_CURRENT_CONTEXT(ctx);
1212  Node *n;
1214  n = alloc_instruction(ctx, OPCODE_DEPTH_FUNC, 1);
1215  if (n) {
1216  n[1].e = func;
1217  }
1218  if (ctx->ExecuteFlag) {
1219  CALL_DepthFunc(ctx->Exec, (func));
1220  }
1221 }
1222 
1223 
1224 static void GLAPIENTRY
1225 save_DepthMask(GLboolean mask)
1226 {
1227  GET_CURRENT_CONTEXT(ctx);
1228  Node *n;
1230  n = alloc_instruction(ctx, OPCODE_DEPTH_MASK, 1);
1231  if (n) {
1232  n[1].b = mask;
1233  }
1234  if (ctx->ExecuteFlag) {
1235  CALL_DepthMask(ctx->Exec, (mask));
1236  }
1237 }
1238 
1239 
1240 static void GLAPIENTRY
1241 save_DepthRange(GLclampd nearval, GLclampd farval)
1242 {
1243  GET_CURRENT_CONTEXT(ctx);
1244  Node *n;
1246  n = alloc_instruction(ctx, OPCODE_DEPTH_RANGE, 2);
1247  if (n) {
1248  n[1].f = (GLfloat) nearval;
1249  n[2].f = (GLfloat) farval;
1250  }
1251  if (ctx->ExecuteFlag) {
1252  CALL_DepthRange(ctx->Exec, (nearval, farval));
1253  }
1254 }
1255 
1256 
1257 static void GLAPIENTRY
1258 save_Disable(GLenum cap)
1259 {
1260  GET_CURRENT_CONTEXT(ctx);
1261  Node *n;
1263  n = alloc_instruction(ctx, OPCODE_DISABLE, 1);
1264  if (n) {
1265  n[1].e = cap;
1266  }
1267  if (ctx->ExecuteFlag) {
1268  CALL_Disable(ctx->Exec, (cap));
1269  }
1270 }
1271 
1272 
1273 static void GLAPIENTRY
1274 save_DrawBuffer(GLenum mode)
1275 {
1276  GET_CURRENT_CONTEXT(ctx);
1277  Node *n;
1279  n = alloc_instruction(ctx, OPCODE_DRAW_BUFFER, 1);
1280  if (n) {
1281  n[1].e = mode;
1282  }
1283  if (ctx->ExecuteFlag) {
1284  CALL_DrawBuffer(ctx->Exec, (mode));
1285  }
1286 }
1287 
1288 
1289 static void GLAPIENTRY
1290 save_DrawPixels(GLsizei width, GLsizei height,
1291  GLenum format, GLenum type, const GLvoid * pixels)
1292 {
1293  GET_CURRENT_CONTEXT(ctx);
1294  Node *n;
1295 
1297 
1298  n = alloc_instruction(ctx, OPCODE_DRAW_PIXELS, 5);
1299  if (n) {
1300  n[1].i = width;
1301  n[2].i = height;
1302  n[3].e = format;
1303  n[4].e = type;
1304  n[5].data = unpack_image(ctx, 2, width, height, 1, format, type,
1305  pixels, &ctx->Unpack);
1306  }
1307  if (ctx->ExecuteFlag) {
1308  CALL_DrawPixels(ctx->Exec, (width, height, format, type, pixels));
1309  }
1310 }
1311 
1312 
1313 
1314 static void GLAPIENTRY
1315 save_Enable(GLenum cap)
1316 {
1317  GET_CURRENT_CONTEXT(ctx);
1318  Node *n;
1320  n = alloc_instruction(ctx, OPCODE_ENABLE, 1);
1321  if (n) {
1322  n[1].e = cap;
1323  }
1324  if (ctx->ExecuteFlag) {
1325  CALL_Enable(ctx->Exec, (cap));
1326  }
1327 }
1328 
1329 
1330 
1331 static void GLAPIENTRY
1332 save_EvalMesh1(GLenum mode, GLint i1, GLint i2)
1333 {
1334  GET_CURRENT_CONTEXT(ctx);
1335  Node *n;
1337  n = alloc_instruction(ctx, OPCODE_EVALMESH1, 3);
1338  if (n) {
1339  n[1].e = mode;
1340  n[2].i = i1;
1341  n[3].i = i2;
1342  }
1343  if (ctx->ExecuteFlag) {
1344  CALL_EvalMesh1(ctx->Exec, (mode, i1, i2));
1345  }
1346 }
1347 
1348 
1349 static void GLAPIENTRY
1350 save_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
1351 {
1352  GET_CURRENT_CONTEXT(ctx);
1353  Node *n;
1355  n = alloc_instruction(ctx, OPCODE_EVALMESH2, 5);
1356  if (n) {
1357  n[1].e = mode;
1358  n[2].i = i1;
1359  n[3].i = i2;
1360  n[4].i = j1;
1361  n[5].i = j2;
1362  }
1363  if (ctx->ExecuteFlag) {
1364  CALL_EvalMesh2(ctx->Exec, (mode, i1, i2, j1, j2));
1365  }
1366 }
1367 
1368 
1369 
1370 
1371 static void GLAPIENTRY
1372 save_Fogfv(GLenum pname, const GLfloat *params)
1373 {
1374  GET_CURRENT_CONTEXT(ctx);
1375  Node *n;
1377  n = alloc_instruction(ctx, OPCODE_FOG, 5);
1378  if (n) {
1379  n[1].e = pname;
1380  n[2].f = params[0];
1381  n[3].f = params[1];
1382  n[4].f = params[2];
1383  n[5].f = params[3];
1384  }
1385  if (ctx->ExecuteFlag) {
1386  CALL_Fogfv(ctx->Exec, (pname, params));
1387  }
1388 }
1389 
1390 
1391 static void GLAPIENTRY
1392 save_Fogf(GLenum pname, GLfloat param)
1393 {
1394  GLfloat parray[4];
1395  parray[0] = param;
1396  parray[1] = parray[2] = parray[3] = 0.0F;
1397  save_Fogfv(pname, parray);
1398 }
1399 
1400 
1401 static void GLAPIENTRY
1402 save_Fogiv(GLenum pname, const GLint *params)
1403 {
1404  GLfloat p[4];
1405  switch (pname) {
1406  case GL_FOG_MODE:
1407  case GL_FOG_DENSITY:
1408  case GL_FOG_START:
1409  case GL_FOG_END:
1410  case GL_FOG_INDEX:
1411  p[0] = (GLfloat) *params;
1412  p[1] = 0.0f;
1413  p[2] = 0.0f;
1414  p[3] = 0.0f;
1415  break;
1416  case GL_FOG_COLOR:
1417  p[0] = INT_TO_FLOAT(params[0]);
1418  p[1] = INT_TO_FLOAT(params[1]);
1419  p[2] = INT_TO_FLOAT(params[2]);
1420  p[3] = INT_TO_FLOAT(params[3]);
1421  break;
1422  default:
1423  /* Error will be caught later in gl_Fogfv */
1424  ASSIGN_4V(p, 0.0F, 0.0F, 0.0F, 0.0F);
1425  }
1426  save_Fogfv(pname, p);
1427 }
1428 
1429 
1430 static void GLAPIENTRY
1431 save_Fogi(GLenum pname, GLint param)
1432 {
1433  GLint parray[4];
1434  parray[0] = param;
1435  parray[1] = parray[2] = parray[3] = 0;
1436  save_Fogiv(pname, parray);
1437 }
1438 
1439 
1440 static void GLAPIENTRY
1441 save_FrontFace(GLenum mode)
1442 {
1443  GET_CURRENT_CONTEXT(ctx);
1444  Node *n;
1446  n = alloc_instruction(ctx, OPCODE_FRONT_FACE, 1);
1447  if (n) {
1448  n[1].e = mode;
1449  }
1450  if (ctx->ExecuteFlag) {
1451  CALL_FrontFace(ctx->Exec, (mode));
1452  }
1453 }
1454 
1455 
1456 static void GLAPIENTRY
1457 save_Frustum(GLdouble left, GLdouble right,
1458  GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval)
1459 {
1460  GET_CURRENT_CONTEXT(ctx);
1461  Node *n;
1463  n = alloc_instruction(ctx, OPCODE_FRUSTUM, 6);
1464  if (n) {
1465  n[1].f = (GLfloat) left;
1466  n[2].f = (GLfloat) right;
1467  n[3].f = (GLfloat) bottom;
1468  n[4].f = (GLfloat) top;
1469  n[5].f = (GLfloat) nearval;
1470  n[6].f = (GLfloat) farval;
1471  }
1472  if (ctx->ExecuteFlag) {
1473  CALL_Frustum(ctx->Exec, (left, right, bottom, top, nearval, farval));
1474  }
1475 }
1476 
1477 
1478 static void GLAPIENTRY
1479 save_Hint(GLenum target, GLenum mode)
1480 {
1481  GET_CURRENT_CONTEXT(ctx);
1482  Node *n;
1484  n = alloc_instruction(ctx, OPCODE_HINT, 2);
1485  if (n) {
1486  n[1].e = target;
1487  n[2].e = mode;
1488  }
1489  if (ctx->ExecuteFlag) {
1490  CALL_Hint(ctx->Exec, (target, mode));
1491  }
1492 }
1493 
1494 
1495 static void GLAPIENTRY
1496 save_IndexMask(GLuint mask)
1497 {
1498  GET_CURRENT_CONTEXT(ctx);
1499  Node *n;
1501  n = alloc_instruction(ctx, OPCODE_INDEX_MASK, 1);
1502  if (n) {
1503  n[1].ui = mask;
1504  }
1505  if (ctx->ExecuteFlag) {
1506  CALL_IndexMask(ctx->Exec, (mask));
1507  }
1508 }
1509 
1510 
1511 static void GLAPIENTRY
1512 save_InitNames(void)
1513 {
1514  GET_CURRENT_CONTEXT(ctx);
1516  (void) alloc_instruction(ctx, OPCODE_INIT_NAMES, 0);
1517  if (ctx->ExecuteFlag) {
1518  CALL_InitNames(ctx->Exec, ());
1519  }
1520 }
1521 
1522 
1523 static void GLAPIENTRY
1524 save_Lightfv(GLenum light, GLenum pname, const GLfloat *params)
1525 {
1526  GET_CURRENT_CONTEXT(ctx);
1527  Node *n;
1529  n = alloc_instruction(ctx, OPCODE_LIGHT, 6);
1530  if (n) {
1531  GLint i, nParams;
1532  n[1].e = light;
1533  n[2].e = pname;
1534  switch (pname) {
1535  case GL_AMBIENT:
1536  nParams = 4;
1537  break;
1538  case GL_DIFFUSE:
1539  nParams = 4;
1540  break;
1541  case GL_SPECULAR:
1542  nParams = 4;
1543  break;
1544  case GL_POSITION:
1545  nParams = 4;
1546  break;
1547  case GL_SPOT_DIRECTION:
1548  nParams = 3;
1549  break;
1550  case GL_SPOT_EXPONENT:
1551  nParams = 1;
1552  break;
1553  case GL_SPOT_CUTOFF:
1554  nParams = 1;
1555  break;
1557  nParams = 1;
1558  break;
1559  case GL_LINEAR_ATTENUATION:
1560  nParams = 1;
1561  break;
1563  nParams = 1;
1564  break;
1565  default:
1566  nParams = 0;
1567  }
1568  for (i = 0; i < nParams; i++) {
1569  n[3 + i].f = params[i];
1570  }
1571  }
1572  if (ctx->ExecuteFlag) {
1573  CALL_Lightfv(ctx->Exec, (light, pname, params));
1574  }
1575 }
1576 
1577 
1578 static void GLAPIENTRY
1579 save_Lightf(GLenum light, GLenum pname, GLfloat param)
1580 {
1581  GLfloat parray[4];
1582  parray[0] = param;
1583  parray[1] = parray[2] = parray[3] = 0.0F;
1584  save_Lightfv(light, pname, parray);
1585 }
1586 
1587 
1588 static void GLAPIENTRY
1589 save_Lightiv(GLenum light, GLenum pname, const GLint *params)
1590 {
1591  GLfloat fparam[4];
1592  switch (pname) {
1593  case GL_AMBIENT:
1594  case GL_DIFFUSE:
1595  case GL_SPECULAR:
1596  fparam[0] = INT_TO_FLOAT(params[0]);
1597  fparam[1] = INT_TO_FLOAT(params[1]);
1598  fparam[2] = INT_TO_FLOAT(params[2]);
1599  fparam[3] = INT_TO_FLOAT(params[3]);
1600  break;
1601  case GL_POSITION:
1602  fparam[0] = (GLfloat) params[0];
1603  fparam[1] = (GLfloat) params[1];
1604  fparam[2] = (GLfloat) params[2];
1605  fparam[3] = (GLfloat) params[3];
1606  break;
1607  case GL_SPOT_DIRECTION:
1608  fparam[0] = (GLfloat) params[0];
1609  fparam[1] = (GLfloat) params[1];
1610  fparam[2] = (GLfloat) params[2];
1611  break;
1612  case GL_SPOT_EXPONENT:
1613  case GL_SPOT_CUTOFF:
1615  case GL_LINEAR_ATTENUATION:
1617  fparam[0] = (GLfloat) params[0];
1618  break;
1619  default:
1620  /* error will be caught later in gl_Lightfv */
1621  ;
1622  }
1623  save_Lightfv(light, pname, fparam);
1624 }
1625 
1626 
1627 static void GLAPIENTRY
1628 save_Lighti(GLenum light, GLenum pname, GLint param)
1629 {
1630  GLint parray[4];
1631  parray[0] = param;
1632  parray[1] = parray[2] = parray[3] = 0;
1633  save_Lightiv(light, pname, parray);
1634 }
1635 
1636 
1637 static void GLAPIENTRY
1638 save_LightModelfv(GLenum pname, const GLfloat *params)
1639 {
1640  GET_CURRENT_CONTEXT(ctx);
1641  Node *n;
1643  n = alloc_instruction(ctx, OPCODE_LIGHT_MODEL, 5);
1644  if (n) {
1645  n[1].e = pname;
1646  n[2].f = params[0];
1647  n[3].f = params[1];
1648  n[4].f = params[2];
1649  n[5].f = params[3];
1650  }
1651  if (ctx->ExecuteFlag) {
1652  CALL_LightModelfv(ctx->Exec, (pname, params));
1653  }
1654 }
1655 
1656 
1657 static void GLAPIENTRY
1658 save_LightModelf(GLenum pname, GLfloat param)
1659 {
1660  GLfloat parray[4];
1661  parray[0] = param;
1662  parray[1] = parray[2] = parray[3] = 0.0F;
1663  save_LightModelfv(pname, parray);
1664 }
1665 
1666 
1667 static void GLAPIENTRY
1668 save_LightModeliv(GLenum pname, const GLint *params)
1669 {
1670  GLfloat fparam[4];
1671  switch (pname) {
1673  fparam[0] = INT_TO_FLOAT(params[0]);
1674  fparam[1] = INT_TO_FLOAT(params[1]);
1675  fparam[2] = INT_TO_FLOAT(params[2]);
1676  fparam[3] = INT_TO_FLOAT(params[3]);
1677  break;
1681  fparam[0] = (GLfloat) params[0];
1682  fparam[1] = 0.0F;
1683  fparam[2] = 0.0F;
1684  fparam[3] = 0.0F;
1685  break;
1686  default:
1687  /* Error will be caught later in gl_LightModelfv */
1688  ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F);
1689  }
1690  save_LightModelfv(pname, fparam);
1691 }
1692 
1693 
1694 static void GLAPIENTRY
1695 save_LightModeli(GLenum pname, GLint param)
1696 {
1697  GLint parray[4];
1698  parray[0] = param;
1699  parray[1] = parray[2] = parray[3] = 0;
1700  save_LightModeliv(pname, parray);
1701 }
1702 
1703 
1704 static void GLAPIENTRY
1705 save_LineStipple(GLint factor, GLushort pattern)
1706 {
1707  GET_CURRENT_CONTEXT(ctx);
1708  Node *n;
1710  n = alloc_instruction(ctx, OPCODE_LINE_STIPPLE, 2);
1711  if (n) {
1712  n[1].i = factor;
1713  n[2].us = pattern;
1714  }
1715  if (ctx->ExecuteFlag) {
1716  CALL_LineStipple(ctx->Exec, (factor, pattern));
1717  }
1718 }
1719 
1720 
1721 static void GLAPIENTRY
1722 save_LineWidth(GLfloat width)
1723 {
1724  GET_CURRENT_CONTEXT(ctx);
1725  Node *n;
1727  n = alloc_instruction(ctx, OPCODE_LINE_WIDTH, 1);
1728  if (n) {
1729  n[1].f = width;
1730  }
1731  if (ctx->ExecuteFlag) {
1732  CALL_LineWidth(ctx->Exec, (width));
1733  }
1734 }
1735 
1736 
1737 static void GLAPIENTRY
1738 save_ListBase(GLuint base)
1739 {
1740  GET_CURRENT_CONTEXT(ctx);
1741  Node *n;
1743  n = alloc_instruction(ctx, OPCODE_LIST_BASE, 1);
1744  if (n) {
1745  n[1].ui = base;
1746  }
1747  if (ctx->ExecuteFlag) {
1748  CALL_ListBase(ctx->Exec, (base));
1749  }
1750 }
1751 
1752 
1753 static void GLAPIENTRY
1754 save_LoadIdentity(void)
1755 {
1756  GET_CURRENT_CONTEXT(ctx);
1758  (void) alloc_instruction(ctx, OPCODE_LOAD_IDENTITY, 0);
1759  if (ctx->ExecuteFlag) {
1760  CALL_LoadIdentity(ctx->Exec, ());
1761  }
1762 }
1763 
1764 
1765 static void GLAPIENTRY
1766 save_LoadMatrixf(const GLfloat * m)
1767 {
1768  GET_CURRENT_CONTEXT(ctx);
1769  Node *n;
1771  n = alloc_instruction(ctx, OPCODE_LOAD_MATRIX, 16);
1772  if (n) {
1773  GLuint i;
1774  for (i = 0; i < 16; i++) {
1775  n[1 + i].f = m[i];
1776  }
1777  }
1778  if (ctx->ExecuteFlag) {
1779  CALL_LoadMatrixf(ctx->Exec, (m));
1780  }
1781 }
1782 
1783 
1784 static void GLAPIENTRY
1785 save_LoadMatrixd(const GLdouble * m)
1786 {
1787  GLfloat f[16];
1788  GLint i;
1789  for (i = 0; i < 16; i++) {
1790  f[i] = (GLfloat) m[i];
1791  }
1792  save_LoadMatrixf(f);
1793 }
1794 
1795 
1796 static void GLAPIENTRY
1797 save_LoadName(GLuint name)
1798 {
1799  GET_CURRENT_CONTEXT(ctx);
1800  Node *n;
1802  n = alloc_instruction(ctx, OPCODE_LOAD_NAME, 1);
1803  if (n) {
1804  n[1].ui = name;
1805  }
1806  if (ctx->ExecuteFlag) {
1807  CALL_LoadName(ctx->Exec, (name));
1808  }
1809 }
1810 
1811 
1812 static void GLAPIENTRY
1813 save_LogicOp(GLenum opcode)
1814 {
1815  GET_CURRENT_CONTEXT(ctx);
1816  Node *n;
1818  n = alloc_instruction(ctx, OPCODE_LOGIC_OP, 1);
1819  if (n) {
1820  n[1].e = opcode;
1821  }
1822  if (ctx->ExecuteFlag) {
1823  CALL_LogicOp(ctx->Exec, (opcode));
1824  }
1825 }
1826 
1827 
1828 static void GLAPIENTRY
1829 save_Map1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride,
1830  GLint order, const GLdouble * points)
1831 {
1832  GET_CURRENT_CONTEXT(ctx);
1833  Node *n;
1835  n = alloc_instruction(ctx, OPCODE_MAP1, 6);
1836  if (n) {
1837  GLfloat *pnts = _mesa_copy_map_points1d(target, stride, order, points);
1838  n[1].e = target;
1839  n[2].f = (GLfloat) u1;
1840  n[3].f = (GLfloat) u2;
1841  n[4].i = _mesa_evaluator_components(target); /* stride */
1842  n[5].i = order;
1843  n[6].data = (void *) pnts;
1844  }
1845  if (ctx->ExecuteFlag) {
1846  CALL_Map1d(ctx->Exec, (target, u1, u2, stride, order, points));
1847  }
1848 }
1849 
1850 static void GLAPIENTRY
1851 save_Map1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
1852  GLint order, const GLfloat * points)
1853 {
1854  GET_CURRENT_CONTEXT(ctx);
1855  Node *n;
1857  n = alloc_instruction(ctx, OPCODE_MAP1, 6);
1858  if (n) {
1859  GLfloat *pnts = _mesa_copy_map_points1f(target, stride, order, points);
1860  n[1].e = target;
1861  n[2].f = u1;
1862  n[3].f = u2;
1863  n[4].i = _mesa_evaluator_components(target); /* stride */
1864  n[5].i = order;
1865  n[6].data = (void *) pnts;
1866  }
1867  if (ctx->ExecuteFlag) {
1868  CALL_Map1f(ctx->Exec, (target, u1, u2, stride, order, points));
1869  }
1870 }
1871 
1872 
1873 static void GLAPIENTRY
1874 save_Map2d(GLenum target,
1877  const GLdouble * points)
1878 {
1879  GET_CURRENT_CONTEXT(ctx);
1880  Node *n;
1882  n = alloc_instruction(ctx, OPCODE_MAP2, 10);
1883  if (n) {
1884  GLfloat *pnts = _mesa_copy_map_points2d(target, ustride, uorder,
1885  vstride, vorder, points);
1886  n[1].e = target;
1887  n[2].f = (GLfloat) u1;
1888  n[3].f = (GLfloat) u2;
1889  n[4].f = (GLfloat) v1;
1890  n[5].f = (GLfloat) v2;
1891  /* XXX verify these strides are correct */
1892  n[6].i = _mesa_evaluator_components(target) * vorder; /*ustride */
1893  n[7].i = _mesa_evaluator_components(target); /*vstride */
1894  n[8].i = uorder;
1895  n[9].i = vorder;
1896  n[10].data = (void *) pnts;
1897  }
1898  if (ctx->ExecuteFlag) {
1899  CALL_Map2d(ctx->Exec, (target,
1900  u1, u2, ustride, uorder,
1901  v1, v2, vstride, vorder, points));
1902  }
1903 }
1904 
1905 
1906 static void GLAPIENTRY
1907 save_Map2f(GLenum target,
1908  GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
1909  GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
1910  const GLfloat * points)
1911 {
1912  GET_CURRENT_CONTEXT(ctx);
1913  Node *n;
1915  n = alloc_instruction(ctx, OPCODE_MAP2, 10);
1916  if (n) {
1917  GLfloat *pnts = _mesa_copy_map_points2f(target, ustride, uorder,
1918  vstride, vorder, points);
1919  n[1].e = target;
1920  n[2].f = u1;
1921  n[3].f = u2;
1922  n[4].f = v1;
1923  n[5].f = v2;
1924  /* XXX verify these strides are correct */
1925  n[6].i = _mesa_evaluator_components(target) * vorder; /*ustride */
1926  n[7].i = _mesa_evaluator_components(target); /*vstride */
1927  n[8].i = uorder;
1928  n[9].i = vorder;
1929  n[10].data = (void *) pnts;
1930  }
1931  if (ctx->ExecuteFlag) {
1932  CALL_Map2f(ctx->Exec, (target, u1, u2, ustride, uorder,
1933  v1, v2, vstride, vorder, points));
1934  }
1935 }
1936 
1937 
1938 static void GLAPIENTRY
1939 save_MapGrid1f(GLint un, GLfloat u1, GLfloat u2)
1940 {
1941  GET_CURRENT_CONTEXT(ctx);
1942  Node *n;
1944  n = alloc_instruction(ctx, OPCODE_MAPGRID1, 3);
1945  if (n) {
1946  n[1].i = un;
1947  n[2].f = u1;
1948  n[3].f = u2;
1949  }
1950  if (ctx->ExecuteFlag) {
1951  CALL_MapGrid1f(ctx->Exec, (un, u1, u2));
1952  }
1953 }
1954 
1955 
1956 static void GLAPIENTRY
1957 save_MapGrid1d(GLint un, GLdouble u1, GLdouble u2)
1958 {
1959  save_MapGrid1f(un, (GLfloat) u1, (GLfloat) u2);
1960 }
1961 
1962 
1963 static void GLAPIENTRY
1964 save_MapGrid2f(GLint un, GLfloat u1, GLfloat u2,
1965  GLint vn, GLfloat v1, GLfloat v2)
1966 {
1967  GET_CURRENT_CONTEXT(ctx);
1968  Node *n;
1970  n = alloc_instruction(ctx, OPCODE_MAPGRID2, 6);
1971  if (n) {
1972  n[1].i = un;
1973  n[2].f = u1;
1974  n[3].f = u2;
1975  n[4].i = vn;
1976  n[5].f = v1;
1977  n[6].f = v2;
1978  }
1979  if (ctx->ExecuteFlag) {
1980  CALL_MapGrid2f(ctx->Exec, (un, u1, u2, vn, v1, v2));
1981  }
1982 }
1983 
1984 
1985 
1986 static void GLAPIENTRY
1987 save_MapGrid2d(GLint un, GLdouble u1, GLdouble u2,
1988  GLint vn, GLdouble v1, GLdouble v2)
1989 {
1990  save_MapGrid2f(un, (GLfloat) u1, (GLfloat) u2,
1991  vn, (GLfloat) v1, (GLfloat) v2);
1992 }
1993 
1994 
1995 static void GLAPIENTRY
1996 save_MatrixMode(GLenum mode)
1997 {
1998  GET_CURRENT_CONTEXT(ctx);
1999  Node *n;
2001  n = alloc_instruction(ctx, OPCODE_MATRIX_MODE, 1);
2002  if (n) {
2003  n[1].e = mode;
2004  }
2005  if (ctx->ExecuteFlag) {
2006  CALL_MatrixMode(ctx->Exec, (mode));
2007  }
2008 }
2009 
2010 
2011 static void GLAPIENTRY
2012 save_MultMatrixf(const GLfloat * m)
2013 {
2014  GET_CURRENT_CONTEXT(ctx);
2015  Node *n;
2017  n = alloc_instruction(ctx, OPCODE_MULT_MATRIX, 16);
2018  if (n) {
2019  GLuint i;
2020  for (i = 0; i < 16; i++) {
2021  n[1 + i].f = m[i];
2022  }
2023  }
2024  if (ctx->ExecuteFlag) {
2025  CALL_MultMatrixf(ctx->Exec, (m));
2026  }
2027 }
2028 
2029 
2030 static void GLAPIENTRY
2031 save_MultMatrixd(const GLdouble * m)
2032 {
2033  GLfloat f[16];
2034  GLint i;
2035  for (i = 0; i < 16; i++) {
2036  f[i] = (GLfloat) m[i];
2037  }
2038  save_MultMatrixf(f);
2039 }
2040 
2041 
2042 static void GLAPIENTRY
2043 save_NewList(GLuint name, GLenum mode)
2044 {
2045  GET_CURRENT_CONTEXT(ctx);
2046  /* It's an error to call this function while building a display list */
2047  _mesa_error(ctx, GL_INVALID_OPERATION, "glNewList");
2048  (void) name;
2049  (void) mode;
2050 }
2051 
2052 
2053 
2054 static void GLAPIENTRY
2055 save_Ortho(GLdouble left, GLdouble right,
2056  GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval)
2057 {
2058  GET_CURRENT_CONTEXT(ctx);
2059  Node *n;
2061  n = alloc_instruction(ctx, OPCODE_ORTHO, 6);
2062  if (n) {
2063  n[1].f = (GLfloat) left;
2064  n[2].f = (GLfloat) right;
2065  n[3].f = (GLfloat) bottom;
2066  n[4].f = (GLfloat) top;
2067  n[5].f = (GLfloat) nearval;
2068  n[6].f = (GLfloat) farval;
2069  }
2070  if (ctx->ExecuteFlag) {
2071  CALL_Ortho(ctx->Exec, (left, right, bottom, top, nearval, farval));
2072  }
2073 }
2074 
2075 
2076 static void GLAPIENTRY
2077 save_PixelMapfv(GLenum map, GLint mapsize, const GLfloat *values)
2078 {
2079  GET_CURRENT_CONTEXT(ctx);
2080  Node *n;
2082  n = alloc_instruction(ctx, OPCODE_PIXEL_MAP, 3);
2083  if (n) {
2084  n[1].e = map;
2085  n[2].i = mapsize;
2086  n[3].data = (void *) malloc(mapsize * sizeof(GLfloat));
2087  memcpy(n[3].data, (void *) values, mapsize * sizeof(GLfloat));
2088  }
2089  if (ctx->ExecuteFlag) {
2090  CALL_PixelMapfv(ctx->Exec, (map, mapsize, values));
2091  }
2092 }
2093 
2094 
2095 static void GLAPIENTRY
2096 save_PixelMapuiv(GLenum map, GLint mapsize, const GLuint *values)
2097 {
2098  GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
2099  GLint i;
2100  if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
2101  for (i = 0; i < mapsize; i++) {
2102  fvalues[i] = (GLfloat) values[i];
2103  }
2104  }
2105  else {
2106  for (i = 0; i < mapsize; i++) {
2107  fvalues[i] = UINT_TO_FLOAT(values[i]);
2108  }
2109  }
2110  save_PixelMapfv(map, mapsize, fvalues);
2111 }
2112 
2113 
2114 static void GLAPIENTRY
2115 save_PixelMapusv(GLenum map, GLint mapsize, const GLushort *values)
2116 {
2117  GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
2118  GLint i;
2119  if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
2120  for (i = 0; i < mapsize; i++) {
2121  fvalues[i] = (GLfloat) values[i];
2122  }
2123  }
2124  else {
2125  for (i = 0; i < mapsize; i++) {
2126  fvalues[i] = USHORT_TO_FLOAT(values[i]);
2127  }
2128  }
2129  save_PixelMapfv(map, mapsize, fvalues);
2130 }
2131 
2132 
2133 static void GLAPIENTRY
2134 save_PixelTransferf(GLenum pname, GLfloat param)
2135 {
2136  GET_CURRENT_CONTEXT(ctx);
2137  Node *n;
2139  n = alloc_instruction(ctx, OPCODE_PIXEL_TRANSFER, 2);
2140  if (n) {
2141  n[1].e = pname;
2142  n[2].f = param;
2143  }
2144  if (ctx->ExecuteFlag) {
2145  CALL_PixelTransferf(ctx->Exec, (pname, param));
2146  }
2147 }
2148 
2149 
2150 static void GLAPIENTRY
2151 save_PixelTransferi(GLenum pname, GLint param)
2152 {
2153  save_PixelTransferf(pname, (GLfloat) param);
2154 }
2155 
2156 
2157 static void GLAPIENTRY
2158 save_PixelZoom(GLfloat xfactor, GLfloat yfactor)
2159 {
2160  GET_CURRENT_CONTEXT(ctx);
2161  Node *n;
2163  n = alloc_instruction(ctx, OPCODE_PIXEL_ZOOM, 2);
2164  if (n) {
2165  n[1].f = xfactor;
2166  n[2].f = yfactor;
2167  }
2168  if (ctx->ExecuteFlag) {
2169  CALL_PixelZoom(ctx->Exec, (xfactor, yfactor));
2170  }
2171 }
2172 
2173 
2174 static void GLAPIENTRY
2175 save_PointParameterfvEXT(GLenum pname, const GLfloat *params)
2176 {
2177  GET_CURRENT_CONTEXT(ctx);
2178  Node *n;
2180  n = alloc_instruction(ctx, OPCODE_POINT_PARAMETERS, 4);
2181  if (n) {
2182  n[1].e = pname;
2183  n[2].f = params[0];
2184  n[3].f = params[1];
2185  n[4].f = params[2];
2186  }
2187  if (ctx->ExecuteFlag) {
2188  CALL_PointParameterfvEXT(ctx->Exec, (pname, params));
2189  }
2190 }
2191 
2192 
2193 static void GLAPIENTRY
2194 save_PointParameterfEXT(GLenum pname, GLfloat param)
2195 {
2196  GLfloat parray[3];
2197  parray[0] = param;
2198  parray[1] = parray[2] = 0.0F;
2199  save_PointParameterfvEXT(pname, parray);
2200 }
2201 
2202 static void GLAPIENTRY
2203 save_PointParameteriNV(GLenum pname, GLint param)
2204 {
2205  GLfloat parray[3];
2206  parray[0] = (GLfloat) param;
2207  parray[1] = parray[2] = 0.0F;
2208  save_PointParameterfvEXT(pname, parray);
2209 }
2210 
2211 static void GLAPIENTRY
2212 save_PointParameterivNV(GLenum pname, const GLint * param)
2213 {
2214  GLfloat parray[3];
2215  parray[0] = (GLfloat) param[0];
2216  parray[1] = parray[2] = 0.0F;
2217  save_PointParameterfvEXT(pname, parray);
2218 }
2219 
2220 
2221 static void GLAPIENTRY
2222 save_PointSize(GLfloat size)
2223 {
2224  GET_CURRENT_CONTEXT(ctx);
2225  Node *n;
2227  n = alloc_instruction(ctx, OPCODE_POINT_SIZE, 1);
2228  if (n) {
2229  n[1].f = size;
2230  }
2231  if (ctx->ExecuteFlag) {
2232  CALL_PointSize(ctx->Exec, (size));
2233  }
2234 }
2235 
2236 
2237 static void GLAPIENTRY
2238 save_PolygonMode(GLenum face, GLenum mode)
2239 {
2240  GET_CURRENT_CONTEXT(ctx);
2241  Node *n;
2243  n = alloc_instruction(ctx, OPCODE_POLYGON_MODE, 2);
2244  if (n) {
2245  n[1].e = face;
2246  n[2].e = mode;
2247  }
2248  if (ctx->ExecuteFlag) {
2249  CALL_PolygonMode(ctx->Exec, (face, mode));
2250  }
2251 }
2252 
2253 
2254 static void GLAPIENTRY
2255 save_PolygonStipple(const GLubyte * pattern)
2256 {
2257  GET_CURRENT_CONTEXT(ctx);
2258  Node *n;
2259 
2261 
2262  n = alloc_instruction(ctx, OPCODE_POLYGON_STIPPLE, 1);
2263  if (n) {
2264  n[1].data = unpack_image(ctx, 2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP,
2265  pattern, &ctx->Unpack);
2266  }
2267  if (ctx->ExecuteFlag) {
2268  CALL_PolygonStipple(ctx->Exec, ((GLubyte *) pattern));
2269  }
2270 }
2271 
2272 
2273 static void GLAPIENTRY
2274 save_PolygonOffset(GLfloat factor, GLfloat units)
2275 {
2276  GET_CURRENT_CONTEXT(ctx);
2277  Node *n;
2279  n = alloc_instruction(ctx, OPCODE_POLYGON_OFFSET, 2);
2280  if (n) {
2281  n[1].f = factor;
2282  n[2].f = units;
2283  }
2284  if (ctx->ExecuteFlag) {
2285  CALL_PolygonOffset(ctx->Exec, (factor, units));
2286  }
2287 }
2288 
2289 
2290 static void GLAPIENTRY
2291 save_PolygonOffsetEXT(GLfloat factor, GLfloat bias)
2292 {
2293  GET_CURRENT_CONTEXT(ctx);
2294  /* XXX mult by DepthMaxF here??? */
2295  save_PolygonOffset(factor, ctx->DrawBuffer->_DepthMaxF * bias);
2296 }
2297 
2298 
2299 static void GLAPIENTRY
2300 save_PopAttrib(void)
2301 {
2302  GET_CURRENT_CONTEXT(ctx);
2304  (void) alloc_instruction(ctx, OPCODE_POP_ATTRIB, 0);
2305  if (ctx->ExecuteFlag) {
2306  CALL_PopAttrib(ctx->Exec, ());
2307  }
2308 }
2309 
2310 
2311 static void GLAPIENTRY
2312 save_PopMatrix(void)
2313 {
2314  GET_CURRENT_CONTEXT(ctx);
2316  (void) alloc_instruction(ctx, OPCODE_POP_MATRIX, 0);
2317  if (ctx->ExecuteFlag) {
2318  CALL_PopMatrix(ctx->Exec, ());
2319  }
2320 }
2321 
2322 
2323 static void GLAPIENTRY
2324 save_PopName(void)
2325 {
2326  GET_CURRENT_CONTEXT(ctx);
2328  (void) alloc_instruction(ctx, OPCODE_POP_NAME, 0);
2329  if (ctx->ExecuteFlag) {
2330  CALL_PopName(ctx->Exec, ());
2331  }
2332 }
2333 
2334 
2335 static void GLAPIENTRY
2336 save_PrioritizeTextures(GLsizei num, const GLuint * textures,
2337  const GLclampf * priorities)
2338 {
2339  GET_CURRENT_CONTEXT(ctx);
2340  GLint i;
2342 
2343  for (i = 0; i < num; i++) {
2344  Node *n;
2345  n = alloc_instruction(ctx, OPCODE_PRIORITIZE_TEXTURE, 2);
2346  if (n) {
2347  n[1].ui = textures[i];
2348  n[2].f = priorities[i];
2349  }
2350  }
2351  if (ctx->ExecuteFlag) {
2352  CALL_PrioritizeTextures(ctx->Exec, (num, textures, priorities));
2353  }
2354 }
2355 
2356 
2357 static void GLAPIENTRY
2358 save_PushAttrib(GLbitfield mask)
2359 {
2360  GET_CURRENT_CONTEXT(ctx);
2361  Node *n;
2363  n = alloc_instruction(ctx, OPCODE_PUSH_ATTRIB, 1);
2364  if (n) {
2365  n[1].bf = mask;
2366  }
2367  if (ctx->ExecuteFlag) {
2368  CALL_PushAttrib(ctx->Exec, (mask));
2369  }
2370 }
2371 
2372 
2373 static void GLAPIENTRY
2374 save_PushMatrix(void)
2375 {
2376  GET_CURRENT_CONTEXT(ctx);
2378  (void) alloc_instruction(ctx, OPCODE_PUSH_MATRIX, 0);
2379  if (ctx->ExecuteFlag) {
2380  CALL_PushMatrix(ctx->Exec, ());
2381  }
2382 }
2383 
2384 
2385 static void GLAPIENTRY
2386 save_PushName(GLuint name)
2387 {
2388  GET_CURRENT_CONTEXT(ctx);
2389  Node *n;
2391  n = alloc_instruction(ctx, OPCODE_PUSH_NAME, 1);
2392  if (n) {
2393  n[1].ui = name;
2394  }
2395  if (ctx->ExecuteFlag) {
2396  CALL_PushName(ctx->Exec, (name));
2397  }
2398 }
2399 
2400 
2401 static void GLAPIENTRY
2402 save_RasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2403 {
2404  GET_CURRENT_CONTEXT(ctx);
2405  Node *n;
2407  n = alloc_instruction(ctx, OPCODE_RASTER_POS, 4);
2408  if (n) {
2409  n[1].f = x;
2410  n[2].f = y;
2411  n[3].f = z;
2412  n[4].f = w;
2413  }
2414  if (ctx->ExecuteFlag) {
2415  CALL_RasterPos4f(ctx->Exec, (x, y, z, w));
2416  }
2417 }
2418 
2419 static void GLAPIENTRY
2420 save_RasterPos2d(GLdouble x, GLdouble y)
2421 {
2422  save_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
2423 }
2424 
2425 static void GLAPIENTRY
2426 save_RasterPos2f(GLfloat x, GLfloat y)
2427 {
2428  save_RasterPos4f(x, y, 0.0F, 1.0F);
2429 }
2430 
2431 static void GLAPIENTRY
2432 save_RasterPos2i(GLint x, GLint y)
2433 {
2434  save_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
2435 }
2436 
2437 static void GLAPIENTRY
2438 save_RasterPos2s(GLshort x, GLshort y)
2439 {
2440  save_RasterPos4f(x, y, 0.0F, 1.0F);
2441 }
2442 
2443 static void GLAPIENTRY
2444 save_RasterPos3d(GLdouble x, GLdouble y, GLdouble z)
2445 {
2446  save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
2447 }
2448 
2449 static void GLAPIENTRY
2450 save_RasterPos3f(GLfloat x, GLfloat y, GLfloat z)
2451 {
2452  save_RasterPos4f(x, y, z, 1.0F);
2453 }
2454 
2455 static void GLAPIENTRY
2456 save_RasterPos3i(GLint x, GLint y, GLint z)
2457 {
2458  save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
2459 }
2460 
2461 static void GLAPIENTRY
2462 save_RasterPos3s(GLshort x, GLshort y, GLshort z)
2463 {
2464  save_RasterPos4f(x, y, z, 1.0F);
2465 }
2466 
2467 static void GLAPIENTRY
2468 save_RasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
2469 {
2470  save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
2471 }
2472 
2473 static void GLAPIENTRY
2474 save_RasterPos4i(GLint x, GLint y, GLint z, GLint w)
2475 {
2476  save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
2477 }
2478 
2479 static void GLAPIENTRY
2480 save_RasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
2481 {
2482  save_RasterPos4f(x, y, z, w);
2483 }
2484 
2485 static void GLAPIENTRY
2486 save_RasterPos2dv(const GLdouble * v)
2487 {
2488  save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
2489 }
2490 
2491 static void GLAPIENTRY
2492 save_RasterPos2fv(const GLfloat * v)
2493 {
2494  save_RasterPos4f(v[0], v[1], 0.0F, 1.0F);
2495 }
2496 
2497 static void GLAPIENTRY
2498 save_RasterPos2iv(const GLint * v)
2499 {
2500  save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
2501 }
2502 
2503 static void GLAPIENTRY
2504 save_RasterPos2sv(const GLshort * v)
2505 {
2506  save_RasterPos4f(v[0], v[1], 0.0F, 1.0F);
2507 }
2508 
2509 static void GLAPIENTRY
2510 save_RasterPos3dv(const GLdouble * v)
2511 {
2512  save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
2513 }
2514 
2515 static void GLAPIENTRY
2516 save_RasterPos3fv(const GLfloat * v)
2517 {
2518  save_RasterPos4f(v[0], v[1], v[2], 1.0F);
2519 }
2520 
2521 static void GLAPIENTRY
2522 save_RasterPos3iv(const GLint * v)
2523 {
2524  save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
2525 }
2526 
2527 static void GLAPIENTRY
2528 save_RasterPos3sv(const GLshort * v)
2529 {
2530  save_RasterPos4f(v[0], v[1], v[2], 1.0F);
2531 }
2532 
2533 static void GLAPIENTRY
2534 save_RasterPos4dv(const GLdouble * v)
2535 {
2536  save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1],
2537  (GLfloat) v[2], (GLfloat) v[3]);
2538 }
2539 
2540 static void GLAPIENTRY
2541 save_RasterPos4fv(const GLfloat * v)
2542 {
2543  save_RasterPos4f(v[0], v[1], v[2], v[3]);
2544 }
2545 
2546 static void GLAPIENTRY
2547 save_RasterPos4iv(const GLint * v)
2548 {
2549  save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1],
2550  (GLfloat) v[2], (GLfloat) v[3]);
2551 }
2552 
2553 static void GLAPIENTRY
2554 save_RasterPos4sv(const GLshort * v)
2555 {
2556  save_RasterPos4f(v[0], v[1], v[2], v[3]);
2557 }
2558 
2559 
2560 static void GLAPIENTRY
2561 save_PassThrough(GLfloat token)
2562 {
2563  GET_CURRENT_CONTEXT(ctx);
2564  Node *n;
2566  n = alloc_instruction(ctx, OPCODE_PASSTHROUGH, 1);
2567  if (n) {
2568  n[1].f = token;
2569  }
2570  if (ctx->ExecuteFlag) {
2571  CALL_PassThrough(ctx->Exec, (token));
2572  }
2573 }
2574 
2575 
2576 static void GLAPIENTRY
2577 save_ReadBuffer(GLenum mode)
2578 {
2579  GET_CURRENT_CONTEXT(ctx);
2580  Node *n;
2582  n = alloc_instruction(ctx, OPCODE_READ_BUFFER, 1);
2583  if (n) {
2584  n[1].e = mode;
2585  }
2586  if (ctx->ExecuteFlag) {
2587  CALL_ReadBuffer(ctx->Exec, (mode));
2588  }
2589 }
2590 
2591 
2592 static void GLAPIENTRY
2593 save_Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
2594 {
2595  GET_CURRENT_CONTEXT(ctx);
2596  Node *n;
2598  n = alloc_instruction(ctx, OPCODE_ROTATE, 4);
2599  if (n) {
2600  n[1].f = angle;
2601  n[2].f = x;
2602  n[3].f = y;
2603  n[4].f = z;
2604  }
2605  if (ctx->ExecuteFlag) {
2606  CALL_Rotatef(ctx->Exec, (angle, x, y, z));
2607  }
2608 }
2609 
2610 
2611 static void GLAPIENTRY
2612 save_Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
2613 {
2614  save_Rotatef((GLfloat) angle, (GLfloat) x, (GLfloat) y, (GLfloat) z);
2615 }
2616 
2617 
2618 static void GLAPIENTRY
2619 save_Scalef(GLfloat x, GLfloat y, GLfloat z)
2620 {
2621  GET_CURRENT_CONTEXT(ctx);
2622  Node *n;
2624  n = alloc_instruction(ctx, OPCODE_SCALE, 3);
2625  if (n) {
2626  n[1].f = x;
2627  n[2].f = y;
2628  n[3].f = z;
2629  }
2630  if (ctx->ExecuteFlag) {
2631  CALL_Scalef(ctx->Exec, (x, y, z));
2632  }
2633 }
2634 
2635 
2636 static void GLAPIENTRY
2637 save_Scaled(GLdouble x, GLdouble y, GLdouble z)
2638 {
2639  save_Scalef((GLfloat) x, (GLfloat) y, (GLfloat) z);
2640 }
2641 
2642 
2643 static void GLAPIENTRY
2644 save_Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
2645 {
2646  GET_CURRENT_CONTEXT(ctx);
2647  Node *n;
2649  n = alloc_instruction(ctx, OPCODE_SCISSOR, 4);
2650  if (n) {
2651  n[1].i = x;
2652  n[2].i = y;
2653  n[3].i = width;
2654  n[4].i = height;
2655  }
2656  if (ctx->ExecuteFlag) {
2657  CALL_Scissor(ctx->Exec, (x, y, width, height));
2658  }
2659 }
2660 
2661 
2662 static void GLAPIENTRY
2663 save_ShadeModel(GLenum mode)
2664 {
2665  GET_CURRENT_CONTEXT(ctx);
2666  Node *n;
2668 
2669  if (ctx->ExecuteFlag) {
2670  CALL_ShadeModel(ctx->Exec, (mode));
2671  }
2672 
2673  if (ctx->ListState.Current.ShadeModel == mode)
2674  return;
2675 
2676  SAVE_FLUSH_VERTICES(ctx);
2677 
2678  /* Only save the value if we know the statechange will take effect:
2679  */
2680  if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END)
2681  ctx->ListState.Current.ShadeModel = mode;
2682 
2683  n = alloc_instruction(ctx, OPCODE_SHADE_MODEL, 1);
2684  if (n) {
2685  n[1].e = mode;
2686  }
2687 }
2688 
2689 
2690 static void GLAPIENTRY
2691 save_StencilFunc(GLenum func, GLint ref, GLuint mask)
2692 {
2693  GET_CURRENT_CONTEXT(ctx);
2694  Node *n;
2696  n = alloc_instruction(ctx, OPCODE_STENCIL_FUNC, 3);
2697  if (n) {
2698  n[1].e = func;
2699  n[2].i = ref;
2700  n[3].ui = mask;
2701  }
2702  if (ctx->ExecuteFlag) {
2703  CALL_StencilFunc(ctx->Exec, (func, ref, mask));
2704  }
2705 }
2706 
2707 
2708 static void GLAPIENTRY
2709 save_StencilMask(GLuint mask)
2710 {
2711  GET_CURRENT_CONTEXT(ctx);
2712  Node *n;
2714  n = alloc_instruction(ctx, OPCODE_STENCIL_MASK, 1);
2715  if (n) {
2716  n[1].ui = mask;
2717  }
2718  if (ctx->ExecuteFlag) {
2719  CALL_StencilMask(ctx->Exec, (mask));
2720  }
2721 }
2722 
2723 
2724 static void GLAPIENTRY
2725 save_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
2726 {
2727  GET_CURRENT_CONTEXT(ctx);
2728  Node *n;
2730  n = alloc_instruction(ctx, OPCODE_STENCIL_OP, 3);
2731  if (n) {
2732  n[1].e = fail;
2733  n[2].e = zfail;
2734  n[3].e = zpass;
2735  }
2736  if (ctx->ExecuteFlag) {
2737  CALL_StencilOp(ctx->Exec, (fail, zfail, zpass));
2738  }
2739 }
2740 
2741 
2742 static void GLAPIENTRY
2743 save_TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
2744 {
2745  GET_CURRENT_CONTEXT(ctx);
2746  Node *n;
2748  n = alloc_instruction(ctx, OPCODE_TEXENV, 6);
2749  if (n) {
2750  n[1].e = target;
2751  n[2].e = pname;
2752  if (pname == GL_TEXTURE_ENV_COLOR) {
2753  n[3].f = params[0];
2754  n[4].f = params[1];
2755  n[5].f = params[2];
2756  n[6].f = params[3];
2757  }
2758  else {
2759  n[3].f = params[0];
2760  n[4].f = n[5].f = n[6].f = 0.0F;
2761  }
2762  }
2763  if (ctx->ExecuteFlag) {
2764  CALL_TexEnvfv(ctx->Exec, (target, pname, params));
2765  }
2766 }
2767 
2768 
2769 static void GLAPIENTRY
2770 save_TexEnvf(GLenum target, GLenum pname, GLfloat param)
2771 {
2772  GLfloat parray[4];
2773  parray[0] = (GLfloat) param;
2774  parray[1] = parray[2] = parray[3] = 0.0F;
2775  save_TexEnvfv(target, pname, parray);
2776 }
2777 
2778 
2779 static void GLAPIENTRY
2780 save_TexEnvi(GLenum target, GLenum pname, GLint param)
2781 {
2782  GLfloat p[4];
2783  p[0] = (GLfloat) param;
2784  p[1] = p[2] = p[3] = 0.0F;
2785  save_TexEnvfv(target, pname, p);
2786 }
2787 
2788 
2789 static void GLAPIENTRY
2790 save_TexEnviv(GLenum target, GLenum pname, const GLint * param)
2791 {
2792  GLfloat p[4];
2793  if (pname == GL_TEXTURE_ENV_COLOR) {
2794  p[0] = INT_TO_FLOAT(param[0]);
2795  p[1] = INT_TO_FLOAT(param[1]);
2796  p[2] = INT_TO_FLOAT(param[2]);
2797  p[3] = INT_TO_FLOAT(param[3]);
2798  }
2799  else {
2800  p[0] = (GLfloat) param[0];
2801  p[1] = p[2] = p[3] = 0.0F;
2802  }
2803  save_TexEnvfv(target, pname, p);
2804 }
2805 
2806 
2807 static void GLAPIENTRY
2808 save_TexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
2809 {
2810  GET_CURRENT_CONTEXT(ctx);
2811  Node *n;
2813  n = alloc_instruction(ctx, OPCODE_TEXGEN, 6);
2814  if (n) {
2815  n[1].e = coord;
2816  n[2].e = pname;
2817  n[3].f = params[0];
2818  n[4].f = params[1];
2819  n[5].f = params[2];
2820  n[6].f = params[3];
2821  }
2822  if (ctx->ExecuteFlag) {
2823  CALL_TexGenfv(ctx->Exec, (coord, pname, params));
2824  }
2825 }
2826 
2827 
2828 static void GLAPIENTRY
2829 save_TexGeniv(GLenum coord, GLenum pname, const GLint *params)
2830 {
2831  GLfloat p[4];
2832  p[0] = (GLfloat) params[0];
2833  p[1] = (GLfloat) params[1];
2834  p[2] = (GLfloat) params[2];
2835  p[3] = (GLfloat) params[3];
2836  save_TexGenfv(coord, pname, p);
2837 }
2838 
2839 
2840 static void GLAPIENTRY
2841 save_TexGend(GLenum coord, GLenum pname, GLdouble param)
2842 {
2843  GLfloat parray[4];
2844  parray[0] = (GLfloat) param;
2845  parray[1] = parray[2] = parray[3] = 0.0F;
2846  save_TexGenfv(coord, pname, parray);
2847 }
2848 
2849 
2850 static void GLAPIENTRY
2851 save_TexGendv(GLenum coord, GLenum pname, const GLdouble *params)
2852 {
2853  GLfloat p[4];
2854  p[0] = (GLfloat) params[0];
2855  p[1] = (GLfloat) params[1];
2856  p[2] = (GLfloat) params[2];
2857  p[3] = (GLfloat) params[3];
2858  save_TexGenfv(coord, pname, p);
2859 }
2860 
2861 
2862 static void GLAPIENTRY
2863 save_TexGenf(GLenum coord, GLenum pname, GLfloat param)
2864 {
2865  GLfloat parray[4];
2866  parray[0] = param;
2867  parray[1] = parray[2] = parray[3] = 0.0F;
2868  save_TexGenfv(coord, pname, parray);
2869 }
2870 
2871 
2872 static void GLAPIENTRY
2873 save_TexGeni(GLenum coord, GLenum pname, GLint param)
2874 {
2875  GLint parray[4];
2876  parray[0] = param;
2877  parray[1] = parray[2] = parray[3] = 0;
2878  save_TexGeniv(coord, pname, parray);
2879 }
2880 
2881 
2882 static void GLAPIENTRY
2883 save_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
2884 {
2885  GET_CURRENT_CONTEXT(ctx);
2886  Node *n;
2888  n = alloc_instruction(ctx, OPCODE_TEXPARAMETER, 6);
2889  if (n) {
2890  n[1].e = target;
2891  n[2].e = pname;
2892  n[3].f = params[0];
2893  n[4].f = params[1];
2894  n[5].f = params[2];
2895  n[6].f = params[3];
2896  }
2897  if (ctx->ExecuteFlag) {
2898  CALL_TexParameterfv(ctx->Exec, (target, pname, params));
2899  }
2900 }
2901 
2902 
2903 static void GLAPIENTRY
2904 save_TexParameterf(GLenum target, GLenum pname, GLfloat param)
2905 {
2906  GLfloat parray[4];
2907  parray[0] = param;
2908  parray[1] = parray[2] = parray[3] = 0.0F;
2909  save_TexParameterfv(target, pname, parray);
2910 }
2911 
2912 
2913 static void GLAPIENTRY
2914 save_TexParameteri(GLenum target, GLenum pname, GLint param)
2915 {
2916  GLfloat fparam[4];
2917  fparam[0] = (GLfloat) param;
2918  fparam[1] = fparam[2] = fparam[3] = 0.0F;
2919  save_TexParameterfv(target, pname, fparam);
2920 }
2921 
2922 
2923 static void GLAPIENTRY
2924 save_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
2925 {
2926  GLfloat fparam[4];
2927  fparam[0] = (GLfloat) params[0];
2928  fparam[1] = fparam[2] = fparam[3] = 0.0F;
2929  save_TexParameterfv(target, pname, fparam);
2930 }
2931 
2932 
2933 static void GLAPIENTRY
2934 save_TexImage1D(GLenum target,
2935  GLint level, GLint components,
2936  GLsizei width, GLint border,
2937  GLenum format, GLenum type, const GLvoid * pixels)
2938 {
2939  GET_CURRENT_CONTEXT(ctx);
2940  if (target == GL_PROXY_TEXTURE_1D) {
2941  /* don't compile, execute immediately */
2942  CALL_TexImage1D(ctx->Exec, (target, level, components, width,
2943  border, format, type, pixels));
2944  }
2945  else {
2946  Node *n;
2948  n = alloc_instruction(ctx, OPCODE_TEX_IMAGE1D, 8);
2949  if (n) {
2950  n[1].e = target;
2951  n[2].i = level;
2952  n[3].i = components;
2953  n[4].i = (GLint) width;
2954  n[5].i = border;
2955  n[6].e = format;
2956  n[7].e = type;
2957  n[8].data = unpack_image(ctx, 1, width, 1, 1, format, type,
2958  pixels, &ctx->Unpack);
2959  }
2960  if (ctx->ExecuteFlag) {
2961  CALL_TexImage1D(ctx->Exec, (target, level, components, width,
2962  border, format, type, pixels));
2963  }
2964  }
2965 }
2966 
2967 
2968 static void GLAPIENTRY
2969 save_TexImage2D(GLenum target,
2970  GLint level, GLint components,
2971  GLsizei width, GLsizei height, GLint border,
2972  GLenum format, GLenum type, const GLvoid * pixels)
2973 {
2974  GET_CURRENT_CONTEXT(ctx);
2975  if (target == GL_PROXY_TEXTURE_2D) {
2976  /* don't compile, execute immediately */
2977  CALL_TexImage2D(ctx->Exec, (target, level, components, width,
2978  height, border, format, type, pixels));
2979  }
2980  else {
2981  Node *n;
2983  n = alloc_instruction(ctx, OPCODE_TEX_IMAGE2D, 9);
2984  if (n) {
2985  n[1].e = target;
2986  n[2].i = level;
2987  n[3].i = components;
2988  n[4].i = (GLint) width;
2989  n[5].i = (GLint) height;
2990  n[6].i = border;
2991  n[7].e = format;
2992  n[8].e = type;
2993  n[9].data = unpack_image(ctx, 2, width, height, 1, format, type,
2994  pixels, &ctx->Unpack);
2995  }
2996  if (ctx->ExecuteFlag) {
2997  CALL_TexImage2D(ctx->Exec, (target, level, components, width,
2998  height, border, format, type, pixels));
2999  }
3000  }
3001 }
3002 
3003 
3004 static void GLAPIENTRY
3005 save_TexSubImage1D(GLenum target, GLint level, GLint xoffset,
3006  GLsizei width, GLenum format, GLenum type,
3007  const GLvoid * pixels)
3008 {
3009  GET_CURRENT_CONTEXT(ctx);
3010  Node *n;
3011 
3013 
3014  n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE1D, 7);
3015  if (n) {
3016  n[1].e = target;
3017  n[2].i = level;
3018  n[3].i = xoffset;
3019  n[4].i = (GLint) width;
3020  n[5].e = format;
3021  n[6].e = type;
3022  n[7].data = unpack_image(ctx, 1, width, 1, 1, format, type,
3023  pixels, &ctx->Unpack);
3024  }
3025  if (ctx->ExecuteFlag) {
3026  CALL_TexSubImage1D(ctx->Exec, (target, level, xoffset, width,
3027  format, type, pixels));
3028  }
3029 }
3030 
3031 
3032 static void GLAPIENTRY
3033 save_TexSubImage2D(GLenum target, GLint level,
3034  GLint xoffset, GLint yoffset,
3035  GLsizei width, GLsizei height,
3036  GLenum format, GLenum type, const GLvoid * pixels)
3037 {
3038  GET_CURRENT_CONTEXT(ctx);
3039  Node *n;
3040 
3042 
3043  n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE2D, 9);
3044  if (n) {
3045  n[1].e = target;
3046  n[2].i = level;
3047  n[3].i = xoffset;
3048  n[4].i = yoffset;
3049  n[5].i = (GLint) width;
3050  n[6].i = (GLint) height;
3051  n[7].e = format;
3052  n[8].e = type;
3053  n[9].data = unpack_image(ctx, 2, width, height, 1, format, type,
3054  pixels, &ctx->Unpack);
3055  }
3056  if (ctx->ExecuteFlag) {
3057  CALL_TexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset,
3058  width, height, format, type, pixels));
3059  }
3060 }
3061 
3062 
3063 static void GLAPIENTRY
3064 save_Translatef(GLfloat x, GLfloat y, GLfloat z)
3065 {
3066  GET_CURRENT_CONTEXT(ctx);
3067  Node *n;
3069  n = alloc_instruction(ctx, OPCODE_TRANSLATE, 3);
3070  if (n) {
3071  n[1].f = x;
3072  n[2].f = y;
3073  n[3].f = z;
3074  }
3075  if (ctx->ExecuteFlag) {
3076  CALL_Translatef(ctx->Exec, (x, y, z));
3077  }
3078 }
3079 
3080 
3081 static void GLAPIENTRY
3082 save_Translated(GLdouble x, GLdouble y, GLdouble z)
3083 {
3084  save_Translatef((GLfloat) x, (GLfloat) y, (GLfloat) z);
3085 }
3086 
3087 
3088 
3089 static void GLAPIENTRY
3090 save_Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3091 {
3092  GET_CURRENT_CONTEXT(ctx);
3093  Node *n;
3095  n = alloc_instruction(ctx, OPCODE_VIEWPORT, 4);
3096  if (n) {
3097  n[1].i = x;
3098  n[2].i = y;
3099  n[3].i = (GLint) width;
3100  n[4].i = (GLint) height;
3101  }
3102  if (ctx->ExecuteFlag) {
3103  CALL_Viewport(ctx->Exec, (x, y, width, height));
3104  }
3105 }
3106 
3107 
3108 static void GLAPIENTRY
3109 save_WindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3110 {
3111  GET_CURRENT_CONTEXT(ctx);
3112  Node *n;
3114  n = alloc_instruction(ctx, OPCODE_WINDOW_POS, 4);
3115  if (n) {
3116  n[1].f = x;
3117  n[2].f = y;
3118  n[3].f = z;
3119  n[4].f = w;
3120  }
3121  if (ctx->ExecuteFlag) {
3122  CALL_WindowPos4fMESA(ctx->Exec, (x, y, z, w));
3123  }
3124 }
3125 
3126 static void GLAPIENTRY
3127 save_WindowPos2dMESA(GLdouble x, GLdouble y)
3128 {
3129  save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
3130 }
3131 
3132 static void GLAPIENTRY
3133 save_WindowPos2fMESA(GLfloat x, GLfloat y)
3134 {
3135  save_WindowPos4fMESA(x, y, 0.0F, 1.0F);
3136 }
3137 
3138 static void GLAPIENTRY
3139 save_WindowPos2iMESA(GLint x, GLint y)
3140 {
3141  save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
3142 }
3143 
3144 static void GLAPIENTRY
3145 save_WindowPos2sMESA(GLshort x, GLshort y)
3146 {
3147  save_WindowPos4fMESA(x, y, 0.0F, 1.0F);
3148 }
3149 
3150 static void GLAPIENTRY
3151 save_WindowPos3dMESA(GLdouble x, GLdouble y, GLdouble z)
3152 {
3153  save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
3154 }
3155 
3156 static void GLAPIENTRY
3157 save_WindowPos3fMESA(GLfloat x, GLfloat y, GLfloat z)
3158 {
3159  save_WindowPos4fMESA(x, y, z, 1.0F);
3160 }
3161 
3162 static void GLAPIENTRY
3163 save_WindowPos3iMESA(GLint x, GLint y, GLint z)
3164 {
3165  save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
3166 }
3167 
3168 static void GLAPIENTRY
3169 save_WindowPos3sMESA(GLshort x, GLshort y, GLshort z)
3170 {
3171  save_WindowPos4fMESA(x, y, z, 1.0F);
3172 }
3173 
3174 static void GLAPIENTRY
3175 save_WindowPos4dMESA(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
3176 {
3177  save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
3178 }
3179 
3180 static void GLAPIENTRY
3181 save_WindowPos4iMESA(GLint x, GLint y, GLint z, GLint w)
3182 {
3183  save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
3184 }
3185 
3186 static void GLAPIENTRY
3187 save_WindowPos4sMESA(GLshort x, GLshort y, GLshort z, GLshort w)
3188 {
3189  save_WindowPos4fMESA(x, y, z, w);
3190 }
3191 
3192 static void GLAPIENTRY
3193 save_WindowPos2dvMESA(const GLdouble * v)
3194 {
3195  save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
3196 }
3197 
3198 static void GLAPIENTRY
3199 save_WindowPos2fvMESA(const GLfloat * v)
3200 {
3201  save_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F);
3202 }
3203 
3204 static void GLAPIENTRY
3205 save_WindowPos2ivMESA(const GLint * v)
3206 {
3207  save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
3208 }
3209 
3210 static void GLAPIENTRY
3211 save_WindowPos2svMESA(const GLshort * v)
3212 {
3213  save_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F);
3214 }
3215 
3216 static void GLAPIENTRY
3217 save_WindowPos3dvMESA(const GLdouble * v)
3218 {
3219  save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
3220 }
3221 
3222 static void GLAPIENTRY
3223 save_WindowPos3fvMESA(const GLfloat * v)
3224 {
3225  save_WindowPos4fMESA(v[0], v[1], v[2], 1.0F);
3226 }
3227 
3228 static void GLAPIENTRY
3229 save_WindowPos3ivMESA(const GLint * v)
3230 {
3231  save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
3232 }
3233 
3234 static void GLAPIENTRY
3235 save_WindowPos3svMESA(const GLshort * v)
3236 {
3237  save_WindowPos4fMESA(v[0], v[1], v[2], 1.0F);
3238 }
3239 
3240 static void GLAPIENTRY
3241 save_WindowPos4dvMESA(const GLdouble * v)
3242 {
3243  save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1],
3244  (GLfloat) v[2], (GLfloat) v[3]);
3245 }
3246 
3247 static void GLAPIENTRY
3248 save_WindowPos4fvMESA(const GLfloat * v)
3249 {
3250  save_WindowPos4fMESA(v[0], v[1], v[2], v[3]);
3251 }
3252 
3253 static void GLAPIENTRY
3254 save_WindowPos4ivMESA(const GLint * v)
3255 {
3256  save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1],
3257  (GLfloat) v[2], (GLfloat) v[3]);
3258 }
3259 
3260 static void GLAPIENTRY
3261 save_WindowPos4svMESA(const GLshort * v)
3262 {
3263  save_WindowPos4fMESA(v[0], v[1], v[2], v[3]);
3264 }
3265 
3266 
3267 /* GL_ARB_transpose_matrix */
3268 
3269 static void GLAPIENTRY
3270 save_LoadTransposeMatrixdARB(const GLdouble m[16])
3271 {
3272  GLfloat tm[16];
3273  _math_transposefd(tm, m);
3274  save_LoadMatrixf(tm);
3275 }
3276 
3277 
3278 static void GLAPIENTRY
3279 save_LoadTransposeMatrixfARB(const GLfloat m[16])
3280 {
3281  GLfloat tm[16];
3282  _math_transposef(tm, m);
3283  save_LoadMatrixf(tm);
3284 }
3285 
3286 
3287 static void GLAPIENTRY
3288 save_MultTransposeMatrixdARB(const GLdouble m[16])
3289 {
3290  GLfloat tm[16];
3291  _math_transposefd(tm, m);
3292  save_MultMatrixf(tm);
3293 }
3294 
3295 
3296 static void GLAPIENTRY
3297 save_MultTransposeMatrixfARB(const GLfloat m[16])
3298 {
3299  GLfloat tm[16];
3300  _math_transposef(tm, m);
3301  save_MultMatrixf(tm);
3302 }
3303 
3304 
3305 /* GL_ARB_multisample */
3306 static void GLAPIENTRY
3307 save_SampleCoverageARB(GLclampf value, GLboolean invert)
3308 {
3309  GET_CURRENT_CONTEXT(ctx);
3310  Node *n;
3312  n = alloc_instruction(ctx, OPCODE_SAMPLE_COVERAGE, 2);
3313  if (n) {
3314  n[1].f = value;
3315  n[2].b = invert;
3316  }
3317  if (ctx->ExecuteFlag) {
3318  CALL_SampleCoverageARB(ctx->Exec, (value, invert));
3319  }
3320 }
3321 
3322 
3323 /* GL_EXT_depth_bounds_test */
3324 static void GLAPIENTRY
3325 save_DepthBoundsEXT(GLclampd zmin, GLclampd zmax)
3326 {
3327  GET_CURRENT_CONTEXT(ctx);
3328  Node *n;
3330  n = alloc_instruction(ctx, OPCODE_DEPTH_BOUNDS_EXT, 2);
3331  if (n) {
3332  n[1].f = (GLfloat) zmin;
3333  n[2].f = (GLfloat) zmax;
3334  }
3335  if (ctx->ExecuteFlag) {
3336  CALL_DepthBoundsEXT(ctx->Exec, (zmin, zmax));
3337  }
3338 }
3339 
3340 static void GLAPIENTRY
3341 save_Attr1fNV(GLenum attr, GLfloat x)
3342 {
3343  GET_CURRENT_CONTEXT(ctx);
3344  Node *n;
3345  SAVE_FLUSH_VERTICES(ctx);
3346  n = alloc_instruction(ctx, OPCODE_ATTR_1F_NV, 2);
3347  if (n) {
3348  n[1].e = attr;
3349  n[2].f = x;
3350  }
3351 
3352  ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
3353  ctx->ListState.ActiveAttribSize[attr] = 1;
3354  ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, 0, 0, 1);
3355 
3356  if (ctx->ExecuteFlag) {
3357  CALL_VertexAttrib1fNV(ctx->Exec, (attr, x));
3358  }
3359 }
3360 
3361 static void GLAPIENTRY
3362 save_Attr2fNV(GLenum attr, GLfloat x, GLfloat y)
3363 {
3364  GET_CURRENT_CONTEXT(ctx);
3365  Node *n;
3366  SAVE_FLUSH_VERTICES(ctx);
3367  n = alloc_instruction(ctx, OPCODE_ATTR_2F_NV, 3);
3368  if (n) {
3369  n[1].e = attr;
3370  n[2].f = x;
3371  n[3].f = y;
3372  }
3373 
3374  ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
3375  ctx->ListState.ActiveAttribSize[attr] = 2;
3376  ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, 0, 1);
3377 
3378  if (ctx->ExecuteFlag) {
3379  CALL_VertexAttrib2fNV(ctx->Exec, (attr, x, y));
3380  }
3381 }
3382 
3383 static void GLAPIENTRY
3384 save_Attr3fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z)
3385 {
3386  GET_CURRENT_CONTEXT(ctx);
3387  Node *n;
3388  SAVE_FLUSH_VERTICES(ctx);
3389  n = alloc_instruction(ctx, OPCODE_ATTR_3F_NV, 4);
3390  if (n) {
3391  n[1].e = attr;
3392  n[2].f = x;
3393  n[3].f = y;
3394  n[4].f = z;
3395  }
3396 
3397  ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
3398  ctx->ListState.ActiveAttribSize[attr] = 3;
3399  ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, 1);
3400 
3401  if (ctx->ExecuteFlag) {
3402  CALL_VertexAttrib3fNV(ctx->Exec, (attr, x, y, z));
3403  }
3404 }
3405 
3406 static void GLAPIENTRY
3407 save_Attr4fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3408 {
3409  GET_CURRENT_CONTEXT(ctx);
3410  Node *n;
3411  SAVE_FLUSH_VERTICES(ctx);
3412  n = alloc_instruction(ctx, OPCODE_ATTR_4F_NV, 5);
3413  if (n) {
3414  n[1].e = attr;
3415  n[2].f = x;
3416  n[3].f = y;
3417  n[4].f = z;
3418  n[5].f = w;
3419  }
3420 
3421  ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS);
3422  ctx->ListState.ActiveAttribSize[attr] = 4;
3423  ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, w);
3424 
3425  if (ctx->ExecuteFlag) {
3426  CALL_VertexAttrib4fNV(ctx->Exec, (attr, x, y, z, w));
3427  }
3428 }
3429 
3430 static void GLAPIENTRY
3431 save_EvalCoord1f(GLfloat x)
3432 {
3433  GET_CURRENT_CONTEXT(ctx);
3434  Node *n;
3435  SAVE_FLUSH_VERTICES(ctx);
3436  n = alloc_instruction(ctx, OPCODE_EVAL_C1, 1);
3437  if (n) {
3438  n[1].f = x;
3439  }
3440  if (ctx->ExecuteFlag) {
3441  CALL_EvalCoord1f(ctx->Exec, (x));
3442  }
3443 }
3444 
3445 static void GLAPIENTRY
3446 save_EvalCoord1fv(const GLfloat * v)
3447 {
3448  save_EvalCoord1f(v[0]);
3449 }
3450 
3451 static void GLAPIENTRY
3452 save_EvalCoord2f(GLfloat x, GLfloat y)
3453 {
3454  GET_CURRENT_CONTEXT(ctx);
3455  Node *n;
3456  SAVE_FLUSH_VERTICES(ctx);
3457  n = alloc_instruction(ctx, OPCODE_EVAL_C2, 2);
3458  if (n) {
3459  n[1].f = x;
3460  n[2].f = y;
3461  }
3462  if (ctx->ExecuteFlag) {
3463  CALL_EvalCoord2f(ctx->Exec, (x, y));
3464  }
3465 }
3466 
3467 static void GLAPIENTRY
3468 save_EvalCoord2fv(const GLfloat * v)
3469 {
3470  save_EvalCoord2f(v[0], v[1]);
3471 }
3472 
3473 
3474 static void GLAPIENTRY
3475 save_EvalPoint1(GLint x)
3476 {
3477  GET_CURRENT_CONTEXT(ctx);
3478  Node *n;
3479  SAVE_FLUSH_VERTICES(ctx);
3480  n = alloc_instruction(ctx, OPCODE_EVAL_P1, 1);
3481  if (n) {
3482  n[1].i = x;
3483  }
3484  if (ctx->ExecuteFlag) {
3485  CALL_EvalPoint1(ctx->Exec, (x));
3486  }
3487 }
3488 
3489 static void GLAPIENTRY
3490 save_EvalPoint2(GLint x, GLint y)
3491 {
3492  GET_CURRENT_CONTEXT(ctx);
3493  Node *n;
3494  SAVE_FLUSH_VERTICES(ctx);
3495  n = alloc_instruction(ctx, OPCODE_EVAL_P2, 2);
3496  if (n) {
3497  n[1].i = x;
3498  n[2].i = y;
3499  }
3500  if (ctx->ExecuteFlag) {
3501  CALL_EvalPoint2(ctx->Exec, (x, y));
3502  }
3503 }
3504 
3505 static void GLAPIENTRY
3506 save_Indexf(GLfloat x)
3507 {
3508  save_Attr1fNV(VERT_ATTRIB_COLOR_INDEX, x);
3509 }
3510 
3511 static void GLAPIENTRY
3512 save_Indexfv(const GLfloat * v)
3513 {
3514  save_Attr1fNV(VERT_ATTRIB_COLOR_INDEX, v[0]);
3515 }
3516 
3517 static void GLAPIENTRY
3518 save_EdgeFlag(GLboolean x)
3519 {
3520  save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? (GLfloat)1.0 : (GLfloat)0.0);
3521 }
3522 
3523 static inline GLboolean compare4fv( const GLfloat *a,
3524  const GLfloat *b,
3525  GLuint count )
3526 {
3527  return memcmp( a, b, count * sizeof(GLfloat) ) == 0;
3528 }
3529 
3530 
3531 static void GLAPIENTRY
3532 save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
3533 {
3534  GET_CURRENT_CONTEXT(ctx);
3535  Node *n;
3536  int args, i;
3537  GLuint bitmask;
3538 
3539  switch (face) {
3540  case GL_BACK:
3541  case GL_FRONT:
3542  case GL_FRONT_AND_BACK:
3543  break;
3544  default:
3545  _mesa_compile_error(ctx, GL_INVALID_ENUM, "material(face)");
3546  return;
3547  }
3548 
3549  switch (pname) {
3550  case GL_EMISSION:
3551  case GL_AMBIENT:
3552  case GL_DIFFUSE:
3553  case GL_SPECULAR:
3555  args = 4;
3556  break;
3557  case GL_SHININESS:
3558  args = 1;
3559  break;
3560  case GL_COLOR_INDEXES:
3561  args = 3;
3562  break;
3563  default:
3564  _mesa_compile_error(ctx, GL_INVALID_ENUM, "material(pname)");
3565  return;
3566  }
3567 
3568  if (ctx->ExecuteFlag) {
3569  CALL_Materialfv(ctx->Exec, (face, pname, param));
3570  }
3571 
3572  bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, NULL);
3573 
3574  /* Try to eliminate redundant statechanges. Because it is legal to
3575  * call glMaterial even inside begin/end calls, don't need to worry
3576  * about ctx->Driver.CurrentSavePrimitive here.
3577  */
3578  for (i = 0; i < MAT_ATTRIB_MAX; i++) {
3579  if (bitmask & (1 << i)) {
3580  if (ctx->ListState.ActiveMaterialSize[i] == args &&
3581  compare4fv(ctx->ListState.CurrentMaterial[i], param, args)) {
3582  bitmask &= ~(1 << i);
3583  }
3584  else {
3585  ctx->ListState.ActiveMaterialSize[i] = args;
3586  COPY_SZ_4V(ctx->ListState.CurrentMaterial[i], args, param);
3587  }
3588  }
3589  }
3590 
3591  /* If this call has effect, return early:
3592  */
3593  if (bitmask == 0)
3594  return;
3595 
3596  SAVE_FLUSH_VERTICES(ctx);
3597 
3598  n = alloc_instruction(ctx, OPCODE_MATERIAL, 6);
3599  if (n) {
3600  n[1].e = face;
3601  n[2].e = pname;
3602  for (i = 0; i < args; i++)
3603  n[3 + i].f = param[i];
3604  }
3605 }
3606 
3607 static void GLAPIENTRY
3608 save_Begin(GLenum mode)
3609 {
3610  GET_CURRENT_CONTEXT(ctx);
3611  Node *n;
3613 
3614  if (!_mesa_valid_prim_mode(ctx, mode)) {
3615  _mesa_compile_error(ctx, GL_INVALID_ENUM, "glBegin(mode)");
3616  error = GL_TRUE;
3617  }
3618  else if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN) {
3619  /* Typically the first begin. This may raise an error on
3620  * playback, depending on whether CallList is issued from inside
3621  * a begin/end or not.
3622  */
3623  ctx->Driver.CurrentSavePrimitive = PRIM_INSIDE_UNKNOWN_PRIM;
3624  }
3625  else if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END) {
3626  ctx->Driver.CurrentSavePrimitive = mode;
3627  }
3628  else {
3629  _mesa_compile_error(ctx, GL_INVALID_OPERATION, "recursive begin");
3630  error = GL_TRUE;
3631  }
3632 
3633  if (!error) {
3634  /* Give the driver an opportunity to hook in an optimized
3635  * display list compiler.
3636  */
3637  if (ctx->Driver.NotifySaveBegin(ctx, mode))
3638  return;
3639 
3640  SAVE_FLUSH_VERTICES(ctx);
3641  n = alloc_instruction(ctx, OPCODE_BEGIN, 1);
3642  if (n) {
3643  n[1].e = mode;
3644  }
3645  }
3646 
3647  if (ctx->ExecuteFlag) {
3648  CALL_Begin(ctx->Exec, (mode));
3649  }
3650 }
3651 
3652 static void GLAPIENTRY
3653 save_End(void)
3654 {
3655  GET_CURRENT_CONTEXT(ctx);
3656  SAVE_FLUSH_VERTICES(ctx);
3657  (void) alloc_instruction(ctx, OPCODE_END, 0);
3658  ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
3659  if (ctx->ExecuteFlag) {
3660  CALL_End(ctx->Exec, ());
3661  }
3662 }
3663 
3664 static void GLAPIENTRY
3665 save_Rectf(GLfloat a, GLfloat b, GLfloat c, GLfloat d)
3666 {
3667  GET_CURRENT_CONTEXT(ctx);
3668  Node *n;
3669  SAVE_FLUSH_VERTICES(ctx);
3670  n = alloc_instruction(ctx, OPCODE_RECTF, 4);
3671  if (n) {
3672  n[1].f = a;
3673  n[2].f = b;
3674  n[3].f = c;
3675  n[4].f = d;
3676  }
3677  if (ctx->ExecuteFlag) {
3678  CALL_Rectf(ctx->Exec, (a, b, c, d));
3679  }
3680 }
3681 
3682 
3683 static void GLAPIENTRY
3684 save_Vertex2f(GLfloat x, GLfloat y)
3685 {
3686  save_Attr2fNV(VERT_ATTRIB_POS, x, y);
3687 }
3688 
3689 static void GLAPIENTRY
3690 save_Vertex2fv(const GLfloat * v)
3691 {
3692  save_Attr2fNV(VERT_ATTRIB_POS, v[0], v[1]);
3693 }
3694 
3695 static void GLAPIENTRY
3696 save_Vertex3f(GLfloat x, GLfloat y, GLfloat z)
3697 {
3698  save_Attr3fNV(VERT_ATTRIB_POS, x, y, z);
3699 }
3700 
3701 static void GLAPIENTRY
3702 save_Vertex3fv(const GLfloat * v)
3703 {
3704  save_Attr3fNV(VERT_ATTRIB_POS, v[0], v[1], v[2]);
3705 }
3706 
3707 static void GLAPIENTRY
3708 save_Vertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3709 {
3710  save_Attr4fNV(VERT_ATTRIB_POS, x, y, z, w);
3711 }
3712 
3713 static void GLAPIENTRY
3714 save_Vertex4fv(const GLfloat * v)
3715 {
3716  save_Attr4fNV(VERT_ATTRIB_POS, v[0], v[1], v[2], v[3]);
3717 }
3718 
3719 static void GLAPIENTRY
3720 save_TexCoord1f(GLfloat x)
3721 {
3722  save_Attr1fNV(VERT_ATTRIB_TEX, x);
3723 }
3724 
3725 static void GLAPIENTRY
3726 save_TexCoord1fv(const GLfloat * v)
3727 {
3728  save_Attr1fNV(VERT_ATTRIB_TEX, v[0]);
3729 }
3730 
3731 static void GLAPIENTRY
3732 save_TexCoord2f(GLfloat x, GLfloat y)
3733 {
3734  save_Attr2fNV(VERT_ATTRIB_TEX, x, y);
3735 }
3736 
3737 static void GLAPIENTRY
3738 save_TexCoord2fv(const GLfloat * v)
3739 {
3740  save_Attr2fNV(VERT_ATTRIB_TEX, v[0], v[1]);
3741 }
3742 
3743 static void GLAPIENTRY
3744 save_TexCoord3f(GLfloat x, GLfloat y, GLfloat z)
3745 {
3746  save_Attr3fNV(VERT_ATTRIB_TEX, x, y, z);
3747 }
3748 
3749 static void GLAPIENTRY
3750 save_TexCoord3fv(const GLfloat * v)
3751 {
3752  save_Attr3fNV(VERT_ATTRIB_TEX, v[0], v[1], v[2]);
3753 }
3754 
3755 static void GLAPIENTRY
3756 save_TexCoord4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3757 {
3758  save_Attr4fNV(VERT_ATTRIB_TEX, x, y, z, w);
3759 }
3760 
3761 static void GLAPIENTRY
3762 save_TexCoord4fv(const GLfloat * v)
3763 {
3764  save_Attr4fNV(VERT_ATTRIB_TEX, v[0], v[1], v[2], v[3]);
3765 }
3766 
3767 static void GLAPIENTRY
3768 save_Normal3f(GLfloat x, GLfloat y, GLfloat z)
3769 {
3770  save_Attr3fNV(VERT_ATTRIB_NORMAL, x, y, z);
3771 }
3772 
3773 static void GLAPIENTRY
3774 save_Normal3fv(const GLfloat * v)
3775 {
3776  save_Attr3fNV(VERT_ATTRIB_NORMAL, v[0], v[1], v[2]);
3777 }
3778 
3779 static void GLAPIENTRY
3780 save_FogCoordfEXT(GLfloat x)
3781 {
3782  save_Attr1fNV(VERT_ATTRIB_FOG, x);
3783 }
3784 
3785 static void GLAPIENTRY
3786 save_FogCoordfvEXT(const GLfloat * v)
3787 {
3788  save_Attr1fNV(VERT_ATTRIB_FOG, v[0]);
3789 }
3790 
3791 static void GLAPIENTRY
3792 save_Color3f(GLfloat x, GLfloat y, GLfloat z)
3793 {
3794  save_Attr3fNV(VERT_ATTRIB_COLOR, x, y, z);
3795 }
3796 
3797 static void GLAPIENTRY
3798 save_Color3fv(const GLfloat * v)
3799 {
3800  save_Attr3fNV(VERT_ATTRIB_COLOR, v[0], v[1], v[2]);
3801 }
3802 
3803 static void GLAPIENTRY
3804 save_Color4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3805 {
3806  save_Attr4fNV(VERT_ATTRIB_COLOR, x, y, z, w);
3807 }
3808 
3809 static void GLAPIENTRY
3810 save_Color4fv(const GLfloat * v)
3811 {
3812  save_Attr4fNV(VERT_ATTRIB_COLOR, v[0], v[1], v[2], v[3]);
3813 }
3814 
3815 
3820 static void
3821 index_error(void)
3822 {
3823  GET_CURRENT_CONTEXT(ctx);
3824  _mesa_error(ctx, GL_INVALID_VALUE, "VertexAttribf(index)");
3825 }
3826 
3827 
3828 /* First level for NV_vertex_program:
3829  *
3830  * Check for errors at compile time?.
3831  */
3832 static void GLAPIENTRY
3833 save_VertexAttrib1fNV(GLuint index, GLfloat x)
3834 {
3835  if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
3836  save_Attr1fNV(index, x);
3837  else
3838  index_error();
3839 }
3840 
3841 static void GLAPIENTRY
3842 save_VertexAttrib1fvNV(GLuint index, const GLfloat * v)
3843 {
3844  if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
3845  save_Attr1fNV(index, v[0]);
3846  else
3847  index_error();
3848 }
3849 
3850 static void GLAPIENTRY
3851 save_VertexAttrib2fNV(GLuint index, GLfloat x, GLfloat y)
3852 {
3853  if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
3854  save_Attr2fNV(index, x, y);
3855  else
3856  index_error();
3857 }
3858 
3859 static void GLAPIENTRY
3860 save_VertexAttrib2fvNV(GLuint index, const GLfloat * v)
3861 {
3862  if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
3863  save_Attr2fNV(index, v[0], v[1]);
3864  else
3865  index_error();
3866 }
3867 
3868 static void GLAPIENTRY
3869 save_VertexAttrib3fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3870 {
3871  if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
3872  save_Attr3fNV(index, x, y, z);
3873  else
3874  index_error();
3875 }
3876 
3877 static void GLAPIENTRY
3878 save_VertexAttrib3fvNV(GLuint index, const GLfloat * v)
3879 {
3880  if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
3881  save_Attr3fNV(index, v[0], v[1], v[2]);
3882  else
3883  index_error();
3884 }
3885 
3886 static void GLAPIENTRY
3887 save_VertexAttrib4fNV(GLuint index, GLfloat x, GLfloat y,
3888  GLfloat z, GLfloat w)
3889 {
3890  if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
3891  save_Attr4fNV(index, x, y, z, w);
3892  else
3893  index_error();
3894 }
3895 
3896 static void GLAPIENTRY
3897 save_VertexAttrib4fvNV(GLuint index, const GLfloat * v)
3898 {
3899  if (index < MAX_NV_VERTEX_PROGRAM_INPUTS)
3900  save_Attr4fNV(index, v[0], v[1], v[2], v[3]);
3901  else
3902  index_error();
3903 }
3904 
3905 
3907 static void GLAPIENTRY
3908 save_ClearColorIi(GLint red, GLint green, GLint blue, GLint alpha)
3909 {
3910  GET_CURRENT_CONTEXT(ctx);
3911  Node *n;
3913  n = alloc_instruction(ctx, OPCODE_CLEARCOLOR_I, 4);
3914  if (n) {
3915  n[1].i = red;
3916  n[2].i = green;
3917  n[3].i = blue;
3918  n[4].i = alpha;
3919  }
3920  if (ctx->ExecuteFlag) {
3921  CALL_ClearColorIiEXT(ctx->Exec, (red, green, blue, alpha));
3922  }
3923 }
3924 
3926 static void GLAPIENTRY
3927 save_ClearColorIui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
3928 {
3929  GET_CURRENT_CONTEXT(ctx);
3930  Node *n;
3932  n = alloc_instruction(ctx, OPCODE_CLEARCOLOR_UI, 4);
3933  if (n) {
3934  n[1].ui = red;
3935  n[2].ui = green;
3936  n[3].ui = blue;
3937  n[4].ui = alpha;
3938  }
3939  if (ctx->ExecuteFlag) {
3940  CALL_ClearColorIuiEXT(ctx->Exec, (red, green, blue, alpha));
3941  }
3942 }
3943 
3945 static void GLAPIENTRY
3946 save_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
3947 {
3948  GET_CURRENT_CONTEXT(ctx);
3949  Node *n;
3951  n = alloc_instruction(ctx, OPCODE_TEXPARAMETER_I, 6);
3952  if (n) {
3953  n[1].e = target;
3954  n[2].e = pname;
3955  n[3].i = params[0];
3956  n[4].i = params[1];
3957  n[5].i = params[2];
3958  n[6].i = params[3];
3959  }
3960  if (ctx->ExecuteFlag) {
3961  CALL_TexParameterIivEXT(ctx->Exec, (target, pname, params));
3962  }
3963 }
3964 
3966 static void GLAPIENTRY
3967 save_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
3968 {
3969  GET_CURRENT_CONTEXT(ctx);
3970  Node *n;
3972  n = alloc_instruction(ctx, OPCODE_TEXPARAMETER_UI, 6);
3973  if (n) {
3974  n[1].e = target;
3975  n[2].e = pname;
3976  n[3].ui = params[0];
3977  n[4].ui = params[1];
3978  n[5].ui = params[2];
3979  n[6].ui = params[3];
3980  }
3981  if (ctx->ExecuteFlag) {
3982  CALL_TexParameterIuivEXT(ctx->Exec, (target, pname, params));
3983  }
3984 }
3985 
3987 static void GLAPIENTRY
3988 exec_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
3989 {
3990  GET_CURRENT_CONTEXT(ctx);
3991  FLUSH_VERTICES(ctx, 0);
3992  CALL_GetTexParameterIivEXT(ctx->Exec, (target, pname, params));
3993 }
3994 
3996 static void GLAPIENTRY
3997 exec_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
3998 {
3999  GET_CURRENT_CONTEXT(ctx);
4000  FLUSH_VERTICES(ctx, 0);
4001  CALL_GetTexParameterIuivEXT(ctx->Exec, (target, pname, params));
4002 }
4003 
4010 static void
4011 save_error(struct gl_context *ctx, GLenum error, const char *s)
4012 {
4013  Node *n;
4014  n = alloc_instruction(ctx, OPCODE_ERROR, 2);
4015  if (n) {
4016  n[1].e = error;
4017  n[2].data = (void *) s;
4018  }
4019 }
4020 
4021 
4025 void
4026 _mesa_compile_error(struct gl_context *ctx, GLenum error, const char *s)
4027 {
4028  if (ctx->CompileFlag)
4029  save_error(ctx, error, s);
4030  if (ctx->ExecuteFlag)
4031  _mesa_error(ctx, error, "%s", s);
4032 }
4033 
4034 
4038 static GLboolean
4039 islist(struct gl_context *ctx, GLuint list)
4040 {
4041  if (list > 0 && lookup_list(ctx, list)) {
4042  return GL_TRUE;
4043  }
4044  else {
4045  return GL_FALSE;
4046  }
4047 }
4048 
4049 
4050 
4051 /**********************************************************************/
4052 /* Display list execution */
4053 /**********************************************************************/
4054 
4055 
4056 /*
4057  * Execute a display list. Note that the ListBase offset must have already
4058  * been added before calling this function. I.e. the list argument is
4059  * the absolute list number, not relative to ListBase.
4060  * \param list - display list number
4061  */
4062 static void
4063 execute_list(struct gl_context *ctx, GLuint list)
4064 {
4065  struct gl_display_list *dlist;
4066  Node *n;
4067  GLboolean done;
4068 
4069  if (list == 0 || !islist(ctx, list))
4070  return;
4071 
4072  if (ctx->ListState.CallDepth == MAX_LIST_NESTING) {
4073  /* raise an error? */
4074  return;
4075  }
4076 
4077  dlist = lookup_list(ctx, list);
4078  if (!dlist)
4079  return;
4080 
4081  ctx->ListState.CallDepth++;
4082 
4083  if (ctx->Driver.BeginCallList)
4084  ctx->Driver.BeginCallList(ctx, dlist);
4085 
4086  n = dlist->Head;
4087 
4088  done = GL_FALSE;
4089  while (!done) {
4090  const OpCode opcode = n[0].opcode;
4091 
4092  if (is_ext_opcode(opcode)) {
4093  n += ext_opcode_execute(ctx, n);
4094  }
4095  else {
4096  switch (opcode) {
4097  case OPCODE_ERROR:
4098  _mesa_error(ctx, n[1].e, "%s", (const char *) n[2].data);
4099  break;
4100  case OPCODE_ACCUM:
4101  CALL_Accum(ctx->Exec, (n[1].e, n[2].f));
4102  break;
4103  case OPCODE_ALPHA_FUNC:
4104  CALL_AlphaFunc(ctx->Exec, (n[1].e, n[2].f));
4105  break;
4106  case OPCODE_BIND_TEXTURE:
4107  CALL_BindTexture(ctx->Exec, (n[1].e, n[2].ui));
4108  break;
4109  case OPCODE_BITMAP:
4110  {
4111  const struct gl_pixelstore_attrib save = ctx->Unpack;
4112  ctx->Unpack = ctx->DefaultPacking;
4113  CALL_Bitmap(ctx->Exec, ((GLsizei) n[1].i, (GLsizei) n[2].i,
4114  n[3].f, n[4].f, n[5].f, n[6].f,
4115  (const GLubyte *) n[7].data));
4116  ctx->Unpack = save; /* restore */
4117  }
4118  break;
4119  case OPCODE_BLEND_FUNC:
4120  CALL_BlendFunc(ctx->Exec, (n[1].e, n[2].e));
4121  break;
4122  case OPCODE_CALL_LIST:
4123  /* Generated by glCallList(), don't add ListBase */
4124  if (ctx->ListState.CallDepth < MAX_LIST_NESTING) {
4125  execute_list(ctx, n[1].ui);
4126  }
4127  break;
4129  /* Generated by glCallLists() so we must add ListBase */
4130  if (n[2].b) {
4131  /* user specified a bad data type at compile time */
4132  _mesa_error(ctx, GL_INVALID_ENUM, "glCallLists(type)");
4133  }
4134  else if (ctx->ListState.CallDepth < MAX_LIST_NESTING) {
4135  GLuint list = (GLuint) (ctx->List.ListBase + n[1].i);
4136  execute_list(ctx, list);
4137  }
4138  break;
4139  case OPCODE_CLEAR:
4140  CALL_Clear(ctx->Exec, (n[1].bf));
4141  break;
4142  case OPCODE_CLEAR_COLOR:
4143  CALL_ClearColor(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
4144  break;
4145  case OPCODE_CLEAR_ACCUM:
4146  CALL_ClearAccum(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
4147  break;
4148  case OPCODE_CLEAR_DEPTH:
4149  CALL_ClearDepth(ctx->Exec, ((GLclampd) n[1].f));
4150  break;
4151  case OPCODE_CLEAR_INDEX:
4152  CALL_ClearIndex(ctx->Exec, ((GLfloat) n[1].ui));
4153  break;
4154  case OPCODE_CLEAR_STENCIL:
4155  CALL_ClearStencil(ctx->Exec, (n[1].i));
4156  break;
4157  case OPCODE_CLIP_PLANE:
4158  {
4159  GLdouble eq[4];
4160  eq[0] = n[2].f;
4161  eq[1] = n[3].f;
4162  eq[2] = n[4].f;
4163  eq[3] = n[5].f;
4164  CALL_ClipPlane(ctx->Exec, (n[1].e, eq));
4165  }
4166  break;
4167  case OPCODE_COLOR_MASK:
4168  CALL_ColorMask(ctx->Exec, (n[1].b, n[2].b, n[3].b, n[4].b));
4169  break;
4170  case OPCODE_COLOR_MATERIAL:
4171  CALL_ColorMaterial(ctx->Exec, (n[1].e, n[2].e));
4172  break;
4173  case OPCODE_COPY_PIXELS:
4174  CALL_CopyPixels(ctx->Exec, (n[1].i, n[2].i,
4175  (GLsizei) n[3].i, (GLsizei) n[4].i,
4176  n[5].e));
4177  break;
4179  CALL_CopyTexImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].e, n[4].i,
4180  n[5].i, n[6].i, n[7].i));
4181  break;
4183  CALL_CopyTexImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].e, n[4].i,
4184  n[5].i, n[6].i, n[7].i, n[8].i));
4185  break;
4187  CALL_CopyTexSubImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
4188  n[4].i, n[5].i, n[6].i));
4189  break;
4191  CALL_CopyTexSubImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
4192  n[4].i, n[5].i, n[6].i, n[7].i,
4193  n[8].i));
4194  break;
4195  case OPCODE_CULL_FACE:
4196  CALL_CullFace(ctx->Exec, (n[1].e));
4197  break;
4198  case OPCODE_DEPTH_FUNC:
4199  CALL_DepthFunc(ctx->Exec, (n[1].e));
4200  break;
4201  case OPCODE_DEPTH_MASK:
4202  CALL_DepthMask(ctx->Exec, (n[1].b));
4203  break;
4204  case OPCODE_DEPTH_RANGE:
4205  CALL_DepthRange(ctx->Exec,
4206  ((GLclampd) n[1].f, (GLclampd) n[2].f));
4207  break;
4208  case OPCODE_DISABLE:
4209  CALL_Disable(ctx->Exec, (n[1].e));
4210  break;
4211  case OPCODE_DRAW_BUFFER:
4212  CALL_DrawBuffer(ctx->Exec, (n[1].e));
4213  break;
4214  case OPCODE_DRAW_PIXELS:
4215  {
4216  const struct gl_pixelstore_attrib save = ctx->Unpack;
4217  ctx->Unpack = ctx->DefaultPacking;
4218  CALL_DrawPixels(ctx->Exec, (n[1].i, n[2].i, n[3].e, n[4].e,
4219  n[5].data));
4220  ctx->Unpack = save; /* restore */
4221  }
4222  break;
4223  case OPCODE_ENABLE:
4224  CALL_Enable(ctx->Exec, (n[1].e));
4225  break;
4226  case OPCODE_EVALMESH1:
4227  CALL_EvalMesh1(ctx->Exec, (n[1].e, n[2].i, n[3].i));
4228  break;
4229  case OPCODE_EVALMESH2:
4230  CALL_EvalMesh2(ctx->Exec,
4231  (n[1].e, n[2].i, n[3].i, n[4].i, n[5].i));
4232  break;
4233  case OPCODE_FOG:
4234  {
4235  GLfloat p[4];
4236  p[0] = n[2].f;
4237  p[1] = n[3].f;
4238  p[2] = n[4].f;
4239  p[3] = n[5].f;
4240  CALL_Fogfv(ctx->Exec, (n[1].e, p));
4241  }
4242  break;
4243  case OPCODE_FRONT_FACE:
4244  CALL_FrontFace(ctx->Exec, (n[1].e));
4245  break;
4246  case OPCODE_FRUSTUM:
4247  CALL_Frustum(ctx->Exec,
4248  (n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f));
4249  break;
4250  case OPCODE_HINT:
4251  CALL_Hint(ctx->Exec, (n[1].e, n[2].e));
4252  break;
4253  case OPCODE_INDEX_MASK:
4254  CALL_IndexMask(ctx->Exec, (n[1].ui));
4255  break;
4256  case OPCODE_INIT_NAMES:
4257  CALL_InitNames(ctx->Exec, ());
4258  break;
4259  case OPCODE_LIGHT:
4260  {
4261  GLfloat p[4];
4262  p[0] = n[3].f;
4263  p[1] = n[4].f;
4264  p[2] = n[5].f;
4265  p[3] = n[6].f;
4266  CALL_Lightfv(ctx->Exec, (n[1].e, n[2].e, p));
4267  }
4268  break;
4269  case OPCODE_LIGHT_MODEL:
4270  {
4271  GLfloat p[4];
4272  p[0] = n[2].f;
4273  p[1] = n[3].f;
4274  p[2] = n[4].f;
4275  p[3] = n[5].f;
4276  CALL_LightModelfv(ctx->Exec, (n[1].e, p));
4277  }
4278  break;
4279  case OPCODE_LINE_STIPPLE:
4280  CALL_LineStipple(ctx->Exec, (n[1].i, n[2].us));
4281  break;
4282  case OPCODE_LINE_WIDTH:
4283  CALL_LineWidth(ctx->Exec, (n[1].f));
4284  break;
4285  case OPCODE_LIST_BASE:
4286  CALL_ListBase(ctx->Exec, (n[1].ui));
4287  break;
4288  case OPCODE_LOAD_IDENTITY:
4289  CALL_LoadIdentity(ctx->Exec, ());
4290  break;
4291  case OPCODE_LOAD_MATRIX:
4292  if (sizeof(Node) == sizeof(GLfloat)) {
4293  CALL_LoadMatrixf(ctx->Exec, (&n[1].f));
4294  }
4295  else {
4296  GLfloat m[16];
4297  GLuint i;
4298  for (i = 0; i < 16; i++) {
4299  m[i] = n[1 + i].f;
4300  }
4301  CALL_LoadMatrixf(ctx->Exec, (m));
4302  }
4303  break;
4304  case OPCODE_LOAD_NAME:
4305  CALL_LoadName(ctx->Exec, (n[1].ui));
4306  break;
4307  case OPCODE_LOGIC_OP:
4308  CALL_LogicOp(ctx->Exec, (n[1].e));
4309  break;
4310  case OPCODE_MAP1:
4311  {
4312  GLenum target = n[1].e;
4313  GLint ustride = _mesa_evaluator_components(target);
4314  GLint uorder = n[5].i;
4315  GLfloat u1 = n[2].f;
4316  GLfloat u2 = n[3].f;
4317  CALL_Map1f(ctx->Exec, (target, u1, u2, ustride, uorder,
4318  (GLfloat *) n[6].data));
4319  }
4320  break;
4321  case OPCODE_MAP2:
4322  {
4323  GLenum target = n[1].e;
4324  GLfloat u1 = n[2].f;
4325  GLfloat u2 = n[3].f;
4326  GLfloat v1 = n[4].f;
4327  GLfloat v2 = n[5].f;
4328  GLint ustride = n[6].i;
4329  GLint vstride = n[7].i;
4330  GLint uorder = n[8].i;
4331  GLint vorder = n[9].i;
4332  CALL_Map2f(ctx->Exec, (target, u1, u2, ustride, uorder,
4333  v1, v2, vstride, vorder,
4334  (GLfloat *) n[10].data));
4335  }
4336  break;
4337  case OPCODE_MAPGRID1:
4338  CALL_MapGrid1f(ctx->Exec, (n[1].i, n[2].f, n[3].f));
4339  break;
4340  case OPCODE_MAPGRID2:
4341  CALL_MapGrid2f(ctx->Exec,
4342  (n[1].i, n[2].f, n[3].f, n[4].i, n[5].f, n[6].f));
4343  break;
4344  case OPCODE_MATRIX_MODE:
4345  CALL_MatrixMode(ctx->Exec, (n[1].e));
4346  break;
4347  case OPCODE_MULT_MATRIX:
4348  if (sizeof(Node) == sizeof(GLfloat)) {
4349  CALL_MultMatrixf(ctx->Exec, (&n[1].f));
4350  }
4351  else {
4352  GLfloat m[16];
4353  GLuint i;
4354  for (i = 0; i < 16; i++) {
4355  m[i] = n[1 + i].f;
4356  }
4357  CALL_MultMatrixf(ctx->Exec, (m));
4358  }
4359  break;
4360  case OPCODE_ORTHO:
4361  CALL_Ortho(ctx->Exec,
4362  (n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f));
4363  break;
4364  case OPCODE_PASSTHROUGH:
4365  CALL_PassThrough(ctx->Exec, (n[1].f));
4366  break;
4367  case OPCODE_PIXEL_MAP:
4368  CALL_PixelMapfv(ctx->Exec,
4369  (n[1].e, n[2].i, (GLfloat *) n[3].data));
4370  break;
4371  case OPCODE_PIXEL_TRANSFER:
4372  CALL_PixelTransferf(ctx->Exec, (n[1].e, n[2].f));
4373  break;
4374  case OPCODE_PIXEL_ZOOM:
4375  CALL_PixelZoom(ctx->Exec, (n[1].f, n[2].f));
4376  break;
4377  case OPCODE_POINT_SIZE:
4378  CALL_PointSize(ctx->Exec, (n[1].f));
4379  break;
4381  {
4382  GLfloat params[3];
4383  params[0] = n[2].f;
4384  params[1] = n[3].f;
4385  params[2] = n[4].f;
4386  CALL_PointParameterfvEXT(ctx->Exec, (n[1].e, params));
4387  }
4388  break;
4389  case OPCODE_POLYGON_MODE:
4390  CALL_PolygonMode(ctx->Exec, (n[1].e, n[2].e));
4391  break;
4393  {
4394  const struct gl_pixelstore_attrib save = ctx->Unpack;
4395  ctx->Unpack = ctx->DefaultPacking;
4396  CALL_PolygonStipple(ctx->Exec, ((GLubyte *) n[1].data));
4397  ctx->Unpack = save; /* restore */
4398  }
4399  break;
4400  case OPCODE_POLYGON_OFFSET:
4401  CALL_PolygonOffset(ctx->Exec, (n[1].f, n[2].f));
4402  break;
4403  case OPCODE_POP_ATTRIB:
4404  CALL_PopAttrib(ctx->Exec, ());
4405  break;
4406  case OPCODE_POP_MATRIX:
4407  CALL_PopMatrix(ctx->Exec, ());
4408  break;
4409  case OPCODE_POP_NAME:
4410  CALL_PopName(ctx->Exec, ());
4411  break;
4413  CALL_PrioritizeTextures(ctx->Exec, (1, &n[1].ui, &n[2].f));
4414  break;
4415  case OPCODE_PUSH_ATTRIB:
4416  CALL_PushAttrib(ctx->Exec, (n[1].bf));
4417  break;
4418  case OPCODE_PUSH_MATRIX:
4419  CALL_PushMatrix(ctx->Exec, ());
4420  break;
4421  case OPCODE_PUSH_NAME:
4422  CALL_PushName(ctx->Exec, (n[1].ui));
4423  break;
4424  case OPCODE_RASTER_POS:
4425  CALL_RasterPos4f(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
4426  break;
4427  case OPCODE_READ_BUFFER:
4428  CALL_ReadBuffer(ctx->Exec, (n[1].e));
4429  break;
4430  case OPCODE_ROTATE:
4431  CALL_Rotatef(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
4432  break;
4433  case OPCODE_SCALE:
4434  CALL_Scalef(ctx->Exec, (n[1].f, n[2].f, n[3].f));
4435  break;
4436  case OPCODE_SCISSOR:
4437  CALL_Scissor(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i));
4438  break;
4439  case OPCODE_SHADE_MODEL:
4440  CALL_ShadeModel(ctx->Exec, (n[1].e));
4441  break;
4442  case OPCODE_STENCIL_FUNC:
4443  CALL_StencilFunc(ctx->Exec, (n[1].e, n[2].i, n[3].ui));
4444  break;
4445  case OPCODE_STENCIL_MASK:
4446  CALL_StencilMask(ctx->Exec, (n[1].ui));
4447  break;
4448  case OPCODE_STENCIL_OP:
4449  CALL_StencilOp(ctx->Exec, (n[1].e, n[2].e, n[3].e));
4450  break;
4451  case OPCODE_TEXENV:
4452  {
4453  GLfloat params[4];
4454  params[0] = n[3].f;
4455  params[1] = n[4].f;
4456  params[2] = n[5].f;
4457  params[3] = n[6].f;
4458  CALL_TexEnvfv(ctx->Exec, (n[1].e, n[2].e, params));
4459  }
4460  break;
4461  case OPCODE_TEXGEN:
4462  {
4463  GLfloat params[4];
4464  params[0] = n[3].f;
4465  params[1] = n[4].f;
4466  params[2] = n[5].f;
4467  params[3] = n[6].f;
4468  CALL_TexGenfv(ctx->Exec, (n[1].e, n[2].e, params));
4469  }
4470  break;
4471  case OPCODE_TEXPARAMETER:
4472  {
4473  GLfloat params[4];
4474  params[0] = n[3].f;
4475  params[1] = n[4].f;
4476  params[2] = n[5].f;
4477  params[3] = n[6].f;
4478  CALL_TexParameterfv(ctx->Exec, (n[1].e, n[2].e, params));
4479  }
4480  break;
4481  case OPCODE_TEX_IMAGE1D:
4482  {
4483  const struct gl_pixelstore_attrib save = ctx->Unpack;
4484  ctx->Unpack = ctx->DefaultPacking;
4485  CALL_TexImage1D(ctx->Exec, (n[1].e, /* target */
4486  n[2].i, /* level */
4487  n[3].i, /* components */
4488  n[4].i, /* width */
4489  n[5].e, /* border */
4490  n[6].e, /* format */
4491  n[7].e, /* type */
4492  n[8].data));
4493  ctx->Unpack = save; /* restore */
4494  }
4495  break;
4496  case OPCODE_TEX_IMAGE2D:
4497  {
4498  const struct gl_pixelstore_attrib save = ctx->Unpack;
4499  ctx->Unpack = ctx->DefaultPacking;
4500  CALL_TexImage2D(ctx->Exec, (n[1].e, /* target */
4501  n[2].i, /* level */
4502  n[3].i, /* components */
4503  n[4].i, /* width */
4504  n[5].i, /* height */
4505  n[6].e, /* border */
4506  n[7].e, /* format */
4507  n[8].e, /* type */
4508  n[9].data));
4509  ctx->Unpack = save; /* restore */
4510  }
4511  break;
4513  {
4514  const struct gl_pixelstore_attrib save = ctx->Unpack;
4515  ctx->Unpack = ctx->DefaultPacking;
4516  CALL_TexSubImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
4517  n[4].i, n[5].e,
4518  n[6].e, n[7].data));
4519  ctx->Unpack = save; /* restore */
4520  }
4521  break;
4523  {
4524  const struct gl_pixelstore_attrib save = ctx->Unpack;
4525  ctx->Unpack = ctx->DefaultPacking;
4526  CALL_TexSubImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
4527  n[4].i, n[5].e,
4528  n[6].i, n[7].e, n[8].e,
4529  n[9].data));
4530  ctx->Unpack = save; /* restore */
4531  }
4532  break;
4533  case OPCODE_TRANSLATE:
4534  CALL_Translatef(ctx->Exec, (n[1].f, n[2].f, n[3].f));
4535  break;
4536  case OPCODE_VIEWPORT:
4537  CALL_Viewport(ctx->Exec, (n[1].i, n[2].i,
4538  (GLsizei) n[3].i, (GLsizei) n[4].i));
4539  break;
4540  case OPCODE_WINDOW_POS:
4541  CALL_WindowPos4fMESA(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
4542  break;
4543  case OPCODE_SAMPLE_COVERAGE: /* GL_ARB_multisample */
4544  CALL_SampleCoverageARB(ctx->Exec, (n[1].f, n[2].b));
4545  break;
4546  case OPCODE_WINDOW_POS_ARB: /* GL_ARB_window_pos */
4547  CALL_WindowPos3fMESA(ctx->Exec, (n[1].f, n[2].f, n[3].f));
4548  break;
4549 
4551  CALL_DepthBoundsEXT(ctx->Exec, (n[1].f, n[2].f));
4552  break;
4553 
4554  case OPCODE_ATTR_1F_NV:
4555  CALL_VertexAttrib1fNV(ctx->Exec, (n[1].e, n[2].f));
4556  break;
4557  case OPCODE_ATTR_2F_NV:
4558  /* Really shouldn't have to do this - the Node structure
4559  * is convenient, but it would be better to store the data
4560  * packed appropriately so that it can be sent directly
4561  * on. With x86_64 becoming common, this will start to
4562  * matter more.
4563  */
4564  if (sizeof(Node) == sizeof(GLfloat))
4565  CALL_VertexAttrib2fvNV(ctx->Exec, (n[1].e, &n[2].f));
4566  else
4567  CALL_VertexAttrib2fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f));
4568  break;
4569  case OPCODE_ATTR_3F_NV:
4570  if (sizeof(Node) == sizeof(GLfloat))
4571  CALL_VertexAttrib3fvNV(ctx->Exec, (n[1].e, &n[2].f));
4572  else
4573  CALL_VertexAttrib3fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f,
4574  n[4].f));
4575  break;
4576  case OPCODE_ATTR_4F_NV:
4577  if (sizeof(Node) == sizeof(GLfloat))
4578  CALL_VertexAttrib4fvNV(ctx->Exec, (n[1].e, &n[2].f));
4579  else
4580  CALL_VertexAttrib4fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f,
4581  n[4].f, n[5].f));
4582  break;
4583  case OPCODE_MATERIAL:
4584  {
4585  GLfloat f[4];
4586  f[0] = n[3].f;
4587  f[1] = n[4].f;
4588  f[2] = n[5].f;
4589  f[3] = n[6].f;
4590  CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, f));
4591  }
4592  break;
4593  case OPCODE_BEGIN:
4594  CALL_Begin(ctx->Exec, (n[1].e));
4595  break;
4596  case OPCODE_END:
4597  CALL_End(ctx->Exec, ());
4598  break;
4599  case OPCODE_RECTF:
4600  CALL_Rectf(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
4601  break;
4602  case OPCODE_EVAL_C1:
4603  CALL_EvalCoord1f(ctx->Exec, (n[1].f));
4604  break;
4605  case OPCODE_EVAL_C2:
4606  CALL_EvalCoord2f(ctx->Exec, (n[1].f, n[2].f));
4607  break;
4608  case OPCODE_EVAL_P1:
4609  CALL_EvalPoint1(ctx->Exec, (n[1].i));
4610  break;
4611  case OPCODE_EVAL_P2:
4612  CALL_EvalPoint2(ctx->Exec, (n[1].i, n[2].i));
4613  break;
4614 
4615  /* GL_EXT_texture_integer */
4616  case OPCODE_CLEARCOLOR_I:
4617  CALL_ClearColorIiEXT(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i));
4618  break;
4619  case OPCODE_CLEARCOLOR_UI:
4621  (n[1].ui, n[2].ui, n[3].ui, n[4].ui));
4622  break;
4623  case OPCODE_TEXPARAMETER_I:
4624  {
4625  GLint params[4];
4626  params[0] = n[3].i;
4627  params[1] = n[4].i;
4628  params[2] = n[5].i;
4629  params[3] = n[6].i;
4630  CALL_TexParameterIivEXT(ctx->Exec, (n[1].e, n[2].e, params));
4631  }
4632  break;
4634  {
4635  GLuint params[4];
4636  params[0] = n[3].ui;
4637  params[1] = n[4].ui;
4638  params[2] = n[5].ui;
4639  params[3] = n[6].ui;
4640  CALL_TexParameterIuivEXT(ctx->Exec, (n[1].e, n[2].e, params));
4641  }
4642  break;
4643 
4644  case OPCODE_CONTINUE:
4645  n = (Node *) n[1].next;
4646  break;
4647  case OPCODE_END_OF_LIST:
4648  done = GL_TRUE;
4649  break;
4650  default:
4651  {
4652  char msg[1000];
4653  _mesa_snprintf(msg, sizeof(msg), "Error in execute_list: opcode=%d",
4654  (int) opcode);
4655  _mesa_problem(ctx, "%s", msg);
4656  }
4657  done = GL_TRUE;
4658  }
4659 
4660  /* increment n to point to next compiled command */
4661  if (opcode != OPCODE_CONTINUE) {
4662  n += InstSize[opcode];
4663  }
4664  }
4665  }
4666 
4667  if (ctx->Driver.EndCallList)
4668  ctx->Driver.EndCallList(ctx);
4669 
4670  ctx->ListState.CallDepth--;
4671 }
4672 
4673 
4674 
4675 /**********************************************************************/
4676 /* GL functions */
4677 /**********************************************************************/
4678 
4682 static GLboolean GLAPIENTRY
4683 _mesa_IsList(GLuint list)
4684 {
4685  GET_CURRENT_CONTEXT(ctx);
4686  FLUSH_VERTICES(ctx, 0); /* must be called before assert */
4688  return islist(ctx, list);
4689 }
4690 
4691 
4695 static void GLAPIENTRY
4696 _mesa_DeleteLists(GLuint list, GLsizei range)
4697 {
4698  GET_CURRENT_CONTEXT(ctx);
4699  GLuint i;
4700  FLUSH_VERTICES(ctx, 0); /* must be called before assert */
4702 
4703  if (range < 0) {
4704  _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteLists");
4705  return;
4706  }
4707  for (i = list; i < list + range; i++) {
4708  destroy_list(ctx, i);
4709  }
4710 }
4711 
4712 
4717 static GLuint GLAPIENTRY
4718 _mesa_GenLists(GLsizei range)
4719 {
4720  GET_CURRENT_CONTEXT(ctx);
4721  GLuint base;
4722  FLUSH_VERTICES(ctx, 0); /* must be called before assert */
4724 
4725  if (range < 0) {
4726  _mesa_error(ctx, GL_INVALID_VALUE, "glGenLists");
4727  return 0;
4728  }
4729  if (range == 0) {
4730  return 0;
4731  }
4732 
4733  /*
4734  * Make this an atomic operation
4735  */
4736  _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
4737 
4738  base = _mesa_HashFindFreeKeyBlock(ctx->Shared->DisplayList, range);
4739  if (base) {
4740  /* reserve the list IDs by with empty/dummy lists */
4741  GLint i;
4742  for (i = 0; i < range; i++) {
4743  _mesa_HashInsert(ctx->Shared->DisplayList, base + i,
4744  make_list(base + i, 1));
4745  }
4746  }
4747 
4748  _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
4749 
4750  return base;
4751 }
4752 
4753 
4757 static void GLAPIENTRY
4758 _mesa_NewList(GLuint name, GLenum mode)
4759 {
4760  GET_CURRENT_CONTEXT(ctx);
4761 
4762  FLUSH_CURRENT(ctx, 0); /* must be called before assert */
4764 
4765  if (MESA_VERBOSE & VERBOSE_API)
4766  _mesa_debug(ctx, "glNewList %u %s\n", name,
4767  _mesa_lookup_enum_by_nr(mode));
4768 
4769  if (name == 0) {
4770  _mesa_error(ctx, GL_INVALID_VALUE, "glNewList");
4771  return;
4772  }
4773 
4774  if (mode != GL_COMPILE && mode != GL_COMPILE_AND_EXECUTE) {
4775  _mesa_error(ctx, GL_INVALID_ENUM, "glNewList");
4776  return;
4777  }
4778 
4779  if (ctx->ListState.CurrentList) {
4780  /* already compiling a display list */
4781  _mesa_error(ctx, GL_INVALID_OPERATION, "glNewList");
4782  return;
4783  }
4784 
4785  ctx->CompileFlag = GL_TRUE;
4786  ctx->ExecuteFlag = (mode == GL_COMPILE_AND_EXECUTE);
4787 
4788  /* Reset acumulated list state:
4789  */
4790  invalidate_saved_current_state( ctx );
4791 
4792  /* Allocate new display list */
4793  ctx->ListState.CurrentList = make_list(name, BLOCK_SIZE);
4794  ctx->ListState.CurrentBlock = ctx->ListState.CurrentList->Head;
4795  ctx->ListState.CurrentPos = 0;
4796 
4797  ctx->Driver.NewList(ctx, name, mode);
4798 
4799  ctx->CurrentDispatch = ctx->Save;
4801 }
4802 
4803 
4807 static void GLAPIENTRY
4808 _mesa_EndList(void)
4809 {
4810  GET_CURRENT_CONTEXT(ctx);
4811  SAVE_FLUSH_VERTICES(ctx);
4813 
4814  if (MESA_VERBOSE & VERBOSE_API)
4815  _mesa_debug(ctx, "glEndList\n");
4816 
4817  /* Check that a list is under construction */
4818  if (!ctx->ListState.CurrentList) {
4819  _mesa_error(ctx, GL_INVALID_OPERATION, "glEndList");
4820  return;
4821  }
4822 
4823  /* Call before emitting END_OF_LIST, in case the driver wants to
4824  * emit opcodes itself.
4825  */
4826  ctx->Driver.EndList(ctx);
4827 
4828  (void) alloc_instruction(ctx, OPCODE_END_OF_LIST, 0);
4829 
4830  /* Destroy old list, if any */
4831  destroy_list(ctx, ctx->ListState.CurrentList->Name);
4832 
4833  /* Install the new list */
4834  _mesa_HashInsert(ctx->Shared->DisplayList,
4835  ctx->ListState.CurrentList->Name,
4836  ctx->ListState.CurrentList);
4837 
4838 
4840  mesa_print_display_list(ctx->ListState.CurrentList->Name);
4841 
4842  ctx->ListState.CurrentList = NULL;
4843  ctx->ExecuteFlag = GL_TRUE;
4844  ctx->CompileFlag = GL_FALSE;
4845 
4846  ctx->CurrentDispatch = ctx->Exec;
4848 }
4849 
4850 
4851 void GLAPIENTRY
4852 _mesa_CallList(GLuint list)
4853 {
4854  GLboolean save_compile_flag;
4855  GET_CURRENT_CONTEXT(ctx);
4856  FLUSH_CURRENT(ctx, 0);
4857 
4858  if (MESA_VERBOSE & VERBOSE_API)
4859  _mesa_debug(ctx, "glCallList %d\n", list);
4860 
4861  if (list == 0) {
4862  _mesa_error(ctx, GL_INVALID_VALUE, "glCallList(list==0)");
4863  return;
4864  }
4865 
4866  if (0)
4867  mesa_print_display_list( list );
4868 
4869  /* VERY IMPORTANT: Save the CompileFlag status, turn it off,
4870  * execute the display list, and restore the CompileFlag.
4871  */
4872  save_compile_flag = ctx->CompileFlag;
4873  if (save_compile_flag) {
4874  ctx->CompileFlag = GL_FALSE;
4875  }
4876 
4877  execute_list(ctx, list);
4878  ctx->CompileFlag = save_compile_flag;
4879 
4880  /* also restore API function pointers to point to "save" versions */
4881  if (save_compile_flag) {
4882  ctx->CurrentDispatch = ctx->Save;
4884  }
4885 }
4886 
4887 
4891 void GLAPIENTRY
4892 _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
4893 {
4894  GET_CURRENT_CONTEXT(ctx);
4895  GLint i;
4896  GLboolean save_compile_flag;
4897 
4898  if (MESA_VERBOSE & VERBOSE_API)
4899  _mesa_debug(ctx, "glCallLists %d\n", n);
4900 
4901  switch (type) {
4902  case GL_BYTE:
4903  case GL_UNSIGNED_BYTE:
4904  case GL_SHORT:
4905  case GL_UNSIGNED_SHORT:
4906  case GL_INT:
4907  case GL_UNSIGNED_INT:
4908  case GL_FLOAT:
4909  case GL_2_BYTES:
4910  case GL_3_BYTES:
4911  case GL_4_BYTES:
4912  /* OK */
4913  break;
4914  default:
4915  _mesa_error(ctx, GL_INVALID_ENUM, "glCallLists(type)");
4916  return;
4917  }
4918 
4919  /* Save the CompileFlag status, turn it off, execute display list,
4920  * and restore the CompileFlag.
4921  */
4922  save_compile_flag = ctx->CompileFlag;
4923  ctx->CompileFlag = GL_FALSE;
4924 
4925  for (i = 0; i < n; i++) {
4926  GLuint list = (GLuint) (ctx->List.ListBase + translate_id(i, type, lists));
4927  execute_list(ctx, list);
4928  }
4929 
4930  ctx->CompileFlag = save_compile_flag;
4931 
4932  /* also restore API function pointers to point to "save" versions */
4933  if (save_compile_flag) {
4934  ctx->CurrentDispatch = ctx->Save;
4936  }
4937 }
4938 
4939 
4943 static void GLAPIENTRY
4944 _mesa_ListBase(GLuint base)
4945 {
4946  GET_CURRENT_CONTEXT(ctx);
4947  FLUSH_VERTICES(ctx, 0); /* must be called before assert */
4949  ctx->List.ListBase = base;
4950 }
4951 
4952 
4953 /* Can no longer assume ctx->Exec->Func is equal to _mesa_Func.
4954  */
4955 static void GLAPIENTRY
4956 exec_Finish(void)
4957 {
4958  GET_CURRENT_CONTEXT(ctx);
4959  FLUSH_VERTICES(ctx, 0);
4960  CALL_Finish(ctx->Exec, ());
4961 }
4962 
4963 static void GLAPIENTRY
4964 exec_Flush(void)
4965 {
4966  GET_CURRENT_CONTEXT(ctx);
4967  FLUSH_VERTICES(ctx, 0);
4968  CALL_Flush(ctx->Exec, ());
4969 }
4970 
4971 static void GLAPIENTRY
4972 exec_GetBooleanv(GLenum pname, GLboolean *params)
4973 {
4974  GET_CURRENT_CONTEXT(ctx);
4975  FLUSH_VERTICES(ctx, 0);
4976  CALL_GetBooleanv(ctx->Exec, (pname, params));
4977 }
4978 
4979 static void GLAPIENTRY
4980 exec_GetClipPlane(GLenum plane, GLdouble * equation)
4981 {
4982  GET_CURRENT_CONTEXT(ctx);
4983  FLUSH_VERTICES(ctx, 0);
4984  CALL_GetClipPlane(ctx->Exec, (plane, equation));
4985 }
4986 
4987 static void GLAPIENTRY
4988 exec_GetDoublev(GLenum pname, GLdouble *params)
4989 {
4990  GET_CURRENT_CONTEXT(ctx);
4991  FLUSH_VERTICES(ctx, 0);
4992  CALL_GetDoublev(ctx->Exec, (pname, params));
4993 }
4994 
4995 static GLenum GLAPIENTRY
4996 exec_GetError(void)
4997 {
4998  GET_CURRENT_CONTEXT(ctx);
4999  FLUSH_VERTICES(ctx, 0);
5000  return CALL_GetError(ctx->Exec, ());
5001 }
5002 
5003 static void GLAPIENTRY
5004 exec_GetFloatv(GLenum pname, GLfloat *params)
5005 {
5006  GET_CURRENT_CONTEXT(ctx);
5007  FLUSH_VERTICES(ctx, 0);
5008  CALL_GetFloatv(ctx->Exec, (pname, params));
5009 }
5010 
5011 static void GLAPIENTRY
5012 exec_GetIntegerv(GLenum pname, GLint *params)
5013 {
5014  GET_CURRENT_CONTEXT(ctx);
5015  FLUSH_VERTICES(ctx, 0);
5016  CALL_GetIntegerv(ctx->Exec, (pname, params));
5017 }
5018 
5019 static void GLAPIENTRY
5020 exec_GetLightfv(GLenum light, GLenum pname, GLfloat *params)
5021 {
5022  GET_CURRENT_CONTEXT(ctx);
5023  FLUSH_VERTICES(ctx, 0);
5024  CALL_GetLightfv(ctx->Exec, (light, pname, params));
5025 }
5026 
5027 static void GLAPIENTRY
5028 exec_GetLightiv(GLenum light, GLenum pname, GLint *params)
5029 {
5030  GET_CURRENT_CONTEXT(ctx);
5031  FLUSH_VERTICES(ctx, 0);
5032  CALL_GetLightiv(ctx->Exec, (light, pname, params));
5033 }
5034 
5035 static void GLAPIENTRY
5036 exec_GetMapdv(GLenum target, GLenum query, GLdouble * v)
5037 {
5038  GET_CURRENT_CONTEXT(ctx);
5039  FLUSH_VERTICES(ctx, 0);
5040  CALL_GetMapdv(ctx->Exec, (target, query, v));
5041 }
5042 
5043 static void GLAPIENTRY
5044 exec_GetMapfv(GLenum target, GLenum query, GLfloat * v)
5045 {
5046  GET_CURRENT_CONTEXT(ctx);
5047  FLUSH_VERTICES(ctx, 0);
5048  CALL_GetMapfv(ctx->Exec, (target, query, v));
5049 }
5050 
5051 static void GLAPIENTRY
5052 exec_GetMapiv(GLenum target, GLenum query, GLint * v)
5053 {
5054  GET_CURRENT_CONTEXT(ctx);
5055  FLUSH_VERTICES(ctx, 0);
5056  CALL_GetMapiv(ctx->Exec, (target, query, v));
5057 }
5058 
5059 static void GLAPIENTRY
5060 exec_GetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
5061 {
5062  GET_CURRENT_CONTEXT(ctx);
5063  FLUSH_VERTICES(ctx, 0);
5064  CALL_GetMaterialfv(ctx->Exec, (face, pname, params));
5065 }
5066 
5067 static void GLAPIENTRY
5068 exec_GetMaterialiv(GLenum face, GLenum pname, GLint *params)
5069 {
5070  GET_CURRENT_CONTEXT(ctx);
5071  FLUSH_VERTICES(ctx, 0);
5072  CALL_GetMaterialiv(ctx->Exec, (face, pname, params));
5073 }
5074 
5075 static void GLAPIENTRY
5076 exec_GetPixelMapfv(GLenum map, GLfloat *values)
5077 {
5078  GET_CURRENT_CONTEXT(ctx);
5079  FLUSH_VERTICES(ctx, 0);
5080  CALL_GetPixelMapfv(ctx->Exec, (map, values));
5081 }
5082 
5083 static void GLAPIENTRY
5084 exec_GetPixelMapuiv(GLenum map, GLuint *values)
5085 {
5086  GET_CURRENT_CONTEXT(ctx);
5087  FLUSH_VERTICES(ctx, 0);
5088  CALL_GetPixelMapuiv(ctx->Exec, (map, values));
5089 }
5090 
5091 static void GLAPIENTRY
5092 exec_GetPixelMapusv(GLenum map, GLushort *values)
5093 {
5094  GET_CURRENT_CONTEXT(ctx);
5095  FLUSH_VERTICES(ctx, 0);
5096  CALL_GetPixelMapusv(ctx->Exec, (map, values));
5097 }
5098 
5099 static void GLAPIENTRY
5100 exec_GetPolygonStipple(GLubyte * dest)
5101 {
5102  GET_CURRENT_CONTEXT(ctx);
5103  FLUSH_VERTICES(ctx, 0);
5104  CALL_GetPolygonStipple(ctx->Exec, (dest));
5105 }
5106 
5107 static const GLubyte *GLAPIENTRY
5108 exec_GetString(GLenum name)
5109 {
5110  GET_CURRENT_CONTEXT(ctx);
5111  FLUSH_VERTICES(ctx, 0);
5112  return CALL_GetString(ctx->Exec, (name));
5113 }
5114 
5115 static void GLAPIENTRY
5116 exec_GetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
5117 {
5118  GET_CURRENT_CONTEXT(ctx);
5119  FLUSH_VERTICES(ctx, 0);
5120  CALL_GetTexEnvfv(ctx->Exec, (target, pname, params));
5121 }
5122 
5123 static void GLAPIENTRY
5124 exec_GetTexEnviv(GLenum target, GLenum pname, GLint *params)
5125 {
5126  GET_CURRENT_CONTEXT(ctx);
5127  FLUSH_VERTICES(ctx, 0);
5128  CALL_GetTexEnviv(ctx->Exec, (target, pname, params));
5129 }
5130 
5131 static void GLAPIENTRY