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