1 /* 2 * (C) Copyright IBM Corporation 2004, 2005 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sub license, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * IBM, 20 * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 */ 25 26 #include <inttypes.h> 27 #include <assert.h> 28 #include <string.h> 29 30 #include "glxclient.h" 31 #include "indirect.h" 32 #include <GL/glxproto.h> 33 #include "glxextensions.h" 34 #include "indirect_vertex_array.h" 35 #include "indirect_vertex_array_priv.h" 36 37 #define __GLX_PAD(n) (((n)+3) & ~3) 38 39 /** 40 * \file indirect_vertex_array.c 41 * Implement GLX protocol for vertex arrays and vertex buffer objects. 42 * 43 * The most important function in this fill is \c fill_array_info_cache. 44 * The \c array_state_vector contains a cache of the ARRAY_INFO data sent 45 * in the DrawArrays protocol. Certain operations, such as enabling or 46 * disabling an array, can invalidate this cache. \c fill_array_info_cache 47 * fills-in this data. Additionally, it examines the enabled state and 48 * other factors to determine what "version" of DrawArrays protocoal can be 49 * used. 50 * 51 * Current, only two versions of DrawArrays protocol are implemented. The 52 * first version is the "none" protocol. This is the fallback when the 53 * server does not support GL 1.1 / EXT_vertex_arrays. It is implemented 54 * by sending batches of immediate mode commands that are equivalent to the 55 * DrawArrays protocol. 56 * 57 * The other protocol that is currently implemented is the "old" protocol. 58 * This is the GL 1.1 DrawArrays protocol. The only difference between GL 59 * 1.1 and EXT_vertex_arrays is the opcode used for the DrawArrays command. 60 * This protocol is called "old" because the ARB is in the process of 61 * defining a new protocol, which will probably be called wither "new" or 62 * "vbo", to support multiple texture coordinate arrays, generic attributes, 63 * and vertex buffer objects. 64 * 65 * \author Ian Romanick <ian.d.romanick (at) intel.com> 66 */ 67 68 static void emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count); 69 static void emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count); 70 71 static void emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type, 72 const GLvoid * indices); 73 static void emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type, 74 const GLvoid * indices); 75 76 77 static GLubyte *emit_element_none(GLubyte * dst, 78 const struct array_state_vector *arrays, 79 unsigned index); 80 static GLubyte *emit_element_old(GLubyte * dst, 81 const struct array_state_vector *arrays, 82 unsigned index); 83 static struct array_state *get_array_entry(const struct array_state_vector 84 *arrays, GLenum key, 85 unsigned index); 86 static void fill_array_info_cache(struct array_state_vector *arrays); 87 static GLboolean validate_mode(struct glx_context * gc, GLenum mode); 88 static GLboolean validate_count(struct glx_context * gc, GLsizei count); 89 static GLboolean validate_type(struct glx_context * gc, GLenum type); 90 91 92 /** 93 * Table of sizes, in bytes, of a GL types. All of the type enums are be in 94 * the range 0x1400 - 0x140F. That includes types added by extensions (i.e., 95 * \c GL_HALF_FLOAT_NV). This elements of this table correspond to the 96 * type enums masked with 0x0f. 97 * 98 * \notes 99 * \c GL_HALF_FLOAT_NV is not included. Neither are \c GL_2_BYTES, 100 * \c GL_3_BYTES, or \c GL_4_BYTES. 101 */ 102 const GLuint __glXTypeSize_table[16] = { 103 1, 1, 2, 2, 4, 4, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0 104 }; 105 106 107 /** 108 * Free the per-context array state that was allocated with 109 * __glXInitVertexArrayState(). 110 */ 111 void 112 __glXFreeVertexArrayState(struct glx_context * gc) 113 { 114 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 115 struct array_state_vector *arrays = state->array_state; 116 117 if (arrays) { 118 if (arrays->stack) { 119 free(arrays->stack); 120 arrays->stack = NULL; 121 } 122 if (arrays->arrays) { 123 free(arrays->arrays); 124 arrays->arrays = NULL; 125 } 126 free(arrays); 127 state->array_state = NULL; 128 } 129 } 130 131 132 /** 133 * Initialize vertex array state of a GLX context. 134 * 135 * \param gc GLX context whose vertex array state is to be initialized. 136 * 137 * \warning 138 * This function may only be called after struct glx_context::gl_extension_bits, 139 * struct glx_context::server_minor, and __GLXcontext::server_major have been 140 * initialized. These values are used to determine what vertex arrays are 141 * supported. 142 * 143 * \bug 144 * Return values from malloc are not properly tested. 145 */ 146 void 147 __glXInitVertexArrayState(struct glx_context * gc) 148 { 149 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 150 struct array_state_vector *arrays; 151 152 unsigned array_count; 153 int texture_units = 1, vertex_program_attribs = 0; 154 unsigned i, j; 155 156 GLboolean got_fog = GL_FALSE; 157 GLboolean got_secondary_color = GL_FALSE; 158 159 160 arrays = calloc(1, sizeof(struct array_state_vector)); 161 state->array_state = arrays; 162 163 arrays->old_DrawArrays_possible = !state->NoDrawArraysProtocol; 164 arrays->new_DrawArrays_possible = GL_FALSE; 165 arrays->DrawArrays = NULL; 166 167 arrays->active_texture_unit = 0; 168 169 170 /* Determine how many arrays are actually needed. Only arrays that 171 * are supported by the server are create. For example, if the server 172 * supports only 2 texture units, then only 2 texture coordinate arrays 173 * are created. 174 * 175 * At the very least, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY, 176 * GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, and 177 * GL_EDGE_FLAG_ARRAY are supported. 178 */ 179 180 array_count = 5; 181 182 if (__glExtensionBitIsEnabled(gc, GL_EXT_fog_coord_bit) 183 || (gc->server_major > 1) || (gc->server_minor >= 4)) { 184 got_fog = GL_TRUE; 185 array_count++; 186 } 187 188 if (__glExtensionBitIsEnabled(gc, GL_EXT_secondary_color_bit) 189 || (gc->server_major > 1) || (gc->server_minor >= 4)) { 190 got_secondary_color = GL_TRUE; 191 array_count++; 192 } 193 194 if (__glExtensionBitIsEnabled(gc, GL_ARB_multitexture_bit) 195 || (gc->server_major > 1) || (gc->server_minor >= 3)) { 196 __indirect_glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texture_units); 197 } 198 199 if (__glExtensionBitIsEnabled(gc, GL_ARB_vertex_program_bit)) { 200 __indirect_glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, 201 GL_MAX_PROGRAM_ATTRIBS_ARB, 202 &vertex_program_attribs); 203 } 204 205 arrays->num_texture_units = texture_units; 206 arrays->num_vertex_program_attribs = vertex_program_attribs; 207 array_count += texture_units + vertex_program_attribs; 208 arrays->num_arrays = array_count; 209 arrays->arrays = calloc(array_count, sizeof(struct array_state)); 210 211 arrays->arrays[0].data_type = GL_FLOAT; 212 arrays->arrays[0].count = 3; 213 arrays->arrays[0].key = GL_NORMAL_ARRAY; 214 arrays->arrays[0].normalized = GL_TRUE; 215 arrays->arrays[0].old_DrawArrays_possible = GL_TRUE; 216 217 arrays->arrays[1].data_type = GL_FLOAT; 218 arrays->arrays[1].count = 4; 219 arrays->arrays[1].key = GL_COLOR_ARRAY; 220 arrays->arrays[1].normalized = GL_TRUE; 221 arrays->arrays[1].old_DrawArrays_possible = GL_TRUE; 222 223 arrays->arrays[2].data_type = GL_FLOAT; 224 arrays->arrays[2].count = 1; 225 arrays->arrays[2].key = GL_INDEX_ARRAY; 226 arrays->arrays[2].old_DrawArrays_possible = GL_TRUE; 227 228 arrays->arrays[3].data_type = GL_UNSIGNED_BYTE; 229 arrays->arrays[3].count = 1; 230 arrays->arrays[3].key = GL_EDGE_FLAG_ARRAY; 231 arrays->arrays[3].old_DrawArrays_possible = GL_TRUE; 232 233 for (i = 0; i < texture_units; i++) { 234 arrays->arrays[4 + i].data_type = GL_FLOAT; 235 arrays->arrays[4 + i].count = 4; 236 arrays->arrays[4 + i].key = GL_TEXTURE_COORD_ARRAY; 237 238 arrays->arrays[4 + i].old_DrawArrays_possible = (i == 0); 239 arrays->arrays[4 + i].index = i; 240 241 arrays->arrays[4 + i].header[1] = i + GL_TEXTURE0; 242 } 243 244 i = 4 + texture_units; 245 246 if (got_fog) { 247 arrays->arrays[i].data_type = GL_FLOAT; 248 arrays->arrays[i].count = 1; 249 arrays->arrays[i].key = GL_FOG_COORDINATE_ARRAY; 250 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE; 251 i++; 252 } 253 254 if (got_secondary_color) { 255 arrays->arrays[i].data_type = GL_FLOAT; 256 arrays->arrays[i].count = 3; 257 arrays->arrays[i].key = GL_SECONDARY_COLOR_ARRAY; 258 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE; 259 arrays->arrays[i].normalized = GL_TRUE; 260 i++; 261 } 262 263 264 for (j = 0; j < vertex_program_attribs; j++) { 265 const unsigned idx = (vertex_program_attribs - (j + 1)); 266 267 268 arrays->arrays[idx + i].data_type = GL_FLOAT; 269 arrays->arrays[idx + i].count = 4; 270 arrays->arrays[idx + i].key = GL_VERTEX_ATTRIB_ARRAY_POINTER; 271 272 arrays->arrays[idx + i].old_DrawArrays_possible = 0; 273 arrays->arrays[idx + i].index = idx; 274 275 arrays->arrays[idx + i].header[1] = idx; 276 } 277 278 i += vertex_program_attribs; 279 280 281 /* Vertex array *must* be last becuase of the way that 282 * emit_DrawArrays_none works. 283 */ 284 285 arrays->arrays[i].data_type = GL_FLOAT; 286 arrays->arrays[i].count = 4; 287 arrays->arrays[i].key = GL_VERTEX_ARRAY; 288 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE; 289 290 assert((i + 1) == arrays->num_arrays); 291 292 arrays->stack_index = 0; 293 arrays->stack = malloc(sizeof(struct array_stack_state) 294 * arrays->num_arrays 295 * __GL_CLIENT_ATTRIB_STACK_DEPTH); 296 } 297 298 299 /** 300 * Calculate the size of a single vertex for the "none" protocol. This is 301 * essentially the size of all the immediate-mode commands required to 302 * implement the enabled vertex arrays. 303 */ 304 static size_t 305 calculate_single_vertex_size_none(const struct array_state_vector *arrays) 306 { 307 size_t single_vertex_size = 0; 308 unsigned i; 309 310 311 for (i = 0; i < arrays->num_arrays; i++) { 312 if (arrays->arrays[i].enabled) { 313 single_vertex_size += ((uint16_t *) arrays->arrays[i].header)[0]; 314 } 315 } 316 317 return single_vertex_size; 318 } 319 320 321 /** 322 * Emit a single element using non-DrawArrays protocol. 323 */ 324 GLubyte * 325 emit_element_none(GLubyte * dst, 326 const struct array_state_vector * arrays, unsigned index) 327 { 328 unsigned i; 329 330 331 for (i = 0; i < arrays->num_arrays; i++) { 332 if (arrays->arrays[i].enabled) { 333 const size_t offset = index * arrays->arrays[i].true_stride; 334 335 /* The generic attributes can have more data than is in the 336 * elements. This is because a vertex array can be a 2 element, 337 * normalized, unsigned short, but the "closest" immediate mode 338 * protocol is for a 4Nus. Since the sizes are small, the 339 * performance impact on modern processors should be negligible. 340 */ 341 (void) memset(dst, 0, ((uint16_t *) arrays->arrays[i].header)[0]); 342 343 (void) memcpy(dst, arrays->arrays[i].header, 344 arrays->arrays[i].header_size); 345 346 dst += arrays->arrays[i].header_size; 347 348 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset, 349 arrays->arrays[i].element_size); 350 351 dst += __GLX_PAD(arrays->arrays[i].element_size); 352 } 353 } 354 355 return dst; 356 } 357 358 359 /** 360 * Emit a single element using "old" DrawArrays protocol from 361 * EXT_vertex_arrays / OpenGL 1.1. 362 */ 363 GLubyte * 364 emit_element_old(GLubyte * dst, 365 const struct array_state_vector * arrays, unsigned index) 366 { 367 unsigned i; 368 369 370 for (i = 0; i < arrays->num_arrays; i++) { 371 if (arrays->arrays[i].enabled) { 372 const size_t offset = index * arrays->arrays[i].true_stride; 373 374 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset, 375 arrays->arrays[i].element_size); 376 377 dst += __GLX_PAD(arrays->arrays[i].element_size); 378 } 379 } 380 381 return dst; 382 } 383 384 385 struct array_state * 386 get_array_entry(const struct array_state_vector *arrays, 387 GLenum key, unsigned index) 388 { 389 unsigned i; 390 391 for (i = 0; i < arrays->num_arrays; i++) { 392 if ((arrays->arrays[i].key == key) 393 && (arrays->arrays[i].index == index)) { 394 return &arrays->arrays[i]; 395 } 396 } 397 398 return NULL; 399 } 400 401 402 static GLboolean 403 allocate_array_info_cache(struct array_state_vector *arrays, 404 size_t required_size) 405 { 406 #define MAX_HEADER_SIZE 20 407 if (arrays->array_info_cache_buffer_size < required_size) { 408 GLubyte *temp = realloc(arrays->array_info_cache_base, 409 required_size + MAX_HEADER_SIZE); 410 411 if (temp == NULL) { 412 return GL_FALSE; 413 } 414 415 arrays->array_info_cache_base = temp; 416 arrays->array_info_cache = temp + MAX_HEADER_SIZE; 417 arrays->array_info_cache_buffer_size = required_size; 418 } 419 420 arrays->array_info_cache_size = required_size; 421 return GL_TRUE; 422 } 423 424 425 /** 426 */ 427 void 428 fill_array_info_cache(struct array_state_vector *arrays) 429 { 430 GLboolean old_DrawArrays_possible; 431 unsigned i; 432 433 434 /* Determine how many arrays are enabled. 435 */ 436 437 arrays->enabled_client_array_count = 0; 438 old_DrawArrays_possible = arrays->old_DrawArrays_possible; 439 for (i = 0; i < arrays->num_arrays; i++) { 440 if (arrays->arrays[i].enabled) { 441 arrays->enabled_client_array_count++; 442 old_DrawArrays_possible &= arrays->arrays[i].old_DrawArrays_possible; 443 } 444 } 445 446 if (arrays->new_DrawArrays_possible) { 447 assert(!arrays->new_DrawArrays_possible); 448 } 449 else if (old_DrawArrays_possible) { 450 const size_t required_size = arrays->enabled_client_array_count * 12; 451 uint32_t *info; 452 453 454 if (!allocate_array_info_cache(arrays, required_size)) { 455 return; 456 } 457 458 459 info = (uint32_t *) arrays->array_info_cache; 460 for (i = 0; i < arrays->num_arrays; i++) { 461 if (arrays->arrays[i].enabled) { 462 *(info++) = arrays->arrays[i].data_type; 463 *(info++) = arrays->arrays[i].count; 464 *(info++) = arrays->arrays[i].key; 465 } 466 } 467 468 arrays->DrawArrays = emit_DrawArrays_old; 469 arrays->DrawElements = emit_DrawElements_old; 470 } 471 else { 472 arrays->DrawArrays = emit_DrawArrays_none; 473 arrays->DrawElements = emit_DrawElements_none; 474 } 475 476 arrays->array_info_cache_valid = GL_TRUE; 477 } 478 479 480 /** 481 * Emit a \c glDrawArrays command using the "none" protocol. That is, 482 * emit immediate-mode commands that are equivalent to the requiested 483 * \c glDrawArrays command. This is used with servers that don't support 484 * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where 485 * vertex state is enabled that is not compatible with that protocol. 486 */ 487 void 488 emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count) 489 { 490 struct glx_context *gc = __glXGetCurrentContext(); 491 const __GLXattribute *state = 492 (const __GLXattribute *) (gc->client_state_private); 493 struct array_state_vector *arrays = state->array_state; 494 495 size_t single_vertex_size; 496 GLubyte *pc; 497 unsigned i; 498 static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin }; 499 static const uint16_t end_cmd[2] = { 4, X_GLrop_End }; 500 501 502 single_vertex_size = calculate_single_vertex_size_none(arrays); 503 504 pc = gc->pc; 505 506 (void) memcpy(pc, begin_cmd, 4); 507 *(int *) (pc + 4) = mode; 508 509 pc += 8; 510 511 for (i = 0; i < count; i++) { 512 if ((pc + single_vertex_size) >= gc->bufEnd) { 513 pc = __glXFlushRenderBuffer(gc, pc); 514 } 515 516 pc = emit_element_none(pc, arrays, first + i); 517 } 518 519 if ((pc + 4) >= gc->bufEnd) { 520 pc = __glXFlushRenderBuffer(gc, pc); 521 } 522 523 (void) memcpy(pc, end_cmd, 4); 524 pc += 4; 525 526 gc->pc = pc; 527 if (gc->pc > gc->limit) { 528 (void) __glXFlushRenderBuffer(gc, gc->pc); 529 } 530 } 531 532 533 /** 534 * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays 535 * protocol. 536 * 537 * \param gc GLX context. 538 * \param arrays Array state. 539 * \param elements_per_request Location to store the number of elements that 540 * can fit in a single Render / RenderLarge 541 * command. 542 * \param total_request Total number of requests for a RenderLarge 543 * command. If a Render command is used, this 544 * will be zero. 545 * \param mode Drawing mode. 546 * \param count Number of vertices. 547 * 548 * \returns 549 * A pointer to the buffer for array data. 550 */ 551 static GLubyte * 552 emit_DrawArrays_header_old(struct glx_context * gc, 553 struct array_state_vector *arrays, 554 size_t * elements_per_request, 555 unsigned int *total_requests, 556 GLenum mode, GLsizei count) 557 { 558 size_t command_size; 559 size_t single_vertex_size; 560 const unsigned header_size = 16; 561 unsigned i; 562 GLubyte *pc; 563 564 565 /* Determine the size of the whole command. This includes the header, 566 * the ARRAY_INFO data and the array data. Once this size is calculated, 567 * it will be known whether a Render or RenderLarge command is needed. 568 */ 569 570 single_vertex_size = 0; 571 for (i = 0; i < arrays->num_arrays; i++) { 572 if (arrays->arrays[i].enabled) { 573 single_vertex_size += __GLX_PAD(arrays->arrays[i].element_size); 574 } 575 } 576 577 command_size = arrays->array_info_cache_size + header_size 578 + (single_vertex_size * count); 579 580 581 /* Write the header for either a Render command or a RenderLarge 582 * command. After the header is written, write the ARRAY_INFO data. 583 */ 584 585 if (command_size > gc->maxSmallRenderCommandSize) { 586 /* maxSize is the maximum amount of data can be stuffed into a single 587 * packet. sz_xGLXRenderReq is added because bufSize is the maximum 588 * packet size minus sz_xGLXRenderReq. 589 */ 590 const size_t maxSize = (gc->bufSize + sz_xGLXRenderReq) 591 - sz_xGLXRenderLargeReq; 592 unsigned vertex_requests; 593 594 595 /* Calculate the number of data packets that will be required to send 596 * the whole command. To do this, the number of verticies that 597 * will fit in a single buffer must be calculated. 598 * 599 * The important value here is elements_per_request. This is the 600 * number of complete array elements that will fit in a single 601 * buffer. There may be some wasted space at the end of the buffer, 602 * but splitting elements across buffer boundries would be painful. 603 */ 604 605 elements_per_request[0] = maxSize / single_vertex_size; 606 607 vertex_requests = (count + elements_per_request[0] - 1) 608 / elements_per_request[0]; 609 610 *total_requests = vertex_requests + 1; 611 612 613 __glXFlushRenderBuffer(gc, gc->pc); 614 615 command_size += 4; 616 617 pc = ((GLubyte *) arrays->array_info_cache) - (header_size + 4); 618 *(uint32_t *) (pc + 0) = command_size; 619 *(uint32_t *) (pc + 4) = X_GLrop_DrawArrays; 620 *(uint32_t *) (pc + 8) = count; 621 *(uint32_t *) (pc + 12) = arrays->enabled_client_array_count; 622 *(uint32_t *) (pc + 16) = mode; 623 624 __glXSendLargeChunk(gc, 1, *total_requests, pc, 625 header_size + 4 + arrays->array_info_cache_size); 626 627 pc = gc->pc; 628 } 629 else { 630 if ((gc->pc + command_size) >= gc->bufEnd) { 631 (void) __glXFlushRenderBuffer(gc, gc->pc); 632 } 633 634 pc = gc->pc; 635 *(uint16_t *) (pc + 0) = command_size; 636 *(uint16_t *) (pc + 2) = X_GLrop_DrawArrays; 637 *(uint32_t *) (pc + 4) = count; 638 *(uint32_t *) (pc + 8) = arrays->enabled_client_array_count; 639 *(uint32_t *) (pc + 12) = mode; 640 641 pc += header_size; 642 643 (void) memcpy(pc, arrays->array_info_cache, 644 arrays->array_info_cache_size); 645 pc += arrays->array_info_cache_size; 646 647 *elements_per_request = count; 648 *total_requests = 0; 649 } 650 651 652 return pc; 653 } 654 655 656 /** 657 */ 658 void 659 emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count) 660 { 661 struct glx_context *gc = __glXGetCurrentContext(); 662 const __GLXattribute *state = 663 (const __GLXattribute *) (gc->client_state_private); 664 struct array_state_vector *arrays = state->array_state; 665 666 GLubyte *pc; 667 size_t elements_per_request; 668 unsigned total_requests = 0; 669 unsigned i; 670 size_t total_sent = 0; 671 672 673 pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request, 674 &total_requests, mode, count); 675 676 677 /* Write the arrays. 678 */ 679 680 if (total_requests == 0) { 681 assert(elements_per_request >= count); 682 683 for (i = 0; i < count; i++) { 684 pc = emit_element_old(pc, arrays, i + first); 685 } 686 687 assert(pc <= gc->bufEnd); 688 689 gc->pc = pc; 690 if (gc->pc > gc->limit) { 691 (void) __glXFlushRenderBuffer(gc, gc->pc); 692 } 693 } 694 else { 695 unsigned req; 696 697 698 for (req = 2; req <= total_requests; req++) { 699 if (count < elements_per_request) { 700 elements_per_request = count; 701 } 702 703 pc = gc->pc; 704 for (i = 0; i < elements_per_request; i++) { 705 pc = emit_element_old(pc, arrays, i + first); 706 } 707 708 first += elements_per_request; 709 710 total_sent += (size_t) (pc - gc->pc); 711 __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc); 712 713 count -= elements_per_request; 714 } 715 } 716 } 717 718 719 void 720 emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type, 721 const GLvoid * indices) 722 { 723 struct glx_context *gc = __glXGetCurrentContext(); 724 const __GLXattribute *state = 725 (const __GLXattribute *) (gc->client_state_private); 726 struct array_state_vector *arrays = state->array_state; 727 static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin }; 728 static const uint16_t end_cmd[2] = { 4, X_GLrop_End }; 729 730 GLubyte *pc; 731 size_t single_vertex_size; 732 unsigned i; 733 734 735 single_vertex_size = calculate_single_vertex_size_none(arrays); 736 737 738 if ((gc->pc + single_vertex_size) >= gc->bufEnd) { 739 gc->pc = __glXFlushRenderBuffer(gc, gc->pc); 740 } 741 742 pc = gc->pc; 743 744 (void) memcpy(pc, begin_cmd, 4); 745 *(int *) (pc + 4) = mode; 746 747 pc += 8; 748 749 for (i = 0; i < count; i++) { 750 unsigned index = 0; 751 752 if ((pc + single_vertex_size) >= gc->bufEnd) { 753 pc = __glXFlushRenderBuffer(gc, pc); 754 } 755 756 switch (type) { 757 case GL_UNSIGNED_INT: 758 index = (unsigned) (((GLuint *) indices)[i]); 759 break; 760 case GL_UNSIGNED_SHORT: 761 index = (unsigned) (((GLushort *) indices)[i]); 762 break; 763 case GL_UNSIGNED_BYTE: 764 index = (unsigned) (((GLubyte *) indices)[i]); 765 break; 766 } 767 pc = emit_element_none(pc, arrays, index); 768 } 769 770 if ((pc + 4) >= gc->bufEnd) { 771 pc = __glXFlushRenderBuffer(gc, pc); 772 } 773 774 (void) memcpy(pc, end_cmd, 4); 775 pc += 4; 776 777 gc->pc = pc; 778 if (gc->pc > gc->limit) { 779 (void) __glXFlushRenderBuffer(gc, gc->pc); 780 } 781 } 782 783 784 /** 785 */ 786 void 787 emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type, 788 const GLvoid * indices) 789 { 790 struct glx_context *gc = __glXGetCurrentContext(); 791 const __GLXattribute *state = 792 (const __GLXattribute *) (gc->client_state_private); 793 struct array_state_vector *arrays = state->array_state; 794 795 GLubyte *pc; 796 size_t elements_per_request; 797 unsigned total_requests = 0; 798 unsigned i; 799 unsigned req; 800 unsigned req_element = 0; 801 802 803 pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request, 804 &total_requests, mode, count); 805 806 807 /* Write the arrays. 808 */ 809 810 req = 2; 811 while (count > 0) { 812 if (count < elements_per_request) { 813 elements_per_request = count; 814 } 815 816 switch (type) { 817 case GL_UNSIGNED_INT:{ 818 const GLuint *ui_ptr = (const GLuint *) indices + req_element; 819 820 for (i = 0; i < elements_per_request; i++) { 821 const GLint index = (GLint) * (ui_ptr++); 822 pc = emit_element_old(pc, arrays, index); 823 } 824 break; 825 } 826 case GL_UNSIGNED_SHORT:{ 827 const GLushort *us_ptr = (const GLushort *) indices + req_element; 828 829 for (i = 0; i < elements_per_request; i++) { 830 const GLint index = (GLint) * (us_ptr++); 831 pc = emit_element_old(pc, arrays, index); 832 } 833 break; 834 } 835 case GL_UNSIGNED_BYTE:{ 836 const GLubyte *ub_ptr = (const GLubyte *) indices + req_element; 837 838 for (i = 0; i < elements_per_request; i++) { 839 const GLint index = (GLint) * (ub_ptr++); 840 pc = emit_element_old(pc, arrays, index); 841 } 842 break; 843 } 844 } 845 846 if (total_requests != 0) { 847 __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc); 848 pc = gc->pc; 849 req++; 850 } 851 852 count -= elements_per_request; 853 req_element += elements_per_request; 854 } 855 856 857 assert((total_requests == 0) || ((req - 1) == total_requests)); 858 859 if (total_requests == 0) { 860 assert(pc <= gc->bufEnd); 861 862 gc->pc = pc; 863 if (gc->pc > gc->limit) { 864 (void) __glXFlushRenderBuffer(gc, gc->pc); 865 } 866 } 867 } 868 869 870 /** 871 * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid. 872 * If it is not valid, then an error code is set in the GLX context. 873 * 874 * \returns 875 * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not. 876 */ 877 static GLboolean 878 validate_mode(struct glx_context * gc, GLenum mode) 879 { 880 switch (mode) { 881 case GL_POINTS: 882 case GL_LINE_STRIP: 883 case GL_LINE_LOOP: 884 case GL_LINES: 885 case GL_TRIANGLE_STRIP: 886 case GL_TRIANGLE_FAN: 887 case GL_TRIANGLES: 888 case GL_QUAD_STRIP: 889 case GL_QUADS: 890 case GL_POLYGON: 891 break; 892 default: 893 __glXSetError(gc, GL_INVALID_ENUM); 894 return GL_FALSE; 895 } 896 897 return GL_TRUE; 898 } 899 900 901 /** 902 * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid. 903 * A value less than zero is invalid and will result in \c GL_INVALID_VALUE 904 * being set. A value of zero will not result in an error being set, but 905 * will result in \c GL_FALSE being returned. 906 * 907 * \returns 908 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not. 909 */ 910 static GLboolean 911 validate_count(struct glx_context * gc, GLsizei count) 912 { 913 if (count < 0) { 914 __glXSetError(gc, GL_INVALID_VALUE); 915 } 916 917 return (count > 0); 918 } 919 920 921 /** 922 * Validate that the \c type parameter to \c glDrawElements, et. al. is 923 * valid. Only \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, and 924 * \c GL_UNSIGNED_INT are valid. 925 * 926 * \returns 927 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not. 928 */ 929 static GLboolean 930 validate_type(struct glx_context * gc, GLenum type) 931 { 932 switch (type) { 933 case GL_UNSIGNED_INT: 934 case GL_UNSIGNED_SHORT: 935 case GL_UNSIGNED_BYTE: 936 return GL_TRUE; 937 default: 938 __glXSetError(gc, GL_INVALID_ENUM); 939 return GL_FALSE; 940 } 941 } 942 943 944 void 945 __indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count) 946 { 947 struct glx_context *gc = __glXGetCurrentContext(); 948 const __GLXattribute *state = 949 (const __GLXattribute *) (gc->client_state_private); 950 struct array_state_vector *arrays = state->array_state; 951 952 953 if (validate_mode(gc, mode) && validate_count(gc, count)) { 954 if (!arrays->array_info_cache_valid) { 955 fill_array_info_cache(arrays); 956 } 957 958 arrays->DrawArrays(mode, first, count); 959 } 960 } 961 962 963 void 964 __indirect_glArrayElement(GLint index) 965 { 966 struct glx_context *gc = __glXGetCurrentContext(); 967 const __GLXattribute *state = 968 (const __GLXattribute *) (gc->client_state_private); 969 struct array_state_vector *arrays = state->array_state; 970 971 size_t single_vertex_size; 972 973 974 single_vertex_size = calculate_single_vertex_size_none(arrays); 975 976 if ((gc->pc + single_vertex_size) >= gc->bufEnd) { 977 gc->pc = __glXFlushRenderBuffer(gc, gc->pc); 978 } 979 980 gc->pc = emit_element_none(gc->pc, arrays, index); 981 982 if (gc->pc > gc->limit) { 983 (void) __glXFlushRenderBuffer(gc, gc->pc); 984 } 985 } 986 987 988 void 989 __indirect_glDrawElements(GLenum mode, GLsizei count, GLenum type, 990 const GLvoid * indices) 991 { 992 struct glx_context *gc = __glXGetCurrentContext(); 993 const __GLXattribute *state = 994 (const __GLXattribute *) (gc->client_state_private); 995 struct array_state_vector *arrays = state->array_state; 996 997 998 if (validate_mode(gc, mode) && validate_count(gc, count) 999 && validate_type(gc, type)) { 1000 if (!arrays->array_info_cache_valid) { 1001 fill_array_info_cache(arrays); 1002 } 1003 1004 arrays->DrawElements(mode, count, type, indices); 1005 } 1006 } 1007 1008 1009 void 1010 __indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end, 1011 GLsizei count, GLenum type, 1012 const GLvoid * indices) 1013 { 1014 struct glx_context *gc = __glXGetCurrentContext(); 1015 const __GLXattribute *state = 1016 (const __GLXattribute *) (gc->client_state_private); 1017 struct array_state_vector *arrays = state->array_state; 1018 1019 1020 if (validate_mode(gc, mode) && validate_count(gc, count) 1021 && validate_type(gc, type)) { 1022 if (end < start) { 1023 __glXSetError(gc, GL_INVALID_VALUE); 1024 return; 1025 } 1026 1027 if (!arrays->array_info_cache_valid) { 1028 fill_array_info_cache(arrays); 1029 } 1030 1031 arrays->DrawElements(mode, count, type, indices); 1032 } 1033 } 1034 1035 1036 void 1037 __indirect_glMultiDrawArraysEXT(GLenum mode, const GLint *first, 1038 const GLsizei *count, GLsizei primcount) 1039 { 1040 struct glx_context *gc = __glXGetCurrentContext(); 1041 const __GLXattribute *state = 1042 (const __GLXattribute *) (gc->client_state_private); 1043 struct array_state_vector *arrays = state->array_state; 1044 GLsizei i; 1045 1046 1047 if (validate_mode(gc, mode)) { 1048 if (!arrays->array_info_cache_valid) { 1049 fill_array_info_cache(arrays); 1050 } 1051 1052 for (i = 0; i < primcount; i++) { 1053 if (validate_count(gc, count[i])) { 1054 arrays->DrawArrays(mode, first[i], count[i]); 1055 } 1056 } 1057 } 1058 } 1059 1060 1061 void 1062 __indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei * count, 1063 GLenum type, const GLvoid ** indices, 1064 GLsizei primcount) 1065 { 1066 struct glx_context *gc = __glXGetCurrentContext(); 1067 const __GLXattribute *state = 1068 (const __GLXattribute *) (gc->client_state_private); 1069 struct array_state_vector *arrays = state->array_state; 1070 GLsizei i; 1071 1072 1073 if (validate_mode(gc, mode) && validate_type(gc, type)) { 1074 if (!arrays->array_info_cache_valid) { 1075 fill_array_info_cache(arrays); 1076 } 1077 1078 for (i = 0; i < primcount; i++) { 1079 if (validate_count(gc, count[i])) { 1080 arrays->DrawElements(mode, count[i], type, indices[i]); 1081 } 1082 } 1083 } 1084 } 1085 1086 1087 #define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, NORMALIZED, HDR_SIZE, OPCODE) \ 1088 do { \ 1089 (a)->data = PTR; \ 1090 (a)->data_type = TYPE; \ 1091 (a)->user_stride = STRIDE; \ 1092 (a)->count = COUNT; \ 1093 (a)->normalized = NORMALIZED; \ 1094 \ 1095 (a)->element_size = __glXTypeSize( TYPE ) * COUNT; \ 1096 (a)->true_stride = (STRIDE == 0) \ 1097 ? (a)->element_size : STRIDE; \ 1098 \ 1099 (a)->header_size = HDR_SIZE; \ 1100 ((uint16_t *) (a)->header)[0] = __GLX_PAD((a)->header_size + (a)->element_size); \ 1101 ((uint16_t *) (a)->header)[1] = OPCODE; \ 1102 } while(0) 1103 1104 1105 void 1106 __indirect_glVertexPointer(GLint size, GLenum type, GLsizei stride, 1107 const GLvoid * pointer) 1108 { 1109 static const uint16_t short_ops[5] = { 1110 0, 0, X_GLrop_Vertex2sv, X_GLrop_Vertex3sv, X_GLrop_Vertex4sv 1111 }; 1112 static const uint16_t int_ops[5] = { 1113 0, 0, X_GLrop_Vertex2iv, X_GLrop_Vertex3iv, X_GLrop_Vertex4iv 1114 }; 1115 static const uint16_t float_ops[5] = { 1116 0, 0, X_GLrop_Vertex2fv, X_GLrop_Vertex3fv, X_GLrop_Vertex4fv 1117 }; 1118 static const uint16_t double_ops[5] = { 1119 0, 0, X_GLrop_Vertex2dv, X_GLrop_Vertex3dv, X_GLrop_Vertex4dv 1120 }; 1121 uint16_t opcode; 1122 struct glx_context *gc = __glXGetCurrentContext(); 1123 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 1124 struct array_state_vector *arrays = state->array_state; 1125 struct array_state *a; 1126 1127 1128 if (size < 2 || size > 4 || stride < 0) { 1129 __glXSetError(gc, GL_INVALID_VALUE); 1130 return; 1131 } 1132 1133 switch (type) { 1134 case GL_SHORT: 1135 opcode = short_ops[size]; 1136 break; 1137 case GL_INT: 1138 opcode = int_ops[size]; 1139 break; 1140 case GL_FLOAT: 1141 opcode = float_ops[size]; 1142 break; 1143 case GL_DOUBLE: 1144 opcode = double_ops[size]; 1145 break; 1146 default: 1147 __glXSetError(gc, GL_INVALID_ENUM); 1148 return; 1149 } 1150 1151 a = get_array_entry(arrays, GL_VERTEX_ARRAY, 0); 1152 assert(a != NULL); 1153 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE, 4, 1154 opcode); 1155 1156 if (a->enabled) { 1157 arrays->array_info_cache_valid = GL_FALSE; 1158 } 1159 } 1160 1161 1162 void 1163 __indirect_glNormalPointer(GLenum type, GLsizei stride, 1164 const GLvoid * pointer) 1165 { 1166 uint16_t opcode; 1167 struct glx_context *gc = __glXGetCurrentContext(); 1168 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 1169 struct array_state_vector *arrays = state->array_state; 1170 struct array_state *a; 1171 1172 1173 if (stride < 0) { 1174 __glXSetError(gc, GL_INVALID_VALUE); 1175 return; 1176 } 1177 1178 switch (type) { 1179 case GL_BYTE: 1180 opcode = X_GLrop_Normal3bv; 1181 break; 1182 case GL_SHORT: 1183 opcode = X_GLrop_Normal3sv; 1184 break; 1185 case GL_INT: 1186 opcode = X_GLrop_Normal3iv; 1187 break; 1188 case GL_FLOAT: 1189 opcode = X_GLrop_Normal3fv; 1190 break; 1191 case GL_DOUBLE: 1192 opcode = X_GLrop_Normal3dv; 1193 break; 1194 default: 1195 __glXSetError(gc, GL_INVALID_ENUM); 1196 return; 1197 } 1198 1199 a = get_array_entry(arrays, GL_NORMAL_ARRAY, 0); 1200 assert(a != NULL); 1201 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 3, GL_TRUE, 4, opcode); 1202 1203 if (a->enabled) { 1204 arrays->array_info_cache_valid = GL_FALSE; 1205 } 1206 } 1207 1208 1209 void 1210 __indirect_glColorPointer(GLint size, GLenum type, GLsizei stride, 1211 const GLvoid * pointer) 1212 { 1213 static const uint16_t byte_ops[5] = { 1214 0, 0, 0, X_GLrop_Color3bv, X_GLrop_Color4bv 1215 }; 1216 static const uint16_t ubyte_ops[5] = { 1217 0, 0, 0, X_GLrop_Color3ubv, X_GLrop_Color4ubv 1218 }; 1219 static const uint16_t short_ops[5] = { 1220 0, 0, 0, X_GLrop_Color3sv, X_GLrop_Color4sv 1221 }; 1222 static const uint16_t ushort_ops[5] = { 1223 0, 0, 0, X_GLrop_Color3usv, X_GLrop_Color4usv 1224 }; 1225 static const uint16_t int_ops[5] = { 1226 0, 0, 0, X_GLrop_Color3iv, X_GLrop_Color4iv 1227 }; 1228 static const uint16_t uint_ops[5] = { 1229 0, 0, 0, X_GLrop_Color3uiv, X_GLrop_Color4uiv 1230 }; 1231 static const uint16_t float_ops[5] = { 1232 0, 0, 0, X_GLrop_Color3fv, X_GLrop_Color4fv 1233 }; 1234 static const uint16_t double_ops[5] = { 1235 0, 0, 0, X_GLrop_Color3dv, X_GLrop_Color4dv 1236 }; 1237 uint16_t opcode; 1238 struct glx_context *gc = __glXGetCurrentContext(); 1239 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 1240 struct array_state_vector *arrays = state->array_state; 1241 struct array_state *a; 1242 1243 1244 if (size < 3 || size > 4 || stride < 0) { 1245 __glXSetError(gc, GL_INVALID_VALUE); 1246 return; 1247 } 1248 1249 switch (type) { 1250 case GL_BYTE: 1251 opcode = byte_ops[size]; 1252 break; 1253 case GL_UNSIGNED_BYTE: 1254 opcode = ubyte_ops[size]; 1255 break; 1256 case GL_SHORT: 1257 opcode = short_ops[size]; 1258 break; 1259 case GL_UNSIGNED_SHORT: 1260 opcode = ushort_ops[size]; 1261 break; 1262 case GL_INT: 1263 opcode = int_ops[size]; 1264 break; 1265 case GL_UNSIGNED_INT: 1266 opcode = uint_ops[size]; 1267 break; 1268 case GL_FLOAT: 1269 opcode = float_ops[size]; 1270 break; 1271 case GL_DOUBLE: 1272 opcode = double_ops[size]; 1273 break; 1274 default: 1275 __glXSetError(gc, GL_INVALID_ENUM); 1276 return; 1277 } 1278 1279 a = get_array_entry(arrays, GL_COLOR_ARRAY, 0); 1280 assert(a != NULL); 1281 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode); 1282 1283 if (a->enabled) { 1284 arrays->array_info_cache_valid = GL_FALSE; 1285 } 1286 } 1287 1288 1289 void 1290 __indirect_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer) 1291 { 1292 uint16_t opcode; 1293 struct glx_context *gc = __glXGetCurrentContext(); 1294 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 1295 struct array_state_vector *arrays = state->array_state; 1296 struct array_state *a; 1297 1298 1299 if (stride < 0) { 1300 __glXSetError(gc, GL_INVALID_VALUE); 1301 return; 1302 } 1303 1304 switch (type) { 1305 case GL_UNSIGNED_BYTE: 1306 opcode = X_GLrop_Indexubv; 1307 break; 1308 case GL_SHORT: 1309 opcode = X_GLrop_Indexsv; 1310 break; 1311 case GL_INT: 1312 opcode = X_GLrop_Indexiv; 1313 break; 1314 case GL_FLOAT: 1315 opcode = X_GLrop_Indexfv; 1316 break; 1317 case GL_DOUBLE: 1318 opcode = X_GLrop_Indexdv; 1319 break; 1320 default: 1321 __glXSetError(gc, GL_INVALID_ENUM); 1322 return; 1323 } 1324 1325 a = get_array_entry(arrays, GL_INDEX_ARRAY, 0); 1326 assert(a != NULL); 1327 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode); 1328 1329 if (a->enabled) { 1330 arrays->array_info_cache_valid = GL_FALSE; 1331 } 1332 } 1333 1334 1335 void 1336 __indirect_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer) 1337 { 1338 struct glx_context *gc = __glXGetCurrentContext(); 1339 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 1340 struct array_state_vector *arrays = state->array_state; 1341 struct array_state *a; 1342 1343 1344 if (stride < 0) { 1345 __glXSetError(gc, GL_INVALID_VALUE); 1346 return; 1347 } 1348 1349 1350 a = get_array_entry(arrays, GL_EDGE_FLAG_ARRAY, 0); 1351 assert(a != NULL); 1352 COMMON_ARRAY_DATA_INIT(a, pointer, GL_UNSIGNED_BYTE, stride, 1, GL_FALSE, 1353 4, X_GLrop_EdgeFlagv); 1354 1355 if (a->enabled) { 1356 arrays->array_info_cache_valid = GL_FALSE; 1357 } 1358 } 1359 1360 1361 void 1362 __indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, 1363 const GLvoid * pointer) 1364 { 1365 static const uint16_t short_ops[5] = { 1366 0, X_GLrop_TexCoord1sv, X_GLrop_TexCoord2sv, X_GLrop_TexCoord3sv, 1367 X_GLrop_TexCoord4sv 1368 }; 1369 static const uint16_t int_ops[5] = { 1370 0, X_GLrop_TexCoord1iv, X_GLrop_TexCoord2iv, X_GLrop_TexCoord3iv, 1371 X_GLrop_TexCoord4iv 1372 }; 1373 static const uint16_t float_ops[5] = { 1374 0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2fv, X_GLrop_TexCoord3fv, 1375 X_GLrop_TexCoord4fv 1376 }; 1377 static const uint16_t double_ops[5] = { 1378 0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2dv, X_GLrop_TexCoord3dv, 1379 X_GLrop_TexCoord4dv 1380 }; 1381 1382 static const uint16_t mshort_ops[5] = { 1383 0, X_GLrop_MultiTexCoord1svARB, X_GLrop_MultiTexCoord2svARB, 1384 X_GLrop_MultiTexCoord3svARB, X_GLrop_MultiTexCoord4svARB 1385 }; 1386 static const uint16_t mint_ops[5] = { 1387 0, X_GLrop_MultiTexCoord1ivARB, X_GLrop_MultiTexCoord2ivARB, 1388 X_GLrop_MultiTexCoord3ivARB, X_GLrop_MultiTexCoord4ivARB 1389 }; 1390 static const uint16_t mfloat_ops[5] = { 1391 0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2fvARB, 1392 X_GLrop_MultiTexCoord3fvARB, X_GLrop_MultiTexCoord4fvARB 1393 }; 1394 static const uint16_t mdouble_ops[5] = { 1395 0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2dvARB, 1396 X_GLrop_MultiTexCoord3dvARB, X_GLrop_MultiTexCoord4dvARB 1397 }; 1398 1399 uint16_t opcode; 1400 struct glx_context *gc = __glXGetCurrentContext(); 1401 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 1402 struct array_state_vector *arrays = state->array_state; 1403 struct array_state *a; 1404 unsigned header_size; 1405 unsigned index; 1406 1407 1408 if (size < 1 || size > 4 || stride < 0) { 1409 __glXSetError(gc, GL_INVALID_VALUE); 1410 return; 1411 } 1412 1413 index = arrays->active_texture_unit; 1414 if (index == 0) { 1415 switch (type) { 1416 case GL_SHORT: 1417 opcode = short_ops[size]; 1418 break; 1419 case GL_INT: 1420 opcode = int_ops[size]; 1421 break; 1422 case GL_FLOAT: 1423 opcode = float_ops[size]; 1424 break; 1425 case GL_DOUBLE: 1426 opcode = double_ops[size]; 1427 break; 1428 default: 1429 __glXSetError(gc, GL_INVALID_ENUM); 1430 return; 1431 } 1432 1433 header_size = 4; 1434 } 1435 else { 1436 switch (type) { 1437 case GL_SHORT: 1438 opcode = mshort_ops[size]; 1439 break; 1440 case GL_INT: 1441 opcode = mint_ops[size]; 1442 break; 1443 case GL_FLOAT: 1444 opcode = mfloat_ops[size]; 1445 break; 1446 case GL_DOUBLE: 1447 opcode = mdouble_ops[size]; 1448 break; 1449 default: 1450 __glXSetError(gc, GL_INVALID_ENUM); 1451 return; 1452 } 1453 1454 header_size = 8; 1455 } 1456 1457 a = get_array_entry(arrays, GL_TEXTURE_COORD_ARRAY, index); 1458 assert(a != NULL); 1459 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE, 1460 header_size, opcode); 1461 1462 if (a->enabled) { 1463 arrays->array_info_cache_valid = GL_FALSE; 1464 } 1465 } 1466 1467 1468 void 1469 __indirect_glSecondaryColorPointerEXT(GLint size, GLenum type, GLsizei stride, 1470 const GLvoid * pointer) 1471 { 1472 uint16_t opcode; 1473 struct glx_context *gc = __glXGetCurrentContext(); 1474 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 1475 struct array_state_vector *arrays = state->array_state; 1476 struct array_state *a; 1477 1478 1479 if (size != 3 || stride < 0) { 1480 __glXSetError(gc, GL_INVALID_VALUE); 1481 return; 1482 } 1483 1484 switch (type) { 1485 case GL_BYTE: 1486 opcode = 4126; 1487 break; 1488 case GL_UNSIGNED_BYTE: 1489 opcode = 4131; 1490 break; 1491 case GL_SHORT: 1492 opcode = 4127; 1493 break; 1494 case GL_UNSIGNED_SHORT: 1495 opcode = 4132; 1496 break; 1497 case GL_INT: 1498 opcode = 4128; 1499 break; 1500 case GL_UNSIGNED_INT: 1501 opcode = 4133; 1502 break; 1503 case GL_FLOAT: 1504 opcode = 4129; 1505 break; 1506 case GL_DOUBLE: 1507 opcode = 4130; 1508 break; 1509 default: 1510 __glXSetError(gc, GL_INVALID_ENUM); 1511 return; 1512 } 1513 1514 a = get_array_entry(arrays, GL_SECONDARY_COLOR_ARRAY, 0); 1515 if (a == NULL) { 1516 __glXSetError(gc, GL_INVALID_OPERATION); 1517 return; 1518 } 1519 1520 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode); 1521 1522 if (a->enabled) { 1523 arrays->array_info_cache_valid = GL_FALSE; 1524 } 1525 } 1526 1527 1528 void 1529 __indirect_glFogCoordPointerEXT(GLenum type, GLsizei stride, 1530 const GLvoid * pointer) 1531 { 1532 uint16_t opcode; 1533 struct glx_context *gc = __glXGetCurrentContext(); 1534 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 1535 struct array_state_vector *arrays = state->array_state; 1536 struct array_state *a; 1537 1538 1539 if (stride < 0) { 1540 __glXSetError(gc, GL_INVALID_VALUE); 1541 return; 1542 } 1543 1544 switch (type) { 1545 case GL_FLOAT: 1546 opcode = 4124; 1547 break; 1548 case GL_DOUBLE: 1549 opcode = 4125; 1550 break; 1551 default: 1552 __glXSetError(gc, GL_INVALID_ENUM); 1553 return; 1554 } 1555 1556 a = get_array_entry(arrays, GL_FOG_COORD_ARRAY, 0); 1557 if (a == NULL) { 1558 __glXSetError(gc, GL_INVALID_OPERATION); 1559 return; 1560 } 1561 1562 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode); 1563 1564 if (a->enabled) { 1565 arrays->array_info_cache_valid = GL_FALSE; 1566 } 1567 } 1568 1569 1570 void 1571 __indirect_glVertexAttribPointerARB(GLuint index, GLint size, 1572 GLenum type, GLboolean normalized, 1573 GLsizei stride, const GLvoid * pointer) 1574 { 1575 static const uint16_t short_ops[5] = { 0, 4189, 4190, 4191, 4192 }; 1576 static const uint16_t float_ops[5] = { 0, 4193, 4194, 4195, 4196 }; 1577 static const uint16_t double_ops[5] = { 0, 4197, 4198, 4199, 4200 }; 1578 1579 uint16_t opcode; 1580 struct glx_context *gc = __glXGetCurrentContext(); 1581 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); 1582 struct array_state_vector *arrays = state->array_state; 1583 struct array_state *a; 1584 unsigned true_immediate_count; 1585 unsigned true_immediate_size; 1586 1587 1588 if ((size < 1) || (size > 4) || (stride < 0) 1589 || (index > arrays->num_vertex_program_attribs)) { 1590 __glXSetError(gc, GL_INVALID_VALUE); 1591 return; 1592 } 1593 1594 if (normalized && (type != GL_FLOAT) && (type != GL_DOUBLE)) { 1595 switch (type) { 1596 case GL_BYTE: 1597 opcode = X_GLrop_VertexAttrib4NbvARB; 1598 break; 1599 case GL_UNSIGNED_BYTE: 1600 opcode = X_GLrop_VertexAttrib4NubvARB; 1601 break; 1602 case GL_SHORT: 1603 opcode = X_GLrop_VertexAttrib4NsvARB; 1604 break; 1605 case GL_UNSIGNED_SHORT: 1606 opcode = X_GLrop_VertexAttrib4NusvARB; 1607 break; 1608 case GL_INT: 1609 opcode = X_GLrop_VertexAttrib4NivARB; 1610 break; 1611 case GL_UNSIGNED_INT: 1612 opcode = X_GLrop_VertexAttrib4NuivARB; 1613 break; 1614 default: 1615 __glXSetError(gc, GL_INVALID_ENUM); 1616 return; 1617 } 1618 1619 true_immediate_count = 4; 1620 } 1621 else { 1622 true_immediate_count = size; 1623 1624 switch (type) { 1625 case GL_BYTE: 1626 opcode = X_GLrop_VertexAttrib4bvARB; 1627 true_immediate_count = 4; 1628 break; 1629 case GL_UNSIGNED_BYTE: 1630 opcode = X_GLrop_VertexAttrib4ubvARB; 1631 true_immediate_count = 4; 1632 break; 1633 case GL_SHORT: 1634 opcode = short_ops[size]; 1635 break; 1636 case GL_UNSIGNED_SHORT: 1637 opcode = X_GLrop_VertexAttrib4usvARB; 1638 true_immediate_count = 4; 1639 break; 1640 case GL_INT: 1641 opcode = X_GLrop_VertexAttrib4ivARB; 1642 true_immediate_count = 4; 1643 break; 1644 case GL_UNSIGNED_INT: 1645 opcode = X_GLrop_VertexAttrib4uivARB; 1646 true_immediate_count = 4; 1647 break; 1648 case GL_FLOAT: 1649 opcode = float_ops[size]; 1650 break; 1651 case GL_DOUBLE: 1652 opcode = double_ops[size]; 1653 break; 1654 default: 1655 __glXSetError(gc, GL_INVALID_ENUM); 1656 return; 1657 } 1658 } 1659 1660 a = get_array_entry(arrays, GL_VERTEX_ATTRIB_ARRAY_POINTER, index); 1661 if (a == NULL) { 1662 __glXSetError(gc, GL_INVALID_OPERATION); 1663 return; 1664 } 1665 1666 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, normalized, 8, 1667 opcode); 1668 1669 true_immediate_size = __glXTypeSize(type) * true_immediate_count; 1670 ((uint16_t *) (a)->header)[0] = __GLX_PAD(a->header_size 1671 + true_immediate_size); 1672 1673 if (a->enabled) { 1674 arrays->array_info_cache_valid = GL_FALSE; 1675 } 1676 } 1677 1678 1679 /** 1680 * I don't have 100% confidence that this is correct. The different rules 1681 * about whether or not generic vertex attributes alias "classic" vertex 1682 * attributes (i.e., attrib1 ?= primary color) between ARB_vertex_program, 1683 * ARB_vertex_shader, and NV_vertex_program are a bit confusing. My 1684 * feeling is that the client-side doesn't have to worry about it. The 1685 * client just sends all the data to the server and lets the server deal 1686 * with it. 1687 */ 1688 void 1689 __indirect_glVertexAttribPointerNV(GLuint index, GLint size, 1690 GLenum type, GLsizei stride, 1691 const GLvoid * pointer) 1692 { 1693 struct glx_context *gc = __glXGetCurrentContext(); 1694 GLboolean normalized = GL_FALSE; 1695 1696 1697 switch (type) { 1698 case GL_UNSIGNED_BYTE: 1699 if (size != 4) { 1700 __glXSetError(gc, GL_INVALID_VALUE); 1701 return; 1702 } 1703 normalized = GL_TRUE; 1704 1705 case GL_SHORT: 1706 case GL_FLOAT: 1707 case GL_DOUBLE: 1708 __indirect_glVertexAttribPointerARB(index, size, type, 1709 normalized, stride, pointer); 1710 return; 1711 default: 1712 __glXSetError(gc, GL_INVALID_ENUM); 1713 return; 1714 } 1715 } 1716 1717 1718 void 1719 __indirect_glClientActiveTextureARB(GLenum texture) 1720 { 1721 struct glx_context *const gc = __glXGetCurrentContext(); 1722 __GLXattribute *const state = 1723 (__GLXattribute *) (gc->client_state_private); 1724 struct array_state_vector *const arrays = state->array_state; 1725 const GLint unit = (GLint) texture - GL_TEXTURE0; 1726 1727 1728 if ((unit < 0) || (unit >= arrays->num_texture_units)) { 1729 __glXSetError(gc, GL_INVALID_ENUM); 1730 return; 1731 } 1732 1733 arrays->active_texture_unit = unit; 1734 } 1735 1736 1737 /** 1738 * Modify the enable state for the selected array 1739 */ 1740 GLboolean 1741 __glXSetArrayEnable(__GLXattribute * state, GLenum key, unsigned index, 1742 GLboolean enable) 1743 { 1744 struct array_state_vector *arrays = state->array_state; 1745 struct array_state *a; 1746 1747 1748 /* Texture coordinate arrays have an implict index set when the 1749 * application calls glClientActiveTexture. 1750 */ 1751 if (key == GL_TEXTURE_COORD_ARRAY) { 1752 index = arrays->active_texture_unit; 1753 } 1754 1755 a = get_array_entry(arrays, key, index); 1756 1757 if ((a != NULL) && (a->enabled != enable)) { 1758 a->enabled = enable; 1759 arrays->array_info_cache_valid = GL_FALSE; 1760 } 1761 1762 return (a != NULL); 1763 } 1764 1765 1766 void 1767 __glXArrayDisableAll(__GLXattribute * state) 1768 { 1769 struct array_state_vector *arrays = state->array_state; 1770 unsigned i; 1771 1772 1773 for (i = 0; i < arrays->num_arrays; i++) { 1774 arrays->arrays[i].enabled = GL_FALSE; 1775 } 1776 1777 arrays->array_info_cache_valid = GL_FALSE; 1778 } 1779 1780 1781 /** 1782 */ 1783 GLboolean 1784 __glXGetArrayEnable(const __GLXattribute * const state, 1785 GLenum key, unsigned index, GLintptr * dest) 1786 { 1787 const struct array_state_vector *arrays = state->array_state; 1788 const struct array_state *a = 1789 get_array_entry((struct array_state_vector *) arrays, 1790 key, index); 1791 1792 if (a != NULL) { 1793 *dest = (GLintptr) a->enabled; 1794 } 1795 1796 return (a != NULL); 1797 } 1798 1799 1800 /** 1801 */ 1802 GLboolean 1803 __glXGetArrayType(const __GLXattribute * const state, 1804 GLenum key, unsigned index, GLintptr * dest) 1805 { 1806 const struct array_state_vector *arrays = state->array_state; 1807 const struct array_state *a = 1808 get_array_entry((struct array_state_vector *) arrays, 1809 key, index); 1810 1811 if (a != NULL) { 1812 *dest = (GLintptr) a->data_type; 1813 } 1814 1815 return (a != NULL); 1816 } 1817 1818 1819 /** 1820 */ 1821 GLboolean 1822 __glXGetArraySize(const __GLXattribute * const state, 1823 GLenum key, unsigned index, GLintptr * dest) 1824 { 1825 const struct array_state_vector *arrays = state->array_state; 1826 const struct array_state *a = 1827 get_array_entry((struct array_state_vector *) arrays, 1828 key, index); 1829 1830 if (a != NULL) { 1831 *dest = (GLintptr) a->count; 1832 } 1833 1834 return (a != NULL); 1835 } 1836 1837 1838 /** 1839 */ 1840 GLboolean 1841 __glXGetArrayStride(const __GLXattribute * const state, 1842 GLenum key, unsigned index, GLintptr * dest) 1843 { 1844 const struct array_state_vector *arrays = state->array_state; 1845 const struct array_state *a = 1846 get_array_entry((struct array_state_vector *) arrays, 1847 key, index); 1848 1849 if (a != NULL) { 1850 *dest = (GLintptr) a->user_stride; 1851 } 1852 1853 return (a != NULL); 1854 } 1855 1856 1857 /** 1858 */ 1859 GLboolean 1860 __glXGetArrayPointer(const __GLXattribute * const state, 1861 GLenum key, unsigned index, void **dest) 1862 { 1863 const struct array_state_vector *arrays = state->array_state; 1864 const struct array_state *a = 1865 get_array_entry((struct array_state_vector *) arrays, 1866 key, index); 1867 1868 1869 if (a != NULL) { 1870 *dest = (void *) (a->data); 1871 } 1872 1873 return (a != NULL); 1874 } 1875 1876 1877 /** 1878 */ 1879 GLboolean 1880 __glXGetArrayNormalized(const __GLXattribute * const state, 1881 GLenum key, unsigned index, GLintptr * dest) 1882 { 1883 const struct array_state_vector *arrays = state->array_state; 1884 const struct array_state *a = 1885 get_array_entry((struct array_state_vector *) arrays, 1886 key, index); 1887 1888 1889 if (a != NULL) { 1890 *dest = (GLintptr) a->normalized; 1891 } 1892 1893 return (a != NULL); 1894 } 1895 1896 1897 /** 1898 */ 1899 GLuint 1900 __glXGetActiveTextureUnit(const __GLXattribute * const state) 1901 { 1902 return state->array_state->active_texture_unit; 1903 } 1904 1905 1906 void 1907 __glXPushArrayState(__GLXattribute * state) 1908 { 1909 struct array_state_vector *arrays = state->array_state; 1910 struct array_stack_state *stack = 1911 &arrays->stack[(arrays->stack_index * arrays->num_arrays)]; 1912 unsigned i; 1913 1914 /* XXX are we pushing _all_ the necessary fields? */ 1915 for (i = 0; i < arrays->num_arrays; i++) { 1916 stack[i].data = arrays->arrays[i].data; 1917 stack[i].data_type = arrays->arrays[i].data_type; 1918 stack[i].user_stride = arrays->arrays[i].user_stride; 1919 stack[i].count = arrays->arrays[i].count; 1920 stack[i].key = arrays->arrays[i].key; 1921 stack[i].index = arrays->arrays[i].index; 1922 stack[i].enabled = arrays->arrays[i].enabled; 1923 } 1924 1925 arrays->active_texture_unit_stack[arrays->stack_index] = 1926 arrays->active_texture_unit; 1927 1928 arrays->stack_index++; 1929 } 1930 1931 1932 void 1933 __glXPopArrayState(__GLXattribute * state) 1934 { 1935 struct array_state_vector *arrays = state->array_state; 1936 struct array_stack_state *stack; 1937 unsigned i; 1938 1939 1940 arrays->stack_index--; 1941 stack = &arrays->stack[(arrays->stack_index * arrays->num_arrays)]; 1942 1943 for (i = 0; i < arrays->num_arrays; i++) { 1944 switch (stack[i].key) { 1945 case GL_NORMAL_ARRAY: 1946 __indirect_glNormalPointer(stack[i].data_type, 1947 stack[i].user_stride, stack[i].data); 1948 break; 1949 case GL_COLOR_ARRAY: 1950 __indirect_glColorPointer(stack[i].count, 1951 stack[i].data_type, 1952 stack[i].user_stride, stack[i].data); 1953 break; 1954 case GL_INDEX_ARRAY: 1955 __indirect_glIndexPointer(stack[i].data_type, 1956 stack[i].user_stride, stack[i].data); 1957 break; 1958 case GL_EDGE_FLAG_ARRAY: 1959 __indirect_glEdgeFlagPointer(stack[i].user_stride, stack[i].data); 1960 break; 1961 case GL_TEXTURE_COORD_ARRAY: 1962 arrays->active_texture_unit = stack[i].index; 1963 __indirect_glTexCoordPointer(stack[i].count, 1964 stack[i].data_type, 1965 stack[i].user_stride, stack[i].data); 1966 break; 1967 case GL_SECONDARY_COLOR_ARRAY: 1968 __indirect_glSecondaryColorPointerEXT(stack[i].count, 1969 stack[i].data_type, 1970 stack[i].user_stride, 1971 stack[i].data); 1972 break; 1973 case GL_FOG_COORDINATE_ARRAY: 1974 __indirect_glFogCoordPointerEXT(stack[i].data_type, 1975 stack[i].user_stride, stack[i].data); 1976 break; 1977 1978 } 1979 1980 __glXSetArrayEnable(state, stack[i].key, stack[i].index, 1981 stack[i].enabled); 1982 } 1983 1984 arrays->active_texture_unit = 1985 arrays->active_texture_unit_stack[arrays->stack_index]; 1986 } 1987