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