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