1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 27 /** 28 * \file dlist.c 29 * Display lists management functions. 30 */ 31 32 #include "c99_math.h" 33 #include "glheader.h" 34 #include "imports.h" 35 #include "api_arrayelt.h" 36 #include "api_exec.h" 37 #include "api_loopback.h" 38 #include "api_validate.h" 39 #include "atifragshader.h" 40 #include "config.h" 41 #include "bufferobj.h" 42 #include "arrayobj.h" 43 #include "context.h" 44 #include "dlist.h" 45 #include "enums.h" 46 #include "eval.h" 47 #include "fbobject.h" 48 #include "framebuffer.h" 49 #include "glapi/glapi.h" 50 #include "glformats.h" 51 #include "hash.h" 52 #include "image.h" 53 #include "light.h" 54 #include "macros.h" 55 #include "pack.h" 56 #include "pbo.h" 57 #include "queryobj.h" 58 #include "samplerobj.h" 59 #include "shaderapi.h" 60 #include "syncobj.h" 61 #include "teximage.h" 62 #include "texstorage.h" 63 #include "mtypes.h" 64 #include "varray.h" 65 #include "arbprogram.h" 66 #include "transformfeedback.h" 67 68 #include "math/m_matrix.h" 69 70 #include "main/dispatch.h" 71 72 #include "vbo/vbo.h" 73 74 75 #define USE_BITMAP_ATLAS 1 76 77 78 79 /** 80 * Other parts of Mesa (such as the VBO module) can plug into the display 81 * list system. This structure describes new display list instructions. 82 */ 83 struct gl_list_instruction 84 { 85 GLuint Size; 86 void (*Execute)( struct gl_context *ctx, void *data ); 87 void (*Destroy)( struct gl_context *ctx, void *data ); 88 void (*Print)( struct gl_context *ctx, void *data, FILE *f ); 89 }; 90 91 92 #define MAX_DLIST_EXT_OPCODES 16 93 94 /** 95 * Used by device drivers to hook new commands into display lists. 96 */ 97 struct gl_list_extensions 98 { 99 struct gl_list_instruction Opcode[MAX_DLIST_EXT_OPCODES]; 100 GLuint NumOpcodes; 101 }; 102 103 104 105 /** 106 * Flush vertices. 107 * 108 * \param ctx GL context. 109 * 110 * Checks if dd_function_table::SaveNeedFlush is marked to flush 111 * stored (save) vertices, and calls vbo_save_SaveFlushVertices if so. 112 */ 113 #define SAVE_FLUSH_VERTICES(ctx) \ 114 do { \ 115 if (ctx->Driver.SaveNeedFlush) \ 116 vbo_save_SaveFlushVertices(ctx); \ 117 } while (0) 118 119 120 /** 121 * Macro to assert that the API call was made outside the 122 * glBegin()/glEnd() pair, with return value. 123 * 124 * \param ctx GL context. 125 * \param retval value to return value in case the assertion fails. 126 */ 127 #define ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval) \ 128 do { \ 129 if (ctx->Driver.CurrentSavePrimitive <= PRIM_MAX) { \ 130 _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glBegin/End" ); \ 131 return retval; \ 132 } \ 133 } while (0) 134 135 /** 136 * Macro to assert that the API call was made outside the 137 * glBegin()/glEnd() pair. 138 * 139 * \param ctx GL context. 140 */ 141 #define ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx) \ 142 do { \ 143 if (ctx->Driver.CurrentSavePrimitive <= PRIM_MAX) { \ 144 _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glBegin/End" ); \ 145 return; \ 146 } \ 147 } while (0) 148 149 /** 150 * Macro to assert that the API call was made outside the 151 * glBegin()/glEnd() pair and flush the vertices. 152 * 153 * \param ctx GL context. 154 */ 155 #define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx) \ 156 do { \ 157 ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx); \ 158 SAVE_FLUSH_VERTICES(ctx); \ 159 } while (0) 160 161 /** 162 * Macro to assert that the API call was made outside the 163 * glBegin()/glEnd() pair and flush the vertices, with return value. 164 * 165 * \param ctx GL context. 166 * \param retval value to return value in case the assertion fails. 167 */ 168 #define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, retval) \ 169 do { \ 170 ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval); \ 171 SAVE_FLUSH_VERTICES(ctx); \ 172 } while (0) 173 174 175 /** 176 * Display list opcodes. 177 * 178 * The fact that these identifiers are assigned consecutive 179 * integer values starting at 0 is very important, see InstSize array usage) 180 */ 181 typedef enum 182 { 183 OPCODE_INVALID = -1, /* Force signed enum */ 184 OPCODE_ACCUM, 185 OPCODE_ALPHA_FUNC, 186 OPCODE_BIND_TEXTURE, 187 OPCODE_BITMAP, 188 OPCODE_BLEND_COLOR, 189 OPCODE_BLEND_EQUATION, 190 OPCODE_BLEND_EQUATION_SEPARATE, 191 OPCODE_BLEND_FUNC_SEPARATE, 192 193 OPCODE_BLEND_EQUATION_I, 194 OPCODE_BLEND_EQUATION_SEPARATE_I, 195 OPCODE_BLEND_FUNC_I, 196 OPCODE_BLEND_FUNC_SEPARATE_I, 197 198 OPCODE_CALL_LIST, 199 OPCODE_CALL_LISTS, 200 OPCODE_CLEAR, 201 OPCODE_CLEAR_ACCUM, 202 OPCODE_CLEAR_COLOR, 203 OPCODE_CLEAR_DEPTH, 204 OPCODE_CLEAR_INDEX, 205 OPCODE_CLEAR_STENCIL, 206 OPCODE_CLEAR_BUFFER_IV, 207 OPCODE_CLEAR_BUFFER_UIV, 208 OPCODE_CLEAR_BUFFER_FV, 209 OPCODE_CLEAR_BUFFER_FI, 210 OPCODE_CLIP_PLANE, 211 OPCODE_COLOR_MASK, 212 OPCODE_COLOR_MASK_INDEXED, 213 OPCODE_COLOR_MATERIAL, 214 OPCODE_COPY_PIXELS, 215 OPCODE_COPY_TEX_IMAGE1D, 216 OPCODE_COPY_TEX_IMAGE2D, 217 OPCODE_COPY_TEX_SUB_IMAGE1D, 218 OPCODE_COPY_TEX_SUB_IMAGE2D, 219 OPCODE_COPY_TEX_SUB_IMAGE3D, 220 OPCODE_CULL_FACE, 221 OPCODE_DEPTH_FUNC, 222 OPCODE_DEPTH_MASK, 223 OPCODE_DEPTH_RANGE, 224 OPCODE_DISABLE, 225 OPCODE_DISABLE_INDEXED, 226 OPCODE_DRAW_BUFFER, 227 OPCODE_DRAW_PIXELS, 228 OPCODE_ENABLE, 229 OPCODE_ENABLE_INDEXED, 230 OPCODE_EVALMESH1, 231 OPCODE_EVALMESH2, 232 OPCODE_FOG, 233 OPCODE_FRONT_FACE, 234 OPCODE_FRUSTUM, 235 OPCODE_HINT, 236 OPCODE_INDEX_MASK, 237 OPCODE_INIT_NAMES, 238 OPCODE_LIGHT, 239 OPCODE_LIGHT_MODEL, 240 OPCODE_LINE_STIPPLE, 241 OPCODE_LINE_WIDTH, 242 OPCODE_LIST_BASE, 243 OPCODE_LOAD_IDENTITY, 244 OPCODE_LOAD_MATRIX, 245 OPCODE_LOAD_NAME, 246 OPCODE_LOGIC_OP, 247 OPCODE_MAP1, 248 OPCODE_MAP2, 249 OPCODE_MAPGRID1, 250 OPCODE_MAPGRID2, 251 OPCODE_MATRIX_MODE, 252 OPCODE_MULT_MATRIX, 253 OPCODE_ORTHO, 254 OPCODE_PASSTHROUGH, 255 OPCODE_PIXEL_MAP, 256 OPCODE_PIXEL_TRANSFER, 257 OPCODE_PIXEL_ZOOM, 258 OPCODE_POINT_SIZE, 259 OPCODE_POINT_PARAMETERS, 260 OPCODE_POLYGON_MODE, 261 OPCODE_POLYGON_STIPPLE, 262 OPCODE_POLYGON_OFFSET, 263 OPCODE_POP_ATTRIB, 264 OPCODE_POP_MATRIX, 265 OPCODE_POP_NAME, 266 OPCODE_PRIORITIZE_TEXTURE, 267 OPCODE_PUSH_ATTRIB, 268 OPCODE_PUSH_MATRIX, 269 OPCODE_PUSH_NAME, 270 OPCODE_RASTER_POS, 271 OPCODE_READ_BUFFER, 272 OPCODE_ROTATE, 273 OPCODE_SCALE, 274 OPCODE_SCISSOR, 275 OPCODE_SELECT_TEXTURE_SGIS, 276 OPCODE_SELECT_TEXTURE_COORD_SET, 277 OPCODE_SHADE_MODEL, 278 OPCODE_STENCIL_FUNC, 279 OPCODE_STENCIL_MASK, 280 OPCODE_STENCIL_OP, 281 OPCODE_TEXENV, 282 OPCODE_TEXGEN, 283 OPCODE_TEXPARAMETER, 284 OPCODE_TEX_IMAGE1D, 285 OPCODE_TEX_IMAGE2D, 286 OPCODE_TEX_IMAGE3D, 287 OPCODE_TEX_SUB_IMAGE1D, 288 OPCODE_TEX_SUB_IMAGE2D, 289 OPCODE_TEX_SUB_IMAGE3D, 290 OPCODE_TRANSLATE, 291 OPCODE_VIEWPORT, 292 OPCODE_WINDOW_POS, 293 /* GL_ARB_multitexture */ 294 OPCODE_ACTIVE_TEXTURE, 295 /* GL_ARB_texture_compression */ 296 OPCODE_COMPRESSED_TEX_IMAGE_1D, 297 OPCODE_COMPRESSED_TEX_IMAGE_2D, 298 OPCODE_COMPRESSED_TEX_IMAGE_3D, 299 OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, 300 OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, 301 OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, 302 /* GL_ARB_multisample */ 303 OPCODE_SAMPLE_COVERAGE, 304 /* GL_ARB_window_pos */ 305 OPCODE_WINDOW_POS_ARB, 306 /* GL_ARB_vertex_program */ 307 OPCODE_BIND_PROGRAM_ARB, 308 OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 309 /* GL_EXT_stencil_two_side */ 310 OPCODE_ACTIVE_STENCIL_FACE_EXT, 311 /* GL_EXT_depth_bounds_test */ 312 OPCODE_DEPTH_BOUNDS_EXT, 313 /* GL_ARB_vertex/fragment_program */ 314 OPCODE_PROGRAM_STRING_ARB, 315 OPCODE_PROGRAM_ENV_PARAMETER_ARB, 316 /* GL_ARB_occlusion_query */ 317 OPCODE_BEGIN_QUERY_ARB, 318 OPCODE_END_QUERY_ARB, 319 /* GL_ARB_draw_buffers */ 320 OPCODE_DRAW_BUFFERS_ARB, 321 /* GL_ATI_fragment_shader */ 322 OPCODE_BIND_FRAGMENT_SHADER_ATI, 323 OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI, 324 /* OpenGL 2.0 */ 325 OPCODE_STENCIL_FUNC_SEPARATE, 326 OPCODE_STENCIL_OP_SEPARATE, 327 OPCODE_STENCIL_MASK_SEPARATE, 328 /* GL_NV_primitive_restart */ 329 OPCODE_PRIMITIVE_RESTART_NV, 330 /* GL_ARB_shader_objects */ 331 OPCODE_USE_PROGRAM, 332 OPCODE_UNIFORM_1F, 333 OPCODE_UNIFORM_2F, 334 OPCODE_UNIFORM_3F, 335 OPCODE_UNIFORM_4F, 336 OPCODE_UNIFORM_1FV, 337 OPCODE_UNIFORM_2FV, 338 OPCODE_UNIFORM_3FV, 339 OPCODE_UNIFORM_4FV, 340 OPCODE_UNIFORM_1I, 341 OPCODE_UNIFORM_2I, 342 OPCODE_UNIFORM_3I, 343 OPCODE_UNIFORM_4I, 344 OPCODE_UNIFORM_1IV, 345 OPCODE_UNIFORM_2IV, 346 OPCODE_UNIFORM_3IV, 347 OPCODE_UNIFORM_4IV, 348 OPCODE_UNIFORM_MATRIX22, 349 OPCODE_UNIFORM_MATRIX33, 350 OPCODE_UNIFORM_MATRIX44, 351 OPCODE_UNIFORM_MATRIX23, 352 OPCODE_UNIFORM_MATRIX32, 353 OPCODE_UNIFORM_MATRIX24, 354 OPCODE_UNIFORM_MATRIX42, 355 OPCODE_UNIFORM_MATRIX34, 356 OPCODE_UNIFORM_MATRIX43, 357 358 /* OpenGL 3.0 */ 359 OPCODE_UNIFORM_1UI, 360 OPCODE_UNIFORM_2UI, 361 OPCODE_UNIFORM_3UI, 362 OPCODE_UNIFORM_4UI, 363 OPCODE_UNIFORM_1UIV, 364 OPCODE_UNIFORM_2UIV, 365 OPCODE_UNIFORM_3UIV, 366 OPCODE_UNIFORM_4UIV, 367 368 /* OpenGL 4.2 / GL_ARB_separate_shader_objects */ 369 OPCODE_USE_PROGRAM_STAGES, 370 OPCODE_PROGRAM_UNIFORM_1F, 371 OPCODE_PROGRAM_UNIFORM_2F, 372 OPCODE_PROGRAM_UNIFORM_3F, 373 OPCODE_PROGRAM_UNIFORM_4F, 374 OPCODE_PROGRAM_UNIFORM_1FV, 375 OPCODE_PROGRAM_UNIFORM_2FV, 376 OPCODE_PROGRAM_UNIFORM_3FV, 377 OPCODE_PROGRAM_UNIFORM_4FV, 378 OPCODE_PROGRAM_UNIFORM_1I, 379 OPCODE_PROGRAM_UNIFORM_2I, 380 OPCODE_PROGRAM_UNIFORM_3I, 381 OPCODE_PROGRAM_UNIFORM_4I, 382 OPCODE_PROGRAM_UNIFORM_1IV, 383 OPCODE_PROGRAM_UNIFORM_2IV, 384 OPCODE_PROGRAM_UNIFORM_3IV, 385 OPCODE_PROGRAM_UNIFORM_4IV, 386 OPCODE_PROGRAM_UNIFORM_1UI, 387 OPCODE_PROGRAM_UNIFORM_2UI, 388 OPCODE_PROGRAM_UNIFORM_3UI, 389 OPCODE_PROGRAM_UNIFORM_4UI, 390 OPCODE_PROGRAM_UNIFORM_1UIV, 391 OPCODE_PROGRAM_UNIFORM_2UIV, 392 OPCODE_PROGRAM_UNIFORM_3UIV, 393 OPCODE_PROGRAM_UNIFORM_4UIV, 394 OPCODE_PROGRAM_UNIFORM_MATRIX22F, 395 OPCODE_PROGRAM_UNIFORM_MATRIX33F, 396 OPCODE_PROGRAM_UNIFORM_MATRIX44F, 397 OPCODE_PROGRAM_UNIFORM_MATRIX23F, 398 OPCODE_PROGRAM_UNIFORM_MATRIX32F, 399 OPCODE_PROGRAM_UNIFORM_MATRIX24F, 400 OPCODE_PROGRAM_UNIFORM_MATRIX42F, 401 OPCODE_PROGRAM_UNIFORM_MATRIX34F, 402 OPCODE_PROGRAM_UNIFORM_MATRIX43F, 403 404 /* GL_ARB_clip_control */ 405 OPCODE_CLIP_CONTROL, 406 407 /* GL_ARB_color_buffer_float */ 408 OPCODE_CLAMP_COLOR, 409 410 /* GL_EXT_framebuffer_blit */ 411 OPCODE_BLIT_FRAMEBUFFER, 412 413 /* Vertex attributes -- fallback for when optimized display 414 * list build isn't active. 415 */ 416 OPCODE_ATTR_1F_NV, 417 OPCODE_ATTR_2F_NV, 418 OPCODE_ATTR_3F_NV, 419 OPCODE_ATTR_4F_NV, 420 OPCODE_ATTR_1F_ARB, 421 OPCODE_ATTR_2F_ARB, 422 OPCODE_ATTR_3F_ARB, 423 OPCODE_ATTR_4F_ARB, 424 OPCODE_MATERIAL, 425 OPCODE_BEGIN, 426 OPCODE_END, 427 OPCODE_RECTF, 428 OPCODE_EVAL_C1, 429 OPCODE_EVAL_C2, 430 OPCODE_EVAL_P1, 431 OPCODE_EVAL_P2, 432 433 /* GL_EXT_provoking_vertex */ 434 OPCODE_PROVOKING_VERTEX, 435 436 /* GL_EXT_transform_feedback */ 437 OPCODE_BEGIN_TRANSFORM_FEEDBACK, 438 OPCODE_END_TRANSFORM_FEEDBACK, 439 OPCODE_BIND_TRANSFORM_FEEDBACK, 440 OPCODE_PAUSE_TRANSFORM_FEEDBACK, 441 OPCODE_RESUME_TRANSFORM_FEEDBACK, 442 OPCODE_DRAW_TRANSFORM_FEEDBACK, 443 444 /* GL_EXT_texture_integer */ 445 OPCODE_CLEARCOLOR_I, 446 OPCODE_CLEARCOLOR_UI, 447 OPCODE_TEXPARAMETER_I, 448 OPCODE_TEXPARAMETER_UI, 449 450 /* GL_ARB_instanced_arrays */ 451 OPCODE_VERTEX_ATTRIB_DIVISOR, 452 453 /* GL_NV_texture_barrier */ 454 OPCODE_TEXTURE_BARRIER_NV, 455 456 /* GL_ARB_sampler_object */ 457 OPCODE_BIND_SAMPLER, 458 OPCODE_SAMPLER_PARAMETERIV, 459 OPCODE_SAMPLER_PARAMETERFV, 460 OPCODE_SAMPLER_PARAMETERIIV, 461 OPCODE_SAMPLER_PARAMETERUIV, 462 463 /* GL_ARB_sync */ 464 OPCODE_WAIT_SYNC, 465 466 /* GL_NV_conditional_render */ 467 OPCODE_BEGIN_CONDITIONAL_RENDER, 468 OPCODE_END_CONDITIONAL_RENDER, 469 470 /* ARB_timer_query */ 471 OPCODE_QUERY_COUNTER, 472 473 /* ARB_transform_feedback3 */ 474 OPCODE_BEGIN_QUERY_INDEXED, 475 OPCODE_END_QUERY_INDEXED, 476 OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM, 477 478 /* ARB_transform_feedback_instanced */ 479 OPCODE_DRAW_TRANSFORM_FEEDBACK_INSTANCED, 480 OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM_INSTANCED, 481 482 /* ARB_uniform_buffer_object */ 483 OPCODE_UNIFORM_BLOCK_BINDING, 484 485 /* EXT_polygon_offset_clamp */ 486 OPCODE_POLYGON_OFFSET_CLAMP, 487 488 /* EXT_window_rectangles */ 489 OPCODE_WINDOW_RECTANGLES, 490 491 /* The following three are meta instructions */ 492 OPCODE_ERROR, /* raise compiled-in error */ 493 OPCODE_CONTINUE, 494 OPCODE_NOP, /* No-op (used for 8-byte alignment */ 495 OPCODE_END_OF_LIST, 496 OPCODE_EXT_0 497 } OpCode; 498 499 500 501 /** 502 * Display list node. 503 * 504 * Display list instructions are stored as sequences of "nodes". Nodes 505 * are allocated in blocks. Each block has BLOCK_SIZE nodes. Blocks 506 * are linked together with a pointer. 507 * 508 * Each instruction in the display list is stored as a sequence of 509 * contiguous nodes in memory. 510 * Each node is the union of a variety of data types. 511 * 512 * Note, all of these members should be 4 bytes in size or less for the 513 * sake of compact display lists. We store 8-byte pointers in a pair of 514 * these nodes using the save/get_pointer() functions below. 515 */ 516 union gl_dlist_node 517 { 518 OpCode opcode; 519 GLboolean b; 520 GLbitfield bf; 521 GLubyte ub; 522 GLshort s; 523 GLushort us; 524 GLint i; 525 GLuint ui; 526 GLenum e; 527 GLfloat f; 528 GLsizei si; 529 }; 530 531 532 typedef union gl_dlist_node Node; 533 534 535 /** How many 4-byte dwords to store a pointer */ 536 #define POINTER_DWORDS (sizeof(void *) / 4) 537 538 /* We want to keep sizeof(union gl_dlist_node) == 4 to minimize 539 * space for display lists. The following types and functions are 540 * used to help store 4- and 8-byte pointers in 1 or 2 dlist_nodes. 541 */ 542 union pointer 543 { 544 void *ptr; 545 GLuint dwords[POINTER_DWORDS]; 546 }; 547 548 549 /** 550 * Save a 4 or 8-byte pointer at dest (and dest+1). 551 */ 552 static inline void 553 save_pointer(Node *dest, void *src) 554 { 555 union pointer p; 556 unsigned i; 557 558 STATIC_ASSERT(POINTER_DWORDS == 1 || POINTER_DWORDS == 2); 559 STATIC_ASSERT(sizeof(Node) == 4); 560 561 p.ptr = src; 562 563 for (i = 0; i < POINTER_DWORDS; i++) 564 dest[i].ui = p.dwords[i]; 565 } 566 567 568 /** 569 * Retrieve a 4 or 8-byte pointer from node (node+1). 570 */ 571 static inline void * 572 get_pointer(const Node *node) 573 { 574 union pointer p; 575 unsigned i; 576 577 for (i = 0; i < POINTER_DWORDS; i++) 578 p.dwords[i] = node[i].ui; 579 580 return p.ptr; 581 } 582 583 584 /** 585 * Used to store a 64-bit uint in a pair of "Nodes" for the sake of 32-bit 586 * environment. 587 */ 588 union uint64_pair 589 { 590 GLuint64 uint64; 591 GLuint uint32[2]; 592 }; 593 594 595 /** 596 * How many nodes to allocate at a time. Note that bulk vertex data 597 * from glBegin/glVertex/glEnd primitives will typically wind up in 598 * a VBO, and not directly in the display list itself. 599 */ 600 #define BLOCK_SIZE 256 601 602 603 604 /** 605 * Number of nodes of storage needed for each instruction. 606 * Sizes for dynamically allocated opcodes are stored in the context struct. 607 */ 608 static GLuint InstSize[OPCODE_END_OF_LIST + 1]; 609 610 611 void mesa_print_display_list(GLuint list); 612 613 614 /** 615 * Does the given display list only contain a single glBitmap call? 616 */ 617 static bool 618 is_bitmap_list(const struct gl_display_list *dlist) 619 { 620 const Node *n = dlist->Head; 621 if (n[0].opcode == OPCODE_BITMAP) { 622 n += InstSize[OPCODE_BITMAP]; 623 if (n[0].opcode == OPCODE_END_OF_LIST) 624 return true; 625 } 626 return false; 627 } 628 629 630 /** 631 * Is the given display list an empty list? 632 */ 633 static bool 634 is_empty_list(const struct gl_display_list *dlist) 635 { 636 const Node *n = dlist->Head; 637 return n[0].opcode == OPCODE_END_OF_LIST; 638 } 639 640 641 /** 642 * Delete/free a gl_bitmap_atlas. Called during context tear-down. 643 */ 644 void 645 _mesa_delete_bitmap_atlas(struct gl_context *ctx, struct gl_bitmap_atlas *atlas) 646 { 647 if (atlas->texObj) { 648 ctx->Driver.DeleteTexture(ctx, atlas->texObj); 649 } 650 free(atlas->glyphs); 651 } 652 653 654 /** 655 * Lookup a gl_bitmap_atlas by listBase ID. 656 */ 657 static struct gl_bitmap_atlas * 658 lookup_bitmap_atlas(struct gl_context *ctx, GLuint listBase) 659 { 660 struct gl_bitmap_atlas *atlas; 661 662 assert(listBase > 0); 663 atlas = _mesa_HashLookup(ctx->Shared->BitmapAtlas, listBase); 664 return atlas; 665 } 666 667 668 /** 669 * Create new bitmap atlas and insert into hash table. 670 */ 671 static struct gl_bitmap_atlas * 672 alloc_bitmap_atlas(struct gl_context *ctx, GLuint listBase) 673 { 674 struct gl_bitmap_atlas *atlas; 675 676 assert(listBase > 0); 677 assert(_mesa_HashLookup(ctx->Shared->BitmapAtlas, listBase) == NULL); 678 679 atlas = calloc(1, sizeof(*atlas)); 680 if (atlas) { 681 _mesa_HashInsert(ctx->Shared->BitmapAtlas, listBase, atlas); 682 } 683 684 return atlas; 685 } 686 687 688 /** 689 * Try to build a bitmap atlas. This involves examining a sequence of 690 * display lists which contain glBitmap commands and putting the bitmap 691 * images into a texture map (the atlas). 692 * If we succeed, gl_bitmap_atlas::complete will be set to true. 693 * If we fail, gl_bitmap_atlas::incomplete will be set to true. 694 */ 695 static void 696 build_bitmap_atlas(struct gl_context *ctx, struct gl_bitmap_atlas *atlas, 697 GLuint listBase) 698 { 699 unsigned i, row_height = 0, xpos = 0, ypos = 0; 700 GLubyte *map; 701 GLint map_stride; 702 703 assert(atlas); 704 assert(!atlas->complete); 705 assert(atlas->numBitmaps > 0); 706 707 /* We use a rectangle texture (non-normalized coords) for the atlas */ 708 assert(ctx->Extensions.NV_texture_rectangle); 709 assert(ctx->Const.MaxTextureRectSize >= 1024); 710 711 atlas->texWidth = 1024; 712 atlas->texHeight = 0; /* determined below */ 713 714 atlas->glyphs = malloc(atlas->numBitmaps * sizeof(atlas->glyphs[0])); 715 if (!atlas->glyphs) { 716 /* give up */ 717 atlas->incomplete = true; 718 return; 719 } 720 721 /* Loop over the display lists. They should all contain a single glBitmap 722 * call. If not, bail out. Also, compute the position and sizes of each 723 * bitmap in the atlas to determine the texture atlas size. 724 */ 725 for (i = 0; i < atlas->numBitmaps; i++) { 726 const struct gl_display_list *list = _mesa_lookup_list(ctx, listBase + i); 727 const Node *n; 728 struct gl_bitmap_glyph *g = &atlas->glyphs[i]; 729 unsigned bitmap_width, bitmap_height; 730 float bitmap_xmove, bitmap_ymove, bitmap_xorig, bitmap_yorig; 731 732 if (!list || is_empty_list(list)) { 733 /* stop here */ 734 atlas->numBitmaps = i; 735 break; 736 } 737 738 if (!is_bitmap_list(list)) { 739 /* This list does not contain exactly one glBitmap command. Give up. */ 740 atlas->incomplete = true; 741 return; 742 } 743 744 /* get bitmap info from the display list command */ 745 n = list->Head; 746 assert(n[0].opcode == OPCODE_BITMAP); 747 bitmap_width = n[1].i; 748 bitmap_height = n[2].i; 749 bitmap_xorig = n[3].f; 750 bitmap_yorig = n[4].f; 751 bitmap_xmove = n[5].f; 752 bitmap_ymove = n[6].f; 753 754 if (xpos + bitmap_width > atlas->texWidth) { 755 /* advance to the next row of the texture */ 756 xpos = 0; 757 ypos += row_height; 758 row_height = 0; 759 } 760 761 /* save the bitmap's position in the atlas */ 762 g->x = xpos; 763 g->y = ypos; 764 g->w = bitmap_width; 765 g->h = bitmap_height; 766 g->xorig = bitmap_xorig; 767 g->yorig = bitmap_yorig; 768 g->xmove = bitmap_xmove; 769 g->ymove = bitmap_ymove; 770 771 xpos += bitmap_width; 772 773 /* keep track of tallest bitmap in the row */ 774 row_height = MAX2(row_height, bitmap_height); 775 } 776 777 /* Now we know the texture height */ 778 atlas->texHeight = ypos + row_height; 779 780 if (atlas->texHeight == 0) { 781 /* no glyphs found, give up */ 782 goto fail; 783 } 784 else if (atlas->texHeight > ctx->Const.MaxTextureRectSize) { 785 /* too large, give up */ 786 goto fail; 787 } 788 789 /* Create atlas texture (texture ID is irrelevant) */ 790 atlas->texObj = ctx->Driver.NewTextureObject(ctx, 999, GL_TEXTURE_RECTANGLE); 791 if (!atlas->texObj) { 792 goto out_of_memory; 793 } 794 795 atlas->texObj->Sampler.MinFilter = GL_NEAREST; 796 atlas->texObj->Sampler.MagFilter = GL_NEAREST; 797 atlas->texObj->MaxLevel = 0; 798 atlas->texObj->Immutable = GL_TRUE; 799 800 atlas->texImage = _mesa_get_tex_image(ctx, atlas->texObj, 801 GL_TEXTURE_RECTANGLE, 0); 802 if (!atlas->texImage) { 803 goto out_of_memory; 804 } 805 806 _mesa_init_teximage_fields(ctx, atlas->texImage, 807 atlas->texWidth, atlas->texHeight, 1, 0, 808 GL_ALPHA, MESA_FORMAT_A_UNORM8); 809 810 /* alloc image storage */ 811 if (!ctx->Driver.AllocTextureImageBuffer(ctx, atlas->texImage)) { 812 goto out_of_memory; 813 } 814 815 /* map teximage, load with bitmap glyphs */ 816 ctx->Driver.MapTextureImage(ctx, atlas->texImage, 0, 817 0, 0, atlas->texWidth, atlas->texHeight, 818 GL_MAP_WRITE_BIT, &map, &map_stride); 819 if (!map) { 820 goto out_of_memory; 821 } 822 823 /* Background/clear pixels are 0xff, foreground/set pixels are 0x0 */ 824 memset(map, 0xff, map_stride * atlas->texHeight); 825 826 for (i = 0; i < atlas->numBitmaps; i++) { 827 const struct gl_display_list *list = _mesa_lookup_list(ctx, listBase + i); 828 const Node *n = list->Head; 829 830 assert(n[0].opcode == OPCODE_BITMAP || 831 n[0].opcode == OPCODE_END_OF_LIST); 832 833 if (n[0].opcode == OPCODE_BITMAP) { 834 unsigned bitmap_width = n[1].i; 835 unsigned bitmap_height = n[2].i; 836 unsigned xpos = atlas->glyphs[i].x; 837 unsigned ypos = atlas->glyphs[i].y; 838 const void *bitmap_image = get_pointer(&n[7]); 839 840 assert(atlas->glyphs[i].w == bitmap_width); 841 assert(atlas->glyphs[i].h == bitmap_height); 842 843 /* put the bitmap image into the texture image */ 844 _mesa_expand_bitmap(bitmap_width, bitmap_height, 845 &ctx->DefaultPacking, bitmap_image, 846 map + map_stride * ypos + xpos, /* dest addr */ 847 map_stride, 0x0); 848 } 849 } 850 851 ctx->Driver.UnmapTextureImage(ctx, atlas->texImage, 0); 852 853 atlas->complete = true; 854 855 return; 856 857 out_of_memory: 858 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Display list bitmap atlas"); 859 fail: 860 if (atlas->texObj) { 861 ctx->Driver.DeleteTexture(ctx, atlas->texObj); 862 } 863 free(atlas->glyphs); 864 atlas->glyphs = NULL; 865 atlas->incomplete = true; 866 } 867 868 869 /** 870 * Allocate a gl_display_list object with an initial block of storage. 871 * \param count how many display list nodes/tokens to allocate 872 */ 873 static struct gl_display_list * 874 make_list(GLuint name, GLuint count) 875 { 876 struct gl_display_list *dlist = CALLOC_STRUCT(gl_display_list); 877 dlist->Name = name; 878 dlist->Head = malloc(sizeof(Node) * count); 879 dlist->Head[0].opcode = OPCODE_END_OF_LIST; 880 return dlist; 881 } 882 883 884 /** 885 * Lookup function to just encapsulate casting. 886 */ 887 struct gl_display_list * 888 _mesa_lookup_list(struct gl_context *ctx, GLuint list) 889 { 890 return (struct gl_display_list *) 891 _mesa_HashLookup(ctx->Shared->DisplayList, list); 892 } 893 894 895 /** Is the given opcode an extension code? */ 896 static inline GLboolean 897 is_ext_opcode(OpCode opcode) 898 { 899 return (opcode >= OPCODE_EXT_0); 900 } 901 902 903 /** Destroy an extended opcode instruction */ 904 static GLint 905 ext_opcode_destroy(struct gl_context *ctx, Node *node) 906 { 907 const GLint i = node[0].opcode - OPCODE_EXT_0; 908 GLint step; 909 ctx->ListExt->Opcode[i].Destroy(ctx, &node[1]); 910 step = ctx->ListExt->Opcode[i].Size; 911 return step; 912 } 913 914 915 /** Execute an extended opcode instruction */ 916 static GLint 917 ext_opcode_execute(struct gl_context *ctx, Node *node) 918 { 919 const GLint i = node[0].opcode - OPCODE_EXT_0; 920 GLint step; 921 ctx->ListExt->Opcode[i].Execute(ctx, &node[1]); 922 step = ctx->ListExt->Opcode[i].Size; 923 return step; 924 } 925 926 927 /** Print an extended opcode instruction */ 928 static GLint 929 ext_opcode_print(struct gl_context *ctx, Node *node, FILE *f) 930 { 931 const GLint i = node[0].opcode - OPCODE_EXT_0; 932 GLint step; 933 ctx->ListExt->Opcode[i].Print(ctx, &node[1], f); 934 step = ctx->ListExt->Opcode[i].Size; 935 return step; 936 } 937 938 939 /** 940 * Delete the named display list, but don't remove from hash table. 941 * \param dlist - display list pointer 942 */ 943 void 944 _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist) 945 { 946 Node *n, *block; 947 GLboolean done; 948 949 n = block = dlist->Head; 950 951 done = block ? GL_FALSE : GL_TRUE; 952 while (!done) { 953 const OpCode opcode = n[0].opcode; 954 955 /* check for extension opcodes first */ 956 if (is_ext_opcode(opcode)) { 957 n += ext_opcode_destroy(ctx, n); 958 } 959 else { 960 switch (opcode) { 961 /* for some commands, we need to free malloc'd memory */ 962 case OPCODE_MAP1: 963 free(get_pointer(&n[6])); 964 n += InstSize[n[0].opcode]; 965 break; 966 case OPCODE_MAP2: 967 free(get_pointer(&n[10])); 968 n += InstSize[n[0].opcode]; 969 break; 970 case OPCODE_CALL_LISTS: 971 free(get_pointer(&n[3])); 972 n += InstSize[n[0].opcode]; 973 break; 974 case OPCODE_DRAW_PIXELS: 975 free(get_pointer(&n[5])); 976 n += InstSize[n[0].opcode]; 977 break; 978 case OPCODE_BITMAP: 979 free(get_pointer(&n[7])); 980 n += InstSize[n[0].opcode]; 981 break; 982 case OPCODE_POLYGON_STIPPLE: 983 free(get_pointer(&n[1])); 984 n += InstSize[n[0].opcode]; 985 break; 986 case OPCODE_TEX_IMAGE1D: 987 free(get_pointer(&n[8])); 988 n += InstSize[n[0].opcode]; 989 break; 990 case OPCODE_TEX_IMAGE2D: 991 free(get_pointer(&n[9])); 992 n += InstSize[n[0].opcode]; 993 break; 994 case OPCODE_TEX_IMAGE3D: 995 free(get_pointer(&n[10])); 996 n += InstSize[n[0].opcode]; 997 break; 998 case OPCODE_TEX_SUB_IMAGE1D: 999 free(get_pointer(&n[7])); 1000 n += InstSize[n[0].opcode]; 1001 break; 1002 case OPCODE_TEX_SUB_IMAGE2D: 1003 free(get_pointer(&n[9])); 1004 n += InstSize[n[0].opcode]; 1005 break; 1006 case OPCODE_TEX_SUB_IMAGE3D: 1007 free(get_pointer(&n[11])); 1008 n += InstSize[n[0].opcode]; 1009 break; 1010 case OPCODE_COMPRESSED_TEX_IMAGE_1D: 1011 free(get_pointer(&n[7])); 1012 n += InstSize[n[0].opcode]; 1013 break; 1014 case OPCODE_COMPRESSED_TEX_IMAGE_2D: 1015 free(get_pointer(&n[8])); 1016 n += InstSize[n[0].opcode]; 1017 break; 1018 case OPCODE_COMPRESSED_TEX_IMAGE_3D: 1019 free(get_pointer(&n[9])); 1020 n += InstSize[n[0].opcode]; 1021 break; 1022 case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D: 1023 free(get_pointer(&n[7])); 1024 n += InstSize[n[0].opcode]; 1025 break; 1026 case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D: 1027 free(get_pointer(&n[9])); 1028 n += InstSize[n[0].opcode]; 1029 break; 1030 case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D: 1031 free(get_pointer(&n[11])); 1032 n += InstSize[n[0].opcode]; 1033 break; 1034 case OPCODE_PROGRAM_STRING_ARB: 1035 free(get_pointer(&n[4])); /* program string */ 1036 n += InstSize[n[0].opcode]; 1037 break; 1038 case OPCODE_UNIFORM_1FV: 1039 case OPCODE_UNIFORM_2FV: 1040 case OPCODE_UNIFORM_3FV: 1041 case OPCODE_UNIFORM_4FV: 1042 case OPCODE_UNIFORM_1IV: 1043 case OPCODE_UNIFORM_2IV: 1044 case OPCODE_UNIFORM_3IV: 1045 case OPCODE_UNIFORM_4IV: 1046 case OPCODE_UNIFORM_1UIV: 1047 case OPCODE_UNIFORM_2UIV: 1048 case OPCODE_UNIFORM_3UIV: 1049 case OPCODE_UNIFORM_4UIV: 1050 free(get_pointer(&n[3])); 1051 n += InstSize[n[0].opcode]; 1052 break; 1053 case OPCODE_UNIFORM_MATRIX22: 1054 case OPCODE_UNIFORM_MATRIX33: 1055 case OPCODE_UNIFORM_MATRIX44: 1056 case OPCODE_UNIFORM_MATRIX24: 1057 case OPCODE_UNIFORM_MATRIX42: 1058 case OPCODE_UNIFORM_MATRIX23: 1059 case OPCODE_UNIFORM_MATRIX32: 1060 case OPCODE_UNIFORM_MATRIX34: 1061 case OPCODE_UNIFORM_MATRIX43: 1062 free(get_pointer(&n[4])); 1063 n += InstSize[n[0].opcode]; 1064 break; 1065 case OPCODE_PROGRAM_UNIFORM_1FV: 1066 case OPCODE_PROGRAM_UNIFORM_2FV: 1067 case OPCODE_PROGRAM_UNIFORM_3FV: 1068 case OPCODE_PROGRAM_UNIFORM_4FV: 1069 case OPCODE_PROGRAM_UNIFORM_1IV: 1070 case OPCODE_PROGRAM_UNIFORM_2IV: 1071 case OPCODE_PROGRAM_UNIFORM_3IV: 1072 case OPCODE_PROGRAM_UNIFORM_4IV: 1073 case OPCODE_PROGRAM_UNIFORM_1UIV: 1074 case OPCODE_PROGRAM_UNIFORM_2UIV: 1075 case OPCODE_PROGRAM_UNIFORM_3UIV: 1076 case OPCODE_PROGRAM_UNIFORM_4UIV: 1077 free(get_pointer(&n[4])); 1078 n += InstSize[n[0].opcode]; 1079 break; 1080 case OPCODE_PROGRAM_UNIFORM_MATRIX22F: 1081 case OPCODE_PROGRAM_UNIFORM_MATRIX33F: 1082 case OPCODE_PROGRAM_UNIFORM_MATRIX44F: 1083 case OPCODE_PROGRAM_UNIFORM_MATRIX24F: 1084 case OPCODE_PROGRAM_UNIFORM_MATRIX42F: 1085 case OPCODE_PROGRAM_UNIFORM_MATRIX23F: 1086 case OPCODE_PROGRAM_UNIFORM_MATRIX32F: 1087 case OPCODE_PROGRAM_UNIFORM_MATRIX34F: 1088 case OPCODE_PROGRAM_UNIFORM_MATRIX43F: 1089 free(get_pointer(&n[5])); 1090 n += InstSize[n[0].opcode]; 1091 break; 1092 case OPCODE_PIXEL_MAP: 1093 free(get_pointer(&n[3])); 1094 n += InstSize[n[0].opcode]; 1095 break; 1096 case OPCODE_WINDOW_RECTANGLES: 1097 free(get_pointer(&n[3])); 1098 n += InstSize[n[0].opcode]; 1099 break; 1100 case OPCODE_CONTINUE: 1101 n = (Node *) get_pointer(&n[1]); 1102 free(block); 1103 block = n; 1104 break; 1105 case OPCODE_END_OF_LIST: 1106 free(block); 1107 done = GL_TRUE; 1108 break; 1109 default: 1110 /* Most frequent case */ 1111 n += InstSize[n[0].opcode]; 1112 break; 1113 } 1114 } 1115 } 1116 1117 free(dlist->Label); 1118 free(dlist); 1119 } 1120 1121 1122 /** 1123 * Called by _mesa_HashWalk() to check if a display list which is being 1124 * deleted belongs to a bitmap texture atlas. 1125 */ 1126 static void 1127 check_atlas_for_deleted_list(GLuint atlas_id, void *data, void *userData) 1128 { 1129 struct gl_bitmap_atlas *atlas = (struct gl_bitmap_atlas *) data; 1130 GLuint list_id = *((GLuint *) userData); /* the list being deleted */ 1131 1132 /* See if the list_id falls in the range contained in this texture atlas */ 1133 if (atlas->complete && 1134 list_id >= atlas_id && 1135 list_id < atlas_id + atlas->numBitmaps) { 1136 /* Mark the atlas as incomplete so it doesn't get used. But don't 1137 * delete it yet since we don't want to try to recreate it in the next 1138 * glCallLists. 1139 */ 1140 atlas->complete = false; 1141 atlas->incomplete = true; 1142 } 1143 } 1144 1145 1146 /** 1147 * Destroy a display list and remove from hash table. 1148 * \param list - display list number 1149 */ 1150 static void 1151 destroy_list(struct gl_context *ctx, GLuint list) 1152 { 1153 struct gl_display_list *dlist; 1154 1155 if (list == 0) 1156 return; 1157 1158 dlist = _mesa_lookup_list(ctx, list); 1159 if (!dlist) 1160 return; 1161 1162 if (is_bitmap_list(dlist)) { 1163 /* If we're destroying a simple glBitmap display list, there's a 1164 * chance that we're destroying a bitmap image that's in a texture 1165 * atlas. Examine all atlases to see if that's the case. There's 1166 * usually few (if any) atlases so this isn't expensive. 1167 */ 1168 _mesa_HashWalk(ctx->Shared->BitmapAtlas, 1169 check_atlas_for_deleted_list, &list); 1170 } 1171 1172 _mesa_delete_list(ctx, dlist); 1173 _mesa_HashRemove(ctx->Shared->DisplayList, list); 1174 } 1175 1176 1177 /* 1178 * Translate the nth element of list from <type> to GLint. 1179 */ 1180 static GLint 1181 translate_id(GLsizei n, GLenum type, const GLvoid * list) 1182 { 1183 GLbyte *bptr; 1184 GLubyte *ubptr; 1185 GLshort *sptr; 1186 GLushort *usptr; 1187 GLint *iptr; 1188 GLuint *uiptr; 1189 GLfloat *fptr; 1190 1191 switch (type) { 1192 case GL_BYTE: 1193 bptr = (GLbyte *) list; 1194 return (GLint) bptr[n]; 1195 case GL_UNSIGNED_BYTE: 1196 ubptr = (GLubyte *) list; 1197 return (GLint) ubptr[n]; 1198 case GL_SHORT: 1199 sptr = (GLshort *) list; 1200 return (GLint) sptr[n]; 1201 case GL_UNSIGNED_SHORT: 1202 usptr = (GLushort *) list; 1203 return (GLint) usptr[n]; 1204 case GL_INT: 1205 iptr = (GLint *) list; 1206 return iptr[n]; 1207 case GL_UNSIGNED_INT: 1208 uiptr = (GLuint *) list; 1209 return (GLint) uiptr[n]; 1210 case GL_FLOAT: 1211 fptr = (GLfloat *) list; 1212 return (GLint) floorf(fptr[n]); 1213 case GL_2_BYTES: 1214 ubptr = ((GLubyte *) list) + 2 * n; 1215 return (GLint) ubptr[0] * 256 1216 + (GLint) ubptr[1]; 1217 case GL_3_BYTES: 1218 ubptr = ((GLubyte *) list) + 3 * n; 1219 return (GLint) ubptr[0] * 65536 1220 + (GLint) ubptr[1] * 256 1221 + (GLint) ubptr[2]; 1222 case GL_4_BYTES: 1223 ubptr = ((GLubyte *) list) + 4 * n; 1224 return (GLint) ubptr[0] * 16777216 1225 + (GLint) ubptr[1] * 65536 1226 + (GLint) ubptr[2] * 256 1227 + (GLint) ubptr[3]; 1228 default: 1229 return 0; 1230 } 1231 } 1232 1233 1234 /** 1235 * Wrapper for _mesa_unpack_image/bitmap() that handles pixel buffer objects. 1236 * If width < 0 or height < 0 or format or type are invalid we'll just 1237 * return NULL. We will not generate an error since OpenGL command 1238 * arguments aren't error-checked until the command is actually executed 1239 * (not when they're compiled). 1240 * But if we run out of memory, GL_OUT_OF_MEMORY will be recorded. 1241 */ 1242 static GLvoid * 1243 unpack_image(struct gl_context *ctx, GLuint dimensions, 1244 GLsizei width, GLsizei height, GLsizei depth, 1245 GLenum format, GLenum type, const GLvoid * pixels, 1246 const struct gl_pixelstore_attrib *unpack) 1247 { 1248 if (width <= 0 || height <= 0) { 1249 return NULL; 1250 } 1251 1252 if (_mesa_bytes_per_pixel(format, type) < 0) { 1253 /* bad format and/or type */ 1254 return NULL; 1255 } 1256 1257 if (!_mesa_is_bufferobj(unpack->BufferObj)) { 1258 /* no PBO */ 1259 GLvoid *image; 1260 1261 image = _mesa_unpack_image(dimensions, width, height, depth, 1262 format, type, pixels, unpack); 1263 if (pixels && !image) { 1264 _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction"); 1265 } 1266 return image; 1267 } 1268 else if (_mesa_validate_pbo_access(dimensions, unpack, width, height, 1269 depth, format, type, INT_MAX, pixels)) { 1270 const GLubyte *map, *src; 1271 GLvoid *image; 1272 1273 map = (GLubyte *) 1274 ctx->Driver.MapBufferRange(ctx, 0, unpack->BufferObj->Size, 1275 GL_MAP_READ_BIT, unpack->BufferObj, 1276 MAP_INTERNAL); 1277 if (!map) { 1278 /* unable to map src buffer! */ 1279 _mesa_error(ctx, GL_INVALID_OPERATION, "unable to map PBO"); 1280 return NULL; 1281 } 1282 1283 src = ADD_POINTERS(map, pixels); 1284 image = _mesa_unpack_image(dimensions, width, height, depth, 1285 format, type, src, unpack); 1286 1287 ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj, MAP_INTERNAL); 1288 1289 if (!image) { 1290 _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction"); 1291 } 1292 return image; 1293 } 1294 1295 /* bad access! */ 1296 _mesa_error(ctx, GL_INVALID_OPERATION, "invalid PBO access"); 1297 return NULL; 1298 } 1299 1300 1301 /** Return copy of memory */ 1302 static void * 1303 memdup(const void *src, GLsizei bytes) 1304 { 1305 void *b = bytes >= 0 ? malloc(bytes) : NULL; 1306 if (b) 1307 memcpy(b, src, bytes); 1308 return b; 1309 } 1310 1311 1312 /** 1313 * Allocate space for a display list instruction (opcode + payload space). 1314 * \param opcode the instruction opcode (OPCODE_* value) 1315 * \param bytes instruction payload size (not counting opcode) 1316 * \param align8 does the payload need to be 8-byte aligned? 1317 * This is only relevant in 64-bit environments. 1318 * \return pointer to allocated memory (the payload will be at pointer+1) 1319 */ 1320 static Node * 1321 dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes, bool align8) 1322 { 1323 const GLuint numNodes = 1 + (bytes + sizeof(Node) - 1) / sizeof(Node); 1324 const GLuint contNodes = 1 + POINTER_DWORDS; /* size of continue info */ 1325 GLuint nopNode; 1326 Node *n; 1327 1328 if (opcode < OPCODE_EXT_0) { 1329 if (InstSize[opcode] == 0) { 1330 /* save instruction size now */ 1331 InstSize[opcode] = numNodes; 1332 } 1333 else { 1334 /* make sure instruction size agrees */ 1335 assert(numNodes == InstSize[opcode]); 1336 } 1337 } 1338 1339 if (sizeof(void *) > sizeof(Node) && align8 1340 && ctx->ListState.CurrentPos % 2 == 0) { 1341 /* The opcode would get placed at node[0] and the payload would start 1342 * at node[1]. But the payload needs to be at an even offset (8-byte 1343 * multiple). 1344 */ 1345 nopNode = 1; 1346 } 1347 else { 1348 nopNode = 0; 1349 } 1350 1351 if (ctx->ListState.CurrentPos + nopNode + numNodes + contNodes 1352 > BLOCK_SIZE) { 1353 /* This block is full. Allocate a new block and chain to it */ 1354 Node *newblock; 1355 n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos; 1356 n[0].opcode = OPCODE_CONTINUE; 1357 newblock = malloc(sizeof(Node) * BLOCK_SIZE); 1358 if (!newblock) { 1359 _mesa_error(ctx, GL_OUT_OF_MEMORY, "Building display list"); 1360 return NULL; 1361 } 1362 1363 /* a fresh block should be 8-byte aligned on 64-bit systems */ 1364 assert(((GLintptr) newblock) % sizeof(void *) == 0); 1365 1366 save_pointer(&n[1], newblock); 1367 ctx->ListState.CurrentBlock = newblock; 1368 ctx->ListState.CurrentPos = 0; 1369 1370 /* Display list nodes are always 4 bytes. If we need 8-byte alignment 1371 * we have to insert a NOP so that the payload of the real opcode lands 1372 * on an even location: 1373 * node[0] = OPCODE_NOP 1374 * node[1] = OPCODE_x; 1375 * node[2] = start of payload 1376 */ 1377 nopNode = sizeof(void *) > sizeof(Node) && align8; 1378 } 1379 1380 n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos; 1381 if (nopNode) { 1382 assert(ctx->ListState.CurrentPos % 2 == 0); /* even value */ 1383 n[0].opcode = OPCODE_NOP; 1384 n++; 1385 /* The "real" opcode will now be at an odd location and the payload 1386 * will be at an even location. 1387 */ 1388 } 1389 ctx->ListState.CurrentPos += nopNode + numNodes; 1390 1391 n[0].opcode = opcode; 1392 1393 return n; 1394 } 1395 1396 1397 1398 /** 1399 * Allocate space for a display list instruction. Used by callers outside 1400 * this file for things like VBO vertex data. 1401 * 1402 * \param opcode the instruction opcode (OPCODE_* value) 1403 * \param bytes instruction size in bytes, not counting opcode. 1404 * \return pointer to the usable data area (not including the internal 1405 * opcode). 1406 */ 1407 void * 1408 _mesa_dlist_alloc(struct gl_context *ctx, GLuint opcode, GLuint bytes) 1409 { 1410 Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes, false); 1411 if (n) 1412 return n + 1; /* return pointer to payload area, after opcode */ 1413 else 1414 return NULL; 1415 } 1416 1417 1418 /** 1419 * Same as _mesa_dlist_alloc(), but return a pointer which is 8-byte 1420 * aligned in 64-bit environments, 4-byte aligned otherwise. 1421 */ 1422 void * 1423 _mesa_dlist_alloc_aligned(struct gl_context *ctx, GLuint opcode, GLuint bytes) 1424 { 1425 Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes, true); 1426 if (n) 1427 return n + 1; /* return pointer to payload area, after opcode */ 1428 else 1429 return NULL; 1430 } 1431 1432 1433 /** 1434 * This function allows modules and drivers to get their own opcodes 1435 * for extending display list functionality. 1436 * \param ctx the rendering context 1437 * \param size number of bytes for storing the new display list command 1438 * \param execute function to execute the new display list command 1439 * \param destroy function to destroy the new display list command 1440 * \param print function to print the new display list command 1441 * \return the new opcode number or -1 if error 1442 */ 1443 GLint 1444 _mesa_dlist_alloc_opcode(struct gl_context *ctx, 1445 GLuint size, 1446 void (*execute) (struct gl_context *, void *), 1447 void (*destroy) (struct gl_context *, void *), 1448 void (*print) (struct gl_context *, void *, FILE *)) 1449 { 1450 if (ctx->ListExt->NumOpcodes < MAX_DLIST_EXT_OPCODES) { 1451 const GLuint i = ctx->ListExt->NumOpcodes++; 1452 ctx->ListExt->Opcode[i].Size = 1453 1 + (size + sizeof(Node) - 1) / sizeof(Node); 1454 ctx->ListExt->Opcode[i].Execute = execute; 1455 ctx->ListExt->Opcode[i].Destroy = destroy; 1456 ctx->ListExt->Opcode[i].Print = print; 1457 return i + OPCODE_EXT_0; 1458 } 1459 return -1; 1460 } 1461 1462 1463 /** 1464 * Allocate space for a display list instruction. The space is basically 1465 * an array of Nodes where node[0] holds the opcode, node[1] is the first 1466 * function parameter, node[2] is the second parameter, etc. 1467 * 1468 * \param opcode one of OPCODE_x 1469 * \param nparams number of function parameters 1470 * \return pointer to start of instruction space 1471 */ 1472 static inline Node * 1473 alloc_instruction(struct gl_context *ctx, OpCode opcode, GLuint nparams) 1474 { 1475 return dlist_alloc(ctx, opcode, nparams * sizeof(Node), false); 1476 } 1477 1478 1479 /** 1480 * Called by EndList to try to reduce memory used for the list. 1481 */ 1482 static void 1483 trim_list(struct gl_context *ctx) 1484 { 1485 /* If the list we're ending only has one allocated block of nodes/tokens 1486 * and its size isn't a full block size, realloc the block to use less 1487 * memory. This is important for apps that create many small display 1488 * lists and apps that use glXUseXFont (many lists each containing one 1489 * glBitmap call). 1490 * Note: we currently only trim display lists that allocated one block 1491 * of tokens. That hits the short list case which is what we're mainly 1492 * concerned with. Trimming longer lists would involve traversing the 1493 * linked list of blocks. 1494 */ 1495 struct gl_dlist_state *list = &ctx->ListState; 1496 1497 if ((list->CurrentList->Head == list->CurrentBlock) && 1498 (list->CurrentPos < BLOCK_SIZE)) { 1499 /* There's only one block and it's not full, so realloc */ 1500 GLuint newSize = list->CurrentPos * sizeof(Node); 1501 list->CurrentList->Head = 1502 list->CurrentBlock = realloc(list->CurrentBlock, newSize); 1503 if (!list->CurrentBlock) { 1504 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEndList"); 1505 } 1506 } 1507 } 1508 1509 1510 1511 /* 1512 * Display List compilation functions 1513 */ 1514 static void GLAPIENTRY 1515 save_Accum(GLenum op, GLfloat value) 1516 { 1517 GET_CURRENT_CONTEXT(ctx); 1518 Node *n; 1519 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 1520 n = alloc_instruction(ctx, OPCODE_ACCUM, 2); 1521 if (n) { 1522 n[1].e = op; 1523 n[2].f = value; 1524 } 1525 if (ctx->ExecuteFlag) { 1526 CALL_Accum(ctx->Exec, (op, value)); 1527 } 1528 } 1529 1530 1531 static void GLAPIENTRY 1532 save_AlphaFunc(GLenum func, GLclampf ref) 1533 { 1534 GET_CURRENT_CONTEXT(ctx); 1535 Node *n; 1536 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 1537 n = alloc_instruction(ctx, OPCODE_ALPHA_FUNC, 2); 1538 if (n) { 1539 n[1].e = func; 1540 n[2].f = (GLfloat) ref; 1541 } 1542 if (ctx->ExecuteFlag) { 1543 CALL_AlphaFunc(ctx->Exec, (func, ref)); 1544 } 1545 } 1546 1547 1548 static void GLAPIENTRY 1549 save_BindTexture(GLenum target, GLuint texture) 1550 { 1551 GET_CURRENT_CONTEXT(ctx); 1552 Node *n; 1553 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 1554 n = alloc_instruction(ctx, OPCODE_BIND_TEXTURE, 2); 1555 if (n) { 1556 n[1].e = target; 1557 n[2].ui = texture; 1558 } 1559 if (ctx->ExecuteFlag) { 1560 CALL_BindTexture(ctx->Exec, (target, texture)); 1561 } 1562 } 1563 1564 1565 static void GLAPIENTRY 1566 save_Bitmap(GLsizei width, GLsizei height, 1567 GLfloat xorig, GLfloat yorig, 1568 GLfloat xmove, GLfloat ymove, const GLubyte * pixels) 1569 { 1570 GET_CURRENT_CONTEXT(ctx); 1571 Node *n; 1572 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 1573 n = alloc_instruction(ctx, OPCODE_BITMAP, 6 + POINTER_DWORDS); 1574 if (n) { 1575 n[1].i = (GLint) width; 1576 n[2].i = (GLint) height; 1577 n[3].f = xorig; 1578 n[4].f = yorig; 1579 n[5].f = xmove; 1580 n[6].f = ymove; 1581 save_pointer(&n[7], 1582 unpack_image(ctx, 2, width, height, 1, GL_COLOR_INDEX, 1583 GL_BITMAP, pixels, &ctx->Unpack)); 1584 } 1585 if (ctx->ExecuteFlag) { 1586 CALL_Bitmap(ctx->Exec, (width, height, 1587 xorig, yorig, xmove, ymove, pixels)); 1588 } 1589 } 1590 1591 1592 static void GLAPIENTRY 1593 save_BlendEquation(GLenum mode) 1594 { 1595 GET_CURRENT_CONTEXT(ctx); 1596 Node *n; 1597 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 1598 n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION, 1); 1599 if (n) { 1600 n[1].e = mode; 1601 } 1602 if (ctx->ExecuteFlag) { 1603 CALL_BlendEquation(ctx->Exec, (mode)); 1604 } 1605 } 1606 1607 1608 static void GLAPIENTRY 1609 save_BlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA) 1610 { 1611 GET_CURRENT_CONTEXT(ctx); 1612 Node *n; 1613 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 1614 n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION_SEPARATE, 2); 1615 if (n) { 1616 n[1].e = modeRGB; 1617 n[2].e = modeA; 1618 } 1619 if (ctx->ExecuteFlag) { 1620 CALL_BlendEquationSeparate(ctx->Exec, (modeRGB, modeA)); 1621 } 1622 } 1623 1624 1625 static void GLAPIENTRY 1626 save_BlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB, 1627 GLenum sfactorA, GLenum dfactorA) 1628 { 1629 GET_CURRENT_CONTEXT(ctx); 1630 Node *n; 1631 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 1632 n = alloc_instruction(ctx, OPCODE_BLEND_FUNC_SEPARATE, 4); 1633 if (n) { 1634 n[1].e = sfactorRGB; 1635 n[2].e = dfactorRGB; 1636 n[3].e = sfactorA; 1637 n[4].e = dfactorA; 1638 } 1639 if (ctx->ExecuteFlag) { 1640 CALL_BlendFuncSeparate(ctx->Exec, 1641 (sfactorRGB, dfactorRGB, sfactorA, dfactorA)); 1642 } 1643 } 1644 1645 1646 static void GLAPIENTRY 1647 save_BlendFunc(GLenum srcfactor, GLenum dstfactor) 1648 { 1649 save_BlendFuncSeparateEXT(srcfactor, dstfactor, srcfactor, dstfactor); 1650 } 1651 1652 1653 static void GLAPIENTRY 1654 save_BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) 1655 { 1656 GET_CURRENT_CONTEXT(ctx); 1657 Node *n; 1658 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 1659 n = alloc_instruction(ctx, OPCODE_BLEND_COLOR, 4); 1660 if (n) { 1661 n[1].f = red; 1662 n[2].f = green; 1663 n[3].f = blue; 1664 n[4].f = alpha; 1665 } 1666 if (ctx->ExecuteFlag) { 1667 CALL_BlendColor(ctx->Exec, (red, green, blue, alpha)); 1668 } 1669 } 1670 1671 /* GL_ARB_draw_buffers_blend */ 1672 static void GLAPIENTRY 1673 save_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, 1674 GLenum sfactorA, GLenum dfactorA) 1675 { 1676 GET_CURRENT_CONTEXT(ctx); 1677 Node *n; 1678 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 1679 n = alloc_instruction(ctx, OPCODE_BLEND_FUNC_SEPARATE_I, 5); 1680 if (n) { 1681 n[1].ui = buf; 1682 n[2].e = sfactorRGB; 1683 n[3].e = dfactorRGB; 1684 n[4].e = sfactorA; 1685 n[5].e = dfactorA; 1686 } 1687 if (ctx->ExecuteFlag) { 1688 CALL_BlendFuncSeparateiARB(ctx->Exec, (buf, sfactorRGB, dfactorRGB, 1689 sfactorA, dfactorA)); 1690 } 1691 } 1692 1693 /* GL_ARB_draw_buffers_blend */ 1694 static void GLAPIENTRY 1695 save_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) 1696 { 1697 GET_CURRENT_CONTEXT(ctx); 1698 Node *n; 1699 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 1700 n = alloc_instruction(ctx, OPCODE_BLEND_FUNC_I, 3); 1701 if (n) { 1702 n[1].ui = buf; 1703 n[2].e = sfactor; 1704 n[3].e = dfactor; 1705 } 1706 if (ctx->ExecuteFlag) { 1707 CALL_BlendFunciARB(ctx->Exec, (buf, sfactor, dfactor)); 1708 } 1709 } 1710 1711 /* GL_ARB_draw_buffers_blend */ 1712 static void GLAPIENTRY 1713 save_BlendEquationi(GLuint buf, GLenum mode) 1714 { 1715 GET_CURRENT_CONTEXT(ctx); 1716 Node *n; 1717 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 1718 n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION_I, 2); 1719 if (n) { 1720 n[1].ui = buf; 1721 n[2].e = mode; 1722 } 1723 if (ctx->ExecuteFlag) { 1724 CALL_BlendEquationiARB(ctx->Exec, (buf, mode)); 1725 } 1726 } 1727 1728 /* GL_ARB_draw_buffers_blend */ 1729 static void GLAPIENTRY 1730 save_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA) 1731 { 1732 GET_CURRENT_CONTEXT(ctx); 1733 Node *n; 1734 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 1735 n = alloc_instruction(ctx, OPCODE_BLEND_EQUATION_SEPARATE_I, 3); 1736 if (n) { 1737 n[1].ui = buf; 1738 n[2].e = modeRGB; 1739 n[3].e = modeA; 1740 } 1741 if (ctx->ExecuteFlag) { 1742 CALL_BlendEquationSeparateiARB(ctx->Exec, (buf, modeRGB, modeA)); 1743 } 1744 } 1745 1746 1747 /* GL_ARB_draw_instanced. */ 1748 static void GLAPIENTRY 1749 save_DrawArraysInstancedARB(UNUSED GLenum mode, 1750 UNUSED GLint first, 1751 UNUSED GLsizei count, 1752 UNUSED GLsizei primcount) 1753 { 1754 GET_CURRENT_CONTEXT(ctx); 1755 _mesa_error(ctx, GL_INVALID_OPERATION, 1756 "glDrawArraysInstanced() during display list compile"); 1757 } 1758 1759 static void GLAPIENTRY 1760 save_DrawElementsInstancedARB(UNUSED GLenum mode, 1761 UNUSED GLsizei count, 1762 UNUSED GLenum type, 1763 UNUSED const GLvoid *indices, 1764 UNUSED GLsizei primcount) 1765 { 1766 GET_CURRENT_CONTEXT(ctx); 1767 _mesa_error(ctx, GL_INVALID_OPERATION, 1768 "glDrawElementsInstanced() during display list compile"); 1769 } 1770 1771 static void GLAPIENTRY 1772 save_DrawElementsInstancedBaseVertexARB(UNUSED GLenum mode, 1773 UNUSED GLsizei count, 1774 UNUSED GLenum type, 1775 UNUSED const GLvoid *indices, 1776 UNUSED GLsizei primcount, 1777 UNUSED GLint basevertex) 1778 { 1779 GET_CURRENT_CONTEXT(ctx); 1780 _mesa_error(ctx, GL_INVALID_OPERATION, 1781 "glDrawElementsInstancedBaseVertex() during display list compile"); 1782 } 1783 1784 /* GL_ARB_base_instance. */ 1785 static void GLAPIENTRY 1786 save_DrawArraysInstancedBaseInstance(UNUSED GLenum mode, 1787 UNUSED GLint first, 1788 UNUSED GLsizei count, 1789 UNUSED GLsizei primcount, 1790 UNUSED GLuint baseinstance) 1791 { 1792 GET_CURRENT_CONTEXT(ctx); 1793 _mesa_error(ctx, GL_INVALID_OPERATION, 1794 "glDrawArraysInstancedBaseInstance() during display list compile"); 1795 } 1796 1797 static void APIENTRY 1798 save_DrawElementsInstancedBaseInstance(UNUSED GLenum mode, 1799 UNUSED GLsizei count, 1800 UNUSED GLenum type, 1801 UNUSED const void *indices, 1802 UNUSED GLsizei primcount, 1803 UNUSED GLuint baseinstance) 1804 { 1805 GET_CURRENT_CONTEXT(ctx); 1806 _mesa_error(ctx, GL_INVALID_OPERATION, 1807 "glDrawElementsInstancedBaseInstance() during display list compile"); 1808 } 1809 1810 static void APIENTRY 1811 save_DrawElementsInstancedBaseVertexBaseInstance(UNUSED GLenum mode, 1812 UNUSED GLsizei count, 1813 UNUSED GLenum type, 1814 UNUSED const void *indices, 1815 UNUSED GLsizei primcount, 1816 UNUSED GLint basevertex, 1817 UNUSED GLuint baseinstance) 1818 { 1819 GET_CURRENT_CONTEXT(ctx); 1820 _mesa_error(ctx, GL_INVALID_OPERATION, 1821 "glDrawElementsInstancedBaseVertexBaseInstance() during display list compile"); 1822 } 1823 1824 1825 /** 1826 * While building a display list we cache some OpenGL state. 1827 * Under some circumstances we need to invalidate that state (immediately 1828 * when we start compiling a list, or after glCallList(s)). 1829 */ 1830 static void 1831 invalidate_saved_current_state(struct gl_context *ctx) 1832 { 1833 GLint i; 1834 1835 for (i = 0; i < VERT_ATTRIB_MAX; i++) 1836 ctx->ListState.ActiveAttribSize[i] = 0; 1837 1838 for (i = 0; i < MAT_ATTRIB_MAX; i++) 1839 ctx->ListState.ActiveMaterialSize[i] = 0; 1840 1841 memset(&ctx->ListState.Current, 0, sizeof ctx->ListState.Current); 1842 1843 ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; 1844 } 1845 1846 1847 static void GLAPIENTRY 1848 save_CallList(GLuint list) 1849 { 1850 GET_CURRENT_CONTEXT(ctx); 1851 Node *n; 1852 SAVE_FLUSH_VERTICES(ctx); 1853 1854 n = alloc_instruction(ctx, OPCODE_CALL_LIST, 1); 1855 if (n) { 1856 n[1].ui = list; 1857 } 1858 1859 /* After this, we don't know what state we're in. Invalidate all 1860 * cached information previously gathered: 1861 */ 1862 invalidate_saved_current_state( ctx ); 1863 1864 if (ctx->ExecuteFlag) { 1865 _mesa_CallList(list); 1866 } 1867 } 1868 1869 1870 static void GLAPIENTRY 1871 save_CallLists(GLsizei num, GLenum type, const GLvoid * lists) 1872 { 1873 GET_CURRENT_CONTEXT(ctx); 1874 unsigned type_size; 1875 Node *n; 1876 void *lists_copy; 1877 1878 SAVE_FLUSH_VERTICES(ctx); 1879 1880 switch (type) { 1881 case GL_BYTE: 1882 case GL_UNSIGNED_BYTE: 1883 type_size = 1; 1884 break; 1885 case GL_SHORT: 1886 case GL_UNSIGNED_SHORT: 1887 case GL_2_BYTES: 1888 type_size = 2; 1889 break; 1890 case GL_3_BYTES: 1891 type_size = 3; 1892 break; 1893 case GL_INT: 1894 case GL_UNSIGNED_INT: 1895 case GL_FLOAT: 1896 case GL_4_BYTES: 1897 type_size = 4; 1898 break; 1899 default: 1900 type_size = 0; 1901 } 1902 1903 if (num > 0 && type_size > 0) { 1904 /* create a copy of the array of list IDs to save in the display list */ 1905 lists_copy = memdup(lists, num * type_size); 1906 } else { 1907 lists_copy = NULL; 1908 } 1909 1910 n = alloc_instruction(ctx, OPCODE_CALL_LISTS, 2 + POINTER_DWORDS); 1911 if (n) { 1912 n[1].i = num; 1913 n[2].e = type; 1914 save_pointer(&n[3], lists_copy); 1915 } 1916 1917 /* After this, we don't know what state we're in. Invalidate all 1918 * cached information previously gathered: 1919 */ 1920 invalidate_saved_current_state( ctx ); 1921 1922 if (ctx->ExecuteFlag) { 1923 CALL_CallLists(ctx->Exec, (num, type, lists)); 1924 } 1925 } 1926 1927 1928 static void GLAPIENTRY 1929 save_Clear(GLbitfield mask) 1930 { 1931 GET_CURRENT_CONTEXT(ctx); 1932 Node *n; 1933 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 1934 n = alloc_instruction(ctx, OPCODE_CLEAR, 1); 1935 if (n) { 1936 n[1].bf = mask; 1937 } 1938 if (ctx->ExecuteFlag) { 1939 CALL_Clear(ctx->Exec, (mask)); 1940 } 1941 } 1942 1943 1944 static void GLAPIENTRY 1945 save_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) 1946 { 1947 GET_CURRENT_CONTEXT(ctx); 1948 Node *n; 1949 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 1950 n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_IV, 6); 1951 if (n) { 1952 n[1].e = buffer; 1953 n[2].i = drawbuffer; 1954 n[3].i = value[0]; 1955 if (buffer == GL_COLOR) { 1956 n[4].i = value[1]; 1957 n[5].i = value[2]; 1958 n[6].i = value[3]; 1959 } 1960 else { 1961 n[4].i = 0; 1962 n[5].i = 0; 1963 n[6].i = 0; 1964 } 1965 } 1966 if (ctx->ExecuteFlag) { 1967 CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value)); 1968 } 1969 } 1970 1971 1972 static void GLAPIENTRY 1973 save_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) 1974 { 1975 GET_CURRENT_CONTEXT(ctx); 1976 Node *n; 1977 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 1978 n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_UIV, 6); 1979 if (n) { 1980 n[1].e = buffer; 1981 n[2].i = drawbuffer; 1982 n[3].ui = value[0]; 1983 if (buffer == GL_COLOR) { 1984 n[4].ui = value[1]; 1985 n[5].ui = value[2]; 1986 n[6].ui = value[3]; 1987 } 1988 else { 1989 n[4].ui = 0; 1990 n[5].ui = 0; 1991 n[6].ui = 0; 1992 } 1993 } 1994 if (ctx->ExecuteFlag) { 1995 CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value)); 1996 } 1997 } 1998 1999 2000 static void GLAPIENTRY 2001 save_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) 2002 { 2003 GET_CURRENT_CONTEXT(ctx); 2004 Node *n; 2005 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2006 n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_FV, 6); 2007 if (n) { 2008 n[1].e = buffer; 2009 n[2].i = drawbuffer; 2010 n[3].f = value[0]; 2011 if (buffer == GL_COLOR) { 2012 n[4].f = value[1]; 2013 n[5].f = value[2]; 2014 n[6].f = value[3]; 2015 } 2016 else { 2017 n[4].f = 0.0F; 2018 n[5].f = 0.0F; 2019 n[6].f = 0.0F; 2020 } 2021 } 2022 if (ctx->ExecuteFlag) { 2023 CALL_ClearBufferfv(ctx->Exec, (buffer, drawbuffer, value)); 2024 } 2025 } 2026 2027 2028 static void GLAPIENTRY 2029 save_ClearBufferfi(GLenum buffer, GLint drawbuffer, 2030 GLfloat depth, GLint stencil) 2031 { 2032 GET_CURRENT_CONTEXT(ctx); 2033 Node *n; 2034 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2035 n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_FI, 4); 2036 if (n) { 2037 n[1].e = buffer; 2038 n[2].i = drawbuffer; 2039 n[3].f = depth; 2040 n[4].i = stencil; 2041 } 2042 if (ctx->ExecuteFlag) { 2043 CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil)); 2044 } 2045 } 2046 2047 2048 static void GLAPIENTRY 2049 save_ClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) 2050 { 2051 GET_CURRENT_CONTEXT(ctx); 2052 Node *n; 2053 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2054 n = alloc_instruction(ctx, OPCODE_CLEAR_ACCUM, 4); 2055 if (n) { 2056 n[1].f = red; 2057 n[2].f = green; 2058 n[3].f = blue; 2059 n[4].f = alpha; 2060 } 2061 if (ctx->ExecuteFlag) { 2062 CALL_ClearAccum(ctx->Exec, (red, green, blue, alpha)); 2063 } 2064 } 2065 2066 2067 static void GLAPIENTRY 2068 save_ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) 2069 { 2070 GET_CURRENT_CONTEXT(ctx); 2071 Node *n; 2072 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2073 n = alloc_instruction(ctx, OPCODE_CLEAR_COLOR, 4); 2074 if (n) { 2075 n[1].f = red; 2076 n[2].f = green; 2077 n[3].f = blue; 2078 n[4].f = alpha; 2079 } 2080 if (ctx->ExecuteFlag) { 2081 CALL_ClearColor(ctx->Exec, (red, green, blue, alpha)); 2082 } 2083 } 2084 2085 2086 static void GLAPIENTRY 2087 save_ClearDepth(GLclampd depth) 2088 { 2089 GET_CURRENT_CONTEXT(ctx); 2090 Node *n; 2091 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2092 n = alloc_instruction(ctx, OPCODE_CLEAR_DEPTH, 1); 2093 if (n) { 2094 n[1].f = (GLfloat) depth; 2095 } 2096 if (ctx->ExecuteFlag) { 2097 CALL_ClearDepth(ctx->Exec, (depth)); 2098 } 2099 } 2100 2101 2102 static void GLAPIENTRY 2103 save_ClearIndex(GLfloat c) 2104 { 2105 GET_CURRENT_CONTEXT(ctx); 2106 Node *n; 2107 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2108 n = alloc_instruction(ctx, OPCODE_CLEAR_INDEX, 1); 2109 if (n) { 2110 n[1].f = c; 2111 } 2112 if (ctx->ExecuteFlag) { 2113 CALL_ClearIndex(ctx->Exec, (c)); 2114 } 2115 } 2116 2117 2118 static void GLAPIENTRY 2119 save_ClearStencil(GLint s) 2120 { 2121 GET_CURRENT_CONTEXT(ctx); 2122 Node *n; 2123 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2124 n = alloc_instruction(ctx, OPCODE_CLEAR_STENCIL, 1); 2125 if (n) { 2126 n[1].i = s; 2127 } 2128 if (ctx->ExecuteFlag) { 2129 CALL_ClearStencil(ctx->Exec, (s)); 2130 } 2131 } 2132 2133 2134 static void GLAPIENTRY 2135 save_ClipPlane(GLenum plane, const GLdouble * equ) 2136 { 2137 GET_CURRENT_CONTEXT(ctx); 2138 Node *n; 2139 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2140 n = alloc_instruction(ctx, OPCODE_CLIP_PLANE, 5); 2141 if (n) { 2142 n[1].e = plane; 2143 n[2].f = (GLfloat) equ[0]; 2144 n[3].f = (GLfloat) equ[1]; 2145 n[4].f = (GLfloat) equ[2]; 2146 n[5].f = (GLfloat) equ[3]; 2147 } 2148 if (ctx->ExecuteFlag) { 2149 CALL_ClipPlane(ctx->Exec, (plane, equ)); 2150 } 2151 } 2152 2153 2154 2155 static void GLAPIENTRY 2156 save_ColorMask(GLboolean red, GLboolean green, 2157 GLboolean blue, GLboolean alpha) 2158 { 2159 GET_CURRENT_CONTEXT(ctx); 2160 Node *n; 2161 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2162 n = alloc_instruction(ctx, OPCODE_COLOR_MASK, 4); 2163 if (n) { 2164 n[1].b = red; 2165 n[2].b = green; 2166 n[3].b = blue; 2167 n[4].b = alpha; 2168 } 2169 if (ctx->ExecuteFlag) { 2170 CALL_ColorMask(ctx->Exec, (red, green, blue, alpha)); 2171 } 2172 } 2173 2174 2175 static void GLAPIENTRY 2176 save_ColorMaskIndexed(GLuint buf, GLboolean red, GLboolean green, 2177 GLboolean blue, GLboolean alpha) 2178 { 2179 GET_CURRENT_CONTEXT(ctx); 2180 Node *n; 2181 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2182 n = alloc_instruction(ctx, OPCODE_COLOR_MASK_INDEXED, 5); 2183 if (n) { 2184 n[1].ui = buf; 2185 n[2].b = red; 2186 n[3].b = green; 2187 n[4].b = blue; 2188 n[5].b = alpha; 2189 } 2190 if (ctx->ExecuteFlag) { 2191 /*CALL_ColorMaski(ctx->Exec, (buf, red, green, blue, alpha));*/ 2192 } 2193 } 2194 2195 2196 static void GLAPIENTRY 2197 save_ColorMaterial(GLenum face, GLenum mode) 2198 { 2199 GET_CURRENT_CONTEXT(ctx); 2200 Node *n; 2201 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2202 2203 n = alloc_instruction(ctx, OPCODE_COLOR_MATERIAL, 2); 2204 if (n) { 2205 n[1].e = face; 2206 n[2].e = mode; 2207 } 2208 if (ctx->ExecuteFlag) { 2209 CALL_ColorMaterial(ctx->Exec, (face, mode)); 2210 } 2211 } 2212 2213 2214 static void GLAPIENTRY 2215 save_CopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) 2216 { 2217 GET_CURRENT_CONTEXT(ctx); 2218 Node *n; 2219 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2220 n = alloc_instruction(ctx, OPCODE_COPY_PIXELS, 5); 2221 if (n) { 2222 n[1].i = x; 2223 n[2].i = y; 2224 n[3].i = (GLint) width; 2225 n[4].i = (GLint) height; 2226 n[5].e = type; 2227 } 2228 if (ctx->ExecuteFlag) { 2229 CALL_CopyPixels(ctx->Exec, (x, y, width, height, type)); 2230 } 2231 } 2232 2233 2234 2235 static void GLAPIENTRY 2236 save_CopyTexImage1D(GLenum target, GLint level, GLenum internalformat, 2237 GLint x, GLint y, GLsizei width, GLint border) 2238 { 2239 GET_CURRENT_CONTEXT(ctx); 2240 Node *n; 2241 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2242 n = alloc_instruction(ctx, OPCODE_COPY_TEX_IMAGE1D, 7); 2243 if (n) { 2244 n[1].e = target; 2245 n[2].i = level; 2246 n[3].e = internalformat; 2247 n[4].i = x; 2248 n[5].i = y; 2249 n[6].i = width; 2250 n[7].i = border; 2251 } 2252 if (ctx->ExecuteFlag) { 2253 CALL_CopyTexImage1D(ctx->Exec, (target, level, internalformat, 2254 x, y, width, border)); 2255 } 2256 } 2257 2258 2259 static void GLAPIENTRY 2260 save_CopyTexImage2D(GLenum target, GLint level, 2261 GLenum internalformat, 2262 GLint x, GLint y, GLsizei width, 2263 GLsizei height, GLint border) 2264 { 2265 GET_CURRENT_CONTEXT(ctx); 2266 Node *n; 2267 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2268 n = alloc_instruction(ctx, OPCODE_COPY_TEX_IMAGE2D, 8); 2269 if (n) { 2270 n[1].e = target; 2271 n[2].i = level; 2272 n[3].e = internalformat; 2273 n[4].i = x; 2274 n[5].i = y; 2275 n[6].i = width; 2276 n[7].i = height; 2277 n[8].i = border; 2278 } 2279 if (ctx->ExecuteFlag) { 2280 CALL_CopyTexImage2D(ctx->Exec, (target, level, internalformat, 2281 x, y, width, height, border)); 2282 } 2283 } 2284 2285 2286 2287 static void GLAPIENTRY 2288 save_CopyTexSubImage1D(GLenum target, GLint level, 2289 GLint xoffset, GLint x, GLint y, GLsizei width) 2290 { 2291 GET_CURRENT_CONTEXT(ctx); 2292 Node *n; 2293 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2294 n = alloc_instruction(ctx, OPCODE_COPY_TEX_SUB_IMAGE1D, 6); 2295 if (n) { 2296 n[1].e = target; 2297 n[2].i = level; 2298 n[3].i = xoffset; 2299 n[4].i = x; 2300 n[5].i = y; 2301 n[6].i = width; 2302 } 2303 if (ctx->ExecuteFlag) { 2304 CALL_CopyTexSubImage1D(ctx->Exec, 2305 (target, level, xoffset, x, y, width)); 2306 } 2307 } 2308 2309 2310 static void GLAPIENTRY 2311 save_CopyTexSubImage2D(GLenum target, GLint level, 2312 GLint xoffset, GLint yoffset, 2313 GLint x, GLint y, GLsizei width, GLint height) 2314 { 2315 GET_CURRENT_CONTEXT(ctx); 2316 Node *n; 2317 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2318 n = alloc_instruction(ctx, OPCODE_COPY_TEX_SUB_IMAGE2D, 8); 2319 if (n) { 2320 n[1].e = target; 2321 n[2].i = level; 2322 n[3].i = xoffset; 2323 n[4].i = yoffset; 2324 n[5].i = x; 2325 n[6].i = y; 2326 n[7].i = width; 2327 n[8].i = height; 2328 } 2329 if (ctx->ExecuteFlag) { 2330 CALL_CopyTexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset, 2331 x, y, width, height)); 2332 } 2333 } 2334 2335 2336 static void GLAPIENTRY 2337 save_CopyTexSubImage3D(GLenum target, GLint level, 2338 GLint xoffset, GLint yoffset, GLint zoffset, 2339 GLint x, GLint y, GLsizei width, GLint height) 2340 { 2341 GET_CURRENT_CONTEXT(ctx); 2342 Node *n; 2343 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2344 n = alloc_instruction(ctx, OPCODE_COPY_TEX_SUB_IMAGE3D, 9); 2345 if (n) { 2346 n[1].e = target; 2347 n[2].i = level; 2348 n[3].i = xoffset; 2349 n[4].i = yoffset; 2350 n[5].i = zoffset; 2351 n[6].i = x; 2352 n[7].i = y; 2353 n[8].i = width; 2354 n[9].i = height; 2355 } 2356 if (ctx->ExecuteFlag) { 2357 CALL_CopyTexSubImage3D(ctx->Exec, (target, level, 2358 xoffset, yoffset, zoffset, 2359 x, y, width, height)); 2360 } 2361 } 2362 2363 2364 static void GLAPIENTRY 2365 save_CullFace(GLenum mode) 2366 { 2367 GET_CURRENT_CONTEXT(ctx); 2368 Node *n; 2369 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2370 n = alloc_instruction(ctx, OPCODE_CULL_FACE, 1); 2371 if (n) { 2372 n[1].e = mode; 2373 } 2374 if (ctx->ExecuteFlag) { 2375 CALL_CullFace(ctx->Exec, (mode)); 2376 } 2377 } 2378 2379 2380 static void GLAPIENTRY 2381 save_DepthFunc(GLenum func) 2382 { 2383 GET_CURRENT_CONTEXT(ctx); 2384 Node *n; 2385 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2386 n = alloc_instruction(ctx, OPCODE_DEPTH_FUNC, 1); 2387 if (n) { 2388 n[1].e = func; 2389 } 2390 if (ctx->ExecuteFlag) { 2391 CALL_DepthFunc(ctx->Exec, (func)); 2392 } 2393 } 2394 2395 2396 static void GLAPIENTRY 2397 save_DepthMask(GLboolean mask) 2398 { 2399 GET_CURRENT_CONTEXT(ctx); 2400 Node *n; 2401 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2402 n = alloc_instruction(ctx, OPCODE_DEPTH_MASK, 1); 2403 if (n) { 2404 n[1].b = mask; 2405 } 2406 if (ctx->ExecuteFlag) { 2407 CALL_DepthMask(ctx->Exec, (mask)); 2408 } 2409 } 2410 2411 2412 static void GLAPIENTRY 2413 save_DepthRange(GLclampd nearval, GLclampd farval) 2414 { 2415 GET_CURRENT_CONTEXT(ctx); 2416 Node *n; 2417 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2418 n = alloc_instruction(ctx, OPCODE_DEPTH_RANGE, 2); 2419 if (n) { 2420 n[1].f = (GLfloat) nearval; 2421 n[2].f = (GLfloat) farval; 2422 } 2423 if (ctx->ExecuteFlag) { 2424 CALL_DepthRange(ctx->Exec, (nearval, farval)); 2425 } 2426 } 2427 2428 2429 static void GLAPIENTRY 2430 save_Disable(GLenum cap) 2431 { 2432 GET_CURRENT_CONTEXT(ctx); 2433 Node *n; 2434 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2435 n = alloc_instruction(ctx, OPCODE_DISABLE, 1); 2436 if (n) { 2437 n[1].e = cap; 2438 } 2439 if (ctx->ExecuteFlag) { 2440 CALL_Disable(ctx->Exec, (cap)); 2441 } 2442 } 2443 2444 2445 static void GLAPIENTRY 2446 save_DisableIndexed(GLuint index, GLenum cap) 2447 { 2448 GET_CURRENT_CONTEXT(ctx); 2449 Node *n; 2450 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2451 n = alloc_instruction(ctx, OPCODE_DISABLE_INDEXED, 2); 2452 if (n) { 2453 n[1].ui = index; 2454 n[2].e = cap; 2455 } 2456 if (ctx->ExecuteFlag) { 2457 CALL_Disablei(ctx->Exec, (index, cap)); 2458 } 2459 } 2460 2461 2462 static void GLAPIENTRY 2463 save_DrawBuffer(GLenum mode) 2464 { 2465 GET_CURRENT_CONTEXT(ctx); 2466 Node *n; 2467 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2468 n = alloc_instruction(ctx, OPCODE_DRAW_BUFFER, 1); 2469 if (n) { 2470 n[1].e = mode; 2471 } 2472 if (ctx->ExecuteFlag) { 2473 CALL_DrawBuffer(ctx->Exec, (mode)); 2474 } 2475 } 2476 2477 2478 static void GLAPIENTRY 2479 save_DrawPixels(GLsizei width, GLsizei height, 2480 GLenum format, GLenum type, const GLvoid * pixels) 2481 { 2482 GET_CURRENT_CONTEXT(ctx); 2483 Node *n; 2484 2485 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2486 2487 n = alloc_instruction(ctx, OPCODE_DRAW_PIXELS, 4 + POINTER_DWORDS); 2488 if (n) { 2489 n[1].i = width; 2490 n[2].i = height; 2491 n[3].e = format; 2492 n[4].e = type; 2493 save_pointer(&n[5], 2494 unpack_image(ctx, 2, width, height, 1, format, type, 2495 pixels, &ctx->Unpack)); 2496 } 2497 if (ctx->ExecuteFlag) { 2498 CALL_DrawPixels(ctx->Exec, (width, height, format, type, pixels)); 2499 } 2500 } 2501 2502 2503 2504 static void GLAPIENTRY 2505 save_Enable(GLenum cap) 2506 { 2507 GET_CURRENT_CONTEXT(ctx); 2508 Node *n; 2509 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2510 n = alloc_instruction(ctx, OPCODE_ENABLE, 1); 2511 if (n) { 2512 n[1].e = cap; 2513 } 2514 if (ctx->ExecuteFlag) { 2515 CALL_Enable(ctx->Exec, (cap)); 2516 } 2517 } 2518 2519 2520 2521 static void GLAPIENTRY 2522 save_EnableIndexed(GLuint index, GLenum cap) 2523 { 2524 GET_CURRENT_CONTEXT(ctx); 2525 Node *n; 2526 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2527 n = alloc_instruction(ctx, OPCODE_ENABLE_INDEXED, 2); 2528 if (n) { 2529 n[1].ui = index; 2530 n[2].e = cap; 2531 } 2532 if (ctx->ExecuteFlag) { 2533 CALL_Enablei(ctx->Exec, (index, cap)); 2534 } 2535 } 2536 2537 2538 2539 static void GLAPIENTRY 2540 save_EvalMesh1(GLenum mode, GLint i1, GLint i2) 2541 { 2542 GET_CURRENT_CONTEXT(ctx); 2543 Node *n; 2544 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2545 n = alloc_instruction(ctx, OPCODE_EVALMESH1, 3); 2546 if (n) { 2547 n[1].e = mode; 2548 n[2].i = i1; 2549 n[3].i = i2; 2550 } 2551 if (ctx->ExecuteFlag) { 2552 CALL_EvalMesh1(ctx->Exec, (mode, i1, i2)); 2553 } 2554 } 2555 2556 2557 static void GLAPIENTRY 2558 save_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) 2559 { 2560 GET_CURRENT_CONTEXT(ctx); 2561 Node *n; 2562 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2563 n = alloc_instruction(ctx, OPCODE_EVALMESH2, 5); 2564 if (n) { 2565 n[1].e = mode; 2566 n[2].i = i1; 2567 n[3].i = i2; 2568 n[4].i = j1; 2569 n[5].i = j2; 2570 } 2571 if (ctx->ExecuteFlag) { 2572 CALL_EvalMesh2(ctx->Exec, (mode, i1, i2, j1, j2)); 2573 } 2574 } 2575 2576 2577 2578 2579 static void GLAPIENTRY 2580 save_Fogfv(GLenum pname, const GLfloat *params) 2581 { 2582 GET_CURRENT_CONTEXT(ctx); 2583 Node *n; 2584 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2585 n = alloc_instruction(ctx, OPCODE_FOG, 5); 2586 if (n) { 2587 n[1].e = pname; 2588 n[2].f = params[0]; 2589 n[3].f = params[1]; 2590 n[4].f = params[2]; 2591 n[5].f = params[3]; 2592 } 2593 if (ctx->ExecuteFlag) { 2594 CALL_Fogfv(ctx->Exec, (pname, params)); 2595 } 2596 } 2597 2598 2599 static void GLAPIENTRY 2600 save_Fogf(GLenum pname, GLfloat param) 2601 { 2602 GLfloat parray[4]; 2603 parray[0] = param; 2604 parray[1] = parray[2] = parray[3] = 0.0F; 2605 save_Fogfv(pname, parray); 2606 } 2607 2608 2609 static void GLAPIENTRY 2610 save_Fogiv(GLenum pname, const GLint *params) 2611 { 2612 GLfloat p[4]; 2613 switch (pname) { 2614 case GL_FOG_MODE: 2615 case GL_FOG_DENSITY: 2616 case GL_FOG_START: 2617 case GL_FOG_END: 2618 case GL_FOG_INDEX: 2619 p[0] = (GLfloat) *params; 2620 p[1] = 0.0f; 2621 p[2] = 0.0f; 2622 p[3] = 0.0f; 2623 break; 2624 case GL_FOG_COLOR: 2625 p[0] = INT_TO_FLOAT(params[0]); 2626 p[1] = INT_TO_FLOAT(params[1]); 2627 p[2] = INT_TO_FLOAT(params[2]); 2628 p[3] = INT_TO_FLOAT(params[3]); 2629 break; 2630 default: 2631 /* Error will be caught later in gl_Fogfv */ 2632 ASSIGN_4V(p, 0.0F, 0.0F, 0.0F, 0.0F); 2633 } 2634 save_Fogfv(pname, p); 2635 } 2636 2637 2638 static void GLAPIENTRY 2639 save_Fogi(GLenum pname, GLint param) 2640 { 2641 GLint parray[4]; 2642 parray[0] = param; 2643 parray[1] = parray[2] = parray[3] = 0; 2644 save_Fogiv(pname, parray); 2645 } 2646 2647 2648 static void GLAPIENTRY 2649 save_FrontFace(GLenum mode) 2650 { 2651 GET_CURRENT_CONTEXT(ctx); 2652 Node *n; 2653 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2654 n = alloc_instruction(ctx, OPCODE_FRONT_FACE, 1); 2655 if (n) { 2656 n[1].e = mode; 2657 } 2658 if (ctx->ExecuteFlag) { 2659 CALL_FrontFace(ctx->Exec, (mode)); 2660 } 2661 } 2662 2663 2664 static void GLAPIENTRY 2665 save_Frustum(GLdouble left, GLdouble right, 2666 GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval) 2667 { 2668 GET_CURRENT_CONTEXT(ctx); 2669 Node *n; 2670 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2671 n = alloc_instruction(ctx, OPCODE_FRUSTUM, 6); 2672 if (n) { 2673 n[1].f = (GLfloat) left; 2674 n[2].f = (GLfloat) right; 2675 n[3].f = (GLfloat) bottom; 2676 n[4].f = (GLfloat) top; 2677 n[5].f = (GLfloat) nearval; 2678 n[6].f = (GLfloat) farval; 2679 } 2680 if (ctx->ExecuteFlag) { 2681 CALL_Frustum(ctx->Exec, (left, right, bottom, top, nearval, farval)); 2682 } 2683 } 2684 2685 2686 static void GLAPIENTRY 2687 save_Hint(GLenum target, GLenum mode) 2688 { 2689 GET_CURRENT_CONTEXT(ctx); 2690 Node *n; 2691 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2692 n = alloc_instruction(ctx, OPCODE_HINT, 2); 2693 if (n) { 2694 n[1].e = target; 2695 n[2].e = mode; 2696 } 2697 if (ctx->ExecuteFlag) { 2698 CALL_Hint(ctx->Exec, (target, mode)); 2699 } 2700 } 2701 2702 2703 static void GLAPIENTRY 2704 save_IndexMask(GLuint mask) 2705 { 2706 GET_CURRENT_CONTEXT(ctx); 2707 Node *n; 2708 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2709 n = alloc_instruction(ctx, OPCODE_INDEX_MASK, 1); 2710 if (n) { 2711 n[1].ui = mask; 2712 } 2713 if (ctx->ExecuteFlag) { 2714 CALL_IndexMask(ctx->Exec, (mask)); 2715 } 2716 } 2717 2718 2719 static void GLAPIENTRY 2720 save_InitNames(void) 2721 { 2722 GET_CURRENT_CONTEXT(ctx); 2723 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2724 (void) alloc_instruction(ctx, OPCODE_INIT_NAMES, 0); 2725 if (ctx->ExecuteFlag) { 2726 CALL_InitNames(ctx->Exec, ()); 2727 } 2728 } 2729 2730 2731 static void GLAPIENTRY 2732 save_Lightfv(GLenum light, GLenum pname, const GLfloat *params) 2733 { 2734 GET_CURRENT_CONTEXT(ctx); 2735 Node *n; 2736 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2737 n = alloc_instruction(ctx, OPCODE_LIGHT, 6); 2738 if (n) { 2739 GLint i, nParams; 2740 n[1].e = light; 2741 n[2].e = pname; 2742 switch (pname) { 2743 case GL_AMBIENT: 2744 nParams = 4; 2745 break; 2746 case GL_DIFFUSE: 2747 nParams = 4; 2748 break; 2749 case GL_SPECULAR: 2750 nParams = 4; 2751 break; 2752 case GL_POSITION: 2753 nParams = 4; 2754 break; 2755 case GL_SPOT_DIRECTION: 2756 nParams = 3; 2757 break; 2758 case GL_SPOT_EXPONENT: 2759 nParams = 1; 2760 break; 2761 case GL_SPOT_CUTOFF: 2762 nParams = 1; 2763 break; 2764 case GL_CONSTANT_ATTENUATION: 2765 nParams = 1; 2766 break; 2767 case GL_LINEAR_ATTENUATION: 2768 nParams = 1; 2769 break; 2770 case GL_QUADRATIC_ATTENUATION: 2771 nParams = 1; 2772 break; 2773 default: 2774 nParams = 0; 2775 } 2776 for (i = 0; i < nParams; i++) { 2777 n[3 + i].f = params[i]; 2778 } 2779 } 2780 if (ctx->ExecuteFlag) { 2781 CALL_Lightfv(ctx->Exec, (light, pname, params)); 2782 } 2783 } 2784 2785 2786 static void GLAPIENTRY 2787 save_Lightf(GLenum light, GLenum pname, GLfloat param) 2788 { 2789 GLfloat parray[4]; 2790 parray[0] = param; 2791 parray[1] = parray[2] = parray[3] = 0.0F; 2792 save_Lightfv(light, pname, parray); 2793 } 2794 2795 2796 static void GLAPIENTRY 2797 save_Lightiv(GLenum light, GLenum pname, const GLint *params) 2798 { 2799 GLfloat fparam[4]; 2800 switch (pname) { 2801 case GL_AMBIENT: 2802 case GL_DIFFUSE: 2803 case GL_SPECULAR: 2804 fparam[0] = INT_TO_FLOAT(params[0]); 2805 fparam[1] = INT_TO_FLOAT(params[1]); 2806 fparam[2] = INT_TO_FLOAT(params[2]); 2807 fparam[3] = INT_TO_FLOAT(params[3]); 2808 break; 2809 case GL_POSITION: 2810 fparam[0] = (GLfloat) params[0]; 2811 fparam[1] = (GLfloat) params[1]; 2812 fparam[2] = (GLfloat) params[2]; 2813 fparam[3] = (GLfloat) params[3]; 2814 break; 2815 case GL_SPOT_DIRECTION: 2816 fparam[0] = (GLfloat) params[0]; 2817 fparam[1] = (GLfloat) params[1]; 2818 fparam[2] = (GLfloat) params[2]; 2819 break; 2820 case GL_SPOT_EXPONENT: 2821 case GL_SPOT_CUTOFF: 2822 case GL_CONSTANT_ATTENUATION: 2823 case GL_LINEAR_ATTENUATION: 2824 case GL_QUADRATIC_ATTENUATION: 2825 fparam[0] = (GLfloat) params[0]; 2826 break; 2827 default: 2828 /* error will be caught later in gl_Lightfv */ 2829 ; 2830 } 2831 save_Lightfv(light, pname, fparam); 2832 } 2833 2834 2835 static void GLAPIENTRY 2836 save_Lighti(GLenum light, GLenum pname, GLint param) 2837 { 2838 GLint parray[4]; 2839 parray[0] = param; 2840 parray[1] = parray[2] = parray[3] = 0; 2841 save_Lightiv(light, pname, parray); 2842 } 2843 2844 2845 static void GLAPIENTRY 2846 save_LightModelfv(GLenum pname, const GLfloat *params) 2847 { 2848 GET_CURRENT_CONTEXT(ctx); 2849 Node *n; 2850 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2851 n = alloc_instruction(ctx, OPCODE_LIGHT_MODEL, 5); 2852 if (n) { 2853 n[1].e = pname; 2854 n[2].f = params[0]; 2855 n[3].f = params[1]; 2856 n[4].f = params[2]; 2857 n[5].f = params[3]; 2858 } 2859 if (ctx->ExecuteFlag) { 2860 CALL_LightModelfv(ctx->Exec, (pname, params)); 2861 } 2862 } 2863 2864 2865 static void GLAPIENTRY 2866 save_LightModelf(GLenum pname, GLfloat param) 2867 { 2868 GLfloat parray[4]; 2869 parray[0] = param; 2870 parray[1] = parray[2] = parray[3] = 0.0F; 2871 save_LightModelfv(pname, parray); 2872 } 2873 2874 2875 static void GLAPIENTRY 2876 save_LightModeliv(GLenum pname, const GLint *params) 2877 { 2878 GLfloat fparam[4]; 2879 switch (pname) { 2880 case GL_LIGHT_MODEL_AMBIENT: 2881 fparam[0] = INT_TO_FLOAT(params[0]); 2882 fparam[1] = INT_TO_FLOAT(params[1]); 2883 fparam[2] = INT_TO_FLOAT(params[2]); 2884 fparam[3] = INT_TO_FLOAT(params[3]); 2885 break; 2886 case GL_LIGHT_MODEL_LOCAL_VIEWER: 2887 case GL_LIGHT_MODEL_TWO_SIDE: 2888 case GL_LIGHT_MODEL_COLOR_CONTROL: 2889 fparam[0] = (GLfloat) params[0]; 2890 fparam[1] = 0.0F; 2891 fparam[2] = 0.0F; 2892 fparam[3] = 0.0F; 2893 break; 2894 default: 2895 /* Error will be caught later in gl_LightModelfv */ 2896 ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F); 2897 } 2898 save_LightModelfv(pname, fparam); 2899 } 2900 2901 2902 static void GLAPIENTRY 2903 save_LightModeli(GLenum pname, GLint param) 2904 { 2905 GLint parray[4]; 2906 parray[0] = param; 2907 parray[1] = parray[2] = parray[3] = 0; 2908 save_LightModeliv(pname, parray); 2909 } 2910 2911 2912 static void GLAPIENTRY 2913 save_LineStipple(GLint factor, GLushort pattern) 2914 { 2915 GET_CURRENT_CONTEXT(ctx); 2916 Node *n; 2917 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2918 n = alloc_instruction(ctx, OPCODE_LINE_STIPPLE, 2); 2919 if (n) { 2920 n[1].i = factor; 2921 n[2].us = pattern; 2922 } 2923 if (ctx->ExecuteFlag) { 2924 CALL_LineStipple(ctx->Exec, (factor, pattern)); 2925 } 2926 } 2927 2928 2929 static void GLAPIENTRY 2930 save_LineWidth(GLfloat width) 2931 { 2932 GET_CURRENT_CONTEXT(ctx); 2933 Node *n; 2934 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2935 n = alloc_instruction(ctx, OPCODE_LINE_WIDTH, 1); 2936 if (n) { 2937 n[1].f = width; 2938 } 2939 if (ctx->ExecuteFlag) { 2940 CALL_LineWidth(ctx->Exec, (width)); 2941 } 2942 } 2943 2944 2945 static void GLAPIENTRY 2946 save_ListBase(GLuint base) 2947 { 2948 GET_CURRENT_CONTEXT(ctx); 2949 Node *n; 2950 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2951 n = alloc_instruction(ctx, OPCODE_LIST_BASE, 1); 2952 if (n) { 2953 n[1].ui = base; 2954 } 2955 if (ctx->ExecuteFlag) { 2956 CALL_ListBase(ctx->Exec, (base)); 2957 } 2958 } 2959 2960 2961 static void GLAPIENTRY 2962 save_LoadIdentity(void) 2963 { 2964 GET_CURRENT_CONTEXT(ctx); 2965 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2966 (void) alloc_instruction(ctx, OPCODE_LOAD_IDENTITY, 0); 2967 if (ctx->ExecuteFlag) { 2968 CALL_LoadIdentity(ctx->Exec, ()); 2969 } 2970 } 2971 2972 2973 static void GLAPIENTRY 2974 save_LoadMatrixf(const GLfloat * m) 2975 { 2976 GET_CURRENT_CONTEXT(ctx); 2977 Node *n; 2978 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 2979 n = alloc_instruction(ctx, OPCODE_LOAD_MATRIX, 16); 2980 if (n) { 2981 GLuint i; 2982 for (i = 0; i < 16; i++) { 2983 n[1 + i].f = m[i]; 2984 } 2985 } 2986 if (ctx->ExecuteFlag) { 2987 CALL_LoadMatrixf(ctx->Exec, (m)); 2988 } 2989 } 2990 2991 2992 static void GLAPIENTRY 2993 save_LoadMatrixd(const GLdouble * m) 2994 { 2995 GLfloat f[16]; 2996 GLint i; 2997 for (i = 0; i < 16; i++) { 2998 f[i] = (GLfloat) m[i]; 2999 } 3000 save_LoadMatrixf(f); 3001 } 3002 3003 3004 static void GLAPIENTRY 3005 save_LoadName(GLuint name) 3006 { 3007 GET_CURRENT_CONTEXT(ctx); 3008 Node *n; 3009 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3010 n = alloc_instruction(ctx, OPCODE_LOAD_NAME, 1); 3011 if (n) { 3012 n[1].ui = name; 3013 } 3014 if (ctx->ExecuteFlag) { 3015 CALL_LoadName(ctx->Exec, (name)); 3016 } 3017 } 3018 3019 3020 static void GLAPIENTRY 3021 save_LogicOp(GLenum opcode) 3022 { 3023 GET_CURRENT_CONTEXT(ctx); 3024 Node *n; 3025 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3026 n = alloc_instruction(ctx, OPCODE_LOGIC_OP, 1); 3027 if (n) { 3028 n[1].e = opcode; 3029 } 3030 if (ctx->ExecuteFlag) { 3031 CALL_LogicOp(ctx->Exec, (opcode)); 3032 } 3033 } 3034 3035 3036 static void GLAPIENTRY 3037 save_Map1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, 3038 GLint order, const GLdouble * points) 3039 { 3040 GET_CURRENT_CONTEXT(ctx); 3041 Node *n; 3042 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3043 n = alloc_instruction(ctx, OPCODE_MAP1, 5 + POINTER_DWORDS); 3044 if (n) { 3045 GLfloat *pnts = _mesa_copy_map_points1d(target, stride, order, points); 3046 n[1].e = target; 3047 n[2].f = (GLfloat) u1; 3048 n[3].f = (GLfloat) u2; 3049 n[4].i = _mesa_evaluator_components(target); /* stride */ 3050 n[5].i = order; 3051 save_pointer(&n[6], pnts); 3052 } 3053 if (ctx->ExecuteFlag) { 3054 CALL_Map1d(ctx->Exec, (target, u1, u2, stride, order, points)); 3055 } 3056 } 3057 3058 static void GLAPIENTRY 3059 save_Map1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, 3060 GLint order, const GLfloat * points) 3061 { 3062 GET_CURRENT_CONTEXT(ctx); 3063 Node *n; 3064 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3065 n = alloc_instruction(ctx, OPCODE_MAP1, 5 + POINTER_DWORDS); 3066 if (n) { 3067 GLfloat *pnts = _mesa_copy_map_points1f(target, stride, order, points); 3068 n[1].e = target; 3069 n[2].f = u1; 3070 n[3].f = u2; 3071 n[4].i = _mesa_evaluator_components(target); /* stride */ 3072 n[5].i = order; 3073 save_pointer(&n[6], pnts); 3074 } 3075 if (ctx->ExecuteFlag) { 3076 CALL_Map1f(ctx->Exec, (target, u1, u2, stride, order, points)); 3077 } 3078 } 3079 3080 3081 static void GLAPIENTRY 3082 save_Map2d(GLenum target, 3083 GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, 3084 GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, 3085 const GLdouble * points) 3086 { 3087 GET_CURRENT_CONTEXT(ctx); 3088 Node *n; 3089 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3090 n = alloc_instruction(ctx, OPCODE_MAP2, 9 + POINTER_DWORDS); 3091 if (n) { 3092 GLfloat *pnts = _mesa_copy_map_points2d(target, ustride, uorder, 3093 vstride, vorder, points); 3094 n[1].e = target; 3095 n[2].f = (GLfloat) u1; 3096 n[3].f = (GLfloat) u2; 3097 n[4].f = (GLfloat) v1; 3098 n[5].f = (GLfloat) v2; 3099 /* XXX verify these strides are correct */ 3100 n[6].i = _mesa_evaluator_components(target) * vorder; /*ustride */ 3101 n[7].i = _mesa_evaluator_components(target); /*vstride */ 3102 n[8].i = uorder; 3103 n[9].i = vorder; 3104 save_pointer(&n[10], pnts); 3105 } 3106 if (ctx->ExecuteFlag) { 3107 CALL_Map2d(ctx->Exec, (target, 3108 u1, u2, ustride, uorder, 3109 v1, v2, vstride, vorder, points)); 3110 } 3111 } 3112 3113 3114 static void GLAPIENTRY 3115 save_Map2f(GLenum target, 3116 GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, 3117 GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, 3118 const GLfloat * points) 3119 { 3120 GET_CURRENT_CONTEXT(ctx); 3121 Node *n; 3122 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3123 n = alloc_instruction(ctx, OPCODE_MAP2, 9 + POINTER_DWORDS); 3124 if (n) { 3125 GLfloat *pnts = _mesa_copy_map_points2f(target, ustride, uorder, 3126 vstride, vorder, points); 3127 n[1].e = target; 3128 n[2].f = u1; 3129 n[3].f = u2; 3130 n[4].f = v1; 3131 n[5].f = v2; 3132 /* XXX verify these strides are correct */ 3133 n[6].i = _mesa_evaluator_components(target) * vorder; /*ustride */ 3134 n[7].i = _mesa_evaluator_components(target); /*vstride */ 3135 n[8].i = uorder; 3136 n[9].i = vorder; 3137 save_pointer(&n[10], pnts); 3138 } 3139 if (ctx->ExecuteFlag) { 3140 CALL_Map2f(ctx->Exec, (target, u1, u2, ustride, uorder, 3141 v1, v2, vstride, vorder, points)); 3142 } 3143 } 3144 3145 3146 static void GLAPIENTRY 3147 save_MapGrid1f(GLint un, GLfloat u1, GLfloat u2) 3148 { 3149 GET_CURRENT_CONTEXT(ctx); 3150 Node *n; 3151 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3152 n = alloc_instruction(ctx, OPCODE_MAPGRID1, 3); 3153 if (n) { 3154 n[1].i = un; 3155 n[2].f = u1; 3156 n[3].f = u2; 3157 } 3158 if (ctx->ExecuteFlag) { 3159 CALL_MapGrid1f(ctx->Exec, (un, u1, u2)); 3160 } 3161 } 3162 3163 3164 static void GLAPIENTRY 3165 save_MapGrid1d(GLint un, GLdouble u1, GLdouble u2) 3166 { 3167 save_MapGrid1f(un, (GLfloat) u1, (GLfloat) u2); 3168 } 3169 3170 3171 static void GLAPIENTRY 3172 save_MapGrid2f(GLint un, GLfloat u1, GLfloat u2, 3173 GLint vn, GLfloat v1, GLfloat v2) 3174 { 3175 GET_CURRENT_CONTEXT(ctx); 3176 Node *n; 3177 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3178 n = alloc_instruction(ctx, OPCODE_MAPGRID2, 6); 3179 if (n) { 3180 n[1].i = un; 3181 n[2].f = u1; 3182 n[3].f = u2; 3183 n[4].i = vn; 3184 n[5].f = v1; 3185 n[6].f = v2; 3186 } 3187 if (ctx->ExecuteFlag) { 3188 CALL_MapGrid2f(ctx->Exec, (un, u1, u2, vn, v1, v2)); 3189 } 3190 } 3191 3192 3193 3194 static void GLAPIENTRY 3195 save_MapGrid2d(GLint un, GLdouble u1, GLdouble u2, 3196 GLint vn, GLdouble v1, GLdouble v2) 3197 { 3198 save_MapGrid2f(un, (GLfloat) u1, (GLfloat) u2, 3199 vn, (GLfloat) v1, (GLfloat) v2); 3200 } 3201 3202 3203 static void GLAPIENTRY 3204 save_MatrixMode(GLenum mode) 3205 { 3206 GET_CURRENT_CONTEXT(ctx); 3207 Node *n; 3208 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3209 n = alloc_instruction(ctx, OPCODE_MATRIX_MODE, 1); 3210 if (n) { 3211 n[1].e = mode; 3212 } 3213 if (ctx->ExecuteFlag) { 3214 CALL_MatrixMode(ctx->Exec, (mode)); 3215 } 3216 } 3217 3218 3219 static void GLAPIENTRY 3220 save_MultMatrixf(const GLfloat * m) 3221 { 3222 GET_CURRENT_CONTEXT(ctx); 3223 Node *n; 3224 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3225 n = alloc_instruction(ctx, OPCODE_MULT_MATRIX, 16); 3226 if (n) { 3227 GLuint i; 3228 for (i = 0; i < 16; i++) { 3229 n[1 + i].f = m[i]; 3230 } 3231 } 3232 if (ctx->ExecuteFlag) { 3233 CALL_MultMatrixf(ctx->Exec, (m)); 3234 } 3235 } 3236 3237 3238 static void GLAPIENTRY 3239 save_MultMatrixd(const GLdouble * m) 3240 { 3241 GLfloat f[16]; 3242 GLint i; 3243 for (i = 0; i < 16; i++) { 3244 f[i] = (GLfloat) m[i]; 3245 } 3246 save_MultMatrixf(f); 3247 } 3248 3249 3250 static void GLAPIENTRY 3251 save_NewList(GLuint name, GLenum mode) 3252 { 3253 GET_CURRENT_CONTEXT(ctx); 3254 /* It's an error to call this function while building a display list */ 3255 _mesa_error(ctx, GL_INVALID_OPERATION, "glNewList"); 3256 (void) name; 3257 (void) mode; 3258 } 3259 3260 3261 3262 static void GLAPIENTRY 3263 save_Ortho(GLdouble left, GLdouble right, 3264 GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval) 3265 { 3266 GET_CURRENT_CONTEXT(ctx); 3267 Node *n; 3268 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3269 n = alloc_instruction(ctx, OPCODE_ORTHO, 6); 3270 if (n) { 3271 n[1].f = (GLfloat) left; 3272 n[2].f = (GLfloat) right; 3273 n[3].f = (GLfloat) bottom; 3274 n[4].f = (GLfloat) top; 3275 n[5].f = (GLfloat) nearval; 3276 n[6].f = (GLfloat) farval; 3277 } 3278 if (ctx->ExecuteFlag) { 3279 CALL_Ortho(ctx->Exec, (left, right, bottom, top, nearval, farval)); 3280 } 3281 } 3282 3283 3284 static void GLAPIENTRY 3285 save_PixelMapfv(GLenum map, GLint mapsize, const GLfloat *values) 3286 { 3287 GET_CURRENT_CONTEXT(ctx); 3288 Node *n; 3289 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3290 n = alloc_instruction(ctx, OPCODE_PIXEL_MAP, 2 + POINTER_DWORDS); 3291 if (n) { 3292 n[1].e = map; 3293 n[2].i = mapsize; 3294 save_pointer(&n[3], memdup(values, mapsize * sizeof(GLfloat))); 3295 } 3296 if (ctx->ExecuteFlag) { 3297 CALL_PixelMapfv(ctx->Exec, (map, mapsize, values)); 3298 } 3299 } 3300 3301 3302 static void GLAPIENTRY 3303 save_PixelMapuiv(GLenum map, GLint mapsize, const GLuint *values) 3304 { 3305 GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; 3306 GLint i; 3307 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) { 3308 for (i = 0; i < mapsize; i++) { 3309 fvalues[i] = (GLfloat) values[i]; 3310 } 3311 } 3312 else { 3313 for (i = 0; i < mapsize; i++) { 3314 fvalues[i] = UINT_TO_FLOAT(values[i]); 3315 } 3316 } 3317 save_PixelMapfv(map, mapsize, fvalues); 3318 } 3319 3320 3321 static void GLAPIENTRY 3322 save_PixelMapusv(GLenum map, GLint mapsize, const GLushort *values) 3323 { 3324 GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; 3325 GLint i; 3326 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) { 3327 for (i = 0; i < mapsize; i++) { 3328 fvalues[i] = (GLfloat) values[i]; 3329 } 3330 } 3331 else { 3332 for (i = 0; i < mapsize; i++) { 3333 fvalues[i] = USHORT_TO_FLOAT(values[i]); 3334 } 3335 } 3336 save_PixelMapfv(map, mapsize, fvalues); 3337 } 3338 3339 3340 static void GLAPIENTRY 3341 save_PixelTransferf(GLenum pname, GLfloat param) 3342 { 3343 GET_CURRENT_CONTEXT(ctx); 3344 Node *n; 3345 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3346 n = alloc_instruction(ctx, OPCODE_PIXEL_TRANSFER, 2); 3347 if (n) { 3348 n[1].e = pname; 3349 n[2].f = param; 3350 } 3351 if (ctx->ExecuteFlag) { 3352 CALL_PixelTransferf(ctx->Exec, (pname, param)); 3353 } 3354 } 3355 3356 3357 static void GLAPIENTRY 3358 save_PixelTransferi(GLenum pname, GLint param) 3359 { 3360 save_PixelTransferf(pname, (GLfloat) param); 3361 } 3362 3363 3364 static void GLAPIENTRY 3365 save_PixelZoom(GLfloat xfactor, GLfloat yfactor) 3366 { 3367 GET_CURRENT_CONTEXT(ctx); 3368 Node *n; 3369 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3370 n = alloc_instruction(ctx, OPCODE_PIXEL_ZOOM, 2); 3371 if (n) { 3372 n[1].f = xfactor; 3373 n[2].f = yfactor; 3374 } 3375 if (ctx->ExecuteFlag) { 3376 CALL_PixelZoom(ctx->Exec, (xfactor, yfactor)); 3377 } 3378 } 3379 3380 3381 static void GLAPIENTRY 3382 save_PointParameterfvEXT(GLenum pname, const GLfloat *params) 3383 { 3384 GET_CURRENT_CONTEXT(ctx); 3385 Node *n; 3386 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3387 n = alloc_instruction(ctx, OPCODE_POINT_PARAMETERS, 4); 3388 if (n) { 3389 n[1].e = pname; 3390 n[2].f = params[0]; 3391 n[3].f = params[1]; 3392 n[4].f = params[2]; 3393 } 3394 if (ctx->ExecuteFlag) { 3395 CALL_PointParameterfv(ctx->Exec, (pname, params)); 3396 } 3397 } 3398 3399 3400 static void GLAPIENTRY 3401 save_PointParameterfEXT(GLenum pname, GLfloat param) 3402 { 3403 GLfloat parray[3]; 3404 parray[0] = param; 3405 parray[1] = parray[2] = 0.0F; 3406 save_PointParameterfvEXT(pname, parray); 3407 } 3408 3409 static void GLAPIENTRY 3410 save_PointParameteriNV(GLenum pname, GLint param) 3411 { 3412 GLfloat parray[3]; 3413 parray[0] = (GLfloat) param; 3414 parray[1] = parray[2] = 0.0F; 3415 save_PointParameterfvEXT(pname, parray); 3416 } 3417 3418 static void GLAPIENTRY 3419 save_PointParameterivNV(GLenum pname, const GLint * param) 3420 { 3421 GLfloat parray[3]; 3422 parray[0] = (GLfloat) param[0]; 3423 parray[1] = parray[2] = 0.0F; 3424 save_PointParameterfvEXT(pname, parray); 3425 } 3426 3427 3428 static void GLAPIENTRY 3429 save_PointSize(GLfloat size) 3430 { 3431 GET_CURRENT_CONTEXT(ctx); 3432 Node *n; 3433 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3434 n = alloc_instruction(ctx, OPCODE_POINT_SIZE, 1); 3435 if (n) { 3436 n[1].f = size; 3437 } 3438 if (ctx->ExecuteFlag) { 3439 CALL_PointSize(ctx->Exec, (size)); 3440 } 3441 } 3442 3443 3444 static void GLAPIENTRY 3445 save_PolygonMode(GLenum face, GLenum mode) 3446 { 3447 GET_CURRENT_CONTEXT(ctx); 3448 Node *n; 3449 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3450 n = alloc_instruction(ctx, OPCODE_POLYGON_MODE, 2); 3451 if (n) { 3452 n[1].e = face; 3453 n[2].e = mode; 3454 } 3455 if (ctx->ExecuteFlag) { 3456 CALL_PolygonMode(ctx->Exec, (face, mode)); 3457 } 3458 } 3459 3460 3461 static void GLAPIENTRY 3462 save_PolygonStipple(const GLubyte * pattern) 3463 { 3464 GET_CURRENT_CONTEXT(ctx); 3465 Node *n; 3466 3467 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3468 3469 n = alloc_instruction(ctx, OPCODE_POLYGON_STIPPLE, POINTER_DWORDS); 3470 if (n) { 3471 save_pointer(&n[1], 3472 unpack_image(ctx, 2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP, 3473 pattern, &ctx->Unpack)); 3474 } 3475 if (ctx->ExecuteFlag) { 3476 CALL_PolygonStipple(ctx->Exec, ((GLubyte *) pattern)); 3477 } 3478 } 3479 3480 3481 static void GLAPIENTRY 3482 save_PolygonOffset(GLfloat factor, GLfloat units) 3483 { 3484 GET_CURRENT_CONTEXT(ctx); 3485 Node *n; 3486 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3487 n = alloc_instruction(ctx, OPCODE_POLYGON_OFFSET, 2); 3488 if (n) { 3489 n[1].f = factor; 3490 n[2].f = units; 3491 } 3492 if (ctx->ExecuteFlag) { 3493 CALL_PolygonOffset(ctx->Exec, (factor, units)); 3494 } 3495 } 3496 3497 3498 static void GLAPIENTRY 3499 save_PolygonOffsetEXT(GLfloat factor, GLfloat bias) 3500 { 3501 GET_CURRENT_CONTEXT(ctx); 3502 /* XXX mult by DepthMaxF here??? */ 3503 save_PolygonOffset(factor, ctx->DrawBuffer->_DepthMaxF * bias); 3504 } 3505 3506 static void GLAPIENTRY 3507 save_PolygonOffsetClampEXT(GLfloat factor, GLfloat units, GLfloat clamp) 3508 { 3509 GET_CURRENT_CONTEXT(ctx); 3510 Node *n; 3511 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3512 n = alloc_instruction(ctx, OPCODE_POLYGON_OFFSET_CLAMP, 3); 3513 if (n) { 3514 n[1].f = factor; 3515 n[2].f = units; 3516 n[3].f = clamp; 3517 } 3518 if (ctx->ExecuteFlag) { 3519 CALL_PolygonOffsetClampEXT(ctx->Exec, (factor, units, clamp)); 3520 } 3521 } 3522 3523 static void GLAPIENTRY 3524 save_PopAttrib(void) 3525 { 3526 GET_CURRENT_CONTEXT(ctx); 3527 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3528 (void) alloc_instruction(ctx, OPCODE_POP_ATTRIB, 0); 3529 if (ctx->ExecuteFlag) { 3530 CALL_PopAttrib(ctx->Exec, ()); 3531 } 3532 } 3533 3534 3535 static void GLAPIENTRY 3536 save_PopMatrix(void) 3537 { 3538 GET_CURRENT_CONTEXT(ctx); 3539 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3540 (void) alloc_instruction(ctx, OPCODE_POP_MATRIX, 0); 3541 if (ctx->ExecuteFlag) { 3542 CALL_PopMatrix(ctx->Exec, ()); 3543 } 3544 } 3545 3546 3547 static void GLAPIENTRY 3548 save_PopName(void) 3549 { 3550 GET_CURRENT_CONTEXT(ctx); 3551 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3552 (void) alloc_instruction(ctx, OPCODE_POP_NAME, 0); 3553 if (ctx->ExecuteFlag) { 3554 CALL_PopName(ctx->Exec, ()); 3555 } 3556 } 3557 3558 3559 static void GLAPIENTRY 3560 save_PrioritizeTextures(GLsizei num, const GLuint * textures, 3561 const GLclampf * priorities) 3562 { 3563 GET_CURRENT_CONTEXT(ctx); 3564 GLint i; 3565 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3566 3567 for (i = 0; i < num; i++) { 3568 Node *n; 3569 n = alloc_instruction(ctx, OPCODE_PRIORITIZE_TEXTURE, 2); 3570 if (n) { 3571 n[1].ui = textures[i]; 3572 n[2].f = priorities[i]; 3573 } 3574 } 3575 if (ctx->ExecuteFlag) { 3576 CALL_PrioritizeTextures(ctx->Exec, (num, textures, priorities)); 3577 } 3578 } 3579 3580 3581 static void GLAPIENTRY 3582 save_PushAttrib(GLbitfield mask) 3583 { 3584 GET_CURRENT_CONTEXT(ctx); 3585 Node *n; 3586 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3587 n = alloc_instruction(ctx, OPCODE_PUSH_ATTRIB, 1); 3588 if (n) { 3589 n[1].bf = mask; 3590 } 3591 if (ctx->ExecuteFlag) { 3592 CALL_PushAttrib(ctx->Exec, (mask)); 3593 } 3594 } 3595 3596 3597 static void GLAPIENTRY 3598 save_PushMatrix(void) 3599 { 3600 GET_CURRENT_CONTEXT(ctx); 3601 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3602 (void) alloc_instruction(ctx, OPCODE_PUSH_MATRIX, 0); 3603 if (ctx->ExecuteFlag) { 3604 CALL_PushMatrix(ctx->Exec, ()); 3605 } 3606 } 3607 3608 3609 static void GLAPIENTRY 3610 save_PushName(GLuint name) 3611 { 3612 GET_CURRENT_CONTEXT(ctx); 3613 Node *n; 3614 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3615 n = alloc_instruction(ctx, OPCODE_PUSH_NAME, 1); 3616 if (n) { 3617 n[1].ui = name; 3618 } 3619 if (ctx->ExecuteFlag) { 3620 CALL_PushName(ctx->Exec, (name)); 3621 } 3622 } 3623 3624 3625 static void GLAPIENTRY 3626 save_RasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) 3627 { 3628 GET_CURRENT_CONTEXT(ctx); 3629 Node *n; 3630 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3631 n = alloc_instruction(ctx, OPCODE_RASTER_POS, 4); 3632 if (n) { 3633 n[1].f = x; 3634 n[2].f = y; 3635 n[3].f = z; 3636 n[4].f = w; 3637 } 3638 if (ctx->ExecuteFlag) { 3639 CALL_RasterPos4f(ctx->Exec, (x, y, z, w)); 3640 } 3641 } 3642 3643 static void GLAPIENTRY 3644 save_RasterPos2d(GLdouble x, GLdouble y) 3645 { 3646 save_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F); 3647 } 3648 3649 static void GLAPIENTRY 3650 save_RasterPos2f(GLfloat x, GLfloat y) 3651 { 3652 save_RasterPos4f(x, y, 0.0F, 1.0F); 3653 } 3654 3655 static void GLAPIENTRY 3656 save_RasterPos2i(GLint x, GLint y) 3657 { 3658 save_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F); 3659 } 3660 3661 static void GLAPIENTRY 3662 save_RasterPos2s(GLshort x, GLshort y) 3663 { 3664 save_RasterPos4f(x, y, 0.0F, 1.0F); 3665 } 3666 3667 static void GLAPIENTRY 3668 save_RasterPos3d(GLdouble x, GLdouble y, GLdouble z) 3669 { 3670 save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F); 3671 } 3672 3673 static void GLAPIENTRY 3674 save_RasterPos3f(GLfloat x, GLfloat y, GLfloat z) 3675 { 3676 save_RasterPos4f(x, y, z, 1.0F); 3677 } 3678 3679 static void GLAPIENTRY 3680 save_RasterPos3i(GLint x, GLint y, GLint z) 3681 { 3682 save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F); 3683 } 3684 3685 static void GLAPIENTRY 3686 save_RasterPos3s(GLshort x, GLshort y, GLshort z) 3687 { 3688 save_RasterPos4f(x, y, z, 1.0F); 3689 } 3690 3691 static void GLAPIENTRY 3692 save_RasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) 3693 { 3694 save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w); 3695 } 3696 3697 static void GLAPIENTRY 3698 save_RasterPos4i(GLint x, GLint y, GLint z, GLint w) 3699 { 3700 save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w); 3701 } 3702 3703 static void GLAPIENTRY 3704 save_RasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w) 3705 { 3706 save_RasterPos4f(x, y, z, w); 3707 } 3708 3709 static void GLAPIENTRY 3710 save_RasterPos2dv(const GLdouble * v) 3711 { 3712 save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F); 3713 } 3714 3715 static void GLAPIENTRY 3716 save_RasterPos2fv(const GLfloat * v) 3717 { 3718 save_RasterPos4f(v[0], v[1], 0.0F, 1.0F); 3719 } 3720 3721 static void GLAPIENTRY 3722 save_RasterPos2iv(const GLint * v) 3723 { 3724 save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F); 3725 } 3726 3727 static void GLAPIENTRY 3728 save_RasterPos2sv(const GLshort * v) 3729 { 3730 save_RasterPos4f(v[0], v[1], 0.0F, 1.0F); 3731 } 3732 3733 static void GLAPIENTRY 3734 save_RasterPos3dv(const GLdouble * v) 3735 { 3736 save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F); 3737 } 3738 3739 static void GLAPIENTRY 3740 save_RasterPos3fv(const GLfloat * v) 3741 { 3742 save_RasterPos4f(v[0], v[1], v[2], 1.0F); 3743 } 3744 3745 static void GLAPIENTRY 3746 save_RasterPos3iv(const GLint * v) 3747 { 3748 save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F); 3749 } 3750 3751 static void GLAPIENTRY 3752 save_RasterPos3sv(const GLshort * v) 3753 { 3754 save_RasterPos4f(v[0], v[1], v[2], 1.0F); 3755 } 3756 3757 static void GLAPIENTRY 3758 save_RasterPos4dv(const GLdouble * v) 3759 { 3760 save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 3761 (GLfloat) v[2], (GLfloat) v[3]); 3762 } 3763 3764 static void GLAPIENTRY 3765 save_RasterPos4fv(const GLfloat * v) 3766 { 3767 save_RasterPos4f(v[0], v[1], v[2], v[3]); 3768 } 3769 3770 static void GLAPIENTRY 3771 save_RasterPos4iv(const GLint * v) 3772 { 3773 save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 3774 (GLfloat) v[2], (GLfloat) v[3]); 3775 } 3776 3777 static void GLAPIENTRY 3778 save_RasterPos4sv(const GLshort * v) 3779 { 3780 save_RasterPos4f(v[0], v[1], v[2], v[3]); 3781 } 3782 3783 3784 static void GLAPIENTRY 3785 save_PassThrough(GLfloat token) 3786 { 3787 GET_CURRENT_CONTEXT(ctx); 3788 Node *n; 3789 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3790 n = alloc_instruction(ctx, OPCODE_PASSTHROUGH, 1); 3791 if (n) { 3792 n[1].f = token; 3793 } 3794 if (ctx->ExecuteFlag) { 3795 CALL_PassThrough(ctx->Exec, (token)); 3796 } 3797 } 3798 3799 3800 static void GLAPIENTRY 3801 save_ReadBuffer(GLenum mode) 3802 { 3803 GET_CURRENT_CONTEXT(ctx); 3804 Node *n; 3805 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3806 n = alloc_instruction(ctx, OPCODE_READ_BUFFER, 1); 3807 if (n) { 3808 n[1].e = mode; 3809 } 3810 if (ctx->ExecuteFlag) { 3811 CALL_ReadBuffer(ctx->Exec, (mode)); 3812 } 3813 } 3814 3815 3816 static void GLAPIENTRY 3817 save_Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) 3818 { 3819 GET_CURRENT_CONTEXT(ctx); 3820 Node *n; 3821 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3822 n = alloc_instruction(ctx, OPCODE_ROTATE, 4); 3823 if (n) { 3824 n[1].f = angle; 3825 n[2].f = x; 3826 n[3].f = y; 3827 n[4].f = z; 3828 } 3829 if (ctx->ExecuteFlag) { 3830 CALL_Rotatef(ctx->Exec, (angle, x, y, z)); 3831 } 3832 } 3833 3834 3835 static void GLAPIENTRY 3836 save_Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) 3837 { 3838 save_Rotatef((GLfloat) angle, (GLfloat) x, (GLfloat) y, (GLfloat) z); 3839 } 3840 3841 3842 static void GLAPIENTRY 3843 save_Scalef(GLfloat x, GLfloat y, GLfloat z) 3844 { 3845 GET_CURRENT_CONTEXT(ctx); 3846 Node *n; 3847 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3848 n = alloc_instruction(ctx, OPCODE_SCALE, 3); 3849 if (n) { 3850 n[1].f = x; 3851 n[2].f = y; 3852 n[3].f = z; 3853 } 3854 if (ctx->ExecuteFlag) { 3855 CALL_Scalef(ctx->Exec, (x, y, z)); 3856 } 3857 } 3858 3859 3860 static void GLAPIENTRY 3861 save_Scaled(GLdouble x, GLdouble y, GLdouble z) 3862 { 3863 save_Scalef((GLfloat) x, (GLfloat) y, (GLfloat) z); 3864 } 3865 3866 3867 static void GLAPIENTRY 3868 save_Scissor(GLint x, GLint y, GLsizei width, GLsizei height) 3869 { 3870 GET_CURRENT_CONTEXT(ctx); 3871 Node *n; 3872 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3873 n = alloc_instruction(ctx, OPCODE_SCISSOR, 4); 3874 if (n) { 3875 n[1].i = x; 3876 n[2].i = y; 3877 n[3].i = width; 3878 n[4].i = height; 3879 } 3880 if (ctx->ExecuteFlag) { 3881 CALL_Scissor(ctx->Exec, (x, y, width, height)); 3882 } 3883 } 3884 3885 3886 static void GLAPIENTRY 3887 save_ShadeModel(GLenum mode) 3888 { 3889 GET_CURRENT_CONTEXT(ctx); 3890 Node *n; 3891 ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx); 3892 3893 if (ctx->ExecuteFlag) { 3894 CALL_ShadeModel(ctx->Exec, (mode)); 3895 } 3896 3897 /* Don't compile this call if it's a no-op. 3898 * By avoiding this state change we have a better chance of 3899 * coalescing subsequent drawing commands into one batch. 3900 */ 3901 if (ctx->ListState.Current.ShadeModel == mode) 3902 return; 3903 3904 SAVE_FLUSH_VERTICES(ctx); 3905 3906 ctx->ListState.Current.ShadeModel = mode; 3907 3908 n = alloc_instruction(ctx, OPCODE_SHADE_MODEL, 1); 3909 if (n) { 3910 n[1].e = mode; 3911 } 3912 } 3913 3914 3915 static void GLAPIENTRY 3916 save_StencilFunc(GLenum func, GLint ref, GLuint mask) 3917 { 3918 GET_CURRENT_CONTEXT(ctx); 3919 Node *n; 3920 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3921 n = alloc_instruction(ctx, OPCODE_STENCIL_FUNC, 3); 3922 if (n) { 3923 n[1].e = func; 3924 n[2].i = ref; 3925 n[3].ui = mask; 3926 } 3927 if (ctx->ExecuteFlag) { 3928 CALL_StencilFunc(ctx->Exec, (func, ref, mask)); 3929 } 3930 } 3931 3932 3933 static void GLAPIENTRY 3934 save_StencilMask(GLuint mask) 3935 { 3936 GET_CURRENT_CONTEXT(ctx); 3937 Node *n; 3938 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3939 n = alloc_instruction(ctx, OPCODE_STENCIL_MASK, 1); 3940 if (n) { 3941 n[1].ui = mask; 3942 } 3943 if (ctx->ExecuteFlag) { 3944 CALL_StencilMask(ctx->Exec, (mask)); 3945 } 3946 } 3947 3948 3949 static void GLAPIENTRY 3950 save_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) 3951 { 3952 GET_CURRENT_CONTEXT(ctx); 3953 Node *n; 3954 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3955 n = alloc_instruction(ctx, OPCODE_STENCIL_OP, 3); 3956 if (n) { 3957 n[1].e = fail; 3958 n[2].e = zfail; 3959 n[3].e = zpass; 3960 } 3961 if (ctx->ExecuteFlag) { 3962 CALL_StencilOp(ctx->Exec, (fail, zfail, zpass)); 3963 } 3964 } 3965 3966 3967 static void GLAPIENTRY 3968 save_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) 3969 { 3970 GET_CURRENT_CONTEXT(ctx); 3971 Node *n; 3972 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3973 n = alloc_instruction(ctx, OPCODE_STENCIL_FUNC_SEPARATE, 4); 3974 if (n) { 3975 n[1].e = face; 3976 n[2].e = func; 3977 n[3].i = ref; 3978 n[4].ui = mask; 3979 } 3980 if (ctx->ExecuteFlag) { 3981 CALL_StencilFuncSeparate(ctx->Exec, (face, func, ref, mask)); 3982 } 3983 } 3984 3985 3986 static void GLAPIENTRY 3987 save_StencilFuncSeparateATI(GLenum frontfunc, GLenum backfunc, GLint ref, 3988 GLuint mask) 3989 { 3990 GET_CURRENT_CONTEXT(ctx); 3991 Node *n; 3992 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 3993 /* GL_FRONT */ 3994 n = alloc_instruction(ctx, OPCODE_STENCIL_FUNC_SEPARATE, 4); 3995 if (n) { 3996 n[1].e = GL_FRONT; 3997 n[2].e = frontfunc; 3998 n[3].i = ref; 3999 n[4].ui = mask; 4000 } 4001 /* GL_BACK */ 4002 n = alloc_instruction(ctx, OPCODE_STENCIL_FUNC_SEPARATE, 4); 4003 if (n) { 4004 n[1].e = GL_BACK; 4005 n[2].e = backfunc; 4006 n[3].i = ref; 4007 n[4].ui = mask; 4008 } 4009 if (ctx->ExecuteFlag) { 4010 CALL_StencilFuncSeparate(ctx->Exec, (GL_FRONT, frontfunc, ref, mask)); 4011 CALL_StencilFuncSeparate(ctx->Exec, (GL_BACK, backfunc, ref, mask)); 4012 } 4013 } 4014 4015 4016 static void GLAPIENTRY 4017 save_StencilMaskSeparate(GLenum face, GLuint mask) 4018 { 4019 GET_CURRENT_CONTEXT(ctx); 4020 Node *n; 4021 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4022 n = alloc_instruction(ctx, OPCODE_STENCIL_MASK_SEPARATE, 2); 4023 if (n) { 4024 n[1].e = face; 4025 n[2].ui = mask; 4026 } 4027 if (ctx->ExecuteFlag) { 4028 CALL_StencilMaskSeparate(ctx->Exec, (face, mask)); 4029 } 4030 } 4031 4032 4033 static void GLAPIENTRY 4034 save_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) 4035 { 4036 GET_CURRENT_CONTEXT(ctx); 4037 Node *n; 4038 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4039 n = alloc_instruction(ctx, OPCODE_STENCIL_OP_SEPARATE, 4); 4040 if (n) { 4041 n[1].e = face; 4042 n[2].e = fail; 4043 n[3].e = zfail; 4044 n[4].e = zpass; 4045 } 4046 if (ctx->ExecuteFlag) { 4047 CALL_StencilOpSeparate(ctx->Exec, (face, fail, zfail, zpass)); 4048 } 4049 } 4050 4051 4052 static void GLAPIENTRY 4053 save_TexEnvfv(GLenum target, GLenum pname, const GLfloat *params) 4054 { 4055 GET_CURRENT_CONTEXT(ctx); 4056 Node *n; 4057 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4058 n = alloc_instruction(ctx, OPCODE_TEXENV, 6); 4059 if (n) { 4060 n[1].e = target; 4061 n[2].e = pname; 4062 if (pname == GL_TEXTURE_ENV_COLOR) { 4063 n[3].f = params[0]; 4064 n[4].f = params[1]; 4065 n[5].f = params[2]; 4066 n[6].f = params[3]; 4067 } 4068 else { 4069 n[3].f = params[0]; 4070 n[4].f = n[5].f = n[6].f = 0.0F; 4071 } 4072 } 4073 if (ctx->ExecuteFlag) { 4074 CALL_TexEnvfv(ctx->Exec, (target, pname, params)); 4075 } 4076 } 4077 4078 4079 static void GLAPIENTRY 4080 save_TexEnvf(GLenum target, GLenum pname, GLfloat param) 4081 { 4082 GLfloat parray[4]; 4083 parray[0] = (GLfloat) param; 4084 parray[1] = parray[2] = parray[3] = 0.0F; 4085 save_TexEnvfv(target, pname, parray); 4086 } 4087 4088 4089 static void GLAPIENTRY 4090 save_TexEnvi(GLenum target, GLenum pname, GLint param) 4091 { 4092 GLfloat p[4]; 4093 p[0] = (GLfloat) param; 4094 p[1] = p[2] = p[3] = 0.0F; 4095 save_TexEnvfv(target, pname, p); 4096 } 4097 4098 4099 static void GLAPIENTRY 4100 save_TexEnviv(GLenum target, GLenum pname, const GLint * param) 4101 { 4102 GLfloat p[4]; 4103 if (pname == GL_TEXTURE_ENV_COLOR) { 4104 p[0] = INT_TO_FLOAT(param[0]); 4105 p[1] = INT_TO_FLOAT(param[1]); 4106 p[2] = INT_TO_FLOAT(param[2]); 4107 p[3] = INT_TO_FLOAT(param[3]); 4108 } 4109 else { 4110 p[0] = (GLfloat) param[0]; 4111 p[1] = p[2] = p[3] = 0.0F; 4112 } 4113 save_TexEnvfv(target, pname, p); 4114 } 4115 4116 4117 static void GLAPIENTRY 4118 save_TexGenfv(GLenum coord, GLenum pname, const GLfloat *params) 4119 { 4120 GET_CURRENT_CONTEXT(ctx); 4121 Node *n; 4122 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4123 n = alloc_instruction(ctx, OPCODE_TEXGEN, 6); 4124 if (n) { 4125 n[1].e = coord; 4126 n[2].e = pname; 4127 n[3].f = params[0]; 4128 n[4].f = params[1]; 4129 n[5].f = params[2]; 4130 n[6].f = params[3]; 4131 } 4132 if (ctx->ExecuteFlag) { 4133 CALL_TexGenfv(ctx->Exec, (coord, pname, params)); 4134 } 4135 } 4136 4137 4138 static void GLAPIENTRY 4139 save_TexGeniv(GLenum coord, GLenum pname, const GLint *params) 4140 { 4141 GLfloat p[4]; 4142 p[0] = (GLfloat) params[0]; 4143 p[1] = (GLfloat) params[1]; 4144 p[2] = (GLfloat) params[2]; 4145 p[3] = (GLfloat) params[3]; 4146 save_TexGenfv(coord, pname, p); 4147 } 4148 4149 4150 static void GLAPIENTRY 4151 save_TexGend(GLenum coord, GLenum pname, GLdouble param) 4152 { 4153 GLfloat parray[4]; 4154 parray[0] = (GLfloat) param; 4155 parray[1] = parray[2] = parray[3] = 0.0F; 4156 save_TexGenfv(coord, pname, parray); 4157 } 4158 4159 4160 static void GLAPIENTRY 4161 save_TexGendv(GLenum coord, GLenum pname, const GLdouble *params) 4162 { 4163 GLfloat p[4]; 4164 p[0] = (GLfloat) params[0]; 4165 p[1] = (GLfloat) params[1]; 4166 p[2] = (GLfloat) params[2]; 4167 p[3] = (GLfloat) params[3]; 4168 save_TexGenfv(coord, pname, p); 4169 } 4170 4171 4172 static void GLAPIENTRY 4173 save_TexGenf(GLenum coord, GLenum pname, GLfloat param) 4174 { 4175 GLfloat parray[4]; 4176 parray[0] = param; 4177 parray[1] = parray[2] = parray[3] = 0.0F; 4178 save_TexGenfv(coord, pname, parray); 4179 } 4180 4181 4182 static void GLAPIENTRY 4183 save_TexGeni(GLenum coord, GLenum pname, GLint param) 4184 { 4185 GLint parray[4]; 4186 parray[0] = param; 4187 parray[1] = parray[2] = parray[3] = 0; 4188 save_TexGeniv(coord, pname, parray); 4189 } 4190 4191 4192 static void GLAPIENTRY 4193 save_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) 4194 { 4195 GET_CURRENT_CONTEXT(ctx); 4196 Node *n; 4197 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4198 n = alloc_instruction(ctx, OPCODE_TEXPARAMETER, 6); 4199 if (n) { 4200 n[1].e = target; 4201 n[2].e = pname; 4202 n[3].f = params[0]; 4203 n[4].f = params[1]; 4204 n[5].f = params[2]; 4205 n[6].f = params[3]; 4206 } 4207 if (ctx->ExecuteFlag) { 4208 CALL_TexParameterfv(ctx->Exec, (target, pname, params)); 4209 } 4210 } 4211 4212 4213 static void GLAPIENTRY 4214 save_TexParameterf(GLenum target, GLenum pname, GLfloat param) 4215 { 4216 GLfloat parray[4]; 4217 parray[0] = param; 4218 parray[1] = parray[2] = parray[3] = 0.0F; 4219 save_TexParameterfv(target, pname, parray); 4220 } 4221 4222 4223 static void GLAPIENTRY 4224 save_TexParameteri(GLenum target, GLenum pname, GLint param) 4225 { 4226 GLfloat fparam[4]; 4227 fparam[0] = (GLfloat) param; 4228 fparam[1] = fparam[2] = fparam[3] = 0.0F; 4229 save_TexParameterfv(target, pname, fparam); 4230 } 4231 4232 4233 static void GLAPIENTRY 4234 save_TexParameteriv(GLenum target, GLenum pname, const GLint *params) 4235 { 4236 GLfloat fparam[4]; 4237 fparam[0] = (GLfloat) params[0]; 4238 fparam[1] = fparam[2] = fparam[3] = 0.0F; 4239 save_TexParameterfv(target, pname, fparam); 4240 } 4241 4242 4243 static void GLAPIENTRY 4244 save_TexImage1D(GLenum target, 4245 GLint level, GLint components, 4246 GLsizei width, GLint border, 4247 GLenum format, GLenum type, const GLvoid * pixels) 4248 { 4249 GET_CURRENT_CONTEXT(ctx); 4250 if (target == GL_PROXY_TEXTURE_1D) { 4251 /* don't compile, execute immediately */ 4252 CALL_TexImage1D(ctx->Exec, (target, level, components, width, 4253 border, format, type, pixels)); 4254 } 4255 else { 4256 Node *n; 4257 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4258 n = alloc_instruction(ctx, OPCODE_TEX_IMAGE1D, 7 + POINTER_DWORDS); 4259 if (n) { 4260 n[1].e = target; 4261 n[2].i = level; 4262 n[3].i = components; 4263 n[4].i = (GLint) width; 4264 n[5].i = border; 4265 n[6].e = format; 4266 n[7].e = type; 4267 save_pointer(&n[8], 4268 unpack_image(ctx, 1, width, 1, 1, format, type, 4269 pixels, &ctx->Unpack)); 4270 } 4271 if (ctx->ExecuteFlag) { 4272 CALL_TexImage1D(ctx->Exec, (target, level, components, width, 4273 border, format, type, pixels)); 4274 } 4275 } 4276 } 4277 4278 4279 static void GLAPIENTRY 4280 save_TexImage2D(GLenum target, 4281 GLint level, GLint components, 4282 GLsizei width, GLsizei height, GLint border, 4283 GLenum format, GLenum type, const GLvoid * pixels) 4284 { 4285 GET_CURRENT_CONTEXT(ctx); 4286 if (target == GL_PROXY_TEXTURE_2D) { 4287 /* don't compile, execute immediately */ 4288 CALL_TexImage2D(ctx->Exec, (target, level, components, width, 4289 height, border, format, type, pixels)); 4290 } 4291 else { 4292 Node *n; 4293 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4294 n = alloc_instruction(ctx, OPCODE_TEX_IMAGE2D, 8 + POINTER_DWORDS); 4295 if (n) { 4296 n[1].e = target; 4297 n[2].i = level; 4298 n[3].i = components; 4299 n[4].i = (GLint) width; 4300 n[5].i = (GLint) height; 4301 n[6].i = border; 4302 n[7].e = format; 4303 n[8].e = type; 4304 save_pointer(&n[9], 4305 unpack_image(ctx, 2, width, height, 1, format, type, 4306 pixels, &ctx->Unpack)); 4307 } 4308 if (ctx->ExecuteFlag) { 4309 CALL_TexImage2D(ctx->Exec, (target, level, components, width, 4310 height, border, format, type, pixels)); 4311 } 4312 } 4313 } 4314 4315 4316 static void GLAPIENTRY 4317 save_TexImage3D(GLenum target, 4318 GLint level, GLint internalFormat, 4319 GLsizei width, GLsizei height, GLsizei depth, 4320 GLint border, 4321 GLenum format, GLenum type, const GLvoid * pixels) 4322 { 4323 GET_CURRENT_CONTEXT(ctx); 4324 if (target == GL_PROXY_TEXTURE_3D) { 4325 /* don't compile, execute immediately */ 4326 CALL_TexImage3D(ctx->Exec, (target, level, internalFormat, width, 4327 height, depth, border, format, type, 4328 pixels)); 4329 } 4330 else { 4331 Node *n; 4332 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4333 n = alloc_instruction(ctx, OPCODE_TEX_IMAGE3D, 9 + POINTER_DWORDS); 4334 if (n) { 4335 n[1].e = target; 4336 n[2].i = level; 4337 n[3].i = (GLint) internalFormat; 4338 n[4].i = (GLint) width; 4339 n[5].i = (GLint) height; 4340 n[6].i = (GLint) depth; 4341 n[7].i = border; 4342 n[8].e = format; 4343 n[9].e = type; 4344 save_pointer(&n[10], 4345 unpack_image(ctx, 3, width, height, depth, format, type, 4346 pixels, &ctx->Unpack)); 4347 } 4348 if (ctx->ExecuteFlag) { 4349 CALL_TexImage3D(ctx->Exec, (target, level, internalFormat, width, 4350 height, depth, border, format, type, 4351 pixels)); 4352 } 4353 } 4354 } 4355 4356 4357 static void GLAPIENTRY 4358 save_TexSubImage1D(GLenum target, GLint level, GLint xoffset, 4359 GLsizei width, GLenum format, GLenum type, 4360 const GLvoid * pixels) 4361 { 4362 GET_CURRENT_CONTEXT(ctx); 4363 Node *n; 4364 4365 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4366 4367 n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE1D, 6 + POINTER_DWORDS); 4368 if (n) { 4369 n[1].e = target; 4370 n[2].i = level; 4371 n[3].i = xoffset; 4372 n[4].i = (GLint) width; 4373 n[5].e = format; 4374 n[6].e = type; 4375 save_pointer(&n[7], 4376 unpack_image(ctx, 1, width, 1, 1, format, type, 4377 pixels, &ctx->Unpack)); 4378 } 4379 if (ctx->ExecuteFlag) { 4380 CALL_TexSubImage1D(ctx->Exec, (target, level, xoffset, width, 4381 format, type, pixels)); 4382 } 4383 } 4384 4385 4386 static void GLAPIENTRY 4387 save_TexSubImage2D(GLenum target, GLint level, 4388 GLint xoffset, GLint yoffset, 4389 GLsizei width, GLsizei height, 4390 GLenum format, GLenum type, const GLvoid * pixels) 4391 { 4392 GET_CURRENT_CONTEXT(ctx); 4393 Node *n; 4394 4395 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4396 4397 n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE2D, 8 + POINTER_DWORDS); 4398 if (n) { 4399 n[1].e = target; 4400 n[2].i = level; 4401 n[3].i = xoffset; 4402 n[4].i = yoffset; 4403 n[5].i = (GLint) width; 4404 n[6].i = (GLint) height; 4405 n[7].e = format; 4406 n[8].e = type; 4407 save_pointer(&n[9], 4408 unpack_image(ctx, 2, width, height, 1, format, type, 4409 pixels, &ctx->Unpack)); 4410 } 4411 if (ctx->ExecuteFlag) { 4412 CALL_TexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset, 4413 width, height, format, type, pixels)); 4414 } 4415 } 4416 4417 4418 static void GLAPIENTRY 4419 save_TexSubImage3D(GLenum target, GLint level, 4420 GLint xoffset, GLint yoffset, GLint zoffset, 4421 GLsizei width, GLsizei height, GLsizei depth, 4422 GLenum format, GLenum type, const GLvoid * pixels) 4423 { 4424 GET_CURRENT_CONTEXT(ctx); 4425 Node *n; 4426 4427 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4428 4429 n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE3D, 10 + POINTER_DWORDS); 4430 if (n) { 4431 n[1].e = target; 4432 n[2].i = level; 4433 n[3].i = xoffset; 4434 n[4].i = yoffset; 4435 n[5].i = zoffset; 4436 n[6].i = (GLint) width; 4437 n[7].i = (GLint) height; 4438 n[8].i = (GLint) depth; 4439 n[9].e = format; 4440 n[10].e = type; 4441 save_pointer(&n[11], 4442 unpack_image(ctx, 3, width, height, depth, format, type, 4443 pixels, &ctx->Unpack)); 4444 } 4445 if (ctx->ExecuteFlag) { 4446 CALL_TexSubImage3D(ctx->Exec, (target, level, 4447 xoffset, yoffset, zoffset, 4448 width, height, depth, format, type, 4449 pixels)); 4450 } 4451 } 4452 4453 4454 static void GLAPIENTRY 4455 save_Translatef(GLfloat x, GLfloat y, GLfloat z) 4456 { 4457 GET_CURRENT_CONTEXT(ctx); 4458 Node *n; 4459 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4460 n = alloc_instruction(ctx, OPCODE_TRANSLATE, 3); 4461 if (n) { 4462 n[1].f = x; 4463 n[2].f = y; 4464 n[3].f = z; 4465 } 4466 if (ctx->ExecuteFlag) { 4467 CALL_Translatef(ctx->Exec, (x, y, z)); 4468 } 4469 } 4470 4471 4472 static void GLAPIENTRY 4473 save_Translated(GLdouble x, GLdouble y, GLdouble z) 4474 { 4475 save_Translatef((GLfloat) x, (GLfloat) y, (GLfloat) z); 4476 } 4477 4478 4479 4480 static void GLAPIENTRY 4481 save_Viewport(GLint x, GLint y, GLsizei width, GLsizei height) 4482 { 4483 GET_CURRENT_CONTEXT(ctx); 4484 Node *n; 4485 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4486 n = alloc_instruction(ctx, OPCODE_VIEWPORT, 4); 4487 if (n) { 4488 n[1].i = x; 4489 n[2].i = y; 4490 n[3].i = (GLint) width; 4491 n[4].i = (GLint) height; 4492 } 4493 if (ctx->ExecuteFlag) { 4494 CALL_Viewport(ctx->Exec, (x, y, width, height)); 4495 } 4496 } 4497 4498 4499 static void GLAPIENTRY 4500 save_WindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w) 4501 { 4502 GET_CURRENT_CONTEXT(ctx); 4503 Node *n; 4504 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4505 n = alloc_instruction(ctx, OPCODE_WINDOW_POS, 4); 4506 if (n) { 4507 n[1].f = x; 4508 n[2].f = y; 4509 n[3].f = z; 4510 n[4].f = w; 4511 } 4512 if (ctx->ExecuteFlag) { 4513 CALL_WindowPos4fMESA(ctx->Exec, (x, y, z, w)); 4514 } 4515 } 4516 4517 static void GLAPIENTRY 4518 save_WindowPos2dMESA(GLdouble x, GLdouble y) 4519 { 4520 save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, 0.0F, 1.0F); 4521 } 4522 4523 static void GLAPIENTRY 4524 save_WindowPos2fMESA(GLfloat x, GLfloat y) 4525 { 4526 save_WindowPos4fMESA(x, y, 0.0F, 1.0F); 4527 } 4528 4529 static void GLAPIENTRY 4530 save_WindowPos2iMESA(GLint x, GLint y) 4531 { 4532 save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, 0.0F, 1.0F); 4533 } 4534 4535 static void GLAPIENTRY 4536 save_WindowPos2sMESA(GLshort x, GLshort y) 4537 { 4538 save_WindowPos4fMESA(x, y, 0.0F, 1.0F); 4539 } 4540 4541 static void GLAPIENTRY 4542 save_WindowPos3dMESA(GLdouble x, GLdouble y, GLdouble z) 4543 { 4544 save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F); 4545 } 4546 4547 static void GLAPIENTRY 4548 save_WindowPos3fMESA(GLfloat x, GLfloat y, GLfloat z) 4549 { 4550 save_WindowPos4fMESA(x, y, z, 1.0F); 4551 } 4552 4553 static void GLAPIENTRY 4554 save_WindowPos3iMESA(GLint x, GLint y, GLint z) 4555 { 4556 save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F); 4557 } 4558 4559 static void GLAPIENTRY 4560 save_WindowPos3sMESA(GLshort x, GLshort y, GLshort z) 4561 { 4562 save_WindowPos4fMESA(x, y, z, 1.0F); 4563 } 4564 4565 static void GLAPIENTRY 4566 save_WindowPos4dMESA(GLdouble x, GLdouble y, GLdouble z, GLdouble w) 4567 { 4568 save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w); 4569 } 4570 4571 static void GLAPIENTRY 4572 save_WindowPos4iMESA(GLint x, GLint y, GLint z, GLint w) 4573 { 4574 save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w); 4575 } 4576 4577 static void GLAPIENTRY 4578 save_WindowPos4sMESA(GLshort x, GLshort y, GLshort z, GLshort w) 4579 { 4580 save_WindowPos4fMESA(x, y, z, w); 4581 } 4582 4583 static void GLAPIENTRY 4584 save_WindowPos2dvMESA(const GLdouble * v) 4585 { 4586 save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F); 4587 } 4588 4589 static void GLAPIENTRY 4590 save_WindowPos2fvMESA(const GLfloat * v) 4591 { 4592 save_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F); 4593 } 4594 4595 static void GLAPIENTRY 4596 save_WindowPos2ivMESA(const GLint * v) 4597 { 4598 save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F); 4599 } 4600 4601 static void GLAPIENTRY 4602 save_WindowPos2svMESA(const GLshort * v) 4603 { 4604 save_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F); 4605 } 4606 4607 static void GLAPIENTRY 4608 save_WindowPos3dvMESA(const GLdouble * v) 4609 { 4610 save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F); 4611 } 4612 4613 static void GLAPIENTRY 4614 save_WindowPos3fvMESA(const GLfloat * v) 4615 { 4616 save_WindowPos4fMESA(v[0], v[1], v[2], 1.0F); 4617 } 4618 4619 static void GLAPIENTRY 4620 save_WindowPos3ivMESA(const GLint * v) 4621 { 4622 save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F); 4623 } 4624 4625 static void GLAPIENTRY 4626 save_WindowPos3svMESA(const GLshort * v) 4627 { 4628 save_WindowPos4fMESA(v[0], v[1], v[2], 1.0F); 4629 } 4630 4631 static void GLAPIENTRY 4632 save_WindowPos4dvMESA(const GLdouble * v) 4633 { 4634 save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], 4635 (GLfloat) v[2], (GLfloat) v[3]); 4636 } 4637 4638 static void GLAPIENTRY 4639 save_WindowPos4fvMESA(const GLfloat * v) 4640 { 4641 save_WindowPos4fMESA(v[0], v[1], v[2], v[3]); 4642 } 4643 4644 static void GLAPIENTRY 4645 save_WindowPos4ivMESA(const GLint * v) 4646 { 4647 save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], 4648 (GLfloat) v[2], (GLfloat) v[3]); 4649 } 4650 4651 static void GLAPIENTRY 4652 save_WindowPos4svMESA(const GLshort * v) 4653 { 4654 save_WindowPos4fMESA(v[0], v[1], v[2], v[3]); 4655 } 4656 4657 4658 4659 /* GL_ARB_multitexture */ 4660 static void GLAPIENTRY 4661 save_ActiveTextureARB(GLenum target) 4662 { 4663 GET_CURRENT_CONTEXT(ctx); 4664 Node *n; 4665 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4666 n = alloc_instruction(ctx, OPCODE_ACTIVE_TEXTURE, 1); 4667 if (n) { 4668 n[1].e = target; 4669 } 4670 if (ctx->ExecuteFlag) { 4671 CALL_ActiveTexture(ctx->Exec, (target)); 4672 } 4673 } 4674 4675 4676 /* GL_ARB_transpose_matrix */ 4677 4678 static void GLAPIENTRY 4679 save_LoadTransposeMatrixdARB(const GLdouble m[16]) 4680 { 4681 GLfloat tm[16]; 4682 _math_transposefd(tm, m); 4683 save_LoadMatrixf(tm); 4684 } 4685 4686 4687 static void GLAPIENTRY 4688 save_LoadTransposeMatrixfARB(const GLfloat m[16]) 4689 { 4690 GLfloat tm[16]; 4691 _math_transposef(tm, m); 4692 save_LoadMatrixf(tm); 4693 } 4694 4695 4696 static void GLAPIENTRY 4697 save_MultTransposeMatrixdARB(const GLdouble m[16]) 4698 { 4699 GLfloat tm[16]; 4700 _math_transposefd(tm, m); 4701 save_MultMatrixf(tm); 4702 } 4703 4704 4705 static void GLAPIENTRY 4706 save_MultTransposeMatrixfARB(const GLfloat m[16]) 4707 { 4708 GLfloat tm[16]; 4709 _math_transposef(tm, m); 4710 save_MultMatrixf(tm); 4711 } 4712 4713 static GLvoid *copy_data(const GLvoid *data, GLsizei size, const char *func) 4714 { 4715 GET_CURRENT_CONTEXT(ctx); 4716 GLvoid *image; 4717 4718 if (!data) 4719 return NULL; 4720 4721 image = malloc(size); 4722 if (!image) { 4723 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); 4724 return NULL; 4725 } 4726 memcpy(image, data, size); 4727 4728 return image; 4729 } 4730 4731 4732 /* GL_ARB_texture_compression */ 4733 static void GLAPIENTRY 4734 save_CompressedTexImage1DARB(GLenum target, GLint level, 4735 GLenum internalFormat, GLsizei width, 4736 GLint border, GLsizei imageSize, 4737 const GLvoid * data) 4738 { 4739 GET_CURRENT_CONTEXT(ctx); 4740 if (target == GL_PROXY_TEXTURE_1D) { 4741 /* don't compile, execute immediately */ 4742 CALL_CompressedTexImage1D(ctx->Exec, (target, level, internalFormat, 4743 width, border, imageSize, 4744 data)); 4745 } 4746 else { 4747 Node *n; 4748 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4749 4750 n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D, 4751 6 + POINTER_DWORDS); 4752 if (n) { 4753 n[1].e = target; 4754 n[2].i = level; 4755 n[3].e = internalFormat; 4756 n[4].i = (GLint) width; 4757 n[5].i = border; 4758 n[6].i = imageSize; 4759 save_pointer(&n[7], 4760 copy_data(data, imageSize, "glCompressedTexImage1DARB")); 4761 } 4762 if (ctx->ExecuteFlag) { 4763 CALL_CompressedTexImage1D(ctx->Exec, 4764 (target, level, internalFormat, width, 4765 border, imageSize, data)); 4766 } 4767 } 4768 } 4769 4770 4771 static void GLAPIENTRY 4772 save_CompressedTexImage2DARB(GLenum target, GLint level, 4773 GLenum internalFormat, GLsizei width, 4774 GLsizei height, GLint border, GLsizei imageSize, 4775 const GLvoid * data) 4776 { 4777 GET_CURRENT_CONTEXT(ctx); 4778 if (target == GL_PROXY_TEXTURE_2D) { 4779 /* don't compile, execute immediately */ 4780 CALL_CompressedTexImage2D(ctx->Exec, (target, level, internalFormat, 4781 width, height, border, 4782 imageSize, data)); 4783 } 4784 else { 4785 Node *n; 4786 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4787 4788 n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D, 4789 7 + POINTER_DWORDS); 4790 if (n) { 4791 n[1].e = target; 4792 n[2].i = level; 4793 n[3].e = internalFormat; 4794 n[4].i = (GLint) width; 4795 n[5].i = (GLint) height; 4796 n[6].i = border; 4797 n[7].i = imageSize; 4798 save_pointer(&n[8], 4799 copy_data(data, imageSize, "glCompressedTexImage2DARB")); 4800 } 4801 if (ctx->ExecuteFlag) { 4802 CALL_CompressedTexImage2D(ctx->Exec, 4803 (target, level, internalFormat, width, 4804 height, border, imageSize, data)); 4805 } 4806 } 4807 } 4808 4809 4810 static void GLAPIENTRY 4811 save_CompressedTexImage3DARB(GLenum target, GLint level, 4812 GLenum internalFormat, GLsizei width, 4813 GLsizei height, GLsizei depth, GLint border, 4814 GLsizei imageSize, const GLvoid * data) 4815 { 4816 GET_CURRENT_CONTEXT(ctx); 4817 if (target == GL_PROXY_TEXTURE_3D) { 4818 /* don't compile, execute immediately */ 4819 CALL_CompressedTexImage3D(ctx->Exec, (target, level, internalFormat, 4820 width, height, depth, border, 4821 imageSize, data)); 4822 } 4823 else { 4824 Node *n; 4825 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4826 4827 n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D, 4828 8 + POINTER_DWORDS); 4829 if (n) { 4830 n[1].e = target; 4831 n[2].i = level; 4832 n[3].e = internalFormat; 4833 n[4].i = (GLint) width; 4834 n[5].i = (GLint) height; 4835 n[6].i = (GLint) depth; 4836 n[7].i = border; 4837 n[8].i = imageSize; 4838 save_pointer(&n[9], 4839 copy_data(data, imageSize, "glCompressedTexImage3DARB")); 4840 } 4841 if (ctx->ExecuteFlag) { 4842 CALL_CompressedTexImage3D(ctx->Exec, 4843 (target, level, internalFormat, width, 4844 height, depth, border, imageSize, 4845 data)); 4846 } 4847 } 4848 } 4849 4850 4851 static void GLAPIENTRY 4852 save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, 4853 GLsizei width, GLenum format, 4854 GLsizei imageSize, const GLvoid * data) 4855 { 4856 Node *n; 4857 GET_CURRENT_CONTEXT(ctx); 4858 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4859 4860 n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, 4861 6 + POINTER_DWORDS); 4862 if (n) { 4863 n[1].e = target; 4864 n[2].i = level; 4865 n[3].i = xoffset; 4866 n[4].i = (GLint) width; 4867 n[5].e = format; 4868 n[6].i = imageSize; 4869 save_pointer(&n[7], 4870 copy_data(data, imageSize, "glCompressedTexSubImage1DARB")); 4871 } 4872 if (ctx->ExecuteFlag) { 4873 CALL_CompressedTexSubImage1D(ctx->Exec, (target, level, xoffset, 4874 width, format, imageSize, 4875 data)); 4876 } 4877 } 4878 4879 4880 static void GLAPIENTRY 4881 save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, 4882 GLint yoffset, GLsizei width, GLsizei height, 4883 GLenum format, GLsizei imageSize, 4884 const GLvoid * data) 4885 { 4886 Node *n; 4887 GET_CURRENT_CONTEXT(ctx); 4888 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4889 4890 n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, 4891 8 + POINTER_DWORDS); 4892 if (n) { 4893 n[1].e = target; 4894 n[2].i = level; 4895 n[3].i = xoffset; 4896 n[4].i = yoffset; 4897 n[5].i = (GLint) width; 4898 n[6].i = (GLint) height; 4899 n[7].e = format; 4900 n[8].i = imageSize; 4901 save_pointer(&n[9], 4902 copy_data(data, imageSize, "glCompressedTexSubImage2DARB")); 4903 } 4904 if (ctx->ExecuteFlag) { 4905 CALL_CompressedTexSubImage2D(ctx->Exec, 4906 (target, level, xoffset, yoffset, width, 4907 height, format, imageSize, data)); 4908 } 4909 } 4910 4911 4912 static void GLAPIENTRY 4913 save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, 4914 GLint yoffset, GLint zoffset, GLsizei width, 4915 GLsizei height, GLsizei depth, GLenum format, 4916 GLsizei imageSize, const GLvoid * data) 4917 { 4918 Node *n; 4919 GET_CURRENT_CONTEXT(ctx); 4920 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4921 4922 n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, 4923 10 + POINTER_DWORDS); 4924 if (n) { 4925 n[1].e = target; 4926 n[2].i = level; 4927 n[3].i = xoffset; 4928 n[4].i = yoffset; 4929 n[5].i = zoffset; 4930 n[6].i = (GLint) width; 4931 n[7].i = (GLint) height; 4932 n[8].i = (GLint) depth; 4933 n[9].e = format; 4934 n[10].i = imageSize; 4935 save_pointer(&n[11], 4936 copy_data(data, imageSize, "glCompressedTexSubImage3DARB")); 4937 } 4938 if (ctx->ExecuteFlag) { 4939 CALL_CompressedTexSubImage3D(ctx->Exec, 4940 (target, level, xoffset, yoffset, 4941 zoffset, width, height, depth, format, 4942 imageSize, data)); 4943 } 4944 } 4945 4946 4947 /* GL_ARB_multisample */ 4948 static void GLAPIENTRY 4949 save_SampleCoverageARB(GLclampf value, GLboolean invert) 4950 { 4951 GET_CURRENT_CONTEXT(ctx); 4952 Node *n; 4953 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4954 n = alloc_instruction(ctx, OPCODE_SAMPLE_COVERAGE, 2); 4955 if (n) { 4956 n[1].f = value; 4957 n[2].b = invert; 4958 } 4959 if (ctx->ExecuteFlag) { 4960 CALL_SampleCoverage(ctx->Exec, (value, invert)); 4961 } 4962 } 4963 4964 4965 /* 4966 * GL_ARB_vertex_program 4967 */ 4968 static void GLAPIENTRY 4969 save_BindProgramARB(GLenum target, GLuint id) 4970 { 4971 GET_CURRENT_CONTEXT(ctx); 4972 Node *n; 4973 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4974 n = alloc_instruction(ctx, OPCODE_BIND_PROGRAM_ARB, 2); 4975 if (n) { 4976 n[1].e = target; 4977 n[2].ui = id; 4978 } 4979 if (ctx->ExecuteFlag) { 4980 CALL_BindProgramARB(ctx->Exec, (target, id)); 4981 } 4982 } 4983 4984 static void GLAPIENTRY 4985 save_ProgramEnvParameter4fARB(GLenum target, GLuint index, 4986 GLfloat x, GLfloat y, GLfloat z, GLfloat w) 4987 { 4988 GET_CURRENT_CONTEXT(ctx); 4989 Node *n; 4990 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 4991 n = alloc_instruction(ctx, OPCODE_PROGRAM_ENV_PARAMETER_ARB, 6); 4992 if (n) { 4993 n[1].e = target; 4994 n[2].ui = index; 4995 n[3].f = x; 4996 n[4].f = y; 4997 n[5].f = z; 4998 n[6].f = w; 4999 } 5000 if (ctx->ExecuteFlag) { 5001 CALL_ProgramEnvParameter4fARB(ctx->Exec, (target, index, x, y, z, w)); 5002 } 5003 } 5004 5005 5006 static void GLAPIENTRY 5007 save_ProgramEnvParameter4fvARB(GLenum target, GLuint index, 5008 const GLfloat *params) 5009 { 5010 save_ProgramEnvParameter4fARB(target, index, params[0], params[1], 5011 params[2], params[3]); 5012 } 5013 5014 5015 static void GLAPIENTRY 5016 save_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, 5017 const GLfloat * params) 5018 { 5019 GET_CURRENT_CONTEXT(ctx); 5020 Node *n; 5021 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5022 5023 if (count > 0) { 5024 GLint i; 5025 const GLfloat * p = params; 5026 5027 for (i = 0 ; i < count ; i++) { 5028 n = alloc_instruction(ctx, OPCODE_PROGRAM_ENV_PARAMETER_ARB, 6); 5029 if (n) { 5030 n[1].e = target; 5031 n[2].ui = index; 5032 n[3].f = p[0]; 5033 n[4].f = p[1]; 5034 n[5].f = p[2]; 5035 n[6].f = p[3]; 5036 p += 4; 5037 } 5038 } 5039 } 5040 5041 if (ctx->ExecuteFlag) { 5042 CALL_ProgramEnvParameters4fvEXT(ctx->Exec, (target, index, count, params)); 5043 } 5044 } 5045 5046 5047 static void GLAPIENTRY 5048 save_ProgramEnvParameter4dARB(GLenum target, GLuint index, 5049 GLdouble x, GLdouble y, GLdouble z, GLdouble w) 5050 { 5051 save_ProgramEnvParameter4fARB(target, index, 5052 (GLfloat) x, 5053 (GLfloat) y, (GLfloat) z, (GLfloat) w); 5054 } 5055 5056 5057 static void GLAPIENTRY 5058 save_ProgramEnvParameter4dvARB(GLenum target, GLuint index, 5059 const GLdouble *params) 5060 { 5061 save_ProgramEnvParameter4fARB(target, index, 5062 (GLfloat) params[0], 5063 (GLfloat) params[1], 5064 (GLfloat) params[2], (GLfloat) params[3]); 5065 } 5066 5067 5068 static void GLAPIENTRY 5069 save_ProgramLocalParameter4fARB(GLenum target, GLuint index, 5070 GLfloat x, GLfloat y, GLfloat z, GLfloat w) 5071 { 5072 GET_CURRENT_CONTEXT(ctx); 5073 Node *n; 5074 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5075 n = alloc_instruction(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6); 5076 if (n) { 5077 n[1].e = target; 5078 n[2].ui = index; 5079 n[3].f = x; 5080 n[4].f = y; 5081 n[5].f = z; 5082 n[6].f = w; 5083 } 5084 if (ctx->ExecuteFlag) { 5085 CALL_ProgramLocalParameter4fARB(ctx->Exec, (target, index, x, y, z, w)); 5086 } 5087 } 5088 5089 5090 static void GLAPIENTRY 5091 save_ProgramLocalParameter4fvARB(GLenum target, GLuint index, 5092 const GLfloat *params) 5093 { 5094 GET_CURRENT_CONTEXT(ctx); 5095 Node *n; 5096 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5097 n = alloc_instruction(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6); 5098 if (n) { 5099 n[1].e = target; 5100 n[2].ui = index; 5101 n[3].f = params[0]; 5102 n[4].f = params[1]; 5103 n[5].f = params[2]; 5104 n[6].f = params[3]; 5105 } 5106 if (ctx->ExecuteFlag) { 5107 CALL_ProgramLocalParameter4fvARB(ctx->Exec, (target, index, params)); 5108 } 5109 } 5110 5111 5112 static void GLAPIENTRY 5113 save_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, 5114 const GLfloat *params) 5115 { 5116 GET_CURRENT_CONTEXT(ctx); 5117 Node *n; 5118 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5119 5120 if (count > 0) { 5121 GLint i; 5122 const GLfloat * p = params; 5123 5124 for (i = 0 ; i < count ; i++) { 5125 n = alloc_instruction(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6); 5126 if (n) { 5127 n[1].e = target; 5128 n[2].ui = index; 5129 n[3].f = p[0]; 5130 n[4].f = p[1]; 5131 n[5].f = p[2]; 5132 n[6].f = p[3]; 5133 p += 4; 5134 } 5135 } 5136 } 5137 5138 if (ctx->ExecuteFlag) { 5139 CALL_ProgramLocalParameters4fvEXT(ctx->Exec, (target, index, count, params)); 5140 } 5141 } 5142 5143 5144 static void GLAPIENTRY 5145 save_ProgramLocalParameter4dARB(GLenum target, GLuint index, 5146 GLdouble x, GLdouble y, 5147 GLdouble z, GLdouble w) 5148 { 5149 GET_CURRENT_CONTEXT(ctx); 5150 Node *n; 5151 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5152 n = alloc_instruction(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6); 5153 if (n) { 5154 n[1].e = target; 5155 n[2].ui = index; 5156 n[3].f = (GLfloat) x; 5157 n[4].f = (GLfloat) y; 5158 n[5].f = (GLfloat) z; 5159 n[6].f = (GLfloat) w; 5160 } 5161 if (ctx->ExecuteFlag) { 5162 CALL_ProgramLocalParameter4dARB(ctx->Exec, (target, index, x, y, z, w)); 5163 } 5164 } 5165 5166 5167 static void GLAPIENTRY 5168 save_ProgramLocalParameter4dvARB(GLenum target, GLuint index, 5169 const GLdouble *params) 5170 { 5171 GET_CURRENT_CONTEXT(ctx); 5172 Node *n; 5173 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5174 n = alloc_instruction(ctx, OPCODE_PROGRAM_LOCAL_PARAMETER_ARB, 6); 5175 if (n) { 5176 n[1].e = target; 5177 n[2].ui = index; 5178 n[3].f = (GLfloat) params[0]; 5179 n[4].f = (GLfloat) params[1]; 5180 n[5].f = (GLfloat) params[2]; 5181 n[6].f = (GLfloat) params[3]; 5182 } 5183 if (ctx->ExecuteFlag) { 5184 CALL_ProgramLocalParameter4dvARB(ctx->Exec, (target, index, params)); 5185 } 5186 } 5187 5188 5189 /* GL_EXT_stencil_two_side */ 5190 static void GLAPIENTRY 5191 save_ActiveStencilFaceEXT(GLenum face) 5192 { 5193 GET_CURRENT_CONTEXT(ctx); 5194 Node *n; 5195 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5196 n = alloc_instruction(ctx, OPCODE_ACTIVE_STENCIL_FACE_EXT, 1); 5197 if (n) { 5198 n[1].e = face; 5199 } 5200 if (ctx->ExecuteFlag) { 5201 CALL_ActiveStencilFaceEXT(ctx->Exec, (face)); 5202 } 5203 } 5204 5205 5206 /* GL_EXT_depth_bounds_test */ 5207 static void GLAPIENTRY 5208 save_DepthBoundsEXT(GLclampd zmin, GLclampd zmax) 5209 { 5210 GET_CURRENT_CONTEXT(ctx); 5211 Node *n; 5212 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5213 n = alloc_instruction(ctx, OPCODE_DEPTH_BOUNDS_EXT, 2); 5214 if (n) { 5215 n[1].f = (GLfloat) zmin; 5216 n[2].f = (GLfloat) zmax; 5217 } 5218 if (ctx->ExecuteFlag) { 5219 CALL_DepthBoundsEXT(ctx->Exec, (zmin, zmax)); 5220 } 5221 } 5222 5223 5224 5225 static void GLAPIENTRY 5226 save_ProgramStringARB(GLenum target, GLenum format, GLsizei len, 5227 const GLvoid * string) 5228 { 5229 GET_CURRENT_CONTEXT(ctx); 5230 Node *n; 5231 5232 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5233 5234 n = alloc_instruction(ctx, OPCODE_PROGRAM_STRING_ARB, 3 + POINTER_DWORDS); 5235 if (n) { 5236 GLubyte *programCopy = malloc(len); 5237 if (!programCopy) { 5238 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB"); 5239 return; 5240 } 5241 memcpy(programCopy, string, len); 5242 n[1].e = target; 5243 n[2].e = format; 5244 n[3].i = len; 5245 save_pointer(&n[4], programCopy); 5246 } 5247 if (ctx->ExecuteFlag) { 5248 CALL_ProgramStringARB(ctx->Exec, (target, format, len, string)); 5249 } 5250 } 5251 5252 5253 static void GLAPIENTRY 5254 save_BeginQueryARB(GLenum target, GLuint id) 5255 { 5256 GET_CURRENT_CONTEXT(ctx); 5257 Node *n; 5258 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5259 n = alloc_instruction(ctx, OPCODE_BEGIN_QUERY_ARB, 2); 5260 if (n) { 5261 n[1].e = target; 5262 n[2].ui = id; 5263 } 5264 if (ctx->ExecuteFlag) { 5265 CALL_BeginQuery(ctx->Exec, (target, id)); 5266 } 5267 } 5268 5269 static void GLAPIENTRY 5270 save_EndQueryARB(GLenum target) 5271 { 5272 GET_CURRENT_CONTEXT(ctx); 5273 Node *n; 5274 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5275 n = alloc_instruction(ctx, OPCODE_END_QUERY_ARB, 1); 5276 if (n) { 5277 n[1].e = target; 5278 } 5279 if (ctx->ExecuteFlag) { 5280 CALL_EndQuery(ctx->Exec, (target)); 5281 } 5282 } 5283 5284 static void GLAPIENTRY 5285 save_QueryCounter(GLuint id, GLenum target) 5286 { 5287 GET_CURRENT_CONTEXT(ctx); 5288 Node *n; 5289 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5290 n = alloc_instruction(ctx, OPCODE_QUERY_COUNTER, 2); 5291 if (n) { 5292 n[1].ui = id; 5293 n[2].e = target; 5294 } 5295 if (ctx->ExecuteFlag) { 5296 CALL_QueryCounter(ctx->Exec, (id, target)); 5297 } 5298 } 5299 5300 static void GLAPIENTRY 5301 save_BeginQueryIndexed(GLenum target, GLuint index, GLuint id) 5302 { 5303 GET_CURRENT_CONTEXT(ctx); 5304 Node *n; 5305 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5306 n = alloc_instruction(ctx, OPCODE_BEGIN_QUERY_INDEXED, 3); 5307 if (n) { 5308 n[1].e = target; 5309 n[2].ui = index; 5310 n[3].ui = id; 5311 } 5312 if (ctx->ExecuteFlag) { 5313 CALL_BeginQueryIndexed(ctx->Exec, (target, index, id)); 5314 } 5315 } 5316 5317 static void GLAPIENTRY 5318 save_EndQueryIndexed(GLenum target, GLuint index) 5319 { 5320 GET_CURRENT_CONTEXT(ctx); 5321 Node *n; 5322 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5323 n = alloc_instruction(ctx, OPCODE_END_QUERY_INDEXED, 2); 5324 if (n) { 5325 n[1].e = target; 5326 n[2].ui = index; 5327 } 5328 if (ctx->ExecuteFlag) { 5329 CALL_EndQueryIndexed(ctx->Exec, (target, index)); 5330 } 5331 } 5332 5333 5334 static void GLAPIENTRY 5335 save_DrawBuffersARB(GLsizei count, const GLenum * buffers) 5336 { 5337 GET_CURRENT_CONTEXT(ctx); 5338 Node *n; 5339 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5340 n = alloc_instruction(ctx, OPCODE_DRAW_BUFFERS_ARB, 1 + MAX_DRAW_BUFFERS); 5341 if (n) { 5342 GLint i; 5343 n[1].i = count; 5344 if (count > MAX_DRAW_BUFFERS) 5345 count = MAX_DRAW_BUFFERS; 5346 for (i = 0; i < count; i++) { 5347 n[2 + i].e = buffers[i]; 5348 } 5349 } 5350 if (ctx->ExecuteFlag) { 5351 CALL_DrawBuffers(ctx->Exec, (count, buffers)); 5352 } 5353 } 5354 5355 static void GLAPIENTRY 5356 save_BindFragmentShaderATI(GLuint id) 5357 { 5358 GET_CURRENT_CONTEXT(ctx); 5359 Node *n; 5360 5361 n = alloc_instruction(ctx, OPCODE_BIND_FRAGMENT_SHADER_ATI, 1); 5362 if (n) { 5363 n[1].ui = id; 5364 } 5365 if (ctx->ExecuteFlag) { 5366 CALL_BindFragmentShaderATI(ctx->Exec, (id)); 5367 } 5368 } 5369 5370 static void GLAPIENTRY 5371 save_SetFragmentShaderConstantATI(GLuint dst, const GLfloat *value) 5372 { 5373 GET_CURRENT_CONTEXT(ctx); 5374 Node *n; 5375 5376 n = alloc_instruction(ctx, OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI, 5); 5377 if (n) { 5378 n[1].ui = dst; 5379 n[2].f = value[0]; 5380 n[3].f = value[1]; 5381 n[4].f = value[2]; 5382 n[5].f = value[3]; 5383 } 5384 if (ctx->ExecuteFlag) { 5385 CALL_SetFragmentShaderConstantATI(ctx->Exec, (dst, value)); 5386 } 5387 } 5388 5389 static void GLAPIENTRY 5390 save_Attr1fNV(GLenum attr, GLfloat x) 5391 { 5392 GET_CURRENT_CONTEXT(ctx); 5393 Node *n; 5394 SAVE_FLUSH_VERTICES(ctx); 5395 n = alloc_instruction(ctx, OPCODE_ATTR_1F_NV, 2); 5396 if (n) { 5397 n[1].e = attr; 5398 n[2].f = x; 5399 } 5400 5401 assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); 5402 ctx->ListState.ActiveAttribSize[attr] = 1; 5403 ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, 0, 0, 1); 5404 5405 if (ctx->ExecuteFlag) { 5406 CALL_VertexAttrib1fNV(ctx->Exec, (attr, x)); 5407 } 5408 } 5409 5410 static void GLAPIENTRY 5411 save_Attr2fNV(GLenum attr, GLfloat x, GLfloat y) 5412 { 5413 GET_CURRENT_CONTEXT(ctx); 5414 Node *n; 5415 SAVE_FLUSH_VERTICES(ctx); 5416 n = alloc_instruction(ctx, OPCODE_ATTR_2F_NV, 3); 5417 if (n) { 5418 n[1].e = attr; 5419 n[2].f = x; 5420 n[3].f = y; 5421 } 5422 5423 assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); 5424 ctx->ListState.ActiveAttribSize[attr] = 2; 5425 ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, 0, 1); 5426 5427 if (ctx->ExecuteFlag) { 5428 CALL_VertexAttrib2fNV(ctx->Exec, (attr, x, y)); 5429 } 5430 } 5431 5432 static void GLAPIENTRY 5433 save_Attr3fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z) 5434 { 5435 GET_CURRENT_CONTEXT(ctx); 5436 Node *n; 5437 SAVE_FLUSH_VERTICES(ctx); 5438 n = alloc_instruction(ctx, OPCODE_ATTR_3F_NV, 4); 5439 if (n) { 5440 n[1].e = attr; 5441 n[2].f = x; 5442 n[3].f = y; 5443 n[4].f = z; 5444 } 5445 5446 assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); 5447 ctx->ListState.ActiveAttribSize[attr] = 3; 5448 ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, 1); 5449 5450 if (ctx->ExecuteFlag) { 5451 CALL_VertexAttrib3fNV(ctx->Exec, (attr, x, y, z)); 5452 } 5453 } 5454 5455 static void GLAPIENTRY 5456 save_Attr4fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 5457 { 5458 GET_CURRENT_CONTEXT(ctx); 5459 Node *n; 5460 SAVE_FLUSH_VERTICES(ctx); 5461 n = alloc_instruction(ctx, OPCODE_ATTR_4F_NV, 5); 5462 if (n) { 5463 n[1].e = attr; 5464 n[2].f = x; 5465 n[3].f = y; 5466 n[4].f = z; 5467 n[5].f = w; 5468 } 5469 5470 assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); 5471 ctx->ListState.ActiveAttribSize[attr] = 4; 5472 ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, w); 5473 5474 if (ctx->ExecuteFlag) { 5475 CALL_VertexAttrib4fNV(ctx->Exec, (attr, x, y, z, w)); 5476 } 5477 } 5478 5479 5480 static void GLAPIENTRY 5481 save_Attr1fARB(GLenum attr, GLfloat x) 5482 { 5483 GET_CURRENT_CONTEXT(ctx); 5484 Node *n; 5485 SAVE_FLUSH_VERTICES(ctx); 5486 n = alloc_instruction(ctx, OPCODE_ATTR_1F_ARB, 2); 5487 if (n) { 5488 n[1].e = attr; 5489 n[2].f = x; 5490 } 5491 5492 assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); 5493 ctx->ListState.ActiveAttribSize[attr] = 1; 5494 ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, 0, 0, 1); 5495 5496 if (ctx->ExecuteFlag) { 5497 CALL_VertexAttrib1fARB(ctx->Exec, (attr, x)); 5498 } 5499 } 5500 5501 static void GLAPIENTRY 5502 save_Attr2fARB(GLenum attr, GLfloat x, GLfloat y) 5503 { 5504 GET_CURRENT_CONTEXT(ctx); 5505 Node *n; 5506 SAVE_FLUSH_VERTICES(ctx); 5507 n = alloc_instruction(ctx, OPCODE_ATTR_2F_ARB, 3); 5508 if (n) { 5509 n[1].e = attr; 5510 n[2].f = x; 5511 n[3].f = y; 5512 } 5513 5514 assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); 5515 ctx->ListState.ActiveAttribSize[attr] = 2; 5516 ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, 0, 1); 5517 5518 if (ctx->ExecuteFlag) { 5519 CALL_VertexAttrib2fARB(ctx->Exec, (attr, x, y)); 5520 } 5521 } 5522 5523 static void GLAPIENTRY 5524 save_Attr3fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z) 5525 { 5526 GET_CURRENT_CONTEXT(ctx); 5527 Node *n; 5528 SAVE_FLUSH_VERTICES(ctx); 5529 n = alloc_instruction(ctx, OPCODE_ATTR_3F_ARB, 4); 5530 if (n) { 5531 n[1].e = attr; 5532 n[2].f = x; 5533 n[3].f = y; 5534 n[4].f = z; 5535 } 5536 5537 assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); 5538 ctx->ListState.ActiveAttribSize[attr] = 3; 5539 ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, 1); 5540 5541 if (ctx->ExecuteFlag) { 5542 CALL_VertexAttrib3fARB(ctx->Exec, (attr, x, y, z)); 5543 } 5544 } 5545 5546 static void GLAPIENTRY 5547 save_Attr4fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 5548 { 5549 GET_CURRENT_CONTEXT(ctx); 5550 Node *n; 5551 SAVE_FLUSH_VERTICES(ctx); 5552 n = alloc_instruction(ctx, OPCODE_ATTR_4F_ARB, 5); 5553 if (n) { 5554 n[1].e = attr; 5555 n[2].f = x; 5556 n[3].f = y; 5557 n[4].f = z; 5558 n[5].f = w; 5559 } 5560 5561 assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); 5562 ctx->ListState.ActiveAttribSize[attr] = 4; 5563 ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, w); 5564 5565 if (ctx->ExecuteFlag) { 5566 CALL_VertexAttrib4fARB(ctx->Exec, (attr, x, y, z, w)); 5567 } 5568 } 5569 5570 5571 static void GLAPIENTRY 5572 save_EvalCoord1f(GLfloat x) 5573 { 5574 GET_CURRENT_CONTEXT(ctx); 5575 Node *n; 5576 SAVE_FLUSH_VERTICES(ctx); 5577 n = alloc_instruction(ctx, OPCODE_EVAL_C1, 1); 5578 if (n) { 5579 n[1].f = x; 5580 } 5581 if (ctx->ExecuteFlag) { 5582 CALL_EvalCoord1f(ctx->Exec, (x)); 5583 } 5584 } 5585 5586 static void GLAPIENTRY 5587 save_EvalCoord1fv(const GLfloat * v) 5588 { 5589 save_EvalCoord1f(v[0]); 5590 } 5591 5592 static void GLAPIENTRY 5593 save_EvalCoord2f(GLfloat x, GLfloat y) 5594 { 5595 GET_CURRENT_CONTEXT(ctx); 5596 Node *n; 5597 SAVE_FLUSH_VERTICES(ctx); 5598 n = alloc_instruction(ctx, OPCODE_EVAL_C2, 2); 5599 if (n) { 5600 n[1].f = x; 5601 n[2].f = y; 5602 } 5603 if (ctx->ExecuteFlag) { 5604 CALL_EvalCoord2f(ctx->Exec, (x, y)); 5605 } 5606 } 5607 5608 static void GLAPIENTRY 5609 save_EvalCoord2fv(const GLfloat * v) 5610 { 5611 save_EvalCoord2f(v[0], v[1]); 5612 } 5613 5614 5615 static void GLAPIENTRY 5616 save_EvalPoint1(GLint x) 5617 { 5618 GET_CURRENT_CONTEXT(ctx); 5619 Node *n; 5620 SAVE_FLUSH_VERTICES(ctx); 5621 n = alloc_instruction(ctx, OPCODE_EVAL_P1, 1); 5622 if (n) { 5623 n[1].i = x; 5624 } 5625 if (ctx->ExecuteFlag) { 5626 CALL_EvalPoint1(ctx->Exec, (x)); 5627 } 5628 } 5629 5630 static void GLAPIENTRY 5631 save_EvalPoint2(GLint x, GLint y) 5632 { 5633 GET_CURRENT_CONTEXT(ctx); 5634 Node *n; 5635 SAVE_FLUSH_VERTICES(ctx); 5636 n = alloc_instruction(ctx, OPCODE_EVAL_P2, 2); 5637 if (n) { 5638 n[1].i = x; 5639 n[2].i = y; 5640 } 5641 if (ctx->ExecuteFlag) { 5642 CALL_EvalPoint2(ctx->Exec, (x, y)); 5643 } 5644 } 5645 5646 static void GLAPIENTRY 5647 save_Indexf(GLfloat x) 5648 { 5649 save_Attr1fNV(VERT_ATTRIB_COLOR_INDEX, x); 5650 } 5651 5652 static void GLAPIENTRY 5653 save_Indexfv(const GLfloat * v) 5654 { 5655 save_Attr1fNV(VERT_ATTRIB_COLOR_INDEX, v[0]); 5656 } 5657 5658 static void GLAPIENTRY 5659 save_EdgeFlag(GLboolean x) 5660 { 5661 save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? 1.0f : 0.0f); 5662 } 5663 5664 5665 /** 5666 * Compare 'count' elements of vectors 'a' and 'b'. 5667 * \return GL_TRUE if equal, GL_FALSE if different. 5668 */ 5669 static inline GLboolean 5670 compare_vec(const GLfloat *a, const GLfloat *b, GLuint count) 5671 { 5672 return memcmp( a, b, count * sizeof(GLfloat) ) == 0; 5673 } 5674 5675 5676 /** 5677 * This glMaterial function is used for glMaterial calls that are outside 5678 * a glBegin/End pair. For glMaterial inside glBegin/End, see the VBO code. 5679 */ 5680 static void GLAPIENTRY 5681 save_Materialfv(GLenum face, GLenum pname, const GLfloat * param) 5682 { 5683 GET_CURRENT_CONTEXT(ctx); 5684 Node *n; 5685 int args, i; 5686 GLuint bitmask; 5687 5688 switch (face) { 5689 case GL_BACK: 5690 case GL_FRONT: 5691 case GL_FRONT_AND_BACK: 5692 break; 5693 default: 5694 _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(face)"); 5695 return; 5696 } 5697 5698 switch (pname) { 5699 case GL_EMISSION: 5700 case GL_AMBIENT: 5701 case GL_DIFFUSE: 5702 case GL_SPECULAR: 5703 case GL_AMBIENT_AND_DIFFUSE: 5704 args = 4; 5705 break; 5706 case GL_SHININESS: 5707 args = 1; 5708 break; 5709 case GL_COLOR_INDEXES: 5710 args = 3; 5711 break; 5712 default: 5713 _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(pname)"); 5714 return; 5715 } 5716 5717 if (ctx->ExecuteFlag) { 5718 CALL_Materialfv(ctx->Exec, (face, pname, param)); 5719 } 5720 5721 bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, NULL); 5722 5723 /* Try to eliminate redundant statechanges. Because it is legal to 5724 * call glMaterial even inside begin/end calls, don't need to worry 5725 * about ctx->Driver.CurrentSavePrimitive here. 5726 */ 5727 for (i = 0; i < MAT_ATTRIB_MAX; i++) { 5728 if (bitmask & (1 << i)) { 5729 if (ctx->ListState.ActiveMaterialSize[i] == args && 5730 compare_vec(ctx->ListState.CurrentMaterial[i], param, args)) { 5731 /* no change in material value */ 5732 bitmask &= ~(1 << i); 5733 } 5734 else { 5735 ctx->ListState.ActiveMaterialSize[i] = args; 5736 COPY_SZ_4V(ctx->ListState.CurrentMaterial[i], args, param); 5737 } 5738 } 5739 } 5740 5741 /* If this call has no effect, return early */ 5742 if (bitmask == 0) 5743 return; 5744 5745 SAVE_FLUSH_VERTICES(ctx); 5746 5747 n = alloc_instruction(ctx, OPCODE_MATERIAL, 6); 5748 if (n) { 5749 n[1].e = face; 5750 n[2].e = pname; 5751 for (i = 0; i < args; i++) 5752 n[3 + i].f = param[i]; 5753 } 5754 } 5755 5756 static void GLAPIENTRY 5757 save_Begin(GLenum mode) 5758 { 5759 GET_CURRENT_CONTEXT(ctx); 5760 5761 if (!_mesa_is_valid_prim_mode(ctx, mode)) { 5762 /* compile this error into the display list */ 5763 _mesa_compile_error(ctx, GL_INVALID_ENUM, "glBegin(mode)"); 5764 } 5765 else if (_mesa_inside_dlist_begin_end(ctx)) { 5766 /* compile this error into the display list */ 5767 _mesa_compile_error(ctx, GL_INVALID_OPERATION, "recursive glBegin"); 5768 } 5769 else { 5770 ctx->Driver.CurrentSavePrimitive = mode; 5771 5772 vbo_save_NotifyBegin(ctx, mode); 5773 } 5774 } 5775 5776 static void GLAPIENTRY 5777 save_End(void) 5778 { 5779 GET_CURRENT_CONTEXT(ctx); 5780 SAVE_FLUSH_VERTICES(ctx); 5781 (void) alloc_instruction(ctx, OPCODE_END, 0); 5782 ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END; 5783 if (ctx->ExecuteFlag) { 5784 CALL_End(ctx->Exec, ()); 5785 } 5786 } 5787 5788 static void GLAPIENTRY 5789 save_Rectf(GLfloat a, GLfloat b, GLfloat c, GLfloat d) 5790 { 5791 GET_CURRENT_CONTEXT(ctx); 5792 Node *n; 5793 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 5794 n = alloc_instruction(ctx, OPCODE_RECTF, 4); 5795 if (n) { 5796 n[1].f = a; 5797 n[2].f = b; 5798 n[3].f = c; 5799 n[4].f = d; 5800 } 5801 if (ctx->ExecuteFlag) { 5802 CALL_Rectf(ctx->Exec, (a, b, c, d)); 5803 } 5804 } 5805 5806 5807 static void GLAPIENTRY 5808 save_Vertex2f(GLfloat x, GLfloat y) 5809 { 5810 save_Attr2fNV(VERT_ATTRIB_POS, x, y); 5811 } 5812 5813 static void GLAPIENTRY 5814 save_Vertex2fv(const GLfloat * v) 5815 { 5816 save_Attr2fNV(VERT_ATTRIB_POS, v[0], v[1]); 5817 } 5818 5819 static void GLAPIENTRY 5820 save_Vertex3f(GLfloat x, GLfloat y, GLfloat z) 5821 { 5822 save_Attr3fNV(VERT_ATTRIB_POS, x, y, z); 5823 } 5824 5825 static void GLAPIENTRY 5826 save_Vertex3fv(const GLfloat * v) 5827 { 5828 save_Attr3fNV(VERT_ATTRIB_POS, v[0], v[1], v[2]); 5829 } 5830 5831 static void GLAPIENTRY 5832 save_Vertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) 5833 { 5834 save_Attr4fNV(VERT_ATTRIB_POS, x, y, z, w); 5835 } 5836 5837 static void GLAPIENTRY 5838 save_Vertex4fv(const GLfloat * v) 5839 { 5840 save_Attr4fNV(VERT_ATTRIB_POS, v[0], v[1], v[2], v[3]); 5841 } 5842 5843 static void GLAPIENTRY 5844 save_TexCoord1f(GLfloat x) 5845 { 5846 save_Attr1fNV(VERT_ATTRIB_TEX0, x); 5847 } 5848 5849 static void GLAPIENTRY 5850 save_TexCoord1fv(const GLfloat * v) 5851 { 5852 save_Attr1fNV(VERT_ATTRIB_TEX0, v[0]); 5853 } 5854 5855 static void GLAPIENTRY 5856 save_TexCoord2f(GLfloat x, GLfloat y) 5857 { 5858 save_Attr2fNV(VERT_ATTRIB_TEX0, x, y); 5859 } 5860 5861 static void GLAPIENTRY 5862 save_TexCoord2fv(const GLfloat * v) 5863 { 5864 save_Attr2fNV(VERT_ATTRIB_TEX0, v[0], v[1]); 5865 } 5866 5867 static void GLAPIENTRY 5868 save_TexCoord3f(GLfloat x, GLfloat y, GLfloat z) 5869 { 5870 save_Attr3fNV(VERT_ATTRIB_TEX0, x, y, z); 5871 } 5872 5873 static void GLAPIENTRY 5874 save_TexCoord3fv(const GLfloat * v) 5875 { 5876 save_Attr3fNV(VERT_ATTRIB_TEX0, v[0], v[1], v[2]); 5877 } 5878 5879 static void GLAPIENTRY 5880 save_TexCoord4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) 5881 { 5882 save_Attr4fNV(VERT_ATTRIB_TEX0, x, y, z, w); 5883 } 5884 5885 static void GLAPIENTRY 5886 save_TexCoord4fv(const GLfloat * v) 5887 { 5888 save_Attr4fNV(VERT_ATTRIB_TEX0, v[0], v[1], v[2], v[3]); 5889 } 5890 5891 static void GLAPIENTRY 5892 save_Normal3f(GLfloat x, GLfloat y, GLfloat z) 5893 { 5894 save_Attr3fNV(VERT_ATTRIB_NORMAL, x, y, z); 5895 } 5896 5897 static void GLAPIENTRY 5898 save_Normal3fv(const GLfloat * v) 5899 { 5900 save_Attr3fNV(VERT_ATTRIB_NORMAL, v[0], v[1], v[2]); 5901 } 5902 5903 static void GLAPIENTRY 5904 save_FogCoordfEXT(GLfloat x) 5905 { 5906 save_Attr1fNV(VERT_ATTRIB_FOG, x); 5907 } 5908 5909 static void GLAPIENTRY 5910 save_FogCoordfvEXT(const GLfloat * v) 5911 { 5912 save_Attr1fNV(VERT_ATTRIB_FOG, v[0]); 5913 } 5914 5915 static void GLAPIENTRY 5916 save_Color3f(GLfloat x, GLfloat y, GLfloat z) 5917 { 5918 save_Attr3fNV(VERT_ATTRIB_COLOR0, x, y, z); 5919 } 5920 5921 static void GLAPIENTRY 5922 save_Color3fv(const GLfloat * v) 5923 { 5924 save_Attr3fNV(VERT_ATTRIB_COLOR0, v[0], v[1], v[2]); 5925 } 5926 5927 static void GLAPIENTRY 5928 save_Color4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) 5929 { 5930 save_Attr4fNV(VERT_ATTRIB_COLOR0, x, y, z, w); 5931 } 5932 5933 static void GLAPIENTRY 5934 save_Color4fv(const GLfloat * v) 5935 { 5936 save_Attr4fNV(VERT_ATTRIB_COLOR0, v[0], v[1], v[2], v[3]); 5937 } 5938 5939 static void GLAPIENTRY 5940 save_SecondaryColor3fEXT(GLfloat x, GLfloat y, GLfloat z) 5941 { 5942 save_Attr3fNV(VERT_ATTRIB_COLOR1, x, y, z); 5943 } 5944 5945 static void GLAPIENTRY 5946 save_SecondaryColor3fvEXT(const GLfloat * v) 5947 { 5948 save_Attr3fNV(VERT_ATTRIB_COLOR1, v[0], v[1], v[2]); 5949 } 5950 5951 5952 /* Just call the respective ATTR for texcoord 5953 */ 5954 static void GLAPIENTRY 5955 save_MultiTexCoord1f(GLenum target, GLfloat x) 5956 { 5957 GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0; 5958 save_Attr1fNV(attr, x); 5959 } 5960 5961 static void GLAPIENTRY 5962 save_MultiTexCoord1fv(GLenum target, const GLfloat * v) 5963 { 5964 GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0; 5965 save_Attr1fNV(attr, v[0]); 5966 } 5967 5968 static void GLAPIENTRY 5969 save_MultiTexCoord2f(GLenum target, GLfloat x, GLfloat y) 5970 { 5971 GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0; 5972 save_Attr2fNV(attr, x, y); 5973 } 5974 5975 static void GLAPIENTRY 5976 save_MultiTexCoord2fv(GLenum target, const GLfloat * v) 5977 { 5978 GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0; 5979 save_Attr2fNV(attr, v[0], v[1]); 5980 } 5981 5982 static void GLAPIENTRY 5983 save_MultiTexCoord3f(GLenum target, GLfloat x, GLfloat y, GLfloat z) 5984 { 5985 GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0; 5986 save_Attr3fNV(attr, x, y, z); 5987 } 5988 5989 static void GLAPIENTRY 5990 save_MultiTexCoord3fv(GLenum target, const GLfloat * v) 5991 { 5992 GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0; 5993 save_Attr3fNV(attr, v[0], v[1], v[2]); 5994 } 5995 5996 static void GLAPIENTRY 5997 save_MultiTexCoord4f(GLenum target, GLfloat x, GLfloat y, 5998 GLfloat z, GLfloat w) 5999 { 6000 GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0; 6001 save_Attr4fNV(attr, x, y, z, w); 6002 } 6003 6004 static void GLAPIENTRY 6005 save_MultiTexCoord4fv(GLenum target, const GLfloat * v) 6006 { 6007 GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0; 6008 save_Attr4fNV(attr, v[0], v[1], v[2], v[3]); 6009 } 6010 6011 6012 /** 6013 * Record a GL_INVALID_VALUE error when an invalid vertex attribute 6014 * index is found. 6015 */ 6016 static void 6017 index_error(void) 6018 { 6019 GET_CURRENT_CONTEXT(ctx); 6020 _mesa_error(ctx, GL_INVALID_VALUE, "VertexAttribf(index)"); 6021 } 6022 6023 6024 6025 static void GLAPIENTRY 6026 save_VertexAttrib1fARB(GLuint index, GLfloat x) 6027 { 6028 if (index < MAX_VERTEX_GENERIC_ATTRIBS) 6029 save_Attr1fARB(index, x); 6030 else 6031 index_error(); 6032 } 6033 6034 static void GLAPIENTRY 6035 save_VertexAttrib1fvARB(GLuint index, const GLfloat * v) 6036 { 6037 if (index < MAX_VERTEX_GENERIC_ATTRIBS) 6038 save_Attr1fARB(index, v[0]); 6039 else 6040 index_error(); 6041 } 6042 6043 static void GLAPIENTRY 6044 save_VertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y) 6045 { 6046 if (index < MAX_VERTEX_GENERIC_ATTRIBS) 6047 save_Attr2fARB(index, x, y); 6048 else 6049 index_error(); 6050 } 6051 6052 static void GLAPIENTRY 6053 save_VertexAttrib2fvARB(GLuint index, const GLfloat * v) 6054 { 6055 if (index < MAX_VERTEX_GENERIC_ATTRIBS) 6056 save_Attr2fARB(index, v[0], v[1]); 6057 else 6058 index_error(); 6059 } 6060 6061 static void GLAPIENTRY 6062 save_VertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z) 6063 { 6064 if (index < MAX_VERTEX_GENERIC_ATTRIBS) 6065 save_Attr3fARB(index, x, y, z); 6066 else 6067 index_error(); 6068 } 6069 6070 static void GLAPIENTRY 6071 save_VertexAttrib3fvARB(GLuint index, const GLfloat * v) 6072 { 6073 if (index < MAX_VERTEX_GENERIC_ATTRIBS) 6074 save_Attr3fARB(index, v[0], v[1], v[2]); 6075 else 6076 index_error(); 6077 } 6078 6079 static void GLAPIENTRY 6080 save_VertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z, 6081 GLfloat w) 6082 { 6083 if (index < MAX_VERTEX_GENERIC_ATTRIBS) 6084 save_Attr4fARB(index, x, y, z, w); 6085 else 6086 index_error(); 6087 } 6088 6089 static void GLAPIENTRY 6090 save_VertexAttrib4fvARB(GLuint index, const GLfloat * v) 6091 { 6092 if (index < MAX_VERTEX_GENERIC_ATTRIBS) 6093 save_Attr4fARB(index, v[0], v[1], v[2], v[3]); 6094 else 6095 index_error(); 6096 } 6097 6098 static void GLAPIENTRY 6099 save_PrimitiveRestartNV(void) 6100 { 6101 /* Note: this is used when outside a glBegin/End pair in a display list */ 6102 GET_CURRENT_CONTEXT(ctx); 6103 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 6104 (void) alloc_instruction(ctx, OPCODE_PRIMITIVE_RESTART_NV, 0); 6105 if (ctx->ExecuteFlag) { 6106 CALL_PrimitiveRestartNV(ctx->Exec, ()); 6107 } 6108 } 6109 6110 6111 static void GLAPIENTRY 6112 save_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 6113 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 6114 GLbitfield mask, GLenum filter) 6115 { 6116 GET_CURRENT_CONTEXT(ctx); 6117 Node *n; 6118 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 6119 n = alloc_instruction(ctx, OPCODE_BLIT_FRAMEBUFFER, 10); 6120 if (n) { 6121 n[1].i = srcX0; 6122 n[2].i = srcY0; 6123 n[3].i = srcX1; 6124 n[4].i = srcY1; 6125 n[5].i = dstX0; 6126 n[6].i = dstY0; 6127 n[7].i = dstX1; 6128 n[8].i = dstY1; 6129 n[9].i = mask; 6130 n[10].e = filter; 6131 } 6132 if (ctx->ExecuteFlag) { 6133 CALL_BlitFramebuffer(ctx->Exec, (srcX0, srcY0, srcX1, srcY1, 6134 dstX0, dstY0, dstX1, dstY1, 6135 mask, filter)); 6136 } 6137 } 6138 6139 6140 /** GL_EXT_provoking_vertex */ 6141 static void GLAPIENTRY 6142 save_ProvokingVertexEXT(GLenum mode) 6143 { 6144 GET_CURRENT_CONTEXT(ctx); 6145 Node *n; 6146 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 6147 n = alloc_instruction(ctx, OPCODE_PROVOKING_VERTEX, 1); 6148 if (n) { 6149 n[1].e = mode; 6150 } 6151 if (ctx->ExecuteFlag) { 6152 /*CALL_ProvokingVertex(ctx->Exec, (mode));*/ 6153 _mesa_ProvokingVertex(mode); 6154 } 6155 } 6156 6157 6158 /** GL_EXT_transform_feedback */ 6159 static void GLAPIENTRY 6160 save_BeginTransformFeedback(GLenum mode) 6161 { 6162 GET_CURRENT_CONTEXT(ctx); 6163 Node *n; 6164 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 6165 n = alloc_instruction(ctx, OPCODE_BEGIN_TRANSFORM_FEEDBACK, 1); 6166 if (n) { 6167 n[1].e = mode; 6168 } 6169 if (ctx->ExecuteFlag) { 6170 CALL_BeginTransformFeedback(ctx->Exec, (mode)); 6171 } 6172 } 6173 6174 6175 /** GL_EXT_transform_feedback */ 6176 static void GLAPIENTRY 6177 save_EndTransformFeedback(void) 6178 { 6179 GET_CURRENT_CONTEXT(ctx); 6180 ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); 6181 (void) alloc_instruction(ctx, OPCODE_END_TRANSFORM_FEEDBACK, 0); 6182 if (ctx->ExecuteFlag) { 6183 CALL_EndTransformFeedback(ctx->Exec, ()); 6184 } 6185 } 6186 6187 static void GLAPIENTRY 6188 save_BindTransformFeedback(GLenum target, GLuint name) 6189 {