1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 27#include <stdio.h> 28#include <inttypes.h> /* for PRId64 macro */ 29 30#include "glheader.h" 31 32#include "bufferobj.h" 33#include "context.h" 34#include "enable.h" 35#include "enums.h" 36#include "glformats.h" 37#include "hash.h" 38#include "image.h" 39#include "macros.h" 40#include "mtypes.h" 41#include "varray.h" 42#include "arrayobj.h" 43#include "get.h" 44#include "main/dispatch.h" 45 46 47/** Used to do error checking for GL_EXT_vertex_array_bgra */ 48#define BGRA_OR_4 5 49 50 51/** Used to indicate which GL datatypes are accepted by each of the 52 * glVertex/Color/Attrib/EtcPointer() functions. 53 */ 54#define BOOL_BIT (1 << 0) 55#define BYTE_BIT (1 << 1) 56#define UNSIGNED_BYTE_BIT (1 << 2) 57#define SHORT_BIT (1 << 3) 58#define UNSIGNED_SHORT_BIT (1 << 4) 59#define INT_BIT (1 << 5) 60#define UNSIGNED_INT_BIT (1 << 6) 61#define HALF_BIT (1 << 7) 62#define FLOAT_BIT (1 << 8) 63#define DOUBLE_BIT (1 << 9) 64#define FIXED_ES_BIT (1 << 10) 65#define FIXED_GL_BIT (1 << 11) 66#define UNSIGNED_INT_2_10_10_10_REV_BIT (1 << 12) 67#define INT_2_10_10_10_REV_BIT (1 << 13) 68#define UNSIGNED_INT_10F_11F_11F_REV_BIT (1 << 14) 69#define ALL_TYPE_BITS ((1 << 15) - 1) 70 71#define ATTRIB_FORMAT_TYPES_MASK (BYTE_BIT | UNSIGNED_BYTE_BIT | \ 72 SHORT_BIT | UNSIGNED_SHORT_BIT | \ 73 INT_BIT | UNSIGNED_INT_BIT | \ 74 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | \ 75 FIXED_GL_BIT | \ 76 UNSIGNED_INT_2_10_10_10_REV_BIT | \ 77 INT_2_10_10_10_REV_BIT | \ 78 UNSIGNED_INT_10F_11F_11F_REV_BIT) 79 80#define ATTRIB_IFORMAT_TYPES_MASK (BYTE_BIT | UNSIGNED_BYTE_BIT | \ 81 SHORT_BIT | UNSIGNED_SHORT_BIT | \ 82 INT_BIT | UNSIGNED_INT_BIT) 83 84#define ATTRIB_LFORMAT_TYPES_MASK DOUBLE_BIT 85 86 87/** Convert GL datatype enum into a <type>_BIT value seen above */ 88static GLbitfield 89type_to_bit(const struct gl_context *ctx, GLenum type) 90{ 91 switch (type) { 92 case GL_BOOL: 93 return BOOL_BIT; 94 case GL_BYTE: 95 return BYTE_BIT; 96 case GL_UNSIGNED_BYTE: 97 return UNSIGNED_BYTE_BIT; 98 case GL_SHORT: 99 return SHORT_BIT; 100 case GL_UNSIGNED_SHORT: 101 return UNSIGNED_SHORT_BIT; 102 case GL_INT: 103 return INT_BIT; 104 case GL_UNSIGNED_INT: 105 return UNSIGNED_INT_BIT; 106 case GL_HALF_FLOAT: 107 case GL_HALF_FLOAT_OES: 108 if (ctx->Extensions.ARB_half_float_vertex) 109 return HALF_BIT; 110 else 111 return 0x0; 112 case GL_FLOAT: 113 return FLOAT_BIT; 114 case GL_DOUBLE: 115 return DOUBLE_BIT; 116 case GL_FIXED: 117 return _mesa_is_desktop_gl(ctx) ? FIXED_GL_BIT : FIXED_ES_BIT; 118 case GL_UNSIGNED_INT_2_10_10_10_REV: 119 return UNSIGNED_INT_2_10_10_10_REV_BIT; 120 case GL_INT_2_10_10_10_REV: 121 return INT_2_10_10_10_REV_BIT; 122 case GL_UNSIGNED_INT_10F_11F_11F_REV: 123 return UNSIGNED_INT_10F_11F_11F_REV_BIT; 124 default: 125 return 0; 126 } 127} 128 129 130/** 131 * Depending on the position and generic0 attributes enable flags select 132 * the one that is used for both attributes. 133 * The generic0 attribute takes precedence. 134 */ 135static inline void 136update_attribute_map_mode(const struct gl_context *ctx, 137 struct gl_vertex_array_object *vao) 138{ 139 /* 140 * There is no need to change the mapping away from the 141 * identity mapping if we are not in compat mode. 142 */ 143 if (ctx->API != API_OPENGL_COMPAT) 144 return; 145 /* The generic0 attribute superseeds the position attribute */ 146 const GLbitfield enabled = vao->Enabled; 147 if (enabled & VERT_BIT_GENERIC0) 148 vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_GENERIC0; 149 else if (enabled & VERT_BIT_POS) 150 vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_POSITION; 151 else 152 vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_IDENTITY; 153} 154 155 156/** 157 * Sets the BufferBindingIndex field for the vertex attribute given by 158 * attribIndex. 159 */ 160void 161_mesa_vertex_attrib_binding(struct gl_context *ctx, 162 struct gl_vertex_array_object *vao, 163 gl_vert_attrib attribIndex, 164 GLuint bindingIndex) 165{ 166 struct gl_array_attributes *array = &vao->VertexAttrib[attribIndex]; 167 assert(!vao->SharedAndImmutable); 168 169 if (array->BufferBindingIndex != bindingIndex) { 170 const GLbitfield array_bit = VERT_BIT(attribIndex); 171 172 if (vao->BufferBinding[bindingIndex].BufferObj) 173 vao->VertexAttribBufferMask |= array_bit; 174 else 175 vao->VertexAttribBufferMask &= ~array_bit; 176 177 if (vao->BufferBinding[bindingIndex].InstanceDivisor) 178 vao->NonZeroDivisorMask |= array_bit; 179 else 180 vao->NonZeroDivisorMask &= ~array_bit; 181 182 vao->BufferBinding[array->BufferBindingIndex]._BoundArrays &= ~array_bit; 183 vao->BufferBinding[bindingIndex]._BoundArrays |= array_bit; 184 185 array->BufferBindingIndex = bindingIndex; 186 187 vao->NewArrays |= vao->Enabled & array_bit; 188 vao->NonDefaultStateMask |= array_bit | BITFIELD_BIT(bindingIndex); 189 } 190} 191 192 193/** 194 * Binds a buffer object to the vertex buffer binding point given by index, 195 * and sets the Offset and Stride fields. 196 */ 197void 198_mesa_bind_vertex_buffer(struct gl_context *ctx, 199 struct gl_vertex_array_object *vao, 200 GLuint index, 201 struct gl_buffer_object *vbo, 202 GLintptr offset, GLsizei stride, 203 bool offset_is_int32, bool take_vbo_ownership) 204{ 205 assert(index < ARRAY_SIZE(vao->BufferBinding)); 206 assert(!vao->SharedAndImmutable); 207 struct gl_vertex_buffer_binding *binding = &vao->BufferBinding[index]; 208 209 if (ctx->Const.VertexBufferOffsetIsInt32 && (int)offset < 0 && 210 !offset_is_int32 && vbo) { 211 /* The offset will be interpreted as a signed int, so make sure 212 * the user supplied offset is not negative (driver limitation). 213 */ 214 _mesa_warning(ctx, "Received negative int32 vertex buffer offset. " 215 "(driver limitation)\n"); 216 217 /* We can't disable this binding, so use a non-negative offset value 218 * instead. 219 */ 220 offset = 0; 221 } 222 223 if (binding->BufferObj != vbo || 224 binding->Offset != offset || 225 binding->Stride != stride) { 226 227 if (take_vbo_ownership) { 228 _mesa_reference_buffer_object(ctx, &binding->BufferObj, NULL); 229 binding->BufferObj = vbo; 230 } else { 231 _mesa_reference_buffer_object(ctx, &binding->BufferObj, vbo); 232 } 233 234 binding->Offset = offset; 235 binding->Stride = stride; 236 237 if (!vbo) { 238 vao->VertexAttribBufferMask &= ~binding->_BoundArrays; 239 } else { 240 vao->VertexAttribBufferMask |= binding->_BoundArrays; 241 vbo->UsageHistory |= USAGE_ARRAY_BUFFER; 242 } 243 244 vao->NewArrays |= vao->Enabled & binding->_BoundArrays; 245 vao->NonDefaultStateMask |= BITFIELD_BIT(index); 246 } 247} 248 249 250/** 251 * Sets the InstanceDivisor field in the vertex buffer binding point 252 * given by bindingIndex. 253 */ 254static void 255vertex_binding_divisor(struct gl_context *ctx, 256 struct gl_vertex_array_object *vao, 257 GLuint bindingIndex, 258 GLuint divisor) 259{ 260 struct gl_vertex_buffer_binding *binding = 261 &vao->BufferBinding[bindingIndex]; 262 assert(!vao->SharedAndImmutable); 263 264 if (binding->InstanceDivisor != divisor) { 265 binding->InstanceDivisor = divisor; 266 267 if (divisor) 268 vao->NonZeroDivisorMask |= binding->_BoundArrays; 269 else 270 vao->NonZeroDivisorMask &= ~binding->_BoundArrays; 271 272 vao->NewArrays |= vao->Enabled & binding->_BoundArrays; 273 vao->NonDefaultStateMask |= BITFIELD_BIT(bindingIndex); 274 } 275} 276 277/* vertex_formats[gltype - GL_BYTE][integer*2 + normalized][size - 1] */ 278static const uint16_t vertex_formats[][4][4] = { 279 { /* GL_BYTE */ 280 { 281 PIPE_FORMAT_R8_SSCALED, 282 PIPE_FORMAT_R8G8_SSCALED, 283 PIPE_FORMAT_R8G8B8_SSCALED, 284 PIPE_FORMAT_R8G8B8A8_SSCALED 285 }, 286 { 287 PIPE_FORMAT_R8_SNORM, 288 PIPE_FORMAT_R8G8_SNORM, 289 PIPE_FORMAT_R8G8B8_SNORM, 290 PIPE_FORMAT_R8G8B8A8_SNORM 291 }, 292 { 293 PIPE_FORMAT_R8_SINT, 294 PIPE_FORMAT_R8G8_SINT, 295 PIPE_FORMAT_R8G8B8_SINT, 296 PIPE_FORMAT_R8G8B8A8_SINT 297 }, 298 }, 299 { /* GL_UNSIGNED_BYTE */ 300 { 301 PIPE_FORMAT_R8_USCALED, 302 PIPE_FORMAT_R8G8_USCALED, 303 PIPE_FORMAT_R8G8B8_USCALED, 304 PIPE_FORMAT_R8G8B8A8_USCALED 305 }, 306 { 307 PIPE_FORMAT_R8_UNORM, 308 PIPE_FORMAT_R8G8_UNORM, 309 PIPE_FORMAT_R8G8B8_UNORM, 310 PIPE_FORMAT_R8G8B8A8_UNORM 311 }, 312 { 313 PIPE_FORMAT_R8_UINT, 314 PIPE_FORMAT_R8G8_UINT, 315 PIPE_FORMAT_R8G8B8_UINT, 316 PIPE_FORMAT_R8G8B8A8_UINT 317 }, 318 }, 319 { /* GL_SHORT */ 320 { 321 PIPE_FORMAT_R16_SSCALED, 322 PIPE_FORMAT_R16G16_SSCALED, 323 PIPE_FORMAT_R16G16B16_SSCALED, 324 PIPE_FORMAT_R16G16B16A16_SSCALED 325 }, 326 { 327 PIPE_FORMAT_R16_SNORM, 328 PIPE_FORMAT_R16G16_SNORM, 329 PIPE_FORMAT_R16G16B16_SNORM, 330 PIPE_FORMAT_R16G16B16A16_SNORM 331 }, 332 { 333 PIPE_FORMAT_R16_SINT, 334 PIPE_FORMAT_R16G16_SINT, 335 PIPE_FORMAT_R16G16B16_SINT, 336 PIPE_FORMAT_R16G16B16A16_SINT 337 }, 338 }, 339 { /* GL_UNSIGNED_SHORT */ 340 { 341 PIPE_FORMAT_R16_USCALED, 342 PIPE_FORMAT_R16G16_USCALED, 343 PIPE_FORMAT_R16G16B16_USCALED, 344 PIPE_FORMAT_R16G16B16A16_USCALED 345 }, 346 { 347 PIPE_FORMAT_R16_UNORM, 348 PIPE_FORMAT_R16G16_UNORM, 349 PIPE_FORMAT_R16G16B16_UNORM, 350 PIPE_FORMAT_R16G16B16A16_UNORM 351 }, 352 { 353 PIPE_FORMAT_R16_UINT, 354 PIPE_FORMAT_R16G16_UINT, 355 PIPE_FORMAT_R16G16B16_UINT, 356 PIPE_FORMAT_R16G16B16A16_UINT 357 }, 358 }, 359 { /* GL_INT */ 360 { 361 PIPE_FORMAT_R32_SSCALED, 362 PIPE_FORMAT_R32G32_SSCALED, 363 PIPE_FORMAT_R32G32B32_SSCALED, 364 PIPE_FORMAT_R32G32B32A32_SSCALED 365 }, 366 { 367 PIPE_FORMAT_R32_SNORM, 368 PIPE_FORMAT_R32G32_SNORM, 369 PIPE_FORMAT_R32G32B32_SNORM, 370 PIPE_FORMAT_R32G32B32A32_SNORM 371 }, 372 { 373 PIPE_FORMAT_R32_SINT, 374 PIPE_FORMAT_R32G32_SINT, 375 PIPE_FORMAT_R32G32B32_SINT, 376 PIPE_FORMAT_R32G32B32A32_SINT 377 }, 378 }, 379 { /* GL_UNSIGNED_INT */ 380 { 381 PIPE_FORMAT_R32_USCALED, 382 PIPE_FORMAT_R32G32_USCALED, 383 PIPE_FORMAT_R32G32B32_USCALED, 384 PIPE_FORMAT_R32G32B32A32_USCALED 385 }, 386 { 387 PIPE_FORMAT_R32_UNORM, 388 PIPE_FORMAT_R32G32_UNORM, 389 PIPE_FORMAT_R32G32B32_UNORM, 390 PIPE_FORMAT_R32G32B32A32_UNORM 391 }, 392 { 393 PIPE_FORMAT_R32_UINT, 394 PIPE_FORMAT_R32G32_UINT, 395 PIPE_FORMAT_R32G32B32_UINT, 396 PIPE_FORMAT_R32G32B32A32_UINT 397 }, 398 }, 399 { /* GL_FLOAT */ 400 { 401 PIPE_FORMAT_R32_FLOAT, 402 PIPE_FORMAT_R32G32_FLOAT, 403 PIPE_FORMAT_R32G32B32_FLOAT, 404 PIPE_FORMAT_R32G32B32A32_FLOAT 405 }, 406 { 407 PIPE_FORMAT_R32_FLOAT, 408 PIPE_FORMAT_R32G32_FLOAT, 409 PIPE_FORMAT_R32G32B32_FLOAT, 410 PIPE_FORMAT_R32G32B32A32_FLOAT 411 }, 412 }, 413 {{0}}, /* GL_2_BYTES */ 414 {{0}}, /* GL_3_BYTES */ 415 {{0}}, /* GL_4_BYTES */ 416 { /* GL_DOUBLE */ 417 { 418 PIPE_FORMAT_R64_FLOAT, 419 PIPE_FORMAT_R64G64_FLOAT, 420 PIPE_FORMAT_R64G64B64_FLOAT, 421 PIPE_FORMAT_R64G64B64A64_FLOAT 422 }, 423 { 424 PIPE_FORMAT_R64_FLOAT, 425 PIPE_FORMAT_R64G64_FLOAT, 426 PIPE_FORMAT_R64G64B64_FLOAT, 427 PIPE_FORMAT_R64G64B64A64_FLOAT 428 }, 429 }, 430 { /* GL_HALF_FLOAT */ 431 { 432 PIPE_FORMAT_R16_FLOAT, 433 PIPE_FORMAT_R16G16_FLOAT, 434 PIPE_FORMAT_R16G16B16_FLOAT, 435 PIPE_FORMAT_R16G16B16A16_FLOAT 436 }, 437 { 438 PIPE_FORMAT_R16_FLOAT, 439 PIPE_FORMAT_R16G16_FLOAT, 440 PIPE_FORMAT_R16G16B16_FLOAT, 441 PIPE_FORMAT_R16G16B16A16_FLOAT 442 }, 443 }, 444 { /* GL_FIXED */ 445 { 446 PIPE_FORMAT_R32_FIXED, 447 PIPE_FORMAT_R32G32_FIXED, 448 PIPE_FORMAT_R32G32B32_FIXED, 449 PIPE_FORMAT_R32G32B32A32_FIXED 450 }, 451 { 452 PIPE_FORMAT_R32_FIXED, 453 PIPE_FORMAT_R32G32_FIXED, 454 PIPE_FORMAT_R32G32B32_FIXED, 455 PIPE_FORMAT_R32G32B32A32_FIXED 456 }, 457 }, 458}; 459 460/** 461 * Return a PIPE_FORMAT_x for the given GL datatype and size. 462 */ 463static enum pipe_format 464vertex_format_to_pipe_format(GLubyte size, GLenum16 type, GLenum16 format, 465 bool normalized, bool integer, bool doubles) 466{ 467 assert(size >= 1 && size <= 4); 468 assert(format == GL_RGBA || format == GL_BGRA); 469 470 /* Raw doubles use 64_UINT. */ 471 if (doubles) 472 return PIPE_FORMAT_R64_UINT + size - 1; 473 474 switch (type) { 475 case GL_HALF_FLOAT_OES: 476 type = GL_HALF_FLOAT; 477 break; 478 479 case GL_INT_2_10_10_10_REV: 480 assert(size == 4 && !integer); 481 482 if (format == GL_BGRA) { 483 if (normalized) 484 return PIPE_FORMAT_B10G10R10A2_SNORM; 485 else 486 return PIPE_FORMAT_B10G10R10A2_SSCALED; 487 } else { 488 if (normalized) 489 return PIPE_FORMAT_R10G10B10A2_SNORM; 490 else 491 return PIPE_FORMAT_R10G10B10A2_SSCALED; 492 } 493 break; 494 495 case GL_UNSIGNED_INT_2_10_10_10_REV: 496 assert(size == 4 && !integer); 497 498 if (format == GL_BGRA) { 499 if (normalized) 500 return PIPE_FORMAT_B10G10R10A2_UNORM; 501 else 502 return PIPE_FORMAT_B10G10R10A2_USCALED; 503 } else { 504 if (normalized) 505 return PIPE_FORMAT_R10G10B10A2_UNORM; 506 else 507 return PIPE_FORMAT_R10G10B10A2_USCALED; 508 } 509 break; 510 511 case GL_UNSIGNED_INT_10F_11F_11F_REV: 512 assert(size == 3 && !integer && format == GL_RGBA); 513 return PIPE_FORMAT_R11G11B10_FLOAT; 514 515 case GL_UNSIGNED_BYTE: 516 if (format == GL_BGRA) { 517 /* this is an odd-ball case */ 518 assert(normalized); 519 return PIPE_FORMAT_B8G8R8A8_UNORM; 520 } 521 break; 522 } 523 524 unsigned index = integer*2 + normalized; 525 assert(index <= 2); 526 assert(type >= GL_BYTE && type <= GL_FIXED); 527 return vertex_formats[type - GL_BYTE][index][size-1]; 528} 529 530void 531_mesa_set_vertex_format(struct gl_vertex_format *vertex_format, 532 GLubyte size, GLenum16 type, GLenum16 format, 533 GLboolean normalized, GLboolean integer, 534 GLboolean doubles) 535{ 536 assert(size <= 4); 537 vertex_format->Type = type; 538 vertex_format->Format = format; 539 vertex_format->Size = size; 540 vertex_format->Normalized = normalized; 541 vertex_format->Integer = integer; 542 vertex_format->Doubles = doubles; 543 vertex_format->_ElementSize = _mesa_bytes_per_vertex_attrib(size, type); 544 assert(vertex_format->_ElementSize <= 4*sizeof(double)); 545 vertex_format->_PipeFormat = 546 vertex_format_to_pipe_format(size, type, format, normalized, integer, 547 doubles); 548 /* pipe_vertex_element::src_format has only 8 bits, assuming a signed enum */ 549 assert(vertex_format->_PipeFormat <= 255); 550} 551 552 553/** 554 * Examine the API profile and extensions to determine which types are legal 555 * for vertex arrays. This is called once from update_array_format(). 556 */ 557static GLbitfield 558get_legal_types_mask(const struct gl_context *ctx) 559{ 560 GLbitfield legalTypesMask = ALL_TYPE_BITS; 561 562 if (_mesa_is_gles(ctx)) { 563 legalTypesMask &= ~(FIXED_GL_BIT | 564 DOUBLE_BIT | 565 UNSIGNED_INT_10F_11F_11F_REV_BIT); 566 567 /* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until 568 * 3.0. The 2_10_10_10 types are added in OpenGL ES 3.0 or 569 * GL_OES_vertex_type_10_10_10_2. GL_HALF_FLOAT data is not allowed 570 * until 3.0 or with the GL_OES_vertex_half float extension, which isn't 571 * quite as trivial as we'd like because it uses a different enum value 572 * for GL_HALF_FLOAT_OES. 573 */ 574 if (ctx->Version < 30) { 575 legalTypesMask &= ~(UNSIGNED_INT_BIT | 576 INT_BIT | 577 UNSIGNED_INT_2_10_10_10_REV_BIT | 578 INT_2_10_10_10_REV_BIT); 579 580 if (!_mesa_has_OES_vertex_half_float(ctx)) 581 legalTypesMask &= ~HALF_BIT; 582 } 583 } 584 else { 585 legalTypesMask &= ~FIXED_ES_BIT; 586 587 if (!ctx->Extensions.ARB_ES2_compatibility) 588 legalTypesMask &= ~FIXED_GL_BIT; 589 590 if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) 591 legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT | 592 INT_2_10_10_10_REV_BIT); 593 594 if (!ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev) 595 legalTypesMask &= ~UNSIGNED_INT_10F_11F_11F_REV_BIT; 596 } 597 598 return legalTypesMask; 599} 600 601static GLenum 602get_array_format(const struct gl_context *ctx, GLint sizeMax, GLint *size) 603{ 604 GLenum format = GL_RGBA; 605 606 /* Do size parameter checking. 607 * If sizeMax = BGRA_OR_4 it means that size = GL_BGRA is legal and 608 * must be handled specially. 609 */ 610 if (ctx->Extensions.EXT_vertex_array_bgra && sizeMax == BGRA_OR_4 && 611 *size == GL_BGRA) { 612 format = GL_BGRA; 613 *size = 4; 614 } 615 616 return format; 617} 618 619 620/** 621 * \param attrib The index of the attribute array 622 * \param size Components per element (1, 2, 3 or 4) 623 * \param type Datatype of each component (GL_FLOAT, GL_INT, etc) 624 * \param format Either GL_RGBA or GL_BGRA. 625 * \param normalized Whether integer types are converted to floats in [-1, 1] 626 * \param integer Integer-valued values (will not be normalized to [-1, 1]) 627 * \param doubles Double values not reduced to floats 628 * \param relativeOffset Offset of the first element relative to the binding 629 * offset. 630 */ 631void 632_mesa_update_array_format(struct gl_context *ctx, 633 struct gl_vertex_array_object *vao, 634 gl_vert_attrib attrib, GLint size, GLenum type, 635 GLenum format, GLboolean normalized, 636 GLboolean integer, GLboolean doubles, 637 GLuint relativeOffset) 638{ 639 struct gl_array_attributes *const array = &vao->VertexAttrib[attrib]; 640 struct gl_vertex_format new_format; 641 642 assert(!vao->SharedAndImmutable); 643 assert(size <= 4); 644 645 _mesa_set_vertex_format(&new_format, size, type, format, 646 normalized, integer, doubles); 647 648 if ((array->RelativeOffset == relativeOffset) && 649 !memcmp(&new_format, &array->Format, sizeof(new_format))) 650 return; 651 652 array->RelativeOffset = relativeOffset; 653 array->Format = new_format; 654 655 vao->NewArrays |= vao->Enabled & VERT_BIT(attrib); 656 vao->NonDefaultStateMask |= BITFIELD_BIT(attrib); 657} 658 659/** 660 * Does error checking of the format in an attrib array. 661 * 662 * Called by *Pointer() and VertexAttrib*Format(). 663 * 664 * \param func Name of calling function used for error reporting 665 * \param attrib The index of the attribute array 666 * \param legalTypes Bitmask of *_BIT above indicating legal datatypes 667 * \param sizeMin Min allowable size value 668 * \param sizeMax Max allowable size value (may also be BGRA_OR_4) 669 * \param size Components per element (1, 2, 3 or 4) 670 * \param type Datatype of each component (GL_FLOAT, GL_INT, etc) 671 * \param normalized Whether integer types are converted to floats in [-1, 1] 672 * \param integer Integer-valued values (will not be normalized to [-1, 1]) 673 * \param doubles Double values not reduced to floats 674 * \param relativeOffset Offset of the first element relative to the binding offset. 675 * \return bool True if validation is successful, False otherwise. 676 */ 677static bool 678validate_array_format(struct gl_context *ctx, const char *func, 679 struct gl_vertex_array_object *vao, 680 GLuint attrib, GLbitfield legalTypesMask, 681 GLint sizeMin, GLint sizeMax, 682 GLint size, GLenum type, bool normalized, 683 bool integer, bool doubles, 684 GLuint relativeOffset, GLenum format) 685{ 686 GLbitfield typeBit; 687 688 /* at most, one of these bools can be true */ 689 assert((int) normalized + (int) integer + (int) doubles <= 1); 690 691 if (ctx->Array.LegalTypesMask == 0 || ctx->Array.LegalTypesMaskAPI != ctx->API) { 692 /* Compute the LegalTypesMask only once, unless the context API has 693 * changed, in which case we want to compute it again. We can't do this 694 * in _mesa_init_varrays() below because extensions are not yet enabled 695 * at that point. 696 */ 697 ctx->Array.LegalTypesMask = get_legal_types_mask(ctx); 698 ctx->Array.LegalTypesMaskAPI = ctx->API; 699 } 700 701 legalTypesMask &= ctx->Array.LegalTypesMask; 702 703 if (_mesa_is_gles(ctx) && sizeMax == BGRA_OR_4) { 704 /* BGRA ordering is not supported in ES contexts. 705 */ 706 sizeMax = 4; 707 } 708 709 typeBit = type_to_bit(ctx, type); 710 if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) { 711 _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)", 712 func, _mesa_enum_to_string(type)); 713 return false; 714 } 715 716 if (format == GL_BGRA) { 717 /* Page 298 of the PDF of the OpenGL 4.3 (Core Profile) spec says: 718 * 719 * "An INVALID_OPERATION error is generated under any of the following 720 * conditions: 721 * ... 722 * • size is BGRA and type is not UNSIGNED_BYTE, INT_2_10_10_10_REV 723 * or UNSIGNED_INT_2_10_10_10_REV; 724 * ... 725 * • size is BGRA and normalized is FALSE;" 726 */ 727 bool bgra_error = false; 728 729 if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) { 730 if (type != GL_UNSIGNED_INT_2_10_10_10_REV && 731 type != GL_INT_2_10_10_10_REV && 732 type != GL_UNSIGNED_BYTE) 733 bgra_error = true; 734 } else if (type != GL_UNSIGNED_BYTE) 735 bgra_error = true; 736 737 if (bgra_error) { 738 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=GL_BGRA and type=%s)", 739 func, _mesa_enum_to_string(type)); 740 return false; 741 } 742 743 if (!normalized) { 744 _mesa_error(ctx, GL_INVALID_OPERATION, 745 "%s(size=GL_BGRA and normalized=GL_FALSE)", func); 746 return false; 747 } 748 } 749 else if (size < sizeMin || size > sizeMax || size > 4) { 750 _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size); 751 return false; 752 } 753 754 if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev && 755 (type == GL_UNSIGNED_INT_2_10_10_10_REV || 756 type == GL_INT_2_10_10_10_REV) && size != 4) { 757 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size); 758 return false; 759 } 760 761 /* The ARB_vertex_attrib_binding_spec says: 762 * 763 * An INVALID_VALUE error is generated if <relativeoffset> is larger than 764 * the value of MAX_VERTEX_ATTRIB_RELATIVE_OFFSET. 765 */ 766 if (relativeOffset > ctx->Const.MaxVertexAttribRelativeOffset) { 767 _mesa_error(ctx, GL_INVALID_VALUE, 768 "%s(relativeOffset=%d > " 769 "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET)", 770 func, relativeOffset); 771 return false; 772 } 773 774 if (ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev && 775 type == GL_UNSIGNED_INT_10F_11F_11F_REV && size != 3) { 776 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size); 777 return false; 778 } 779 780 return true; 781} 782 783/** 784 * Do error checking for glVertex/Color/TexCoord/...Pointer functions. 785 * 786 * \param func name of calling function used for error reporting 787 * \param vao the vao to update 788 * \param obj the bound buffer object 789 * \param attrib the attribute array index to update 790 * \param legalTypes bitmask of *_BIT above indicating legal datatypes 791 * \param sizeMin min allowable size value 792 * \param sizeMax max allowable size value (may also be BGRA_OR_4) 793 * \param size components per element (1, 2, 3 or 4) 794 * \param type datatype of each component (GL_FLOAT, GL_INT, etc) 795 * \param stride stride between elements, in elements 796 * \param normalized are integer types converted to floats in [-1, 1]? 797 * \param integer integer-valued values (will not be normalized to [-1,1]) 798 * \param doubles Double values not reduced to floats 799 * \param ptr the address (or offset inside VBO) of the array data 800 */ 801static void 802validate_array(struct gl_context *ctx, const char *func, 803 struct gl_vertex_array_object *vao, 804 struct gl_buffer_object *obj, 805 GLuint attrib, GLbitfield legalTypesMask, 806 GLint sizeMin, GLint sizeMax, 807 GLint size, GLenum type, GLsizei stride, 808 GLboolean normalized, GLboolean integer, GLboolean doubles, 809 const GLvoid *ptr) 810{ 811 /* Page 407 (page 423 of the PDF) of the OpenGL 3.0 spec says: 812 * 813 * "Client vertex arrays - all vertex array attribute pointers must 814 * refer to buffer objects (section 2.9.2). The default vertex array 815 * object (the name zero) is also deprecated. Calling 816 * VertexAttribPointer when no buffer object or no vertex array object 817 * is bound will generate an INVALID_OPERATION error..." 818 * 819 * The check for VBOs is handled below. 820 */ 821 if (ctx->API == API_OPENGL_CORE && (vao == ctx->Array.DefaultVAO)) { 822 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no array object bound)", 823 func); 824 return; 825 } 826 827 if (stride < 0) { 828 _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride ); 829 return; 830 } 831 832 if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 44 && 833 stride > ctx->Const.MaxVertexAttribStride) { 834 _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > " 835 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride); 836 return; 837 } 838 839 /* Page 29 (page 44 of the PDF) of the OpenGL 3.3 spec says: 840 * 841 * "An INVALID_OPERATION error is generated under any of the following 842 * conditions: 843 * 844 * ... 845 * 846 * * any of the *Pointer commands specifying the location and 847 * organization of vertex array data are called while zero is bound 848 * to the ARRAY_BUFFER buffer object binding point (see section 849 * 2.9.6), and the pointer argument is not NULL." 850 */ 851 if (ptr != NULL && vao != ctx->Array.DefaultVAO && 852 !obj) { 853 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func); 854 return; 855 } 856} 857 858 859static bool 860validate_array_and_format(struct gl_context *ctx, const char *func, 861 struct gl_vertex_array_object *vao, 862 struct gl_buffer_object *obj, 863 GLuint attrib, GLbitfield legalTypes, 864 GLint sizeMin, GLint sizeMax, 865 GLint size, GLenum type, GLsizei stride, 866 GLboolean normalized, GLboolean integer, 867 GLboolean doubles, GLenum format, const GLvoid *ptr) 868{ 869 validate_array(ctx, func, vao, obj, attrib, legalTypes, sizeMin, sizeMax, 870 size, type, stride, normalized, integer, doubles, ptr); 871 872 return validate_array_format(ctx, func, vao, attrib, legalTypes, sizeMin, 873 sizeMax, size, type, normalized, integer, 874 doubles, 0, format); 875} 876 877 878/** 879 * Update state for glVertex/Color/TexCoord/...Pointer functions. 880 * 881 * \param vao the vao to update 882 * \param obj the bound buffer object 883 * \param attrib the attribute array index to update 884 * \param format Either GL_RGBA or GL_BGRA. 885 * \param sizeMax max allowable size value (may also be BGRA_OR_4) 886 * \param size components per element (1, 2, 3 or 4) 887 * \param type datatype of each component (GL_FLOAT, GL_INT, etc) 888 * \param stride stride between elements, in elements 889 * \param normalized are integer types converted to floats in [-1, 1]? 890 * \param integer integer-valued values (will not be normalized to [-1,1]) 891 * \param doubles Double values not reduced to floats 892 * \param ptr the address (or offset inside VBO) of the array data 893 */ 894static void 895update_array(struct gl_context *ctx, 896 struct gl_vertex_array_object *vao, 897 struct gl_buffer_object *obj, 898 GLuint attrib, GLenum format, 899 GLint sizeMax, 900 GLint size, GLenum type, GLsizei stride, 901 GLboolean normalized, GLboolean integer, GLboolean doubles, 902 const GLvoid *ptr) 903{ 904 _mesa_update_array_format(ctx, vao, attrib, size, type, format, 905 normalized, integer, doubles, 0); 906 907 /* Reset the vertex attrib binding */ 908 _mesa_vertex_attrib_binding(ctx, vao, attrib, attrib); 909 910 /* The Stride and Ptr fields are not set by update_array_format() */ 911 struct gl_array_attributes *array = &vao->VertexAttrib[attrib]; 912 if ((array->Stride != stride) || (array->Ptr != ptr)) { 913 array->Stride = stride; 914 array->Ptr = ptr; 915 vao->NewArrays |= vao->Enabled & VERT_BIT(attrib); 916 vao->NonDefaultStateMask |= BITFIELD_BIT(attrib); 917 } 918 919 /* Update the vertex buffer binding */ 920 GLsizei effectiveStride = stride != 0 ? 921 stride : array->Format._ElementSize; 922 _mesa_bind_vertex_buffer(ctx, vao, attrib, 923 obj, (GLintptr) ptr, 924 effectiveStride, false, false); 925} 926 927 928/* Helper function for all EXT_direct_state_access glVertexArray* functions */ 929static bool 930_lookup_vao_and_vbo_dsa(struct gl_context *ctx, 931 GLuint vaobj, GLuint buffer, 932 GLintptr offset, 933 struct gl_vertex_array_object** vao, 934 struct gl_buffer_object** vbo, 935 const char* caller) 936{ 937 *vao = _mesa_lookup_vao_err(ctx, vaobj, true, caller); 938 if (!(*vao)) 939 return false; 940 941 if (buffer != 0) { 942 *vbo = _mesa_lookup_bufferobj(ctx, buffer); 943 if (!_mesa_handle_bind_buffer_gen(ctx, buffer, vbo, caller)) 944 return false; 945 946 if (offset < 0) { 947 _mesa_error(ctx, GL_INVALID_VALUE, 948 "%s(negative offset with non-0 buffer)", caller); 949 return false; 950 } 951 } else { 952 *vbo = NULL; 953 } 954 955 return true; 956} 957 958 959void GLAPIENTRY 960_mesa_VertexPointer_no_error(GLint size, GLenum type, GLsizei stride, 961 const GLvoid *ptr) 962{ 963 GET_CURRENT_CONTEXT(ctx); 964 965 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 966 VERT_ATTRIB_POS, GL_RGBA, 4, size, type, stride, 967 GL_FALSE, GL_FALSE, GL_FALSE, ptr); 968} 969 970 971void GLAPIENTRY 972_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) 973{ 974 GET_CURRENT_CONTEXT(ctx); 975 976 GLenum format = GL_RGBA; 977 GLbitfield legalTypes = (ctx->API == API_OPENGLES) 978 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) 979 : (SHORT_BIT | INT_BIT | FLOAT_BIT | 980 DOUBLE_BIT | HALF_BIT | 981 UNSIGNED_INT_2_10_10_10_REV_BIT | 982 INT_2_10_10_10_REV_BIT); 983 984 if (!validate_array_and_format(ctx, "glVertexPointer", 985 ctx->Array.VAO, ctx->Array.ArrayBufferObj, 986 VERT_ATTRIB_POS, legalTypes, 2, 4, size, 987 type, stride, GL_FALSE, GL_FALSE, GL_FALSE, 988 format, ptr)) 989 return; 990 991 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 992 VERT_ATTRIB_POS, format, 4, size, type, stride, 993 GL_FALSE, GL_FALSE, GL_FALSE, ptr); 994} 995 996 997void GLAPIENTRY 998_mesa_VertexArrayVertexOffsetEXT(GLuint vaobj, GLuint buffer, GLint size, 999 GLenum type, GLsizei stride, GLintptr offset) 1000{ 1001 GET_CURRENT_CONTEXT(ctx); 1002 1003 GLenum format = GL_RGBA; 1004 GLbitfield legalTypes = (ctx->API == API_OPENGLES) 1005 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) 1006 : (SHORT_BIT | INT_BIT | FLOAT_BIT | 1007 DOUBLE_BIT | HALF_BIT | 1008 UNSIGNED_INT_2_10_10_10_REV_BIT | 1009 INT_2_10_10_10_REV_BIT); 1010 1011 struct gl_vertex_array_object* vao; 1012 struct gl_buffer_object* vbo; 1013 1014 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset, 1015 &vao, &vbo, 1016 "glVertexArrayVertexOffsetEXT")) 1017 return; 1018 1019 if (!validate_array_and_format(ctx, "glVertexArrayVertexOffsetEXT", 1020 vao, vbo, 1021 VERT_ATTRIB_POS, legalTypes, 2, 4, size, 1022 type, stride, GL_FALSE, GL_FALSE, GL_FALSE, 1023 format, (void*) offset)) 1024 return; 1025 1026 update_array(ctx, vao, vbo, 1027 VERT_ATTRIB_POS, format, 4, size, type, stride, 1028 GL_FALSE, GL_FALSE, GL_FALSE, (void*) offset); 1029} 1030 1031 1032void GLAPIENTRY 1033_mesa_NormalPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr ) 1034{ 1035 GET_CURRENT_CONTEXT(ctx); 1036 1037 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1038 VERT_ATTRIB_NORMAL, GL_RGBA, 3, 3, type, stride, GL_TRUE, 1039 GL_FALSE, GL_FALSE, ptr); 1040} 1041 1042 1043void GLAPIENTRY 1044_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) 1045{ 1046 GET_CURRENT_CONTEXT(ctx); 1047 1048 GLenum format = GL_RGBA; 1049 const GLbitfield legalTypes = (ctx->API == API_OPENGLES) 1050 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) 1051 : (BYTE_BIT | SHORT_BIT | INT_BIT | 1052 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 1053 UNSIGNED_INT_2_10_10_10_REV_BIT | 1054 INT_2_10_10_10_REV_BIT); 1055 1056 if (!validate_array_and_format(ctx, "glNormalPointer", 1057 ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1058 VERT_ATTRIB_NORMAL, legalTypes, 3, 3, 3, 1059 type, stride, GL_TRUE, GL_FALSE, 1060 GL_FALSE, format, ptr)) 1061 return; 1062 1063 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1064 VERT_ATTRIB_NORMAL, format, 3, 3, type, stride, GL_TRUE, 1065 GL_FALSE, GL_FALSE, ptr); 1066} 1067 1068 1069void GLAPIENTRY 1070_mesa_VertexArrayNormalOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type, 1071 GLsizei stride, GLintptr offset) 1072{ 1073 GET_CURRENT_CONTEXT(ctx); 1074 1075 GLenum format = GL_RGBA; 1076 const GLbitfield legalTypes = (ctx->API == API_OPENGLES) 1077 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) 1078 : (BYTE_BIT | SHORT_BIT | INT_BIT | 1079 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 1080 UNSIGNED_INT_2_10_10_10_REV_BIT | 1081 INT_2_10_10_10_REV_BIT); 1082 1083 struct gl_vertex_array_object* vao; 1084 struct gl_buffer_object* vbo; 1085 1086 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset, 1087 &vao, &vbo, 1088 "glNormalPointer")) 1089 return; 1090 1091 if (!validate_array_and_format(ctx, "glNormalPointer", 1092 vao, vbo, 1093 VERT_ATTRIB_NORMAL, legalTypes, 3, 3, 3, 1094 type, stride, GL_TRUE, GL_FALSE, 1095 GL_FALSE, format, (void*) offset)) 1096 return; 1097 1098 update_array(ctx, vao, vbo, 1099 VERT_ATTRIB_NORMAL, format, 3, 3, type, stride, GL_TRUE, 1100 GL_FALSE, GL_FALSE, (void*) offset); 1101} 1102 1103 1104void GLAPIENTRY 1105_mesa_ColorPointer_no_error(GLint size, GLenum type, GLsizei stride, 1106 const GLvoid *ptr) 1107{ 1108 GET_CURRENT_CONTEXT(ctx); 1109 1110 GLenum format = get_array_format(ctx, BGRA_OR_4, &size); 1111 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1112 VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size, 1113 type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr); 1114} 1115 1116 1117void GLAPIENTRY 1118_mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) 1119{ 1120 GET_CURRENT_CONTEXT(ctx); 1121 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 4 : 3; 1122 1123 GLenum format = get_array_format(ctx, BGRA_OR_4, &size); 1124 const GLbitfield legalTypes = (ctx->API == API_OPENGLES) 1125 ? (UNSIGNED_BYTE_BIT | HALF_BIT | FLOAT_BIT | FIXED_ES_BIT) 1126 : (BYTE_BIT | UNSIGNED_BYTE_BIT | 1127 SHORT_BIT | UNSIGNED_SHORT_BIT | 1128 INT_BIT | UNSIGNED_INT_BIT | 1129 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 1130 UNSIGNED_INT_2_10_10_10_REV_BIT | 1131 INT_2_10_10_10_REV_BIT); 1132 1133 if (!validate_array_and_format(ctx, "glColorPointer", 1134 ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1135 VERT_ATTRIB_COLOR0, legalTypes, sizeMin, 1136 BGRA_OR_4, size, type, stride, GL_TRUE, 1137 GL_FALSE, GL_FALSE, format, ptr)) 1138 return; 1139 1140 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1141 VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size, 1142 type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr); 1143} 1144 1145 1146void GLAPIENTRY 1147_mesa_VertexArrayColorOffsetEXT(GLuint vaobj, GLuint buffer, GLint size, 1148 GLenum type, GLsizei stride, GLintptr offset) 1149{ 1150 GET_CURRENT_CONTEXT(ctx); 1151 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 4 : 3; 1152 1153 GLenum format = get_array_format(ctx, BGRA_OR_4, &size); 1154 const GLbitfield legalTypes = (ctx->API == API_OPENGLES) 1155 ? (UNSIGNED_BYTE_BIT | HALF_BIT | FLOAT_BIT | FIXED_ES_BIT) 1156 : (BYTE_BIT | UNSIGNED_BYTE_BIT | 1157 SHORT_BIT | UNSIGNED_SHORT_BIT | 1158 INT_BIT | UNSIGNED_INT_BIT | 1159 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 1160 UNSIGNED_INT_2_10_10_10_REV_BIT | 1161 INT_2_10_10_10_REV_BIT); 1162 1163 struct gl_vertex_array_object* vao; 1164 struct gl_buffer_object* vbo; 1165 1166 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset, 1167 &vao, &vbo, 1168 "glVertexArrayColorOffsetEXT")) 1169 return; 1170 1171 if (!validate_array_and_format(ctx, "glVertexArrayColorOffsetEXT", 1172 vao, vbo, 1173 VERT_ATTRIB_COLOR0, legalTypes, sizeMin, 1174 BGRA_OR_4, size, type, stride, GL_TRUE, 1175 GL_FALSE, GL_FALSE, format, (void*) offset)) 1176 return; 1177 1178 update_array(ctx, vao, vbo, 1179 VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size, 1180 type, stride, GL_TRUE, GL_FALSE, GL_FALSE, (void*) offset); 1181} 1182 1183 1184void GLAPIENTRY 1185_mesa_FogCoordPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr) 1186{ 1187 GET_CURRENT_CONTEXT(ctx); 1188 1189 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1190 VERT_ATTRIB_FOG, GL_RGBA, 1, 1, type, stride, GL_FALSE, 1191 GL_FALSE, GL_FALSE, ptr); 1192} 1193 1194 1195void GLAPIENTRY 1196_mesa_FogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr) 1197{ 1198 GET_CURRENT_CONTEXT(ctx); 1199 1200 GLenum format = GL_RGBA; 1201 const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT); 1202 1203 if (!validate_array_and_format(ctx, "glFogCoordPointer", 1204 ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1205 VERT_ATTRIB_FOG, legalTypes, 1, 1, 1, 1206 type, stride, GL_FALSE, GL_FALSE, 1207 GL_FALSE, format, ptr)) 1208 return; 1209 1210 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1211 VERT_ATTRIB_FOG, format, 1, 1, type, stride, GL_FALSE, 1212 GL_FALSE, GL_FALSE, ptr); 1213} 1214 1215 1216void GLAPIENTRY 1217_mesa_VertexArrayFogCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type, 1218 GLsizei stride, GLintptr offset) 1219{ 1220 GET_CURRENT_CONTEXT(ctx); 1221 1222 GLenum format = GL_RGBA; 1223 const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT); 1224 1225 struct gl_vertex_array_object* vao; 1226 struct gl_buffer_object* vbo; 1227 1228 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset, 1229 &vao, &vbo, 1230 "glVertexArrayFogCoordOffsetEXT")) 1231 return; 1232 1233 if (!validate_array_and_format(ctx, "glVertexArrayFogCoordOffsetEXT", 1234 vao, vbo, 1235 VERT_ATTRIB_FOG, legalTypes, 1, 1, 1, 1236 type, stride, GL_FALSE, GL_FALSE, 1237 GL_FALSE, format, (void*) offset)) 1238 return; 1239 1240 update_array(ctx, vao, vbo, 1241 VERT_ATTRIB_FOG, format, 1, 1, type, stride, GL_FALSE, 1242 GL_FALSE, GL_FALSE, (void*) offset); 1243} 1244 1245 1246void GLAPIENTRY 1247_mesa_IndexPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr) 1248{ 1249 GET_CURRENT_CONTEXT(ctx); 1250 1251 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1252 VERT_ATTRIB_COLOR_INDEX, GL_RGBA, 1, 1, type, stride, 1253 GL_FALSE, GL_FALSE, GL_FALSE, ptr); 1254} 1255 1256 1257void GLAPIENTRY 1258_mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr) 1259{ 1260 GET_CURRENT_CONTEXT(ctx); 1261 1262 GLenum format = GL_RGBA; 1263 const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT | 1264 FLOAT_BIT | DOUBLE_BIT); 1265 1266 if (!validate_array_and_format(ctx, "glIndexPointer", 1267 ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1268 VERT_ATTRIB_COLOR_INDEX, 1269 legalTypes, 1, 1, 1, type, stride, 1270 GL_FALSE, GL_FALSE, GL_FALSE, format, ptr)) 1271 return; 1272 1273 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1274 VERT_ATTRIB_COLOR_INDEX, format, 1, 1, type, stride, 1275 GL_FALSE, GL_FALSE, GL_FALSE, ptr); 1276} 1277 1278 1279void GLAPIENTRY 1280_mesa_VertexArrayIndexOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type, 1281 GLsizei stride, GLintptr offset) 1282{ 1283 GET_CURRENT_CONTEXT(ctx); 1284 1285 GLenum format = GL_RGBA; 1286 const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT | 1287 FLOAT_BIT | DOUBLE_BIT); 1288 1289 struct gl_vertex_array_object* vao; 1290 struct gl_buffer_object* vbo; 1291 1292 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset, 1293 &vao, &vbo, 1294 "glVertexArrayIndexOffsetEXT")) 1295 return; 1296 1297 if (!validate_array_and_format(ctx, "glVertexArrayIndexOffsetEXT", 1298 vao, vbo, 1299 VERT_ATTRIB_COLOR_INDEX, 1300 legalTypes, 1, 1, 1, type, stride, 1301 GL_FALSE, GL_FALSE, GL_FALSE, format, (void*) offset)) 1302 return; 1303 1304 update_array(ctx, vao, vbo, 1305 VERT_ATTRIB_COLOR_INDEX, format, 1, 1, type, stride, 1306 GL_FALSE, GL_FALSE, GL_FALSE, (void*) offset); 1307} 1308 1309 1310void GLAPIENTRY 1311_mesa_SecondaryColorPointer_no_error(GLint size, GLenum type, 1312 GLsizei stride, const GLvoid *ptr) 1313{ 1314 GET_CURRENT_CONTEXT(ctx); 1315 1316 GLenum format = get_array_format(ctx, BGRA_OR_4, &size); 1317 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1318 VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type, 1319 stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr); 1320} 1321 1322 1323void GLAPIENTRY 1324_mesa_SecondaryColorPointer(GLint size, GLenum type, 1325 GLsizei stride, const GLvoid *ptr) 1326{ 1327 GET_CURRENT_CONTEXT(ctx); 1328 1329 GLenum format = get_array_format(ctx, BGRA_OR_4, &size); 1330 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | 1331 SHORT_BIT | UNSIGNED_SHORT_BIT | 1332 INT_BIT | UNSIGNED_INT_BIT | 1333 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 1334 UNSIGNED_INT_2_10_10_10_REV_BIT | 1335 INT_2_10_10_10_REV_BIT); 1336 1337 if (!validate_array_and_format(ctx, "glSecondaryColorPointer", 1338 ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1339 VERT_ATTRIB_COLOR1, legalTypes, 3, 1340 BGRA_OR_4, size, type, stride, 1341 GL_TRUE, GL_FALSE, GL_FALSE, format, ptr)) 1342 return; 1343 1344 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1345 VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type, 1346 stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr); 1347} 1348 1349 1350void GLAPIENTRY 1351_mesa_VertexArraySecondaryColorOffsetEXT(GLuint vaobj, GLuint buffer, GLint size, 1352 GLenum type, GLsizei stride, GLintptr offset) 1353{ 1354 GET_CURRENT_CONTEXT(ctx); 1355 1356 GLenum format = get_array_format(ctx, BGRA_OR_4, &size); 1357 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | 1358 SHORT_BIT | UNSIGNED_SHORT_BIT | 1359 INT_BIT | UNSIGNED_INT_BIT | 1360 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 1361 UNSIGNED_INT_2_10_10_10_REV_BIT | 1362 INT_2_10_10_10_REV_BIT); 1363 1364 struct gl_vertex_array_object* vao; 1365 struct gl_buffer_object* vbo; 1366 1367 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset, 1368 &vao, &vbo, 1369 "glVertexArraySecondaryColorOffsetEXT")) 1370 return; 1371 1372 if (!validate_array_and_format(ctx, "glVertexArraySecondaryColorOffsetEXT", 1373 vao, vbo, 1374 VERT_ATTRIB_COLOR1, legalTypes, 3, 1375 BGRA_OR_4, size, type, stride, 1376 GL_TRUE, GL_FALSE, GL_FALSE, format, (void*) offset)) 1377 return; 1378 1379 update_array(ctx, vao, vbo, 1380 VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type, 1381 stride, GL_TRUE, GL_FALSE, GL_FALSE, (void*) offset); 1382} 1383 1384 1385void GLAPIENTRY 1386_mesa_TexCoordPointer_no_error(GLint size, GLenum type, GLsizei stride, 1387 const GLvoid *ptr) 1388{ 1389 GET_CURRENT_CONTEXT(ctx); 1390 const GLuint unit = ctx->Array.ActiveTexture; 1391 1392 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1393 VERT_ATTRIB_TEX(unit), GL_RGBA, 4, size, type, 1394 stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); 1395} 1396 1397 1398void GLAPIENTRY 1399_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, 1400 const GLvoid *ptr) 1401{ 1402 GET_CURRENT_CONTEXT(ctx); 1403 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1; 1404 const GLuint unit = ctx->Array.ActiveTexture; 1405 1406 GLenum format = GL_RGBA; 1407 const GLbitfield legalTypes = (ctx->API == API_OPENGLES) 1408 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) 1409 : (SHORT_BIT | INT_BIT | 1410 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 1411 UNSIGNED_INT_2_10_10_10_REV_BIT | 1412 INT_2_10_10_10_REV_BIT); 1413 1414 if (!validate_array_and_format(ctx, "glTexCoordPointer", 1415 ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1416 VERT_ATTRIB_TEX(unit), legalTypes, 1417 sizeMin, 4, size, type, stride, 1418 GL_FALSE, GL_FALSE, GL_FALSE, format, ptr)) 1419 return; 1420 1421 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1422 VERT_ATTRIB_TEX(unit), format, 4, size, type, 1423 stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); 1424} 1425 1426 1427void GLAPIENTRY 1428_mesa_VertexArrayTexCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLint size, 1429 GLenum type, GLsizei stride, GLintptr offset) 1430{ 1431 GET_CURRENT_CONTEXT(ctx); 1432 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1; 1433 const GLuint unit = ctx->Array.ActiveTexture; 1434 1435 GLenum format = GL_RGBA; 1436 const GLbitfield legalTypes = (ctx->API == API_OPENGLES) 1437 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) 1438 : (SHORT_BIT | INT_BIT | 1439 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 1440 UNSIGNED_INT_2_10_10_10_REV_BIT | 1441 INT_2_10_10_10_REV_BIT); 1442 1443 struct gl_vertex_array_object* vao; 1444 struct gl_buffer_object* vbo; 1445 1446 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset, 1447 &vao, &vbo, 1448 "glVertexArrayTexCoordOffsetEXT")) 1449 return; 1450 1451 if (!validate_array_and_format(ctx, "glVertexArrayTexCoordOffsetEXT", 1452 vao, vbo, 1453 VERT_ATTRIB_TEX(unit), legalTypes, 1454 sizeMin, 4, size, type, stride, 1455 GL_FALSE, GL_FALSE, GL_FALSE, format, (void*) offset)) 1456 return; 1457 1458 update_array(ctx, vao, vbo, 1459 VERT_ATTRIB_TEX(unit), format, 4, size, type, 1460 stride, GL_FALSE, GL_FALSE, GL_FALSE, (void*) offset); 1461} 1462 1463 1464void GLAPIENTRY 1465_mesa_VertexArrayMultiTexCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLenum texunit, 1466 GLint size, GLenum type, GLsizei stride, 1467 GLintptr offset) 1468{ 1469 GET_CURRENT_CONTEXT(ctx); 1470 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1; 1471 const GLuint unit = texunit - GL_TEXTURE0; 1472 1473 GLenum format = GL_RGBA; 1474 const GLbitfield legalTypes = (ctx->API == API_OPENGLES) 1475 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) 1476 : (SHORT_BIT | INT_BIT | 1477 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 1478 UNSIGNED_INT_2_10_10_10_REV_BIT | 1479 INT_2_10_10_10_REV_BIT); 1480 1481 struct gl_vertex_array_object* vao; 1482 struct gl_buffer_object* vbo; 1483 1484 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset, 1485 &vao, &vbo, 1486 "glVertexArrayMultiTexCoordOffsetEXT")) 1487 return; 1488 1489 if (unit >= ctx->Const.MaxCombinedTextureImageUnits) { 1490 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexArrayMultiTexCoordOffsetEXT(texunit=%d)", 1491 texunit); 1492 return; 1493 } 1494 1495 if (!validate_array_and_format(ctx, "glVertexArrayMultiTexCoordOffsetEXT", 1496 vao, vbo, 1497 VERT_ATTRIB_TEX(unit), legalTypes, 1498 sizeMin, 4, size, type, stride, 1499 GL_FALSE, GL_FALSE, GL_FALSE, format, (void*) offset)) 1500 return; 1501 1502 update_array(ctx, vao, vbo, 1503 VERT_ATTRIB_TEX(unit), format, 4, size, type, 1504 stride, GL_FALSE, GL_FALSE, GL_FALSE, (void*) offset); 1505} 1506 1507 1508void GLAPIENTRY 1509_mesa_EdgeFlagPointer_no_error(GLsizei stride, const GLvoid *ptr) 1510{ 1511 /* this is the same type that glEdgeFlag uses */ 1512 const GLboolean integer = GL_FALSE; 1513 GET_CURRENT_CONTEXT(ctx); 1514 1515 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1516 VERT_ATTRIB_EDGEFLAG, GL_RGBA, 1, 1, GL_UNSIGNED_BYTE, 1517 stride, GL_FALSE, integer, GL_FALSE, ptr); 1518} 1519 1520 1521void GLAPIENTRY 1522_mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr) 1523{ 1524 /* this is the same type that glEdgeFlag uses */ 1525 const GLboolean integer = GL_FALSE; 1526 GET_CURRENT_CONTEXT(ctx); 1527 1528 GLenum format = GL_RGBA; 1529 const GLbitfield legalTypes = UNSIGNED_BYTE_BIT; 1530 1531 if (!validate_array_and_format(ctx, "glEdgeFlagPointer", 1532 ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1533 VERT_ATTRIB_EDGEFLAG, legalTypes, 1534 1, 1, 1, GL_UNSIGNED_BYTE, stride, 1535 GL_FALSE, integer, GL_FALSE, format, ptr)) 1536 return; 1537 1538 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1539 VERT_ATTRIB_EDGEFLAG, format, 1, 1, GL_UNSIGNED_BYTE, 1540 stride, GL_FALSE, integer, GL_FALSE, ptr); 1541} 1542 1543 1544void GLAPIENTRY 1545_mesa_VertexArrayEdgeFlagOffsetEXT(GLuint vaobj, GLuint buffer, GLsizei stride, 1546 GLintptr offset) 1547{ 1548 /* this is the same type that glEdgeFlag uses */ 1549 const GLboolean integer = GL_FALSE; 1550 GET_CURRENT_CONTEXT(ctx); 1551 1552 GLenum format = GL_RGBA; 1553 const GLbitfield legalTypes = UNSIGNED_BYTE_BIT; 1554 1555 struct gl_vertex_array_object* vao; 1556 struct gl_buffer_object* vbo; 1557 1558 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset, 1559 &vao, &vbo, 1560 "glVertexArrayEdgeFlagOffsetEXT")) 1561 return; 1562 1563 if (!validate_array_and_format(ctx, "glVertexArrayEdgeFlagOffsetEXT", 1564 vao, vbo, 1565 VERT_ATTRIB_EDGEFLAG, legalTypes, 1566 1, 1, 1, GL_UNSIGNED_BYTE, stride, 1567 GL_FALSE, integer, GL_FALSE, format, (void*) offset)) 1568 return; 1569 1570 update_array(ctx, vao, vbo, 1571 VERT_ATTRIB_EDGEFLAG, format, 1, 1, GL_UNSIGNED_BYTE, 1572 stride, GL_FALSE, integer, GL_FALSE, (void*) offset); 1573} 1574 1575 1576void GLAPIENTRY 1577_mesa_PointSizePointerOES_no_error(GLenum type, GLsizei stride, 1578 const GLvoid *ptr) 1579{ 1580 GET_CURRENT_CONTEXT(ctx); 1581 1582 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1583 VERT_ATTRIB_POINT_SIZE, GL_RGBA, 1, 1, type, stride, 1584 GL_FALSE, GL_FALSE, GL_FALSE, ptr); 1585} 1586 1587 1588void GLAPIENTRY 1589_mesa_PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *ptr) 1590{ 1591 GET_CURRENT_CONTEXT(ctx); 1592 1593 GLenum format = GL_RGBA; 1594 if (ctx->API != API_OPENGLES) { 1595 _mesa_error(ctx, GL_INVALID_OPERATION, 1596 "glPointSizePointer(ES 1.x only)"); 1597 return; 1598 } 1599 1600 const GLbitfield legalTypes = (FLOAT_BIT | FIXED_ES_BIT); 1601 1602 if (!validate_array_and_format(ctx, "glPointSizePointer", 1603 ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1604 VERT_ATTRIB_POINT_SIZE, legalTypes, 1605 1, 1, 1, type, stride, GL_FALSE, GL_FALSE, 1606 GL_FALSE, format, ptr)) 1607 return; 1608 1609 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1610 VERT_ATTRIB_POINT_SIZE, format, 1, 1, type, stride, 1611 GL_FALSE, GL_FALSE, GL_FALSE, ptr); 1612} 1613 1614 1615void GLAPIENTRY 1616_mesa_VertexAttribPointer_no_error(GLuint index, GLint size, GLenum type, 1617 GLboolean normalized, 1618 GLsizei stride, const GLvoid *ptr) 1619{ 1620 GET_CURRENT_CONTEXT(ctx); 1621 1622 GLenum format = get_array_format(ctx, BGRA_OR_4, &size); 1623 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1624 VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4, 1625 size, type, stride, normalized, GL_FALSE, GL_FALSE, ptr); 1626} 1627 1628 1629/** 1630 * Set a generic vertex attribute array. 1631 * Note that these arrays DO NOT alias the conventional GL vertex arrays 1632 * (position, normal, color, fog, texcoord, etc). 1633 */ 1634void GLAPIENTRY 1635_mesa_VertexAttribPointer(GLuint index, GLint size, GLenum type, 1636 GLboolean normalized, 1637 GLsizei stride, const GLvoid *ptr) 1638{ 1639 GET_CURRENT_CONTEXT(ctx); 1640 1641 GLenum format = get_array_format(ctx, BGRA_OR_4, &size); 1642 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 1643 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(idx)"); 1644 return; 1645 } 1646 1647 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | 1648 SHORT_BIT | UNSIGNED_SHORT_BIT | 1649 INT_BIT | UNSIGNED_INT_BIT | 1650 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 1651 FIXED_ES_BIT | FIXED_GL_BIT | 1652 UNSIGNED_INT_2_10_10_10_REV_BIT | 1653 INT_2_10_10_10_REV_BIT | 1654 UNSIGNED_INT_10F_11F_11F_REV_BIT); 1655 1656 if (!validate_array_and_format(ctx, "glVertexAttribPointer", 1657 ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1658 VERT_ATTRIB_GENERIC(index), legalTypes, 1659 1, BGRA_OR_4, size, type, stride, 1660 normalized, GL_FALSE, GL_FALSE, format, ptr)) 1661 return; 1662 1663 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1664 VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4, 1665 size, type, stride, normalized, GL_FALSE, GL_FALSE, ptr); 1666} 1667 1668 1669void GLAPIENTRY 1670_mesa_VertexArrayVertexAttribOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, 1671 GLenum type, GLboolean normalized, 1672 GLsizei stride, GLintptr offset) 1673{ 1674 GET_CURRENT_CONTEXT(ctx); 1675 GLenum format = get_array_format(ctx, BGRA_OR_4, &size); 1676 struct gl_vertex_array_object* vao; 1677 struct gl_buffer_object* vbo; 1678 1679 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset, 1680 &vao, &vbo, 1681 "glVertexArrayVertexAttribOffsetEXT")) 1682 return; 1683 1684 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 1685 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexArrayVertexAttribOffsetEXT(idx)"); 1686 return; 1687 } 1688 1689 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | 1690 SHORT_BIT | UNSIGNED_SHORT_BIT | 1691 INT_BIT | UNSIGNED_INT_BIT | 1692 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 1693 FIXED_ES_BIT | FIXED_GL_BIT | 1694 UNSIGNED_INT_2_10_10_10_REV_BIT | 1695 INT_2_10_10_10_REV_BIT | 1696 UNSIGNED_INT_10F_11F_11F_REV_BIT); 1697 1698 if (!validate_array_and_format(ctx, "glVertexArrayVertexAttribOffsetEXT", 1699 vao, vbo, 1700 VERT_ATTRIB_GENERIC(index), legalTypes, 1701 1, BGRA_OR_4, size, type, stride, 1702 normalized, GL_FALSE, GL_FALSE, format, (void*) offset)) 1703 return; 1704 1705 update_array(ctx, vao, vbo, 1706 VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4, 1707 size, type, stride, normalized, GL_FALSE, GL_FALSE, (void*) offset); 1708} 1709 1710 1711void GLAPIENTRY 1712_mesa_VertexArrayVertexAttribLOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, 1713 GLenum type, GLsizei stride, GLintptr offset) 1714{ 1715 GET_CURRENT_CONTEXT(ctx); 1716 GLenum format = GL_RGBA; 1717 struct gl_vertex_array_object* vao; 1718 struct gl_buffer_object* vbo; 1719 1720 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset, 1721 &vao, &vbo, 1722 "glVertexArrayVertexAttribLOffsetEXT")) 1723 return; 1724 1725 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 1726 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexArrayVertexAttribLOffsetEXT(idx)"); 1727 return; 1728 } 1729 1730 const GLbitfield legalTypes = DOUBLE_BIT; 1731 1732 if (!validate_array_and_format(ctx, "glVertexArrayVertexAttribLOffsetEXT", 1733 vao, vbo, 1734 VERT_ATTRIB_GENERIC(index), legalTypes, 1735 1, 4, size, type, stride, 1736 GL_FALSE, GL_FALSE, GL_TRUE, format, (void*) offset)) 1737 return; 1738 1739 update_array(ctx, vao, vbo, 1740 VERT_ATTRIB_GENERIC(index), format, 4, 1741 size, type, stride, GL_FALSE, GL_FALSE, GL_TRUE, (void*) offset); 1742} 1743 1744 1745void GLAPIENTRY 1746_mesa_VertexAttribIPointer_no_error(GLuint index, GLint size, GLenum type, 1747 GLsizei stride, const GLvoid *ptr) 1748{ 1749 const GLboolean normalized = GL_FALSE; 1750 const GLboolean integer = GL_TRUE; 1751 GET_CURRENT_CONTEXT(ctx); 1752 1753 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1754 VERT_ATTRIB_GENERIC(index), GL_RGBA, 4, size, type, 1755 stride, normalized, integer, GL_FALSE, ptr); 1756} 1757 1758 1759/** 1760 * GL_EXT_gpu_shader4 / GL 3.0. 1761 * Set an integer-valued vertex attribute array. 1762 * Note that these arrays DO NOT alias the conventional GL vertex arrays 1763 * (position, normal, color, fog, texcoord, etc). 1764 */ 1765void GLAPIENTRY 1766_mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type, 1767 GLsizei stride, const GLvoid *ptr) 1768{ 1769 const GLboolean normalized = GL_FALSE; 1770 const GLboolean integer = GL_TRUE; 1771 GET_CURRENT_CONTEXT(ctx); 1772 1773 GLenum format = GL_RGBA; 1774 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 1775 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIPointer(index)"); 1776 return; 1777 } 1778 1779 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | 1780 SHORT_BIT | UNSIGNED_SHORT_BIT | 1781 INT_BIT | UNSIGNED_INT_BIT); 1782 1783 if (!validate_array_and_format(ctx, "glVertexAttribIPointer", 1784 ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1785 VERT_ATTRIB_GENERIC(index), legalTypes, 1786 1, 4, size, type, stride, 1787 normalized, integer, GL_FALSE, format, ptr)) 1788 return; 1789 1790 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1791 VERT_ATTRIB_GENERIC(index), format, 4, size, type, 1792 stride, normalized, integer, GL_FALSE, ptr); 1793} 1794 1795 1796void GLAPIENTRY 1797_mesa_VertexAttribLPointer_no_error(GLuint index, GLint size, GLenum type, 1798 GLsizei stride, const GLvoid *ptr) 1799{ 1800 GET_CURRENT_CONTEXT(ctx); 1801 1802 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1803 VERT_ATTRIB_GENERIC(index), GL_RGBA, 4, size, type, 1804 stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr); 1805} 1806 1807 1808void GLAPIENTRY 1809_mesa_VertexArrayVertexAttribIOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, 1810 GLenum type, GLsizei stride, GLintptr offset) 1811{ 1812 const GLboolean normalized = GL_FALSE; 1813 const GLboolean integer = GL_TRUE; 1814 GET_CURRENT_CONTEXT(ctx); 1815 GLenum format = GL_RGBA; 1816 1817 struct gl_vertex_array_object* vao; 1818 struct gl_buffer_object* vbo; 1819 1820 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset, 1821 &vao, &vbo, 1822 "glVertexArrayVertexAttribIOffsetEXT")) 1823 return; 1824 1825 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 1826 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexArrayVertexAttribIOffsetEXT(index)"); 1827 return; 1828 } 1829 1830 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | 1831 SHORT_BIT | UNSIGNED_SHORT_BIT | 1832 INT_BIT | UNSIGNED_INT_BIT); 1833 1834 if (!validate_array_and_format(ctx, "glVertexArrayVertexAttribIOffsetEXT", 1835 vao, vbo, 1836 VERT_ATTRIB_GENERIC(index), legalTypes, 1837 1, 4, size, type, stride, 1838 normalized, integer, GL_FALSE, format, (void*) offset)) 1839 return; 1840 1841 update_array(ctx, vao, vbo, 1842 VERT_ATTRIB_GENERIC(index), format, 4, size, type, 1843 stride, normalized, integer, GL_FALSE, (void*) offset); 1844} 1845 1846 1847void GLAPIENTRY 1848_mesa_VertexAttribLPointer(GLuint index, GLint size, GLenum type, 1849 GLsizei stride, const GLvoid *ptr) 1850{ 1851 GET_CURRENT_CONTEXT(ctx); 1852 1853 GLenum format = GL_RGBA; 1854 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 1855 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribLPointer(index)"); 1856 return; 1857 } 1858 1859 const GLbitfield legalTypes = DOUBLE_BIT; 1860 1861 if (!validate_array_and_format(ctx, "glVertexAttribLPointer", 1862 ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1863 VERT_ATTRIB_GENERIC(index), legalTypes, 1864 1, 4, size, type, stride, 1865 GL_FALSE, GL_FALSE, GL_TRUE, format, ptr)) 1866 return; 1867 1868 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 1869 VERT_ATTRIB_GENERIC(index), format, 4, size, type, 1870 stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr); 1871} 1872 1873 1874void 1875_mesa_enable_vertex_array_attribs(struct gl_context *ctx, 1876 struct gl_vertex_array_object *vao, 1877 GLbitfield attrib_bits) 1878{ 1879 assert((attrib_bits & ~VERT_BIT_ALL) == 0); 1880 assert(!vao->SharedAndImmutable); 1881 1882 /* Only work on bits that are disabled */ 1883 attrib_bits &= ~vao->Enabled; 1884 if (attrib_bits) { 1885 /* was disabled, now being enabled */ 1886 vao->Enabled |= attrib_bits; 1887 vao->NewArrays |= attrib_bits; 1888 vao->NonDefaultStateMask |= attrib_bits; 1889 1890 /* Update the map mode if needed */ 1891 if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0)) 1892 update_attribute_map_mode(ctx, vao); 1893 1894 vao->_EnabledWithMapMode = 1895 _mesa_vao_enable_to_vp_inputs(vao->_AttributeMapMode, vao->Enabled); 1896 } 1897} 1898 1899static void 1900enable_vertex_array_attrib(struct gl_context *ctx, 1901 struct gl_vertex_array_object *vao, 1902 GLuint index, 1903 const char *func) 1904{ 1905 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 1906 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func); 1907 return; 1908 } 1909 1910 _mesa_enable_vertex_array_attrib(ctx, vao, VERT_ATTRIB_GENERIC(index)); 1911} 1912 1913 1914void GLAPIENTRY 1915_mesa_EnableVertexAttribArray(GLuint index) 1916{ 1917 GET_CURRENT_CONTEXT(ctx); 1918 enable_vertex_array_attrib(ctx, ctx->Array.VAO, index, 1919 "glEnableVertexAttribArray"); 1920} 1921 1922 1923void GLAPIENTRY 1924_mesa_EnableVertexAttribArray_no_error(GLuint index) 1925{ 1926 GET_CURRENT_CONTEXT(ctx); 1927 _mesa_enable_vertex_array_attrib(ctx, ctx->Array.VAO, 1928 VERT_ATTRIB_GENERIC(index)); 1929} 1930 1931 1932void GLAPIENTRY 1933_mesa_EnableVertexArrayAttrib(GLuint vaobj, GLuint index) 1934{ 1935 GET_CURRENT_CONTEXT(ctx); 1936 struct gl_vertex_array_object *vao; 1937 1938 /* The ARB_direct_state_access specification says: 1939 * 1940 * "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib 1941 * and DisableVertexArrayAttrib if <vaobj> is not 1942 * [compatibility profile: zero or] the name of an existing vertex 1943 * array object." 1944 */ 1945 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glEnableVertexArrayAttrib"); 1946 if (!vao) 1947 return; 1948 1949 enable_vertex_array_attrib(ctx, vao, index, "glEnableVertexArrayAttrib"); 1950} 1951 1952void GLAPIENTRY 1953_mesa_EnableVertexArrayAttribEXT(GLuint vaobj, GLuint index) 1954{ 1955 GET_CURRENT_CONTEXT(ctx); 1956 struct gl_vertex_array_object* vao = _mesa_lookup_vao_err(ctx, vaobj, 1957 true, 1958 "glEnableVertexArrayAttribEXT"); 1959 if (!vao) 1960 return; 1961 1962 enable_vertex_array_attrib(ctx, vao, index, "glEnableVertexArrayAttribEXT"); 1963} 1964 1965 1966void GLAPIENTRY 1967_mesa_EnableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index) 1968{ 1969 GET_CURRENT_CONTEXT(ctx); 1970 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj); 1971 _mesa_enable_vertex_array_attrib(ctx, vao, VERT_ATTRIB_GENERIC(index)); 1972} 1973 1974 1975void 1976_mesa_disable_vertex_array_attribs(struct gl_context *ctx, 1977 struct gl_vertex_array_object *vao, 1978 GLbitfield attrib_bits) 1979{ 1980 assert((attrib_bits & ~VERT_BIT_ALL) == 0); 1981 assert(!vao->SharedAndImmutable); 1982 1983 /* Only work on bits that are enabled */ 1984 attrib_bits &= vao->Enabled; 1985 if (attrib_bits) { 1986 /* was enabled, now being disabled */ 1987 vao->Enabled &= ~attrib_bits; 1988 vao->NewArrays |= attrib_bits; 1989 1990 /* Update the map mode if needed */ 1991 if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0)) 1992 update_attribute_map_mode(ctx, vao); 1993 1994 vao->_EnabledWithMapMode = 1995 _mesa_vao_enable_to_vp_inputs(vao->_AttributeMapMode, vao->Enabled); 1996 } 1997} 1998 1999 2000void GLAPIENTRY 2001_mesa_DisableVertexAttribArray(GLuint index) 2002{ 2003 GET_CURRENT_CONTEXT(ctx); 2004 2005 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 2006 _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexAttribArray(index)"); 2007 return; 2008 } 2009 2010 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index); 2011 _mesa_disable_vertex_array_attrib(ctx, ctx->Array.VAO, attrib); 2012} 2013 2014 2015void GLAPIENTRY 2016_mesa_DisableVertexAttribArray_no_error(GLuint index) 2017{ 2018 GET_CURRENT_CONTEXT(ctx); 2019 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index); 2020 _mesa_disable_vertex_array_attrib(ctx, ctx->Array.VAO, attrib); 2021} 2022 2023 2024void GLAPIENTRY 2025_mesa_DisableVertexArrayAttrib(GLuint vaobj, GLuint index) 2026{ 2027 GET_CURRENT_CONTEXT(ctx); 2028 struct gl_vertex_array_object *vao; 2029 2030 /* The ARB_direct_state_access specification says: 2031 * 2032 * "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib 2033 * and DisableVertexArrayAttrib if <vaobj> is not 2034 * [compatibility profile: zero or] the name of an existing vertex 2035 * array object." 2036 */ 2037 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glDisableVertexArrayAttrib"); 2038 if (!vao) 2039 return; 2040 2041 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 2042 _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexArrayAttrib(index)"); 2043 return; 2044 } 2045 2046 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index); 2047 _mesa_disable_vertex_array_attrib(ctx, vao, attrib); 2048} 2049 2050void GLAPIENTRY 2051_mesa_DisableVertexArrayAttribEXT(GLuint vaobj, GLuint index) 2052{ 2053 GET_CURRENT_CONTEXT(ctx); 2054 struct gl_vertex_array_object* vao = _mesa_lookup_vao_err(ctx, vaobj, 2055 true, 2056 "glEnableVertexArrayAttribEXT"); 2057 if (!vao) 2058 return; 2059 2060 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 2061 _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexArrayAttrib(index)"); 2062 return; 2063 } 2064 2065 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index); 2066 _mesa_disable_vertex_array_attrib(ctx, vao, attrib); 2067} 2068 2069 2070void GLAPIENTRY 2071_mesa_DisableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index) 2072{ 2073 GET_CURRENT_CONTEXT(ctx); 2074 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj); 2075 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index); 2076 _mesa_disable_vertex_array_attrib(ctx, vao, attrib); 2077} 2078 2079 2080/** 2081 * Return info for a vertex attribute array (no alias with legacy 2082 * vertex attributes (pos, normal, color, etc)). This function does 2083 * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query. 2084 */ 2085static GLuint 2086get_vertex_array_attrib(struct gl_context *ctx, 2087 const struct gl_vertex_array_object *vao, 2088 GLuint index, GLenum pname, 2089 const char *caller) 2090{ 2091 const struct gl_array_attributes *array; 2092 struct gl_buffer_object *buf; 2093 2094 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 2095 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index); 2096 return 0; 2097 } 2098 2099 assert(VERT_ATTRIB_GENERIC(index) < ARRAY_SIZE(vao->VertexAttrib)); 2100 2101 array = &vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)]; 2102 2103 switch (pname) { 2104 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB: 2105 return !!(vao->Enabled & VERT_BIT_GENERIC(index)); 2106 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB: 2107 return (array->Format.Format == GL_BGRA) ? GL_BGRA : array->Format.Size; 2108 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB: 2109 return array->Stride; 2110 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB: 2111 return array->Format.Type; 2112 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB: 2113 return array->Format.Normalized; 2114 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB: 2115 buf = vao->BufferBinding[array->BufferBindingIndex].BufferObj; 2116 return buf ? buf->Name : 0; 2117 case GL_VERTEX_ATTRIB_ARRAY_INTEGER: 2118 if ((_mesa_is_desktop_gl(ctx) 2119 && (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4)) 2120 || _mesa_is_gles3(ctx)) { 2121 return array->Format.Integer; 2122 } 2123 goto error; 2124 case GL_VERTEX_ATTRIB_ARRAY_LONG: 2125 if (_mesa_is_desktop_gl(ctx)) { 2126 return array->Format.Doubles; 2127 } 2128 goto error; 2129 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB: 2130 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_instanced_arrays) 2131 || _mesa_is_gles3(ctx)) { 2132 return vao->BufferBinding[array->BufferBindingIndex].InstanceDivisor; 2133 } 2134 goto error; 2135 case GL_VERTEX_ATTRIB_BINDING: 2136 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) { 2137 return array->BufferBindingIndex - VERT_ATTRIB_GENERIC0; 2138 } 2139 goto error; 2140 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET: 2141 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) { 2142 return array->RelativeOffset; 2143 } 2144 goto error; 2145 default: 2146 ; /* fall-through */ 2147 } 2148 2149error: 2150 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname); 2151 return 0; 2152} 2153 2154 2155static const GLfloat * 2156get_current_attrib(struct gl_context *ctx, GLuint index, const char *function) 2157{ 2158 if (index == 0) { 2159 if (_mesa_attr_zero_aliases_vertex(ctx)) { 2160 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function); 2161 return NULL; 2162 } 2163 } 2164 else if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 2165 _mesa_error(ctx, GL_INVALID_VALUE, 2166 "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function); 2167 return NULL; 2168 } 2169 2170 assert(VERT_ATTRIB_GENERIC(index) < 2171 ARRAY_SIZE(ctx->Array.VAO->VertexAttrib)); 2172 2173 FLUSH_CURRENT(ctx, 0); 2174 return ctx->Current.Attrib[VERT_ATTRIB_GENERIC(index)]; 2175} 2176 2177void GLAPIENTRY 2178_mesa_GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params) 2179{ 2180 GET_CURRENT_CONTEXT(ctx); 2181 2182 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 2183 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv"); 2184 if (v != NULL) { 2185 COPY_4V(params, v); 2186 } 2187 } 2188 else { 2189 params[0] = (GLfloat) get_vertex_array_attrib(ctx, ctx->Array.VAO, 2190 index, pname, 2191 "glGetVertexAttribfv"); 2192 } 2193} 2194 2195 2196void GLAPIENTRY 2197_mesa_GetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) 2198{ 2199 GET_CURRENT_CONTEXT(ctx); 2200 2201 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 2202 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv"); 2203 if (v != NULL) { 2204 params[0] = (GLdouble) v[0]; 2205 params[1] = (GLdouble) v[1]; 2206 params[2] = (GLdouble) v[2]; 2207 params[3] = (GLdouble) v[3]; 2208 } 2209 } 2210 else { 2211 params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO, 2212 index, pname, 2213 "glGetVertexAttribdv"); 2214 } 2215} 2216 2217void GLAPIENTRY 2218_mesa_GetVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params) 2219{ 2220 GET_CURRENT_CONTEXT(ctx); 2221 2222 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 2223 const GLdouble *v = 2224 (const GLdouble *)get_current_attrib(ctx, index, 2225 "glGetVertexAttribLdv"); 2226 if (v != NULL) { 2227 params[0] = v[0]; 2228 params[1] = v[1]; 2229 params[2] = v[2]; 2230 params[3] = v[3]; 2231 } 2232 } 2233 else { 2234 params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO, 2235 index, pname, 2236 "glGetVertexAttribLdv"); 2237 } 2238} 2239 2240void GLAPIENTRY 2241_mesa_GetVertexAttribiv(GLuint index, GLenum pname, GLint *params) 2242{ 2243 GET_CURRENT_CONTEXT(ctx); 2244 2245 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 2246 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv"); 2247 if (v != NULL) { 2248 /* XXX should floats in[0,1] be scaled to full int range? */ 2249 params[0] = (GLint) v[0]; 2250 params[1] = (GLint) v[1]; 2251 params[2] = (GLint) v[2]; 2252 params[3] = (GLint) v[3]; 2253 } 2254 } 2255 else { 2256 params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO, 2257 index, pname, 2258 "glGetVertexAttribiv"); 2259 } 2260} 2261 2262void GLAPIENTRY 2263_mesa_GetVertexAttribLui64vARB(GLuint index, GLenum pname, GLuint64EXT *params) 2264{ 2265 GET_CURRENT_CONTEXT(ctx); 2266 2267 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 2268 const GLuint64 *v = 2269 (const GLuint64 *)get_current_attrib(ctx, index, 2270 "glGetVertexAttribLui64vARB"); 2271 if (v != NULL) { 2272 params[0] = v[0]; 2273 params[1] = v[1]; 2274 params[2] = v[2]; 2275 params[3] = v[3]; 2276 } 2277 } 2278 else { 2279 params[0] = (GLuint64) get_vertex_array_attrib(ctx, ctx->Array.VAO, 2280 index, pname, 2281 "glGetVertexAttribLui64vARB"); 2282 } 2283} 2284 2285 2286/** GL 3.0 */ 2287void GLAPIENTRY 2288_mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params) 2289{ 2290 GET_CURRENT_CONTEXT(ctx); 2291 2292 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 2293 const GLint *v = (const GLint *) 2294 get_current_attrib(ctx, index, "glGetVertexAttribIiv"); 2295 if (v != NULL) { 2296 COPY_4V(params, v); 2297 } 2298 } 2299 else { 2300 params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO, 2301 index, pname, 2302 "glGetVertexAttribIiv"); 2303 } 2304} 2305 2306 2307/** GL 3.0 */ 2308void GLAPIENTRY 2309_mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params) 2310{ 2311 GET_CURRENT_CONTEXT(ctx); 2312 2313 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 2314 const GLuint *v = (const GLuint *) 2315 get_current_attrib(ctx, index, "glGetVertexAttribIuiv"); 2316 if (v != NULL) { 2317 COPY_4V(params, v); 2318 } 2319 } 2320 else { 2321 params[0] = get_vertex_array_attrib(ctx, ctx->Array.VAO, 2322 index, pname, 2323 "glGetVertexAttribIuiv"); 2324 } 2325} 2326 2327 2328void GLAPIENTRY 2329_mesa_GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer) 2330{ 2331 GET_CURRENT_CONTEXT(ctx); 2332 2333 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 2334 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)"); 2335 return; 2336 } 2337 2338 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) { 2339 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)"); 2340 return; 2341 } 2342 2343 assert(VERT_ATTRIB_GENERIC(index) < 2344 ARRAY_SIZE(ctx->Array.VAO->VertexAttrib)); 2345 2346 *pointer = (GLvoid *) 2347 ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr; 2348} 2349 2350 2351/** ARB_direct_state_access */ 2352void GLAPIENTRY 2353_mesa_GetVertexArrayIndexediv(GLuint vaobj, GLuint index, 2354 GLenum pname, GLint *params) 2355{ 2356 GET_CURRENT_CONTEXT(ctx); 2357 struct gl_vertex_array_object *vao; 2358 struct gl_buffer_object *buf; 2359 2360 /* The ARB_direct_state_access specification says: 2361 * 2362 * "An INVALID_OPERATION error is generated if <vaobj> is not 2363 * [compatibility profile: zero or] the name of an existing 2364 * vertex array object." 2365 */ 2366 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glGetVertexArrayIndexediv"); 2367 if (!vao) 2368 return; 2369 2370 /* The ARB_direct_state_access specification says: 2371 * 2372 * "For GetVertexArrayIndexediv, <pname> must be one of 2373 * VERTEX_ATTRIB_ARRAY_ENABLED, VERTEX_ATTRIB_ARRAY_SIZE, 2374 * VERTEX_ATTRIB_ARRAY_STRIDE, VERTEX_ATTRIB_ARRAY_TYPE, 2375 * VERTEX_ATTRIB_ARRAY_NORMALIZED, VERTEX_ATTRIB_ARRAY_INTEGER, 2376 * VERTEX_ATTRIB_ARRAY_LONG, VERTEX_ATTRIB_ARRAY_DIVISOR, or 2377 * VERTEX_ATTRIB_RELATIVE_OFFSET." 2378 * 2379 * and: 2380 * 2381 * "Add GetVertexArrayIndexediv in 'Get Command' for 2382 * VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 2383 * VERTEX_ATTRIB_BINDING, 2384 * VERTEX_ATTRIB_RELATIVE_OFFSET, 2385 * VERTEX_BINDING_OFFSET, and 2386 * VERTEX_BINDING_STRIDE states" 2387 * 2388 * The only parameter name common to both lists is 2389 * VERTEX_ATTRIB_RELATIVE_OFFSET. Also note that VERTEX_BINDING_BUFFER 2390 * and VERTEX_BINDING_DIVISOR are missing from both lists. It seems 2391 * pretty clear however that the intent is that it should be possible 2392 * to query all vertex attrib and binding states that can be set with 2393 * a DSA function. 2394 */ 2395 switch (pname) { 2396 case GL_VERTEX_BINDING_OFFSET: 2397 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Offset; 2398 break; 2399 case GL_VERTEX_BINDING_STRIDE: 2400 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Stride; 2401 break; 2402 case GL_VERTEX_BINDING_DIVISOR: 2403 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].InstanceDivisor; 2404 break; 2405 case GL_VERTEX_BINDING_BUFFER: 2406 buf = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].BufferObj; 2407 params[0] = buf ? buf->Name : 0; 2408 break; 2409 default: 2410 params[0] = get_vertex_array_attrib(ctx, vao, index, pname, 2411 "glGetVertexArrayIndexediv"); 2412 break; 2413 } 2414} 2415 2416 2417void GLAPIENTRY 2418_mesa_GetVertexArrayIndexed64iv(GLuint vaobj, GLuint index, 2419 GLenum pname, GLint64 *params) 2420{ 2421 GET_CURRENT_CONTEXT(ctx); 2422 struct gl_vertex_array_object *vao; 2423 2424 /* The ARB_direct_state_access specification says: 2425 * 2426 * "An INVALID_OPERATION error is generated if <vaobj> is not 2427 * [compatibility profile: zero or] the name of an existing 2428 * vertex array object." 2429 */ 2430 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glGetVertexArrayIndexed64iv"); 2431 if (!vao) 2432 return; 2433 2434 /* The ARB_direct_state_access specification says: 2435 * 2436 * "For GetVertexArrayIndexed64iv, <pname> must be 2437 * VERTEX_BINDING_OFFSET." 2438 * 2439 * and: 2440 * 2441 * "An INVALID_ENUM error is generated if <pname> is not one of 2442 * the valid values listed above for the corresponding command." 2443 */ 2444 if (pname != GL_VERTEX_BINDING_OFFSET) { 2445 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayIndexed64iv(" 2446 "pname != GL_VERTEX_BINDING_OFFSET)"); 2447 return; 2448 } 2449 2450 /* The ARB_direct_state_access specification says: 2451 * 2452 * "An INVALID_VALUE error is generated if <index> is greater than 2453 * or equal to the value of MAX_VERTEX_ATTRIBS." 2454 * 2455 * Since the index refers to a buffer binding in this case, the intended 2456 * limit must be MAX_VERTEX_ATTRIB_BINDINGS. Both limits are currently 2457 * required to be the same, so in practice this doesn't matter. 2458 */ 2459 if (index >= ctx->Const.MaxVertexAttribBindings) { 2460 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexArrayIndexed64iv(index" 2461 "%d >= the value of GL_MAX_VERTEX_ATTRIB_BINDINGS (%d))", 2462 index, ctx->Const.MaxVertexAttribBindings); 2463 return; 2464 } 2465 2466 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Offset; 2467} 2468 2469 2470void GLAPIENTRY 2471_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride, 2472 GLsizei count, const GLvoid *ptr) 2473{ 2474 (void) count; 2475 _mesa_VertexPointer(size, type, stride, ptr); 2476} 2477 2478 2479void GLAPIENTRY 2480_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, 2481 const GLvoid *ptr) 2482{ 2483 (void) count; 2484 _mesa_NormalPointer(type, stride, ptr); 2485} 2486 2487 2488void GLAPIENTRY 2489_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, 2490 const GLvoid *ptr) 2491{ 2492 (void) count; 2493 _mesa_ColorPointer(size, type, stride, ptr); 2494} 2495 2496 2497void GLAPIENTRY 2498_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, 2499 const GLvoid *ptr) 2500{ 2501 (void) count; 2502 _mesa_IndexPointer(type, stride, ptr); 2503} 2504 2505 2506void GLAPIENTRY 2507_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, 2508 GLsizei count, const GLvoid *ptr) 2509{ 2510 (void) count; 2511 _mesa_TexCoordPointer(size, type, stride, ptr); 2512} 2513 2514 2515void GLAPIENTRY 2516_mesa_MultiTexCoordPointerEXT(GLenum texunit, GLint size, GLenum type, 2517 GLsizei stride, const GLvoid *ptr) 2518{ 2519 GET_CURRENT_CONTEXT(ctx); 2520 const GLint sizeMin = 1; 2521 const GLuint unit = texunit - GL_TEXTURE0; 2522 2523 GLenum format = GL_RGBA; 2524 const GLbitfield legalTypes = (SHORT_BIT | INT_BIT | 2525 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 2526 UNSIGNED_INT_2_10_10_10_REV_BIT | 2527 INT_2_10_10_10_REV_BIT); 2528 2529 if (!validate_array_and_format(ctx, "glMultiTexCoordPointerEXT", 2530 ctx->Array.VAO, ctx->Array.ArrayBufferObj, 2531 VERT_ATTRIB_TEX(unit), legalTypes, 2532 sizeMin, 4, size, type, stride, 2533 GL_FALSE, GL_FALSE, GL_FALSE, format, ptr)) 2534 return; 2535 2536 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, 2537 VERT_ATTRIB_TEX(unit), format, 4, size, type, 2538 stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); 2539} 2540 2541 2542void GLAPIENTRY 2543_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr) 2544{ 2545 (void) count; 2546 _mesa_EdgeFlagPointer(stride, ptr); 2547} 2548 2549 2550bool 2551_mesa_get_interleaved_layout(GLenum format, 2552 struct gl_interleaved_layout *layout) 2553{ 2554 int f = sizeof(GLfloat); 2555 int c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f); 2556 2557 memset(layout, 0, sizeof(*layout)); 2558 2559 switch (format) { 2560 case GL_V2F: 2561 layout->vcomps = 2; 2562 layout->defstride = 2 * f; 2563 break; 2564 case GL_V3F: 2565 layout->vcomps = 3; 2566 layout->defstride = 3 * f; 2567 break; 2568 case GL_C4UB_V2F: 2569 layout->cflag = true; 2570 layout->ccomps = 4; layout->vcomps = 2; 2571 layout->ctype = GL_UNSIGNED_BYTE; 2572 layout->voffset = c; 2573 layout->defstride = c + 2 * f; 2574 break; 2575 case GL_C4UB_V3F: 2576 layout->cflag = true; 2577 layout->ccomps = 4; layout->vcomps = 3; 2578 layout->ctype = GL_UNSIGNED_BYTE; 2579 layout->voffset = c; 2580 layout->defstride = c + 3 * f; 2581 break; 2582 case GL_C3F_V3F: 2583 layout->cflag = true; 2584 layout->ccomps = 3; layout->vcomps = 3; 2585 layout->ctype = GL_FLOAT; 2586 layout->voffset = 3 * f; 2587 layout->defstride = 6 * f; 2588 break; 2589 case GL_N3F_V3F: 2590 layout->nflag = true; 2591 layout->vcomps = 3; 2592 layout->voffset = 3 * f; 2593 layout->defstride = 6 * f; 2594 break; 2595 case GL_C4F_N3F_V3F: 2596 layout->cflag = true; layout->nflag = true; 2597 layout->ccomps = 4; layout->vcomps = 3; 2598 layout->ctype = GL_FLOAT; 2599 layout->noffset = 4 * f; 2600 layout->voffset = 7 * f; 2601 layout->defstride = 10 * f; 2602 break; 2603 case GL_T2F_V3F: 2604 layout->tflag = true; 2605 layout->tcomps = 2; layout->vcomps = 3; 2606 layout->voffset = 2 * f; 2607 layout->defstride = 5 * f; 2608 break; 2609 case GL_T4F_V4F: 2610 layout->tflag = true; 2611 layout->tcomps = 4; layout->vcomps = 4; 2612 layout->voffset = 4 * f; 2613 layout->defstride = 8 * f; 2614 break; 2615 case GL_T2F_C4UB_V3F: 2616 layout->tflag = true; layout->cflag = true; 2617 layout->tcomps = 2; layout->ccomps = 4; layout->vcomps = 3; 2618 layout->ctype = GL_UNSIGNED_BYTE; 2619 layout->coffset = 2 * f; 2620 layout->voffset = c + 2 * f; 2621 layout->defstride = c + 5 * f; 2622 break; 2623 case GL_T2F_C3F_V3F: 2624 layout->tflag = true; layout->cflag = true; 2625 layout->tcomps = 2; layout->ccomps = 3; layout->vcomps = 3; 2626 layout->ctype = GL_FLOAT; 2627 layout->coffset = 2 * f; 2628 layout->voffset = 5 * f; 2629 layout->defstride = 8 * f; 2630 break; 2631 case GL_T2F_N3F_V3F: 2632 layout->tflag = true; layout->nflag = true; 2633 layout->tcomps = 2; layout->vcomps = 3; 2634 layout->noffset = 2 * f; 2635 layout->voffset = 5 * f; 2636 layout->defstride = 8 * f; 2637 break; 2638 case GL_T2F_C4F_N3F_V3F: 2639 layout->tflag = true; layout->cflag = true; layout->nflag = true; 2640 layout->tcomps = 2; layout->ccomps = 4; layout->vcomps = 3; 2641 layout->ctype = GL_FLOAT; 2642 layout->coffset = 2 * f; 2643 layout->noffset = 6 * f; 2644 layout->voffset = 9 * f; 2645 layout->defstride = 12 * f; 2646 break; 2647 case GL_T4F_C4F_N3F_V4F: 2648 layout->tflag = true; layout->cflag = true; layout->nflag = true; 2649 layout->tcomps = 4; layout->ccomps = 4; layout->vcomps = 4; 2650 layout->ctype = GL_FLOAT; 2651 layout->coffset = 4 * f; 2652 layout->noffset = 8 * f; 2653 layout->voffset = 11 * f; 2654 layout->defstride = 15 * f; 2655 break; 2656 default: 2657 return false; 2658 } 2659 return true; 2660} 2661 2662void GLAPIENTRY 2663_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) 2664{ 2665 GET_CURRENT_CONTEXT(ctx); 2666 struct gl_interleaved_layout layout; 2667 2668 if (stride < 0) { 2669 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" ); 2670 return; 2671 } 2672 2673 if (!_mesa_get_interleaved_layout(format, &layout)) { 2674 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" ); 2675 return; 2676 } 2677 2678 if (stride==0) { 2679 stride = layout.defstride; 2680 } 2681 2682 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY ); 2683 _mesa_DisableClientState( GL_INDEX_ARRAY ); 2684 /* XXX also disable secondary color and generic arrays? */ 2685 2686 /* Texcoords */ 2687 if (layout.tflag) { 2688 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY ); 2689 _mesa_TexCoordPointer( layout.tcomps, GL_FLOAT, stride, 2690 (GLubyte *) pointer + layout.toffset ); 2691 } 2692 else { 2693 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY ); 2694 } 2695 2696 /* Color */ 2697 if (layout.cflag) { 2698 _mesa_EnableClientState( GL_COLOR_ARRAY ); 2699 _mesa_ColorPointer( layout.ccomps, layout.ctype, stride, 2700 (GLubyte *) pointer + layout.coffset ); 2701 } 2702 else { 2703 _mesa_DisableClientState( GL_COLOR_ARRAY ); 2704 } 2705 2706 2707 /* Normals */ 2708 if (layout.nflag) { 2709 _mesa_EnableClientState( GL_NORMAL_ARRAY ); 2710 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + layout.noffset ); 2711 } 2712 else { 2713 _mesa_DisableClientState( GL_NORMAL_ARRAY ); 2714 } 2715 2716 /* Vertices */ 2717 _mesa_EnableClientState( GL_VERTEX_ARRAY ); 2718 _mesa_VertexPointer( layout.vcomps, GL_FLOAT, stride, 2719 (GLubyte *) pointer + layout.voffset ); 2720} 2721 2722 2723void GLAPIENTRY 2724_mesa_LockArraysEXT(GLint first, GLsizei count) 2725{ 2726 GET_CURRENT_CONTEXT(ctx); 2727 2728 if (MESA_VERBOSE & VERBOSE_API) 2729 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count); 2730 2731 if (first < 0) { 2732 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" ); 2733 return; 2734 } 2735 if (count <= 0) { 2736 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" ); 2737 return; 2738 } 2739 if (ctx->Array.LockCount != 0) { 2740 _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" ); 2741 return; 2742 } 2743 2744 ctx->Array.LockFirst = first; 2745 ctx->Array.LockCount = count; 2746} 2747 2748 2749void GLAPIENTRY 2750_mesa_UnlockArraysEXT( void ) 2751{ 2752 GET_CURRENT_CONTEXT(ctx); 2753 2754 if (MESA_VERBOSE & VERBOSE_API) 2755 _mesa_debug(ctx, "glUnlockArrays\n"); 2756 2757 if (ctx->Array.LockCount == 0) { 2758 _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" ); 2759 return; 2760 } 2761 2762 ctx->Array.LockFirst = 0; 2763 ctx->Array.LockCount = 0; 2764} 2765 2766 2767static void 2768primitive_restart_index(struct gl_context *ctx, GLuint index) 2769{ 2770 ctx->Array.RestartIndex = index; 2771 _mesa_update_derived_primitive_restart_state(ctx); 2772} 2773 2774 2775/** 2776 * GL_NV_primitive_restart and GL 3.1 2777 */ 2778void GLAPIENTRY 2779_mesa_PrimitiveRestartIndex_no_error(GLuint index) 2780{ 2781 GET_CURRENT_CONTEXT(ctx); 2782 primitive_restart_index(ctx, index); 2783} 2784 2785 2786void GLAPIENTRY 2787_mesa_PrimitiveRestartIndex(GLuint index) 2788{ 2789 GET_CURRENT_CONTEXT(ctx); 2790 2791 if (!ctx->Extensions.NV_primitive_restart && ctx->Version < 31) { 2792 _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()"); 2793 return; 2794 } 2795 2796 primitive_restart_index(ctx, index); 2797} 2798 2799 2800void GLAPIENTRY 2801_mesa_VertexAttribDivisor_no_error(GLuint index, GLuint divisor) 2802{ 2803 GET_CURRENT_CONTEXT(ctx); 2804 2805 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index); 2806 struct gl_vertex_array_object * const vao = ctx->Array.VAO; 2807 2808 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib)); 2809 2810 /* The ARB_vertex_attrib_binding spec says: 2811 * 2812 * "The command 2813 * 2814 * void VertexAttribDivisor(uint index, uint divisor); 2815 * 2816 * is equivalent to (assuming no errors are generated): 2817 * 2818 * VertexAttribBinding(index, index); 2819 * VertexBindingDivisor(index, divisor);" 2820 */ 2821 _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex); 2822 vertex_binding_divisor(ctx, vao, genericIndex, divisor); 2823} 2824 2825 2826/** 2827 * See GL_ARB_instanced_arrays. 2828 * Note that the instance divisor only applies to generic arrays, not 2829 * the legacy vertex arrays. 2830 */ 2831void GLAPIENTRY 2832_mesa_VertexAttribDivisor(GLuint index, GLuint divisor) 2833{ 2834 GET_CURRENT_CONTEXT(ctx); 2835 2836 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index); 2837 struct gl_vertex_array_object * const vao = ctx->Array.VAO; 2838 2839 if (!ctx->Extensions.ARB_instanced_arrays) { 2840 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()"); 2841 return; 2842 } 2843 2844 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 2845 _mesa_error(ctx, GL_INVALID_VALUE, 2846 "glVertexAttribDivisor(index = %u)", index); 2847 return; 2848 } 2849 2850 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib)); 2851 2852 /* The ARB_vertex_attrib_binding spec says: 2853 * 2854 * "The command 2855 * 2856 * void VertexAttribDivisor(uint index, uint divisor); 2857 * 2858 * is equivalent to (assuming no errors are generated): 2859 * 2860 * VertexAttribBinding(index, index); 2861 * VertexBindingDivisor(index, divisor);" 2862 */ 2863 _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex); 2864 vertex_binding_divisor(ctx, vao, genericIndex, divisor); 2865} 2866 2867 2868void GLAPIENTRY 2869_mesa_VertexArrayVertexAttribDivisorEXT(GLuint vaobj, GLuint index, GLuint divisor) 2870{ 2871 GET_CURRENT_CONTEXT(ctx); 2872 2873 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index); 2874 struct gl_vertex_array_object * vao; 2875 /* The ARB_instanced_arrays spec says: 2876 * 2877 * "The vertex array object named by vaobj must 2878 * be generated by GenVertexArrays (and not since deleted); 2879 * otherwise an INVALID_OPERATION error is generated." 2880 */ 2881 vao = _mesa_lookup_vao_err(ctx, vaobj, 2882 false, 2883 "glVertexArrayVertexAttribDivisorEXT"); 2884 if (!vao) 2885 return; 2886 2887 if (!ctx->Extensions.ARB_instanced_arrays) { 2888 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexArrayVertexAttribDivisorEXT()"); 2889 return; 2890 } 2891 2892 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 2893 _mesa_error(ctx, GL_INVALID_VALUE, 2894 "glVertexArrayVertexAttribDivisorEXT(index = %u)", index); 2895 return; 2896 } 2897 2898 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib)); 2899 2900 /* The ARB_vertex_attrib_binding spec says: 2901 * 2902 * "The command 2903 * 2904 * void VertexAttribDivisor(uint index, uint divisor); 2905 * 2906 * is equivalent to (assuming no errors are generated): 2907 * 2908 * VertexAttribBinding(index, index); 2909 * VertexBindingDivisor(index, divisor);" 2910 */ 2911 _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex); 2912 vertex_binding_divisor(ctx, vao, genericIndex, divisor); 2913} 2914 2915 2916 2917static ALWAYS_INLINE void 2918vertex_array_vertex_buffer(struct gl_context *ctx, 2919 struct gl_vertex_array_object *vao, 2920 GLuint bindingIndex, GLuint buffer, GLintptr offset, 2921 GLsizei stride, bool no_error, const char *func) 2922{ 2923 struct gl_buffer_object *vbo; 2924 struct gl_buffer_object *current_buf = 2925 vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj; 2926 2927 if (current_buf && buffer == current_buf->Name) { 2928 vbo = current_buf; 2929 } else if (buffer != 0) { 2930 vbo = _mesa_lookup_bufferobj(ctx, buffer); 2931 2932 if (!no_error && !vbo && _mesa_is_gles31(ctx)) { 2933 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", func); 2934 return; 2935 } 2936 /* From the GL_ARB_vertex_attrib_array spec: 2937 * 2938 * "[Core profile only:] 2939 * An INVALID_OPERATION error is generated if buffer is not zero or a 2940 * name returned from a previous call to GenBuffers, or if such a name 2941 * has since been deleted with DeleteBuffers. 2942 * 2943 * Otherwise, we fall back to the same compat profile behavior as other 2944 * object references (automatically gen it). 2945 */ 2946 if (!_mesa_handle_bind_buffer_gen(ctx, buffer, &vbo, func)) 2947 return; 2948 } else { 2949 /* The ARB_vertex_attrib_binding spec says: 2950 * 2951 * "If <buffer> is zero, any buffer object attached to this 2952 * bindpoint is detached." 2953 */ 2954 vbo = NULL; 2955 } 2956 2957 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), 2958 vbo, offset, stride, false, false); 2959} 2960 2961 2962/** 2963 * GL_ARB_vertex_attrib_binding 2964 */ 2965static void 2966vertex_array_vertex_buffer_err(struct gl_context *ctx, 2967 struct gl_vertex_array_object *vao, 2968 GLuint bindingIndex, GLuint buffer, 2969 GLintptr offset, GLsizei stride, 2970 const char *func) 2971{ 2972 ASSERT_OUTSIDE_BEGIN_END(ctx); 2973 2974 /* The ARB_vertex_attrib_binding spec says: 2975 * 2976 * "An INVALID_VALUE error is generated if <bindingindex> is greater than 2977 * the value of MAX_VERTEX_ATTRIB_BINDINGS." 2978 */ 2979 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) { 2980 _mesa_error(ctx, GL_INVALID_VALUE, 2981 "%s(bindingindex=%u > " 2982 "GL_MAX_VERTEX_ATTRIB_BINDINGS)", 2983 func, bindingIndex); 2984 return; 2985 } 2986 2987 /* The ARB_vertex_attrib_binding spec says: 2988 * 2989 * "The error INVALID_VALUE is generated if <stride> or <offset> 2990 * are negative." 2991 */ 2992 if (offset < 0) { 2993 _mesa_error(ctx, GL_INVALID_VALUE, 2994 "%s(offset=%" PRId64 " < 0)", 2995 func, (int64_t) offset); 2996 return; 2997 } 2998 2999 if (stride < 0) { 3000 _mesa_error(ctx, GL_INVALID_VALUE, 3001 "%s(stride=%d < 0)", func, stride); 3002 return; 3003 } 3004 3005 if (((_mesa_is_desktop_gl(ctx) && ctx->Version >= 44) || _mesa_is_gles31(ctx)) && 3006 stride > ctx->Const.MaxVertexAttribStride) { 3007 _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > " 3008 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride); 3009 return; 3010 } 3011 3012 vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset, 3013 stride, false, func); 3014} 3015 3016 3017void GLAPIENTRY 3018_mesa_BindVertexBuffer_no_error(GLuint bindingIndex, GLuint buffer, 3019 GLintptr offset, GLsizei stride) 3020{ 3021 GET_CURRENT_CONTEXT(ctx); 3022 vertex_array_vertex_buffer(ctx, ctx->Array.VAO, bindingIndex, 3023 buffer, offset, stride, true, 3024 "glBindVertexBuffer"); 3025} 3026 3027 3028void GLAPIENTRY 3029_mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset, 3030 GLsizei stride) 3031{ 3032 GET_CURRENT_CONTEXT(ctx); 3033 3034 /* The ARB_vertex_attrib_binding spec says: 3035 * 3036 * "An INVALID_OPERATION error is generated if no vertex array object 3037 * is bound." 3038 */ 3039 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) && 3040 ctx->Array.VAO == ctx->Array.DefaultVAO) { 3041 _mesa_error(ctx, GL_INVALID_OPERATION, 3042 "glBindVertexBuffer(No array object bound)"); 3043 return; 3044 } 3045 3046 vertex_array_vertex_buffer_err(ctx, ctx->Array.VAO, bindingIndex, 3047 buffer, offset, stride, 3048 "glBindVertexBuffer"); 3049} 3050 3051 3052void GLAPIENTRY 3053_mesa_VertexArrayVertexBuffer_no_error(GLuint vaobj, GLuint bindingIndex, 3054 GLuint buffer, GLintptr offset, 3055 GLsizei stride) 3056{ 3057 GET_CURRENT_CONTEXT(ctx); 3058 3059 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj); 3060 vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset, 3061 stride, true, "glVertexArrayVertexBuffer"); 3062} 3063 3064 3065void GLAPIENTRY 3066_mesa_VertexArrayVertexBuffer(GLuint vaobj, GLuint bindingIndex, GLuint buffer, 3067 GLintptr offset, GLsizei stride) 3068{ 3069 GET_CURRENT_CONTEXT(ctx); 3070 struct gl_vertex_array_object *vao; 3071 3072 /* The ARB_direct_state_access specification says: 3073 * 3074 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer 3075 * if <vaobj> is not [compatibility profile: zero or] the name of an 3076 * existing vertex array object." 3077 */ 3078 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayVertexBuffer"); 3079 if (!vao) 3080 return; 3081 3082 vertex_array_vertex_buffer_err(ctx, vao, bindingIndex, buffer, offset, 3083 stride, "glVertexArrayVertexBuffer"); 3084} 3085 3086 3087void GLAPIENTRY 3088_mesa_VertexArrayBindVertexBufferEXT(GLuint vaobj, GLuint bindingIndex, GLuint buffer, 3089 GLintptr offset, GLsizei stride) 3090{ 3091 GET_CURRENT_CONTEXT(ctx); 3092 struct gl_vertex_array_object *vao; 3093 vao = _mesa_lookup_vao_err(ctx, vaobj, true, "glVertexArrayBindVertexBufferEXT"); 3094 if (!vao) 3095 return; 3096 3097 vertex_array_vertex_buffer_err(ctx, vao, bindingIndex, buffer, offset, 3098 stride, "glVertexArrayBindVertexBufferEXT"); 3099} 3100 3101 3102static ALWAYS_INLINE void 3103vertex_array_vertex_buffers(struct gl_context *ctx, 3104 struct gl_vertex_array_object *vao, 3105 GLuint first, GLsizei count, const GLuint *buffers, 3106 const GLintptr *offsets, const GLsizei *strides, 3107 bool no_error, const char *func) 3108{ 3109 GLint i; 3110 3111 if (!buffers) { 3112 /** 3113 * The ARB_multi_bind spec says: 3114 * 3115 * "If <buffers> is NULL, each affected vertex buffer binding point 3116 * from <first> through <first>+<count>-1 will be reset to have no 3117 * bound buffer object. In this case, the offsets and strides 3118 * associated with the binding points are set to default values, 3119 * ignoring <offsets> and <strides>." 3120 */ 3121 for (i = 0; i < count; i++) 3122 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i), 3123 NULL, 0, 16, false, false); 3124 3125 return; 3126 } 3127 3128 /* Note that the error semantics for multi-bind commands differ from 3129 * those of other GL commands. 3130 * 3131 * The Issues section in the ARB_multi_bind spec says: 3132 * 3133 * "(11) Typically, OpenGL specifies that if an error is generated by 3134 * a command, that command has no effect. This is somewhat 3135 * unfortunate for multi-bind commands, because it would require 3136 * a first pass to scan the entire list of bound objects for 3137 * errors and then a second pass to actually perform the 3138 * bindings. Should we have different error semantics? 3139 * 3140 * RESOLVED: Yes. In this specification, when the parameters for 3141 * one of the <count> binding points are invalid, that binding 3142 * point is not updated and an error will be generated. However, 3143 * other binding points in the same command will be updated if 3144 * their parameters are valid and no other error occurs." 3145 */ 3146 3147 _mesa_HashLockMaybeLocked(ctx->Shared->BufferObjects, 3148 ctx->BufferObjectsLocked); 3149 3150 for (i = 0; i < count; i++) { 3151 struct gl_buffer_object *vbo; 3152 3153 if (!no_error) { 3154 /* The ARB_multi_bind spec says: 3155 * 3156 * "An INVALID_VALUE error is generated if any value in 3157 * <offsets> or <strides> is negative (per binding)." 3158 */ 3159 if (offsets[i] < 0) { 3160 _mesa_error(ctx, GL_INVALID_VALUE, 3161 "%s(offsets[%u]=%" PRId64 " < 0)", 3162 func, i, (int64_t) offsets[i]); 3163 continue; 3164 } 3165 3166 if (strides[i] < 0) { 3167 _mesa_error(ctx, GL_INVALID_VALUE, 3168 "%s(strides[%u]=%d < 0)", 3169 func, i, strides[i]); 3170 continue; 3171 } 3172 3173 if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 44 && 3174 strides[i] > ctx->Const.MaxVertexAttribStride) { 3175 _mesa_error(ctx, GL_INVALID_VALUE, 3176 "%s(strides[%u]=%d > " 3177 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, i, strides[i]); 3178 continue; 3179 } 3180 } 3181 3182 if (buffers[i]) { 3183 struct gl_vertex_buffer_binding *binding = 3184 &vao->BufferBinding[VERT_ATTRIB_GENERIC(first + i)]; 3185 3186 if (buffers[i] == 0) 3187 vbo = NULL; 3188 else if (binding->BufferObj && binding->BufferObj->Name == buffers[i]) 3189 vbo = binding->BufferObj; 3190 else { 3191 bool error; 3192 vbo = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, func, 3193 &error); 3194 if (error) 3195 continue; 3196 } 3197 } else { 3198 vbo = NULL; 3199 } 3200 3201 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i), 3202 vbo, offsets[i], strides[i], false, false); 3203 } 3204 3205 _mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects, 3206 ctx->BufferObjectsLocked); 3207} 3208 3209 3210static void 3211vertex_array_vertex_buffers_err(struct gl_context *ctx, 3212 struct gl_vertex_array_object *vao, 3213 GLuint first, GLsizei count, 3214 const GLuint *buffers, const GLintptr *offsets, 3215 const GLsizei *strides, const char *func) 3216{ 3217 ASSERT_OUTSIDE_BEGIN_END(ctx); 3218 3219 /* The ARB_multi_bind spec says: 3220 * 3221 * "An INVALID_OPERATION error is generated if <first> + <count> 3222 * is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS." 3223 */ 3224 if (first + count > ctx->Const.MaxVertexAttribBindings) { 3225 _mesa_error(ctx, GL_INVALID_OPERATION, 3226 "%s(first=%u + count=%d > the value of " 3227 "GL_MAX_VERTEX_ATTRIB_BINDINGS=%u)", 3228 func, first, count, ctx->Const.MaxVertexAttribBindings); 3229 return; 3230 } 3231 3232 vertex_array_vertex_buffers(ctx, vao, first, count, buffers, offsets, 3233 strides, false, func); 3234} 3235 3236 3237void GLAPIENTRY 3238_mesa_BindVertexBuffers_no_error(GLuint first, GLsizei count, 3239 const GLuint *buffers, const GLintptr *offsets, 3240 const GLsizei *strides) 3241{ 3242 GET_CURRENT_CONTEXT(ctx); 3243 3244 vertex_array_vertex_buffers(ctx, ctx->Array.VAO, first, count, 3245 buffers, offsets, strides, true, 3246 "glBindVertexBuffers"); 3247} 3248 3249 3250void GLAPIENTRY 3251_mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers, 3252 const GLintptr *offsets, const GLsizei *strides) 3253{ 3254 GET_CURRENT_CONTEXT(ctx); 3255 3256 /* The ARB_vertex_attrib_binding spec says: 3257 * 3258 * "An INVALID_OPERATION error is generated if no 3259 * vertex array object is bound." 3260 */ 3261 if (ctx->API == API_OPENGL_CORE && 3262 ctx->Array.VAO == ctx->Array.DefaultVAO) { 3263 _mesa_error(ctx, GL_INVALID_OPERATION, 3264 "glBindVertexBuffers(No array object bound)"); 3265 return; 3266 } 3267 3268 vertex_array_vertex_buffers_err(ctx, ctx->Array.VAO, first, count, 3269 buffers, offsets, strides, 3270 "glBindVertexBuffers"); 3271} 3272 3273 3274void 3275_mesa_InternalBindVertexBuffers(struct gl_context *ctx, 3276 const struct glthread_attrib_binding *buffers, 3277 GLbitfield buffer_mask, 3278 GLboolean restore_pointers) 3279{ 3280 struct gl_vertex_array_object *vao = ctx->Array.VAO; 3281 unsigned param_index = 0; 3282 3283 if (restore_pointers) { 3284 while (buffer_mask) { 3285 unsigned i = u_bit_scan(&buffer_mask); 3286 3287 _mesa_bind_vertex_buffer(ctx, vao, i, NULL, 3288 (GLintptr)buffers[param_index].original_pointer, 3289 vao->BufferBinding[i].Stride, false, false); 3290 param_index++; 3291 } 3292 return; 3293 } 3294 3295 while (buffer_mask) { 3296 unsigned i = u_bit_scan(&buffer_mask); 3297 struct gl_buffer_object *buf = buffers[param_index].buffer; 3298 3299 /* The buffer reference is passed to _mesa_bind_vertex_buffer. */ 3300 _mesa_bind_vertex_buffer(ctx, vao, i, buf, buffers[param_index].offset, 3301 vao->BufferBinding[i].Stride, true, true); 3302 param_index++; 3303 } 3304} 3305 3306 3307void GLAPIENTRY 3308_mesa_VertexArrayVertexBuffers_no_error(GLuint vaobj, GLuint first, 3309 GLsizei count, const GLuint *buffers, 3310 const GLintptr *offsets, 3311 const GLsizei *strides) 3312{ 3313 GET_CURRENT_CONTEXT(ctx); 3314 3315 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj); 3316 vertex_array_vertex_buffers(ctx, vao, first, count, 3317 buffers, offsets, strides, true, 3318 "glVertexArrayVertexBuffers"); 3319} 3320 3321 3322void GLAPIENTRY 3323_mesa_VertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count, 3324 const GLuint *buffers, 3325 const GLintptr *offsets, const GLsizei *strides) 3326{ 3327 GET_CURRENT_CONTEXT(ctx); 3328 struct gl_vertex_array_object *vao; 3329 3330 /* The ARB_direct_state_access specification says: 3331 * 3332 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer 3333 * if <vaobj> is not [compatibility profile: zero or] the name of an 3334 * existing vertex array object." 3335 */ 3336 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayVertexBuffers"); 3337 if (!vao) 3338 return; 3339 3340 vertex_array_vertex_buffers_err(ctx, vao, first, count, 3341 buffers, offsets, strides, 3342 "glVertexArrayVertexBuffers"); 3343} 3344 3345 3346static void 3347vertex_attrib_format(GLuint attribIndex, GLint size, GLenum type, 3348 GLboolean normalized, GLboolean integer, 3349 GLboolean doubles, GLbitfield legalTypes, 3350 GLsizei sizeMax, GLuint relativeOffset, 3351 const char *func) 3352{ 3353 GET_CURRENT_CONTEXT(ctx); 3354 ASSERT_OUTSIDE_BEGIN_END(ctx); 3355 3356 GLenum format = get_array_format(ctx, sizeMax, &size); 3357 3358 if (!_mesa_is_no_error_enabled(ctx)) { 3359 /* The ARB_vertex_attrib_binding spec says: 3360 * 3361 * "An INVALID_OPERATION error is generated under any of the 3362 * following conditions: 3363 * - if no vertex array object is currently bound (see section 3364 * 2.10); 3365 * - ..." 3366 * 3367 * This error condition only applies to VertexAttribFormat and 3368 * VertexAttribIFormat in the extension spec, but we assume that this 3369 * is an oversight. In the OpenGL 4.3 (Core Profile) spec, it applies 3370 * to all three functions. 3371 */ 3372 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) && 3373 ctx->Array.VAO == ctx->Array.DefaultVAO) { 3374 _mesa_error(ctx, GL_INVALID_OPERATION, 3375 "%s(No array object bound)", func); 3376 return; 3377 } 3378 3379 /* The ARB_vertex_attrib_binding spec says: 3380 * 3381 * "The error INVALID_VALUE is generated if index is greater than or 3382 * equal to the value of MAX_VERTEX_ATTRIBS." 3383 */ 3384 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 3385 _mesa_error(ctx, GL_INVALID_VALUE, 3386 "%s(attribindex=%u > " 3387 "GL_MAX_VERTEX_ATTRIBS)", 3388 func, attribIndex); 3389 return; 3390 } 3391 3392 if (!validate_array_format(ctx, func, ctx->Array.VAO, 3393 VERT_ATTRIB_GENERIC(attribIndex), 3394 legalTypes, 1, sizeMax, size, type, 3395 normalized, integer, doubles, relativeOffset, 3396 format)) { 3397 return; 3398 } 3399 } 3400 3401 _mesa_update_array_format(ctx, ctx->Array.VAO, 3402 VERT_ATTRIB_GENERIC(attribIndex), size, type, 3403 format, normalized, integer, doubles, 3404 relativeOffset); 3405} 3406 3407 3408void GLAPIENTRY 3409_mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type, 3410 GLboolean normalized, GLuint relativeOffset) 3411{ 3412 vertex_attrib_format(attribIndex, size, type, normalized, 3413 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK, 3414 BGRA_OR_4, relativeOffset, 3415 "glVertexAttribFormat"); 3416} 3417 3418 3419void GLAPIENTRY 3420_mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type, 3421 GLuint relativeOffset) 3422{ 3423 vertex_attrib_format(attribIndex, size, type, GL_FALSE, 3424 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK, 4, 3425 relativeOffset, "glVertexAttribIFormat"); 3426} 3427 3428 3429void GLAPIENTRY 3430_mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type, 3431 GLuint relativeOffset) 3432{ 3433 vertex_attrib_format(attribIndex, size, type, GL_FALSE, GL_FALSE, 3434 GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK, 4, 3435 relativeOffset, "glVertexAttribLFormat"); 3436} 3437 3438 3439static void 3440vertex_array_attrib_format(GLuint vaobj, bool isExtDsa, GLuint attribIndex, 3441 GLint size, GLenum type, GLboolean normalized, 3442 GLboolean integer, GLboolean doubles, 3443 GLbitfield legalTypes, GLsizei sizeMax, 3444 GLuint relativeOffset, const char *func) 3445{ 3446 GET_CURRENT_CONTEXT(ctx); 3447 struct gl_vertex_array_object *vao; 3448 3449 ASSERT_OUTSIDE_BEGIN_END(ctx); 3450 3451 GLenum format = get_array_format(ctx, sizeMax, &size); 3452 3453 if (_mesa_is_no_error_enabled(ctx)) { 3454 vao = _mesa_lookup_vao(ctx, vaobj); 3455 if (!vao) 3456 return; 3457 } else { 3458 vao = _mesa_lookup_vao_err(ctx, vaobj, isExtDsa, func); 3459 if (!vao) 3460 return; 3461 3462 /* The ARB_vertex_attrib_binding spec says: 3463 * 3464 * "The error INVALID_VALUE is generated if index is greater than or 3465 * equal to the value of MAX_VERTEX_ATTRIBS." 3466 */ 3467 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 3468 _mesa_error(ctx, GL_INVALID_VALUE, 3469 "%s(attribindex=%u > GL_MAX_VERTEX_ATTRIBS)", 3470 func, attribIndex); 3471 return; 3472 } 3473 3474 if (!validate_array_format(ctx, func, vao, 3475 VERT_ATTRIB_GENERIC(attribIndex), 3476 legalTypes, 1, sizeMax, size, type, 3477 normalized, integer, doubles, relativeOffset, 3478 format)) { 3479 return; 3480 } 3481 } 3482 3483 _mesa_update_array_format(ctx, vao, VERT_ATTRIB_GENERIC(attribIndex), size, 3484 type, format, normalized, integer, doubles, 3485 relativeOffset); 3486} 3487 3488 3489void GLAPIENTRY 3490_mesa_VertexArrayAttribFormat(GLuint vaobj, GLuint attribIndex, GLint size, 3491 GLenum type, GLboolean normalized, 3492 GLuint relativeOffset) 3493{ 3494 vertex_array_attrib_format(vaobj, false, attribIndex, size, type, normalized, 3495 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK, 3496 BGRA_OR_4, relativeOffset, 3497 "glVertexArrayAttribFormat"); 3498} 3499 3500 3501void GLAPIENTRY 3502_mesa_VertexArrayVertexAttribFormatEXT(GLuint vaobj, GLuint attribIndex, GLint size, 3503 GLenum type, GLboolean normalized, 3504 GLuint relativeOffset) 3505{ 3506 vertex_array_attrib_format(vaobj, true, attribIndex, size, type, normalized, 3507 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK, 3508 BGRA_OR_4, relativeOffset, 3509 "glVertexArrayVertexAttribFormatEXT"); 3510} 3511 3512 3513void GLAPIENTRY 3514_mesa_VertexArrayAttribIFormat(GLuint vaobj, GLuint attribIndex, 3515 GLint size, GLenum type, 3516 GLuint relativeOffset) 3517{ 3518 vertex_array_attrib_format(vaobj, false, attribIndex, size, type, GL_FALSE, 3519 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK, 3520 4, relativeOffset, 3521 "glVertexArrayAttribIFormat"); 3522} 3523 3524 3525void GLAPIENTRY 3526_mesa_VertexArrayVertexAttribIFormatEXT(GLuint vaobj, GLuint attribIndex, 3527 GLint size, GLenum type, 3528 GLuint relativeOffset) 3529{ 3530 vertex_array_attrib_format(vaobj, true, attribIndex, size, type, GL_FALSE, 3531 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK, 3532 4, relativeOffset, 3533 "glVertexArrayVertexAttribIFormatEXT"); 3534} 3535 3536 3537void GLAPIENTRY 3538_mesa_VertexArrayAttribLFormat(GLuint vaobj, GLuint attribIndex, 3539 GLint size, GLenum type, 3540 GLuint relativeOffset) 3541{ 3542 vertex_array_attrib_format(vaobj, false, attribIndex, size, type, GL_FALSE, 3543 GL_FALSE, GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK, 3544 4, relativeOffset, 3545 "glVertexArrayAttribLFormat"); 3546} 3547 3548 3549void GLAPIENTRY 3550_mesa_VertexArrayVertexAttribLFormatEXT(GLuint vaobj, GLuint attribIndex, 3551 GLint size, GLenum type, 3552 GLuint relativeOffset) 3553{ 3554 vertex_array_attrib_format(vaobj, true, attribIndex, size, type, GL_FALSE, 3555 GL_FALSE, GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK, 3556 4, relativeOffset, 3557 "glVertexArrayVertexAttribLFormatEXT"); 3558} 3559 3560 3561static void 3562vertex_array_attrib_binding(struct gl_context *ctx, 3563 struct gl_vertex_array_object *vao, 3564 GLuint attribIndex, GLuint bindingIndex, 3565 const char *func) 3566{ 3567 ASSERT_OUTSIDE_BEGIN_END(ctx); 3568 3569 /* The ARB_vertex_attrib_binding spec says: 3570 * 3571 * "<attribindex> must be less than the value of MAX_VERTEX_ATTRIBS and 3572 * <bindingindex> must be less than the value of 3573 * MAX_VERTEX_ATTRIB_BINDINGS, otherwise the error INVALID_VALUE 3574 * is generated." 3575 */ 3576 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 3577 _mesa_error(ctx, GL_INVALID_VALUE, 3578 "%s(attribindex=%u >= " 3579 "GL_MAX_VERTEX_ATTRIBS)", 3580 func, attribIndex); 3581 return; 3582 } 3583 3584 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) { 3585 _mesa_error(ctx, GL_INVALID_VALUE, 3586 "%s(bindingindex=%u >= " 3587 "GL_MAX_VERTEX_ATTRIB_BINDINGS)", 3588 func, bindingIndex); 3589 return; 3590 } 3591 3592 assert(VERT_ATTRIB_GENERIC(attribIndex) < ARRAY_SIZE(vao->VertexAttrib)); 3593 3594 _mesa_vertex_attrib_binding(ctx, vao, 3595 VERT_ATTRIB_GENERIC(attribIndex), 3596 VERT_ATTRIB_GENERIC(bindingIndex)); 3597} 3598 3599 3600void GLAPIENTRY 3601_mesa_VertexAttribBinding_no_error(GLuint attribIndex, GLuint bindingIndex) 3602{ 3603 GET_CURRENT_CONTEXT(ctx); 3604 _mesa_vertex_attrib_binding(ctx, ctx->Array.VAO, 3605 VERT_ATTRIB_GENERIC(attribIndex), 3606 VERT_ATTRIB_GENERIC(bindingIndex)); 3607} 3608 3609 3610void GLAPIENTRY 3611_mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex) 3612{ 3613 GET_CURRENT_CONTEXT(ctx); 3614 3615 /* The ARB_vertex_attrib_binding spec says: 3616 * 3617 * "An INVALID_OPERATION error is generated if no vertex array object 3618 * is bound." 3619 */ 3620 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) && 3621 ctx->Array.VAO == ctx->Array.DefaultVAO) { 3622 _mesa_error(ctx, GL_INVALID_OPERATION, 3623 "glVertexAttribBinding(No array object bound)"); 3624 return; 3625 } 3626 3627 vertex_array_attrib_binding(ctx, ctx->Array.VAO, 3628 attribIndex, bindingIndex, 3629 "glVertexAttribBinding"); 3630} 3631 3632 3633void GLAPIENTRY 3634_mesa_VertexArrayAttribBinding_no_error(GLuint vaobj, GLuint attribIndex, 3635 GLuint bindingIndex) 3636{ 3637 GET_CURRENT_CONTEXT(ctx); 3638 3639 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj); 3640 _mesa_vertex_attrib_binding(ctx, vao, 3641 VERT_ATTRIB_GENERIC(attribIndex), 3642 VERT_ATTRIB_GENERIC(bindingIndex)); 3643} 3644 3645 3646void GLAPIENTRY 3647_mesa_VertexArrayAttribBinding(GLuint vaobj, GLuint attribIndex, GLuint bindingIndex) 3648{ 3649 GET_CURRENT_CONTEXT(ctx); 3650 struct gl_vertex_array_object *vao; 3651 3652 /* The ARB_direct_state_access specification says: 3653 * 3654 * "An INVALID_OPERATION error is generated by VertexArrayAttribBinding 3655 * if <vaobj> is not [compatibility profile: zero or] the name of an 3656 * existing vertex array object." 3657 */ 3658 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayAttribBinding"); 3659 if (!vao) 3660 return; 3661 3662 vertex_array_attrib_binding(ctx, vao, attribIndex, bindingIndex, 3663 "glVertexArrayAttribBinding"); 3664} 3665 3666 3667void GLAPIENTRY 3668_mesa_VertexArrayVertexAttribBindingEXT(GLuint vaobj, GLuint attribIndex, GLuint bindingIndex) 3669{ 3670 GET_CURRENT_CONTEXT(ctx); 3671 struct gl_vertex_array_object *vao; 3672 vao = _mesa_lookup_vao_err(ctx, vaobj, true, "glVertexArrayVertexAttribBindingEXT"); 3673 if (!vao) 3674 return; 3675 3676 vertex_array_attrib_binding(ctx, vao, attribIndex, bindingIndex, 3677 "glVertexArrayVertexAttribBindingEXT"); 3678} 3679 3680 3681static void 3682vertex_array_binding_divisor(struct gl_context *ctx, 3683 struct gl_vertex_array_object *vao, 3684 GLuint bindingIndex, GLuint divisor, 3685 const char *func) 3686{ 3687 ASSERT_OUTSIDE_BEGIN_END(ctx); 3688 3689 if (!ctx->Extensions.ARB_instanced_arrays) { 3690 _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", func); 3691 return; 3692 } 3693 3694 /* The ARB_vertex_attrib_binding spec says: 3695 * 3696 * "An INVALID_VALUE error is generated if <bindingindex> is greater 3697 * than or equal to the value of MAX_VERTEX_ATTRIB_BINDINGS." 3698 */ 3699 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) { 3700 _mesa_error(ctx, GL_INVALID_VALUE, 3701 "%s(bindingindex=%u > " 3702 "GL_MAX_VERTEX_ATTRIB_BINDINGS)", 3703 func, bindingIndex); 3704 return; 3705 } 3706 3707 vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor); 3708} 3709 3710 3711void GLAPIENTRY 3712_mesa_VertexBindingDivisor_no_error(GLuint bindingIndex, GLuint divisor) 3713{ 3714 GET_CURRENT_CONTEXT(ctx); 3715 vertex_binding_divisor(ctx, ctx->Array.VAO, 3716 VERT_ATTRIB_GENERIC(bindingIndex), divisor); 3717} 3718 3719 3720void GLAPIENTRY 3721_mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor) 3722{ 3723 GET_CURRENT_CONTEXT(ctx); 3724 3725 /* The ARB_vertex_attrib_binding spec says: 3726 * 3727 * "An INVALID_OPERATION error is generated if no vertex array object 3728 * is bound." 3729 */ 3730 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) && 3731 ctx->Array.VAO == ctx->Array.DefaultVAO) { 3732 _mesa_error(ctx, GL_INVALID_OPERATION, 3733 "glVertexBindingDivisor(No array object bound)"); 3734 return; 3735 } 3736 3737 vertex_array_binding_divisor(ctx, ctx->Array.VAO, 3738 bindingIndex, divisor, 3739 "glVertexBindingDivisor"); 3740} 3741 3742 3743void GLAPIENTRY 3744_mesa_VertexArrayBindingDivisor_no_error(GLuint vaobj, GLuint bindingIndex, 3745 GLuint divisor) 3746{ 3747 GET_CURRENT_CONTEXT(ctx); 3748 3749 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj); 3750 vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor); 3751} 3752 3753 3754void GLAPIENTRY 3755_mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex, 3756 GLuint divisor) 3757{ 3758 struct gl_vertex_array_object *vao; 3759 GET_CURRENT_CONTEXT(ctx); 3760 3761 /* The ARB_direct_state_access specification says: 3762 * 3763 * "An INVALID_OPERATION error is generated by VertexArrayBindingDivisor 3764 * if <vaobj> is not [compatibility profile: zero or] the name of an 3765 * existing vertex array object." 3766 */ 3767 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayBindingDivisor"); 3768 if (!vao) 3769 return; 3770 3771 vertex_array_binding_divisor(ctx, vao, bindingIndex, divisor, 3772 "glVertexArrayBindingDivisor"); 3773} 3774 3775 3776void GLAPIENTRY 3777_mesa_VertexArrayVertexBindingDivisorEXT(GLuint vaobj, GLuint bindingIndex, 3778 GLuint divisor) 3779{ 3780 struct gl_vertex_array_object *vao; 3781 GET_CURRENT_CONTEXT(ctx); 3782 3783 /* The ARB_direct_state_access specification says: 3784 * 3785 * "An INVALID_OPERATION error is generated by VertexArrayBindingDivisor 3786 * if <vaobj> is not [compatibility profile: zero or] the name of an 3787 * existing vertex array object." 3788 */ 3789 vao = _mesa_lookup_vao_err(ctx, vaobj, true, "glVertexArrayVertexBindingDivisorEXT"); 3790 if (!vao) 3791 return; 3792 3793 vertex_array_binding_divisor(ctx, vao, bindingIndex, divisor, 3794 "glVertexArrayVertexBindingDivisorEXT"); 3795} 3796 3797/** 3798 * Print current vertex object/array info. For debug. 3799 */ 3800void 3801_mesa_print_arrays(struct gl_context *ctx) 3802{ 3803 const struct gl_vertex_array_object *vao = ctx->Array.VAO; 3804 3805 fprintf(stderr, "Array Object %u\n", vao->Name); 3806 3807 GLbitfield mask = vao->Enabled; 3808 while (mask) { 3809 const gl_vert_attrib i = u_bit_scan(&mask); 3810 const struct gl_array_attributes *array = &vao->VertexAttrib[i]; 3811 3812 const struct gl_vertex_buffer_binding *binding = 3813 &vao->BufferBinding[array->BufferBindingIndex]; 3814 const struct gl_buffer_object *bo = binding->BufferObj; 3815 3816 fprintf(stderr, " %s: Ptr=%p, Type=%s, Size=%d, ElemSize=%u, " 3817 "Stride=%d, Buffer=%u(Size %lu)\n", 3818 gl_vert_attrib_name((gl_vert_attrib)i), 3819 array->Ptr, _mesa_enum_to_string(array->Format.Type), 3820 array->Format.Size, 3821 array->Format._ElementSize, binding->Stride, bo ? bo->Name : 0, 3822 (unsigned long)(bo ? bo->Size : 0)); 3823 } 3824} 3825 3826/** 3827 * Initialize attributes of a vertex array within a vertex array object. 3828 * \param vao the container vertex array object 3829 * \param index which array in the VAO to initialize 3830 * \param size number of components (1, 2, 3 or 4) per attribute 3831 * \param type datatype of the attribute (GL_FLOAT, GL_INT, etc). 3832 */ 3833static void 3834init_array(struct gl_context *ctx, 3835 struct gl_vertex_array_object *vao, 3836 gl_vert_attrib index, GLint size, GLint type) 3837{ 3838 assert(index < ARRAY_SIZE(vao->VertexAttrib)); 3839 struct gl_array_attributes *array = &vao->VertexAttrib[index]; 3840 assert(index < ARRAY_SIZE(vao->BufferBinding)); 3841 struct gl_vertex_buffer_binding *binding = &vao->BufferBinding[index]; 3842 3843 _mesa_set_vertex_format(&array->Format, size, type, GL_RGBA, 3844 GL_FALSE, GL_FALSE, GL_FALSE); 3845 array->Stride = 0; 3846 array->Ptr = NULL; 3847 array->RelativeOffset = 0; 3848 ASSERT_BITFIELD_SIZE(struct gl_array_attributes, BufferBindingIndex, 3849 VERT_ATTRIB_MAX - 1); 3850 array->BufferBindingIndex = index; 3851 3852 binding->Offset = 0; 3853 binding->Stride = array->Format._ElementSize; 3854 binding->BufferObj = NULL; 3855 binding->_BoundArrays = BITFIELD_BIT(index); 3856} 3857 3858static void 3859init_default_vao_state(struct gl_context *ctx) 3860{ 3861 struct gl_vertex_array_object *vao = &ctx->Array.DefaultVAOState; 3862 3863 vao->RefCount = 1; 3864 vao->SharedAndImmutable = false; 3865 3866 /* Init the individual arrays */ 3867 for (unsigned i = 0; i < ARRAY_SIZE(vao->VertexAttrib); i++) { 3868 switch (i) { 3869 case VERT_ATTRIB_NORMAL: 3870 init_array(ctx, vao, VERT_ATTRIB_NORMAL, 3, GL_FLOAT); 3871 break; 3872 case VERT_ATTRIB_COLOR1: 3873 init_array(ctx, vao, VERT_ATTRIB_COLOR1, 3, GL_FLOAT); 3874 break; 3875 case VERT_ATTRIB_FOG: 3876 init_array(ctx, vao, VERT_ATTRIB_FOG, 1, GL_FLOAT); 3877 break; 3878 case VERT_ATTRIB_COLOR_INDEX: 3879 init_array(ctx, vao, VERT_ATTRIB_COLOR_INDEX, 1, GL_FLOAT); 3880 break; 3881 case VERT_ATTRIB_EDGEFLAG: 3882 init_array(ctx, vao, VERT_ATTRIB_EDGEFLAG, 1, GL_UNSIGNED_BYTE); 3883 break; 3884 case VERT_ATTRIB_POINT_SIZE: 3885 init_array(ctx, vao, VERT_ATTRIB_POINT_SIZE, 1, GL_FLOAT); 3886 break; 3887 default: 3888 init_array(ctx, vao, i, 4, GL_FLOAT); 3889 break; 3890 } 3891 } 3892 3893 vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_IDENTITY; 3894} 3895 3896/** 3897 * Initialize vertex array state for given context. 3898 */ 3899void 3900_mesa_init_varray(struct gl_context *ctx) 3901{ 3902 init_default_vao_state(ctx); 3903 3904 ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0); 3905 _mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO); 3906 ctx->Array._EmptyVAO = _mesa_new_vao(ctx, ~0u); 3907 _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, ctx->Array._EmptyVAO); 3908 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */ 3909 3910 ctx->Array.Objects = _mesa_NewHashTable(); 3911} 3912 3913 3914/** 3915 * Callback for deleting an array object. Called by _mesa_HashDeleteAll(). 3916 */ 3917static void 3918delete_arrayobj_cb(void *data, void *userData) 3919{ 3920 struct gl_vertex_array_object *vao = (struct gl_vertex_array_object *) data; 3921 struct gl_context *ctx = (struct gl_context *) userData; 3922 _mesa_delete_vao(ctx, vao); 3923} 3924 3925 3926/** 3927 * Free vertex array state for given context. 3928 */ 3929void 3930_mesa_free_varray_data(struct gl_context *ctx) 3931{ 3932 _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx); 3933 _mesa_DeleteHashTable(ctx->Array.Objects); 3934} 3935 3936void GLAPIENTRY 3937_mesa_GetVertexArrayIntegervEXT(GLuint vaobj, GLenum pname, GLint *param) 3938{ 3939 GET_CURRENT_CONTEXT(ctx); 3940 struct gl_vertex_array_object* vao; 3941 struct gl_buffer_object *buf; 3942 void* ptr; 3943 3944 vao = _mesa_lookup_vao_err(ctx, vaobj, true, 3945 "glGetVertexArrayIntegervEXT"); 3946 if (!vao) 3947 return; 3948 3949 /* The EXT_direct_state_access spec says: 3950 * 3951 * "For GetVertexArrayIntegervEXT, pname must be one of the "Get value" tokens 3952 * in tables 6.6, 6.7, 6.8, and 6.9 that use GetIntegerv, IsEnabled, or 3953 * GetPointerv for their "Get command" (so excluding the VERTEX_ATTRIB_* 3954 * tokens)." 3955 */ 3956 switch (pname) { 3957 /* Tokens using GetIntegerv */ 3958 case GL_CLIENT_ACTIVE_TEXTURE: 3959 *param = GL_TEXTURE0_ARB + ctx->Array.ActiveTexture; 3960 break; 3961 case GL_VERTEX_ARRAY_SIZE: 3962 *param = vao->VertexAttrib[VERT_ATTRIB_POS].Format.Size; 3963 break; 3964 case GL_VERTEX_ARRAY_TYPE: 3965 *param = vao->VertexAttrib[VERT_ATTRIB_POS].Format.Type; 3966 break; 3967 case GL_VERTEX_ARRAY_STRIDE: 3968 *param = vao->VertexAttrib[VERT_ATTRIB_POS].Stride; 3969 break; 3970 case GL_VERTEX_ARRAY_BUFFER_BINDING: 3971 buf = vao->BufferBinding[VERT_ATTRIB_POS].BufferObj; 3972 *param = buf ? buf->Name : 0; 3973 break; 3974 case GL_COLOR_ARRAY_SIZE: 3975 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR0].Format.Size; 3976 break; 3977 case GL_COLOR_ARRAY_TYPE: 3978 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR0].Format.Type; 3979 break; 3980 case GL_COLOR_ARRAY_STRIDE: 3981 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR0].Stride; 3982 break; 3983 case GL_COLOR_ARRAY_BUFFER_BINDING: 3984 buf = vao->BufferBinding[VERT_ATTRIB_COLOR0].BufferObj; 3985 *param = buf ? buf->Name : 0; 3986 break; 3987 case GL_EDGE_FLAG_ARRAY_STRIDE: 3988 *param = vao->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Stride; 3989 break; 3990 case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING: 3991 buf = vao->BufferBinding[VERT_ATTRIB_EDGEFLAG].BufferObj; 3992 *param = buf ? buf->Name : 0; 3993 break; 3994 case GL_INDEX_ARRAY_TYPE: 3995 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Format.Type; 3996 break; 3997 case GL_INDEX_ARRAY_STRIDE: 3998 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Stride; 3999 break; 4000 case GL_INDEX_ARRAY_BUFFER_BINDING: 4001 buf = vao->BufferBinding[VERT_ATTRIB_COLOR_INDEX].BufferObj; 4002 *param = buf ? buf->Name : 0; 4003 break; 4004 case GL_NORMAL_ARRAY_TYPE: 4005 *param = vao->VertexAttrib[VERT_ATTRIB_NORMAL].Format.Type; 4006 break; 4007 case GL_NORMAL_ARRAY_STRIDE: 4008 *param = vao->VertexAttrib[VERT_ATTRIB_NORMAL].Stride; 4009 break; 4010 case GL_NORMAL_ARRAY_BUFFER_BINDING: 4011 buf = vao->BufferBinding[VERT_ATTRIB_NORMAL].BufferObj; 4012 *param = buf ? buf->Name : 0; 4013 break; 4014 case GL_TEXTURE_COORD_ARRAY_SIZE: 4015 *param = vao->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].Format.Size; 4016 break; 4017 case GL_TEXTURE_COORD_ARRAY_TYPE: 4018 *param = vao->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].Format.Type; 4019 break; 4020 case GL_TEXTURE_COORD_ARRAY_STRIDE: 4021 *param = vao->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].Stride; 4022 break; 4023 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: 4024 buf = vao->BufferBinding[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].BufferObj; 4025 *param = buf ? buf->Name : 0; 4026 break; 4027 case GL_FOG_COORD_ARRAY_TYPE: 4028 *param = vao->VertexAttrib[VERT_ATTRIB_FOG].Format.Type; 4029 break; 4030 case GL_FOG_COORD_ARRAY_STRIDE: 4031 *param = vao->VertexAttrib[VERT_ATTRIB_FOG].Stride; 4032 break; 4033 case GL_FOG_COORD_ARRAY_BUFFER_BINDING: 4034 buf = vao->BufferBinding[VERT_ATTRIB_FOG].BufferObj; 4035 *param = buf ? buf->Name : 0; 4036 break; 4037 case GL_SECONDARY_COLOR_ARRAY_SIZE: 4038 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR1].Format.Size; 4039 break; 4040 case GL_SECONDARY_COLOR_ARRAY_TYPE: 4041 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR1].Format.Type; 4042 break; 4043 case GL_SECONDARY_COLOR_ARRAY_STRIDE: 4044 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR1].Stride; 4045 break; 4046 case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING: 4047 buf = vao->BufferBinding[VERT_ATTRIB_COLOR1].BufferObj; 4048 *param = buf ? buf->Name : 0; 4049 break; 4050 4051 /* Tokens using IsEnabled */ 4052 case GL_VERTEX_ARRAY: 4053 *param = !!(vao->Enabled & VERT_BIT_POS); 4054 break; 4055 case GL_COLOR_ARRAY: 4056 *param = !!(vao->Enabled & VERT_BIT_COLOR0); 4057 break; 4058 case GL_EDGE_FLAG_ARRAY: 4059 *param = !!(vao->Enabled & VERT_BIT_EDGEFLAG); 4060 break; 4061 case GL_INDEX_ARRAY: 4062 *param = !!(vao->Enabled & VERT_BIT_COLOR_INDEX); 4063 break; 4064 case GL_NORMAL_ARRAY: 4065 *param = !!(vao->Enabled & VERT_BIT_NORMAL); 4066 break; 4067 case GL_TEXTURE_COORD_ARRAY: 4068 *param = !!(vao->Enabled & VERT_BIT_TEX(ctx->Array.ActiveTexture)); 4069 break; 4070 case GL_FOG_COORD_ARRAY: 4071 *param = !!(vao->Enabled & VERT_BIT_FOG); 4072 break; 4073 case GL_SECONDARY_COLOR_ARRAY: 4074 *param = !!(vao->Enabled & VERT_BIT_COLOR1); 4075 break; 4076 4077 /* Tokens using GetPointerv */ 4078 case GL_VERTEX_ARRAY_POINTER: 4079 case GL_COLOR_ARRAY_POINTER: 4080 case GL_EDGE_FLAG_ARRAY_POINTER: 4081 case GL_INDEX_ARRAY_POINTER: 4082 case GL_NORMAL_ARRAY_POINTER: 4083 case GL_TEXTURE_COORD_ARRAY_POINTER: 4084 case GL_FOG_COORD_ARRAY_POINTER: 4085 case GL_SECONDARY_COLOR_ARRAY_POINTER: 4086 _get_vao_pointerv(pname, vao, &ptr, "glGetVertexArrayIntegervEXT"); 4087 *param = (int) ((intptr_t) ptr & 0xFFFFFFFF); 4088 break; 4089 4090 default: 4091 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayIntegervEXT(pname)"); 4092 } 4093} 4094 4095void GLAPIENTRY 4096_mesa_GetVertexArrayPointervEXT(GLuint vaobj, GLenum pname, GLvoid** param) 4097{ 4098 GET_CURRENT_CONTEXT(ctx); 4099 struct gl_vertex_array_object* vao; 4100 4101 vao = _mesa_lookup_vao_err(ctx, vaobj, true, 4102 "glGetVertexArrayPointervEXT"); 4103 if (!vao) 4104 return; 4105 4106 /* The EXT_direct_state_access spec says: 4107 * 4108 * "For GetVertexArrayPointervEXT, pname must be a *_ARRAY_POINTER token from 4109 * tables 6.6, 6.7, and 6.8 excluding VERTEX_ATTRIB_ARRAY_POINT." 4110 */ 4111 switch (pname) { 4112 case GL_VERTEX_ARRAY_POINTER: 4113 case GL_COLOR_ARRAY_POINTER: 4114 case GL_EDGE_FLAG_ARRAY_POINTER: 4115 case GL_INDEX_ARRAY_POINTER: 4116 case GL_NORMAL_ARRAY_POINTER: 4117 case GL_TEXTURE_COORD_ARRAY_POINTER: 4118 case GL_FOG_COORD_ARRAY_POINTER: 4119 case GL_SECONDARY_COLOR_ARRAY_POINTER: 4120 break; 4121 4122 default: 4123 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayPointervEXT(pname)"); 4124 return; 4125 } 4126 4127 /* pname has been validated, we can now use the helper function */ 4128 _get_vao_pointerv(pname, vao, param, "glGetVertexArrayPointervEXT"); 4129} 4130 4131void GLAPIENTRY 4132_mesa_GetVertexArrayIntegeri_vEXT(GLuint vaobj, GLuint index, GLenum pname, GLint *param) 4133{ 4134 GET_CURRENT_CONTEXT(ctx); 4135 struct gl_vertex_array_object* vao; 4136 struct gl_buffer_object *buf; 4137 4138 vao = _mesa_lookup_vao_err(ctx, vaobj, true, 4139 "glGetVertexArrayIntegeri_vEXT"); 4140 if (!vao) 4141 return; 4142 4143 4144 /* The EXT_direct_state_access spec says: 4145 * 4146 * "For GetVertexArrayIntegeri_vEXT, pname must be one of the 4147 * "Get value" tokens in tables 6.8 and 6.9 that use GetVertexAttribiv 4148 * or GetVertexAttribPointerv (so allowing only the VERTEX_ATTRIB_* 4149 * tokens) or a token of the form TEXTURE_COORD_ARRAY (the enable) or 4150 * TEXTURE_COORD_ARRAY_*; index identifies the vertex attribute 4151 * array to query or texture coordinate set index respectively." 4152 */ 4153 4154 switch (pname) { 4155 case GL_TEXTURE_COORD_ARRAY: 4156 *param = !!(vao->Enabled & VERT_BIT_TEX(index)); 4157 break; 4158 case GL_TEXTURE_COORD_ARRAY_SIZE: 4159 *param = vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Format.Size; 4160 break; 4161 case GL_TEXTURE_COORD_ARRAY_TYPE: 4162 *param = vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Format.Type; 4163 break; 4164 case GL_TEXTURE_COORD_ARRAY_STRIDE: 4165 *param = vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Stride; 4166 break; 4167 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: 4168 buf = vao->BufferBinding[VERT_ATTRIB_TEX(index)].BufferObj; 4169 *param = buf ? buf->Name : 0; 4170 break; 4171 default: 4172 *param = get_vertex_array_attrib(ctx, vao, index, pname, "glGetVertexArrayIntegeri_vEXT"); 4173 } 4174} 4175 4176void GLAPIENTRY 4177_mesa_GetVertexArrayPointeri_vEXT(GLuint vaobj, GLuint index, GLenum pname, GLvoid** param) 4178{ 4179 GET_CURRENT_CONTEXT(ctx); 4180 struct gl_vertex_array_object* vao; 4181 4182 vao = _mesa_lookup_vao_err(ctx, vaobj, true, 4183 "glGetVertexArrayPointeri_vEXT"); 4184 if (!vao) 4185 return; 4186 4187 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 4188 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexArrayPointeri_vEXT(index)"); 4189 return; 4190 } 4191 4192 /* The EXT_direct_state_access spec says: 4193 * 4194 * "For GetVertexArrayPointeri_vEXT, pname must be VERTEX_ATTRIB_ARRAY_POINTER 4195 * or TEXTURE_COORD_ARRAY_POINTER with the index parameter indicating the vertex 4196 * attribute or texture coordindate set index." 4197 */ 4198 switch(pname) { 4199 case GL_VERTEX_ATTRIB_ARRAY_POINTER: 4200 *param = (GLvoid *) vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr; 4201 break; 4202 case GL_TEXTURE_COORD_ARRAY_POINTER: 4203 *param = (GLvoid *) vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Ptr; 4204 break; 4205 default: 4206 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayPointeri_vEXT(pname)"); 4207 } 4208} 4209