varray.c revision bbceed268e14593a07a7cc08060ffd20f2718718
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.6 4 * 5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 27#include "glheader.h" 28#include "imports.h" 29#include "bufferobj.h" 30#include "context.h" 31#include "enable.h" 32#include "enums.h" 33#include "hash.h" 34#include "image.h" 35#include "macros.h" 36#include "mfeatures.h" 37#include "mtypes.h" 38#include "varray.h" 39#include "arrayobj.h" 40#include "main/dispatch.h" 41 42 43/** Used to do error checking for GL_EXT_vertex_array_bgra */ 44#define BGRA_OR_4 5 45 46 47/** Used to indicate which GL datatypes are accepted by each of the 48 * glVertex/Color/Attrib/EtcPointer() functions. 49 */ 50#define BOOL_BIT 0x1 51#define BYTE_BIT 0x2 52#define UNSIGNED_BYTE_BIT 0x4 53#define SHORT_BIT 0x8 54#define UNSIGNED_SHORT_BIT 0x10 55#define INT_BIT 0x20 56#define UNSIGNED_INT_BIT 0x40 57#define HALF_BIT 0x80 58#define FLOAT_BIT 0x100 59#define DOUBLE_BIT 0x200 60#define FIXED_ES_BIT 0x400 61#define FIXED_GL_BIT 0x800 62#define UNSIGNED_INT_2_10_10_10_REV_BIT 0x1000 63#define INT_2_10_10_10_REV_BIT 0x2000 64 65 66/** Convert GL datatype enum into a <type>_BIT value seen above */ 67static GLbitfield 68type_to_bit(const struct gl_context *ctx, GLenum type) 69{ 70 switch (type) { 71 case GL_BOOL: 72 return BOOL_BIT; 73 case GL_BYTE: 74 return BYTE_BIT; 75 case GL_UNSIGNED_BYTE: 76 return UNSIGNED_BYTE_BIT; 77 case GL_SHORT: 78 return SHORT_BIT; 79 case GL_UNSIGNED_SHORT: 80 return UNSIGNED_SHORT_BIT; 81 case GL_INT: 82 return INT_BIT; 83 case GL_UNSIGNED_INT: 84 return UNSIGNED_INT_BIT; 85 case GL_HALF_FLOAT: 86 if (ctx->Extensions.ARB_half_float_vertex) 87 return HALF_BIT; 88 else 89 return 0x0; 90 case GL_FLOAT: 91 return FLOAT_BIT; 92 case GL_DOUBLE: 93 return DOUBLE_BIT; 94 case GL_FIXED: 95 return _mesa_is_desktop_gl(ctx) ? FIXED_GL_BIT : FIXED_ES_BIT; 96 case GL_UNSIGNED_INT_2_10_10_10_REV: 97 return UNSIGNED_INT_2_10_10_10_REV_BIT; 98 case GL_INT_2_10_10_10_REV: 99 return INT_2_10_10_10_REV_BIT; 100 default: 101 return 0; 102 } 103} 104 105 106/** 107 * Do error checking and update state for glVertex/Color/TexCoord/...Pointer 108 * functions. 109 * 110 * \param func name of calling function used for error reporting 111 * \param attrib the attribute array index to update 112 * \param legalTypes bitmask of *_BIT above indicating legal datatypes 113 * \param sizeMin min allowable size value 114 * \param sizeMax max allowable size value (may also be BGRA_OR_4) 115 * \param size components per element (1, 2, 3 or 4) 116 * \param type datatype of each component (GL_FLOAT, GL_INT, etc) 117 * \param stride stride between elements, in elements 118 * \param normalized are integer types converted to floats in [-1, 1]? 119 * \param integer integer-valued values (will not be normalized to [-1,1]) 120 * \param ptr the address (or offset inside VBO) of the array data 121 */ 122static void 123update_array(struct gl_context *ctx, 124 const char *func, 125 GLuint attrib, GLbitfield legalTypesMask, 126 GLint sizeMin, GLint sizeMax, 127 GLint size, GLenum type, GLsizei stride, 128 GLboolean normalized, GLboolean integer, 129 const GLvoid *ptr) 130{ 131 struct gl_client_array *array; 132 GLbitfield typeBit; 133 GLsizei elementSize; 134 GLenum format = GL_RGBA; 135 136 if (_mesa_is_gles(ctx)) { 137 /* Once Mesa gets support for GL_OES_vertex_half_float this mask will 138 * change. Adding support for this extension isn't quite as trivial as 139 * we'd like because ES uses a different enum value for GL_HALF_FLOAT. 140 */ 141 legalTypesMask &= ~(FIXED_GL_BIT | HALF_BIT | DOUBLE_BIT); 142 143 /* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until 144 * 3.0. The 2_10_10_10 types are added in OpenGL ES 3.0 or 145 * GL_OES_vertex_type_10_10_10_2. 146 */ 147 if (ctx->Version < 30) { 148 legalTypesMask &= ~(UNSIGNED_INT_BIT 149 | INT_BIT 150 | UNSIGNED_INT_2_10_10_10_REV_BIT 151 | INT_2_10_10_10_REV_BIT); 152 } 153 } else { 154 legalTypesMask &= ~FIXED_ES_BIT; 155 156 if (!ctx->Extensions.ARB_ES2_compatibility) 157 legalTypesMask &= ~FIXED_GL_BIT; 158 159 if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) 160 legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT | 161 INT_2_10_10_10_REV_BIT); 162 } 163 164 typeBit = type_to_bit(ctx, type); 165 if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) { 166 _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)", 167 func, _mesa_lookup_enum_by_nr(type)); 168 return; 169 } 170 171 /* Do size parameter checking. 172 * If sizeMax = BGRA_OR_4 it means that size = GL_BGRA is legal and 173 * must be handled specially. 174 */ 175 if (ctx->Extensions.EXT_vertex_array_bgra && 176 sizeMax == BGRA_OR_4 && 177 size == GL_BGRA) { 178 GLboolean bgra_error = GL_FALSE; 179 180 if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) { 181 if (type != GL_UNSIGNED_INT_2_10_10_10_REV && 182 type != GL_INT_2_10_10_10_REV && 183 type != GL_UNSIGNED_BYTE) 184 bgra_error = GL_TRUE; 185 } else if (type != GL_UNSIGNED_BYTE) 186 bgra_error = GL_TRUE; 187 188 if (bgra_error) { 189 _mesa_error(ctx, GL_INVALID_VALUE, "%s(GL_BGRA/GLubyte)", func); 190 return; 191 } 192 format = GL_BGRA; 193 size = 4; 194 } 195 else if (size < sizeMin || size > sizeMax || size > 4) { 196 _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size); 197 return; 198 } 199 200 if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev && 201 (type == GL_UNSIGNED_INT_2_10_10_10_REV || 202 type == GL_INT_2_10_10_10_REV) && size != 4) { 203 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size); 204 return; 205 } 206 207 ASSERT(size <= 4); 208 209 if (stride < 0) { 210 _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride ); 211 return; 212 } 213 214 if (ctx->Array.ArrayObj->ARBsemantics && 215 !_mesa_is_bufferobj(ctx->Array.ArrayBufferObj)) { 216 /* GL_ARB_vertex_array_object requires that all arrays reside in VBOs. 217 * Generate GL_INVALID_OPERATION if that's not true. 218 */ 219 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func); 220 return; 221 } 222 223 elementSize = _mesa_sizeof_type(type) * size; 224 225 array = &ctx->Array.ArrayObj->VertexAttrib[attrib]; 226 array->Size = size; 227 array->Type = type; 228 array->Format = format; 229 array->Stride = stride; 230 array->StrideB = stride ? stride : elementSize; 231 array->Normalized = normalized; 232 array->Integer = integer; 233 array->Ptr = (const GLubyte *) ptr; 234 array->_ElementSize = elementSize; 235 236 _mesa_reference_buffer_object(ctx, &array->BufferObj, 237 ctx->Array.ArrayBufferObj); 238 239 ctx->NewState |= _NEW_ARRAY; 240 ctx->Array.ArrayObj->NewArrays |= VERT_BIT(attrib); 241} 242 243 244void GLAPIENTRY 245_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) 246{ 247 GLbitfield legalTypes = (SHORT_BIT | INT_BIT | FLOAT_BIT | 248 DOUBLE_BIT | HALF_BIT | FIXED_ES_BIT | 249 UNSIGNED_INT_2_10_10_10_REV_BIT | 250 INT_2_10_10_10_REV_BIT); 251 GET_CURRENT_CONTEXT(ctx); 252 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 253 254 if (ctx->API == API_OPENGLES) 255 legalTypes |= BYTE_BIT; 256 257 update_array(ctx, "glVertexPointer", VERT_ATTRIB_POS, 258 legalTypes, 2, 4, 259 size, type, stride, GL_FALSE, GL_FALSE, ptr); 260} 261 262 263void GLAPIENTRY 264_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) 265{ 266 const GLbitfield legalTypes = (BYTE_BIT | SHORT_BIT | INT_BIT | 267 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 268 FIXED_ES_BIT | 269 UNSIGNED_INT_2_10_10_10_REV_BIT | 270 INT_2_10_10_10_REV_BIT); 271 GET_CURRENT_CONTEXT(ctx); 272 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 273 274 update_array(ctx, "glNormalPointer", VERT_ATTRIB_NORMAL, 275 legalTypes, 3, 3, 276 3, type, stride, GL_TRUE, GL_FALSE, ptr); 277} 278 279 280void GLAPIENTRY 281_mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) 282{ 283 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | 284 SHORT_BIT | UNSIGNED_SHORT_BIT | 285 INT_BIT | UNSIGNED_INT_BIT | 286 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 287 FIXED_ES_BIT | 288 UNSIGNED_INT_2_10_10_10_REV_BIT | 289 INT_2_10_10_10_REV_BIT); 290 GET_CURRENT_CONTEXT(ctx); 291 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 292 293 update_array(ctx, "glColorPointer", VERT_ATTRIB_COLOR0, 294 legalTypes, 3, BGRA_OR_4, 295 size, type, stride, GL_TRUE, GL_FALSE, ptr); 296} 297 298 299void GLAPIENTRY 300_mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr) 301{ 302 const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT); 303 GET_CURRENT_CONTEXT(ctx); 304 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 305 306 update_array(ctx, "glFogCoordPointer", VERT_ATTRIB_FOG, 307 legalTypes, 1, 1, 308 1, type, stride, GL_FALSE, GL_FALSE, ptr); 309} 310 311 312void GLAPIENTRY 313_mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr) 314{ 315 const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT | 316 FLOAT_BIT | DOUBLE_BIT); 317 GET_CURRENT_CONTEXT(ctx); 318 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 319 320 update_array(ctx, "glIndexPointer", VERT_ATTRIB_COLOR_INDEX, 321 legalTypes, 1, 1, 322 1, type, stride, GL_FALSE, GL_FALSE, ptr); 323} 324 325 326void GLAPIENTRY 327_mesa_SecondaryColorPointerEXT(GLint size, GLenum type, 328 GLsizei stride, const GLvoid *ptr) 329{ 330 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | 331 SHORT_BIT | UNSIGNED_SHORT_BIT | 332 INT_BIT | UNSIGNED_INT_BIT | 333 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 334 UNSIGNED_INT_2_10_10_10_REV_BIT | 335 INT_2_10_10_10_REV_BIT); 336 GET_CURRENT_CONTEXT(ctx); 337 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 338 339 update_array(ctx, "glSecondaryColorPointer", VERT_ATTRIB_COLOR1, 340 legalTypes, 3, BGRA_OR_4, 341 size, type, stride, GL_TRUE, GL_FALSE, ptr); 342} 343 344 345void GLAPIENTRY 346_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, 347 const GLvoid *ptr) 348{ 349 GLbitfield legalTypes = (SHORT_BIT | INT_BIT | 350 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 351 FIXED_ES_BIT | 352 UNSIGNED_INT_2_10_10_10_REV_BIT | 353 INT_2_10_10_10_REV_BIT); 354 GET_CURRENT_CONTEXT(ctx); 355 const GLuint unit = ctx->Array.ActiveTexture; 356 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 357 358 if (ctx->API == API_OPENGLES) 359 legalTypes |= BYTE_BIT; 360 361 update_array(ctx, "glTexCoordPointer", VERT_ATTRIB_TEX(unit), 362 legalTypes, 1, 4, 363 size, type, stride, GL_FALSE, GL_FALSE, 364 ptr); 365} 366 367 368void GLAPIENTRY 369_mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr) 370{ 371 const GLbitfield legalTypes = UNSIGNED_BYTE_BIT; 372 /* see table 2.4 edits in GL_EXT_gpu_shader4 spec: */ 373 const GLboolean integer = GL_TRUE; 374 GET_CURRENT_CONTEXT(ctx); 375 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 376 377 update_array(ctx, "glEdgeFlagPointer", VERT_ATTRIB_EDGEFLAG, 378 legalTypes, 1, 1, 379 1, GL_UNSIGNED_BYTE, stride, GL_FALSE, integer, ptr); 380} 381 382 383void GLAPIENTRY 384_mesa_PointSizePointer(GLenum type, GLsizei stride, const GLvoid *ptr) 385{ 386 const GLbitfield legalTypes = (FLOAT_BIT | FIXED_ES_BIT); 387 GET_CURRENT_CONTEXT(ctx); 388 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 389 390 if (ctx->API != API_OPENGLES) { 391 _mesa_error(ctx, GL_INVALID_OPERATION, 392 "glPointSizePointer(ES 1.x only)"); 393 return; 394 } 395 396 update_array(ctx, "glPointSizePointer", VERT_ATTRIB_POINT_SIZE, 397 legalTypes, 1, 1, 398 1, type, stride, GL_FALSE, GL_FALSE, ptr); 399} 400 401 402#if FEATURE_NV_vertex_program 403/** 404 * Set a vertex attribute array. 405 * Note that these arrays DO alias the conventional GL vertex arrays 406 * (position, normal, color, fog, texcoord, etc). 407 * The generic attribute slots at #16 and above are not touched. 408 */ 409void GLAPIENTRY 410_mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type, 411 GLsizei stride, const GLvoid *ptr) 412{ 413 const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | 414 FLOAT_BIT | DOUBLE_BIT); 415 GLboolean normalized = GL_FALSE; 416 GET_CURRENT_CONTEXT(ctx); 417 ASSERT_OUTSIDE_BEGIN_END(ctx); 418 419 if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { 420 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)"); 421 return; 422 } 423 424 if (type == GL_UNSIGNED_BYTE && size != 4) { 425 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)"); 426 return; 427 } 428 429 update_array(ctx, "glVertexAttribPointerNV", VERT_ATTRIB_GENERIC(index), 430 legalTypes, 1, BGRA_OR_4, 431 size, type, stride, normalized, GL_FALSE, ptr); 432} 433#endif 434 435 436#if FEATURE_ARB_vertex_program 437/** 438 * Set a generic vertex attribute array. 439 * Note that these arrays DO NOT alias the conventional GL vertex arrays 440 * (position, normal, color, fog, texcoord, etc). 441 */ 442void GLAPIENTRY 443_mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type, 444 GLboolean normalized, 445 GLsizei stride, const GLvoid *ptr) 446{ 447 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | 448 SHORT_BIT | UNSIGNED_SHORT_BIT | 449 INT_BIT | UNSIGNED_INT_BIT | 450 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | 451 FIXED_ES_BIT | FIXED_GL_BIT | 452 UNSIGNED_INT_2_10_10_10_REV_BIT | 453 INT_2_10_10_10_REV_BIT); 454 GET_CURRENT_CONTEXT(ctx); 455 ASSERT_OUTSIDE_BEGIN_END(ctx); 456 457 if (index >= ctx->Const.VertexProgram.MaxAttribs) { 458 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)"); 459 return; 460 } 461 462 update_array(ctx, "glVertexAttribPointer", VERT_ATTRIB_GENERIC(index), 463 legalTypes, 1, BGRA_OR_4, 464 size, type, stride, normalized, GL_FALSE, ptr); 465} 466#endif 467 468 469/** 470 * GL_EXT_gpu_shader4 / GL 3.0. 471 * Set an integer-valued vertex attribute array. 472 * Note that these arrays DO NOT alias the conventional GL vertex arrays 473 * (position, normal, color, fog, texcoord, etc). 474 */ 475void GLAPIENTRY 476_mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type, 477 GLsizei stride, const GLvoid *ptr) 478{ 479 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | 480 SHORT_BIT | UNSIGNED_SHORT_BIT | 481 INT_BIT | UNSIGNED_INT_BIT); 482 const GLboolean normalized = GL_FALSE; 483 const GLboolean integer = GL_TRUE; 484 GET_CURRENT_CONTEXT(ctx); 485 ASSERT_OUTSIDE_BEGIN_END(ctx); 486 487 if (index >= ctx->Const.VertexProgram.MaxAttribs) { 488 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIPointer(index)"); 489 return; 490 } 491 492 update_array(ctx, "glVertexAttribIPointer", VERT_ATTRIB_GENERIC(index), 493 legalTypes, 1, 4, 494 size, type, stride, normalized, integer, ptr); 495} 496 497 498 499void GLAPIENTRY 500_mesa_EnableVertexAttribArrayARB(GLuint index) 501{ 502 struct gl_array_object *arrayObj; 503 GET_CURRENT_CONTEXT(ctx); 504 ASSERT_OUTSIDE_BEGIN_END(ctx); 505 506 if (index >= ctx->Const.VertexProgram.MaxAttribs) { 507 _mesa_error(ctx, GL_INVALID_VALUE, 508 "glEnableVertexAttribArrayARB(index)"); 509 return; 510 } 511 512 arrayObj = ctx->Array.ArrayObj; 513 514 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(arrayObj->VertexAttrib)); 515 516 if (!arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled) { 517 /* was disabled, now being enabled */ 518 FLUSH_VERTICES(ctx, _NEW_ARRAY); 519 arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_TRUE; 520 arrayObj->_Enabled |= VERT_BIT_GENERIC(index); 521 arrayObj->NewArrays |= VERT_BIT_GENERIC(index); 522 } 523} 524 525 526void GLAPIENTRY 527_mesa_DisableVertexAttribArrayARB(GLuint index) 528{ 529 struct gl_array_object *arrayObj; 530 GET_CURRENT_CONTEXT(ctx); 531 ASSERT_OUTSIDE_BEGIN_END(ctx); 532 533 if (index >= ctx->Const.VertexProgram.MaxAttribs) { 534 _mesa_error(ctx, GL_INVALID_VALUE, 535 "glDisableVertexAttribArrayARB(index)"); 536 return; 537 } 538 539 arrayObj = ctx->Array.ArrayObj; 540 541 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(arrayObj->VertexAttrib)); 542 543 if (arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled) { 544 /* was enabled, now being disabled */ 545 FLUSH_VERTICES(ctx, _NEW_ARRAY); 546 arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_FALSE; 547 arrayObj->_Enabled &= ~VERT_BIT_GENERIC(index); 548 arrayObj->NewArrays |= VERT_BIT_GENERIC(index); 549 } 550} 551 552 553/** 554 * Return info for a vertex attribute array (no alias with legacy 555 * vertex attributes (pos, normal, color, etc)). This function does 556 * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query. 557 */ 558static GLuint 559get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname, 560 const char *caller) 561{ 562 const struct gl_client_array *array; 563 564 if (index >= ctx->Const.VertexProgram.MaxAttribs) { 565 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index); 566 return 0; 567 } 568 569 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib)); 570 571 array = &ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)]; 572 573 switch (pname) { 574 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB: 575 return array->Enabled; 576 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB: 577 return array->Size; 578 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB: 579 return array->Stride; 580 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB: 581 return array->Type; 582 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB: 583 return array->Normalized; 584 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB: 585 return array->BufferObj->Name; 586 case GL_VERTEX_ATTRIB_ARRAY_INTEGER: 587 if (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4) { 588 return array->Integer; 589 } 590 goto error; 591 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB: 592 if (ctx->Extensions.ARB_instanced_arrays) { 593 return array->InstanceDivisor; 594 } 595 goto error; 596 default: 597 ; /* fall-through */ 598 } 599 600error: 601 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname); 602 return 0; 603} 604 605 606static const GLfloat * 607get_current_attrib(struct gl_context *ctx, GLuint index, const char *function) 608{ 609 if (index == 0) { 610 if (ctx->API != API_OPENGLES2) { 611 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function); 612 return NULL; 613 } 614 } 615 else if (index >= ctx->Const.VertexProgram.MaxAttribs) { 616 _mesa_error(ctx, GL_INVALID_VALUE, 617 "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function); 618 return NULL; 619 } 620 621 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib)); 622 623 FLUSH_CURRENT(ctx, 0); 624 return ctx->Current.Attrib[VERT_ATTRIB_GENERIC(index)]; 625} 626 627void GLAPIENTRY 628_mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params) 629{ 630 GET_CURRENT_CONTEXT(ctx); 631 ASSERT_OUTSIDE_BEGIN_END(ctx); 632 633 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 634 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv"); 635 if (v != NULL) { 636 COPY_4V(params, v); 637 } 638 } 639 else { 640 params[0] = (GLfloat) get_vertex_array_attrib(ctx, index, pname, 641 "glGetVertexAttribfv"); 642 } 643} 644 645 646void GLAPIENTRY 647_mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params) 648{ 649 GET_CURRENT_CONTEXT(ctx); 650 ASSERT_OUTSIDE_BEGIN_END(ctx); 651 652 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 653 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv"); 654 if (v != NULL) { 655 params[0] = (GLdouble) v[0]; 656 params[1] = (GLdouble) v[1]; 657 params[2] = (GLdouble) v[2]; 658 params[3] = (GLdouble) v[3]; 659 } 660 } 661 else { 662 params[0] = (GLdouble) get_vertex_array_attrib(ctx, index, pname, 663 "glGetVertexAttribdv"); 664 } 665} 666 667 668void GLAPIENTRY 669_mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params) 670{ 671 GET_CURRENT_CONTEXT(ctx); 672 ASSERT_OUTSIDE_BEGIN_END(ctx); 673 674 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 675 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv"); 676 if (v != NULL) { 677 /* XXX should floats in[0,1] be scaled to full int range? */ 678 params[0] = (GLint) v[0]; 679 params[1] = (GLint) v[1]; 680 params[2] = (GLint) v[2]; 681 params[3] = (GLint) v[3]; 682 } 683 } 684 else { 685 params[0] = (GLint) get_vertex_array_attrib(ctx, index, pname, 686 "glGetVertexAttribiv"); 687 } 688} 689 690 691/** GL 3.0 */ 692void GLAPIENTRY 693_mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params) 694{ 695 GET_CURRENT_CONTEXT(ctx); 696 ASSERT_OUTSIDE_BEGIN_END(ctx); 697 698 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 699 const GLfloat *v = 700 get_current_attrib(ctx, index, "glGetVertexAttribIiv"); 701 if (v != NULL) { 702 /* XXX we don't have true integer-valued vertex attribs yet */ 703 params[0] = (GLint) v[0]; 704 params[1] = (GLint) v[1]; 705 params[2] = (GLint) v[2]; 706 params[3] = (GLint) v[3]; 707 } 708 } 709 else { 710 params[0] = (GLint) get_vertex_array_attrib(ctx, index, pname, 711 "glGetVertexAttribIiv"); 712 } 713} 714 715 716/** GL 3.0 */ 717void GLAPIENTRY 718_mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params) 719{ 720 GET_CURRENT_CONTEXT(ctx); 721 ASSERT_OUTSIDE_BEGIN_END(ctx); 722 723 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { 724 const GLfloat *v = 725 get_current_attrib(ctx, index, "glGetVertexAttribIuiv"); 726 if (v != NULL) { 727 /* XXX we don't have true integer-valued vertex attribs yet */ 728 params[0] = (GLuint) v[0]; 729 params[1] = (GLuint) v[1]; 730 params[2] = (GLuint) v[2]; 731 params[3] = (GLuint) v[3]; 732 } 733 } 734 else { 735 params[0] = get_vertex_array_attrib(ctx, index, pname, 736 "glGetVertexAttribIuiv"); 737 } 738} 739 740 741void GLAPIENTRY 742_mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer) 743{ 744 GET_CURRENT_CONTEXT(ctx); 745 ASSERT_OUTSIDE_BEGIN_END(ctx); 746 747 if (index >= ctx->Const.VertexProgram.MaxAttribs) { 748 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)"); 749 return; 750 } 751 752 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) { 753 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)"); 754 return; 755 } 756 757 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib)); 758 759 *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr; 760} 761 762 763void GLAPIENTRY 764_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride, 765 GLsizei count, const GLvoid *ptr) 766{ 767 (void) count; 768 _mesa_VertexPointer(size, type, stride, ptr); 769} 770 771 772void GLAPIENTRY 773_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, 774 const GLvoid *ptr) 775{ 776 (void) count; 777 _mesa_NormalPointer(type, stride, ptr); 778} 779 780 781void GLAPIENTRY 782_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, 783 const GLvoid *ptr) 784{ 785 (void) count; 786 _mesa_ColorPointer(size, type, stride, ptr); 787} 788 789 790void GLAPIENTRY 791_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, 792 const GLvoid *ptr) 793{ 794 (void) count; 795 _mesa_IndexPointer(type, stride, ptr); 796} 797 798 799void GLAPIENTRY 800_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, 801 GLsizei count, const GLvoid *ptr) 802{ 803 (void) count; 804 _mesa_TexCoordPointer(size, type, stride, ptr); 805} 806 807 808void GLAPIENTRY 809_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr) 810{ 811 (void) count; 812 _mesa_EdgeFlagPointer(stride, ptr); 813} 814 815 816void GLAPIENTRY 817_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) 818{ 819 GET_CURRENT_CONTEXT(ctx); 820 GLboolean tflag, cflag, nflag; /* enable/disable flags */ 821 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */ 822 GLenum ctype = 0; /* color type */ 823 GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */ 824 const GLint toffset = 0; /* always zero */ 825 GLint defstride; /* default stride */ 826 GLint c, f; 827 828 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 829 830 f = sizeof(GLfloat); 831 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f); 832 833 if (stride < 0) { 834 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" ); 835 return; 836 } 837 838 switch (format) { 839 case GL_V2F: 840 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; 841 tcomps = 0; ccomps = 0; vcomps = 2; 842 voffset = 0; 843 defstride = 2*f; 844 break; 845 case GL_V3F: 846 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; 847 tcomps = 0; ccomps = 0; vcomps = 3; 848 voffset = 0; 849 defstride = 3*f; 850 break; 851 case GL_C4UB_V2F: 852 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; 853 tcomps = 0; ccomps = 4; vcomps = 2; 854 ctype = GL_UNSIGNED_BYTE; 855 coffset = 0; 856 voffset = c; 857 defstride = c + 2*f; 858 break; 859 case GL_C4UB_V3F: 860 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; 861 tcomps = 0; ccomps = 4; vcomps = 3; 862 ctype = GL_UNSIGNED_BYTE; 863 coffset = 0; 864 voffset = c; 865 defstride = c + 3*f; 866 break; 867 case GL_C3F_V3F: 868 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; 869 tcomps = 0; ccomps = 3; vcomps = 3; 870 ctype = GL_FLOAT; 871 coffset = 0; 872 voffset = 3*f; 873 defstride = 6*f; 874 break; 875 case GL_N3F_V3F: 876 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE; 877 tcomps = 0; ccomps = 0; vcomps = 3; 878 noffset = 0; 879 voffset = 3*f; 880 defstride = 6*f; 881 break; 882 case GL_C4F_N3F_V3F: 883 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE; 884 tcomps = 0; ccomps = 4; vcomps = 3; 885 ctype = GL_FLOAT; 886 coffset = 0; 887 noffset = 4*f; 888 voffset = 7*f; 889 defstride = 10*f; 890 break; 891 case GL_T2F_V3F: 892 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; 893 tcomps = 2; ccomps = 0; vcomps = 3; 894 voffset = 2*f; 895 defstride = 5*f; 896 break; 897 case GL_T4F_V4F: 898 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; 899 tcomps = 4; ccomps = 0; vcomps = 4; 900 voffset = 4*f; 901 defstride = 8*f; 902 break; 903 case GL_T2F_C4UB_V3F: 904 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; 905 tcomps = 2; ccomps = 4; vcomps = 3; 906 ctype = GL_UNSIGNED_BYTE; 907 coffset = 2*f; 908 voffset = c+2*f; 909 defstride = c+5*f; 910 break; 911 case GL_T2F_C3F_V3F: 912 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; 913 tcomps = 2; ccomps = 3; vcomps = 3; 914 ctype = GL_FLOAT; 915 coffset = 2*f; 916 voffset = 5*f; 917 defstride = 8*f; 918 break; 919 case GL_T2F_N3F_V3F: 920 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE; 921 tcomps = 2; ccomps = 0; vcomps = 3; 922 noffset = 2*f; 923 voffset = 5*f; 924 defstride = 8*f; 925 break; 926 case GL_T2F_C4F_N3F_V3F: 927 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; 928 tcomps = 2; ccomps = 4; vcomps = 3; 929 ctype = GL_FLOAT; 930 coffset = 2*f; 931 noffset = 6*f; 932 voffset = 9*f; 933 defstride = 12*f; 934 break; 935 case GL_T4F_C4F_N3F_V4F: 936 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; 937 tcomps = 4; ccomps = 4; vcomps = 4; 938 ctype = GL_FLOAT; 939 coffset = 4*f; 940 noffset = 8*f; 941 voffset = 11*f; 942 defstride = 15*f; 943 break; 944 default: 945 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" ); 946 return; 947 } 948 949 if (stride==0) { 950 stride = defstride; 951 } 952 953 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY ); 954 _mesa_DisableClientState( GL_INDEX_ARRAY ); 955 /* XXX also disable secondary color and generic arrays? */ 956 957 /* Texcoords */ 958 if (tflag) { 959 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY ); 960 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride, 961 (GLubyte *) pointer + toffset ); 962 } 963 else { 964 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY ); 965 } 966 967 /* Color */ 968 if (cflag) { 969 _mesa_EnableClientState( GL_COLOR_ARRAY ); 970 _mesa_ColorPointer( ccomps, ctype, stride, 971 (GLubyte *) pointer + coffset ); 972 } 973 else { 974 _mesa_DisableClientState( GL_COLOR_ARRAY ); 975 } 976 977 978 /* Normals */ 979 if (nflag) { 980 _mesa_EnableClientState( GL_NORMAL_ARRAY ); 981 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset ); 982 } 983 else { 984 _mesa_DisableClientState( GL_NORMAL_ARRAY ); 985 } 986 987 /* Vertices */ 988 _mesa_EnableClientState( GL_VERTEX_ARRAY ); 989 _mesa_VertexPointer( vcomps, GL_FLOAT, stride, 990 (GLubyte *) pointer + voffset ); 991} 992 993 994void GLAPIENTRY 995_mesa_LockArraysEXT(GLint first, GLsizei count) 996{ 997 GET_CURRENT_CONTEXT(ctx); 998 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 999 1000 if (MESA_VERBOSE & VERBOSE_API) 1001 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count); 1002 1003 if (first < 0) { 1004 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" ); 1005 return; 1006 } 1007 if (count <= 0) { 1008 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" ); 1009 return; 1010 } 1011 if (ctx->Array.LockCount != 0) { 1012 _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" ); 1013 return; 1014 } 1015 1016 ctx->Array.LockFirst = first; 1017 ctx->Array.LockCount = count; 1018 1019 ctx->NewState |= _NEW_ARRAY; 1020} 1021 1022 1023void GLAPIENTRY 1024_mesa_UnlockArraysEXT( void ) 1025{ 1026 GET_CURRENT_CONTEXT(ctx); 1027 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1028 1029 if (MESA_VERBOSE & VERBOSE_API) 1030 _mesa_debug(ctx, "glUnlockArrays\n"); 1031 1032 if (ctx->Array.LockCount == 0) { 1033 _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" ); 1034 return; 1035 } 1036 1037 ctx->Array.LockFirst = 0; 1038 ctx->Array.LockCount = 0; 1039 ctx->NewState |= _NEW_ARRAY; 1040} 1041 1042 1043/* GL_EXT_multi_draw_arrays */ 1044void GLAPIENTRY 1045_mesa_MultiDrawArraysEXT( GLenum mode, const GLint *first, 1046 const GLsizei *count, GLsizei primcount ) 1047{ 1048 GET_CURRENT_CONTEXT(ctx); 1049 GLint i; 1050 1051 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1052 1053 for (i = 0; i < primcount; i++) { 1054 if (count[i] > 0) { 1055 CALL_DrawArrays(ctx->Exec, (mode, first[i], count[i])); 1056 } 1057 } 1058} 1059 1060 1061/* GL_IBM_multimode_draw_arrays */ 1062void GLAPIENTRY 1063_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first, 1064 const GLsizei * count, 1065 GLsizei primcount, GLint modestride ) 1066{ 1067 GET_CURRENT_CONTEXT(ctx); 1068 GLint i; 1069 1070 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1071 1072 for ( i = 0 ; i < primcount ; i++ ) { 1073 if ( count[i] > 0 ) { 1074 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); 1075 CALL_DrawArrays(ctx->Exec, ( m, first[i], count[i] )); 1076 } 1077 } 1078} 1079 1080 1081/* GL_IBM_multimode_draw_arrays */ 1082void GLAPIENTRY 1083_mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count, 1084 GLenum type, const GLvoid * const * indices, 1085 GLsizei primcount, GLint modestride ) 1086{ 1087 GET_CURRENT_CONTEXT(ctx); 1088 GLint i; 1089 1090 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1091 1092 /* XXX not sure about ARB_vertex_buffer_object handling here */ 1093 1094 for ( i = 0 ; i < primcount ; i++ ) { 1095 if ( count[i] > 0 ) { 1096 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); 1097 CALL_DrawElements(ctx->Exec, ( m, count[i], type, indices[i] )); 1098 } 1099 } 1100} 1101 1102 1103/** 1104 * GL_NV_primitive_restart and GL 3.1 1105 */ 1106void GLAPIENTRY 1107_mesa_PrimitiveRestartIndex(GLuint index) 1108{ 1109 GET_CURRENT_CONTEXT(ctx); 1110 1111 if (!ctx->Extensions.NV_primitive_restart && ctx->Version < 31) { 1112 _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()"); 1113 return; 1114 } 1115 1116 ASSERT_OUTSIDE_BEGIN_END(ctx); 1117 1118 if (ctx->Array.RestartIndex != index) { 1119 FLUSH_VERTICES(ctx, _NEW_TRANSFORM); 1120 ctx->Array.RestartIndex = index; 1121 } 1122} 1123 1124 1125/** 1126 * See GL_ARB_instanced_arrays. 1127 * Note that the instance divisor only applies to generic arrays, not 1128 * the legacy vertex arrays. 1129 */ 1130void GLAPIENTRY 1131_mesa_VertexAttribDivisor(GLuint index, GLuint divisor) 1132{ 1133 struct gl_client_array *array; 1134 GET_CURRENT_CONTEXT(ctx); 1135 ASSERT_OUTSIDE_BEGIN_END(ctx); 1136 1137 if (!ctx->Extensions.ARB_instanced_arrays) { 1138 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()"); 1139 return; 1140 } 1141 1142 if (index >= ctx->Const.VertexProgram.MaxAttribs) { 1143 _mesa_error(ctx, GL_INVALID_ENUM, "glVertexAttribDivisor(index = %u)", 1144 index); 1145 return; 1146 } 1147 1148 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib)); 1149 1150 array = &ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)]; 1151 if (array->InstanceDivisor != divisor) { 1152 FLUSH_VERTICES(ctx, _NEW_ARRAY); 1153 array->InstanceDivisor = divisor; 1154 ctx->Array.ArrayObj->NewArrays |= VERT_BIT(VERT_ATTRIB_GENERIC(index)); 1155 } 1156} 1157 1158 1159 1160/** 1161 * Copy one client vertex array to another. 1162 */ 1163void 1164_mesa_copy_client_array(struct gl_context *ctx, 1165 struct gl_client_array *dst, 1166 struct gl_client_array *src) 1167{ 1168 dst->Size = src->Size; 1169 dst->Type = src->Type; 1170 dst->Format = src->Format; 1171 dst->Stride = src->Stride; 1172 dst->StrideB = src->StrideB; 1173 dst->Ptr = src->Ptr; 1174 dst->Enabled = src->Enabled; 1175 dst->Normalized = src->Normalized; 1176 dst->Integer = src->Integer; 1177 dst->InstanceDivisor = src->InstanceDivisor; 1178 dst->_ElementSize = src->_ElementSize; 1179 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj); 1180 dst->_MaxElement = src->_MaxElement; 1181} 1182 1183 1184 1185/** 1186 * Print vertex array's fields. 1187 */ 1188static void 1189print_array(const char *name, GLint index, const struct gl_client_array *array) 1190{ 1191 if (index >= 0) 1192 printf(" %s[%d]: ", name, index); 1193 else 1194 printf(" %s: ", name); 1195 printf("Ptr=%p, Type=0x%x, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %lu), MaxElem=%u\n", 1196 array->Ptr, array->Type, array->Size, 1197 array->_ElementSize, array->StrideB, 1198 array->BufferObj->Name, (unsigned long) array->BufferObj->Size, 1199 array->_MaxElement); 1200} 1201 1202 1203/** 1204 * Print current vertex object/array info. For debug. 1205 */ 1206void 1207_mesa_print_arrays(struct gl_context *ctx) 1208{ 1209 struct gl_array_object *arrayObj = ctx->Array.ArrayObj; 1210 GLuint i; 1211 1212 _mesa_update_array_object_max_element(ctx, arrayObj); 1213 1214 printf("Array Object %u\n", arrayObj->Name); 1215 if (arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) 1216 print_array("Vertex", -1, &arrayObj->VertexAttrib[VERT_ATTRIB_POS]); 1217 if (arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) 1218 print_array("Normal", -1, &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]); 1219 if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) 1220 print_array("Color", -1, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]); 1221 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) 1222 if (arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)].Enabled) 1223 print_array("TexCoord", i, &arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)]); 1224 for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) 1225 if (arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) 1226 print_array("Attrib", i, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)]); 1227 printf(" _MaxElement = %u\n", arrayObj->_MaxElement); 1228} 1229 1230 1231/** 1232 * Initialize vertex array state for given context. 1233 */ 1234void 1235_mesa_init_varray(struct gl_context *ctx) 1236{ 1237 ctx->Array.DefaultArrayObj = ctx->Driver.NewArrayObject(ctx, 0); 1238 _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, 1239 ctx->Array.DefaultArrayObj); 1240 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */ 1241 1242 ctx->Array.Objects = _mesa_NewHashTable(); 1243} 1244 1245 1246/** 1247 * Callback for deleting an array object. Called by _mesa_HashDeleteAll(). 1248 */ 1249static void 1250delete_arrayobj_cb(GLuint id, void *data, void *userData) 1251{ 1252 struct gl_array_object *arrayObj = (struct gl_array_object *) data; 1253 struct gl_context *ctx = (struct gl_context *) userData; 1254 _mesa_delete_array_object(ctx, arrayObj); 1255} 1256 1257 1258/** 1259 * Free vertex array state for given context. 1260 */ 1261void 1262_mesa_free_varray_data(struct gl_context *ctx) 1263{ 1264 _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx); 1265 _mesa_DeleteHashTable(ctx->Array.Objects); 1266} 1267