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