2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
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:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
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.
29 #include "bufferobj.h"
36 #include "mfeatures.h"
40 #include "main/dispatch.h"
43 /** Used to do error checking for GL_EXT_vertex_array_bgra */
47 /** Used to indicate which GL datatypes are accepted by each of the
48 * glVertex/Color/Attrib/EtcPointer() functions.
52 #define UNSIGNED_BYTE_BIT 0x4
54 #define UNSIGNED_SHORT_BIT 0x10
56 #define UNSIGNED_INT_BIT 0x40
58 #define FLOAT_BIT 0x100
59 #define DOUBLE_BIT 0x200
60 #define FIXED_ES_BIT 0x400
61 #define FIXED_GL_BIT 0x800
64 /** Convert GL datatype enum into a <type>_BIT value seen above */
66 type_to_bit(const struct gl_context *ctx, GLenum type)
73 case GL_UNSIGNED_BYTE:
74 return UNSIGNED_BYTE_BIT;
77 case GL_UNSIGNED_SHORT:
78 return UNSIGNED_SHORT_BIT;
82 return UNSIGNED_INT_BIT;
84 if (ctx->Extensions.ARB_half_float_vertex)
93 return ctx->API == API_OPENGL ? FIXED_GL_BIT : FIXED_ES_BIT;
101 * Do error checking and update state for glVertex/Color/TexCoord/...Pointer
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
118 update_array(struct gl_context *ctx,
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,
129 GLenum format = GL_RGBA;
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;
135 if (!ctx->Extensions.ARB_ES2_compatibility) {
136 legalTypesMask &= ~FIXED_GL_BIT;
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));
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.
150 if (ctx->Extensions.EXT_vertex_array_bgra &&
151 sizeMax == BGRA_OR_4 &&
153 if (type != GL_UNSIGNED_BYTE) {
154 _mesa_error(ctx, GL_INVALID_VALUE, "%s(GL_BGRA/GLubyte)", func);
160 else if (size < sizeMin || size > sizeMax || size > 4) {
161 _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size);
168 _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride );
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.
177 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func);
181 elementSize = _mesa_sizeof_type(type) * size;
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;
192 _mesa_reference_buffer_object(ctx, &array->BufferObj,
193 ctx->Array.ArrayBufferObj);
195 ctx->NewState |= _NEW_ARRAY;
196 ctx->Array.NewState |= dirtyBit;
201 _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
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);
208 if (ctx->API == API_OPENGLES)
209 legalTypes |= BYTE_BIT;
211 update_array(ctx, "glVertexPointer",
212 &ctx->Array.ArrayObj->Vertex, _NEW_ARRAY_VERTEX,
214 size, type, stride, GL_FALSE, GL_FALSE, ptr);
219 _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
221 const GLbitfield legalTypes = (BYTE_BIT | SHORT_BIT | INT_BIT |
222 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
224 GET_CURRENT_CONTEXT(ctx);
225 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
227 update_array(ctx, "glNormalPointer",
228 &ctx->Array.ArrayObj->Normal, _NEW_ARRAY_NORMAL,
230 3, type, stride, GL_TRUE, GL_FALSE, ptr);
235 _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
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 |
242 GET_CURRENT_CONTEXT(ctx);
243 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
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);
253 _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
255 const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT);
256 GET_CURRENT_CONTEXT(ctx);
257 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
259 update_array(ctx, "glFogCoordPointer",
260 &ctx->Array.ArrayObj->FogCoord, _NEW_ARRAY_FOGCOORD,
262 1, type, stride, GL_FALSE, GL_FALSE, ptr);
267 _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
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);
274 update_array(ctx, "glIndexPointer",
275 &ctx->Array.ArrayObj->Index, _NEW_ARRAY_INDEX,
277 1, type, stride, GL_FALSE, GL_FALSE, ptr);
282 _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
283 GLsizei stride, const GLvoid *ptr)
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);
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);
300 _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
303 GLbitfield legalTypes = (SHORT_BIT | INT_BIT |
304 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
306 GET_CURRENT_CONTEXT(ctx);
307 const GLuint unit = ctx->Array.ActiveTexture;
308 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
310 if (ctx->API == API_OPENGLES)
311 legalTypes |= BYTE_BIT;
313 ASSERT(unit < Elements(ctx->Array.ArrayObj->TexCoord));
315 update_array(ctx, "glTexCoordPointer",
316 &ctx->Array.ArrayObj->TexCoord[unit],
317 _NEW_ARRAY_TEXCOORD(unit),
319 size, type, stride, GL_FALSE, GL_FALSE,
325 _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
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);
333 update_array(ctx, "glEdgeFlagPointer",
334 &ctx->Array.ArrayObj->EdgeFlag, _NEW_ARRAY_EDGEFLAG,
336 1, GL_UNSIGNED_BYTE, stride, GL_FALSE, integer, ptr);
341 _mesa_PointSizePointer(GLenum type, GLsizei stride, const GLvoid *ptr)
343 const GLbitfield legalTypes = (FLOAT_BIT | FIXED_ES_BIT);
344 GET_CURRENT_CONTEXT(ctx);
345 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
347 if (ctx->API != API_OPENGLES) {
348 _mesa_error(ctx, GL_INVALID_OPERATION,
349 "glPointSizePointer(ES 1.x only)");
353 update_array(ctx, "glPointSizePointer",
354 &ctx->Array.ArrayObj->PointSize, _NEW_ARRAY_POINT_SIZE,
356 1, type, stride, GL_FALSE, GL_FALSE, ptr);
360 #if FEATURE_NV_vertex_program
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.
368 _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
369 GLsizei stride, const GLvoid *ptr)
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);
377 if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
378 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)");
382 if (type == GL_UNSIGNED_BYTE && size != 4) {
383 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)");
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);
396 #if FEATURE_ARB_vertex_program
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).
403 _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
404 GLboolean normalized,
405 GLsizei stride, const GLvoid *ptr)
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);
415 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
416 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)");
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);
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).
436 _mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type,
437 GLsizei stride, const GLvoid *ptr)
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);
447 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
448 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIPointer(index)");
452 update_array(ctx, "glVertexAttribIPointer",
453 &ctx->Array.ArrayObj->VertexAttrib[index],
454 _NEW_ARRAY_ATTRIB(index),
456 size, type, stride, normalized, integer, ptr);
462 _mesa_EnableVertexAttribArrayARB(GLuint index)
464 GET_CURRENT_CONTEXT(ctx);
465 ASSERT_OUTSIDE_BEGIN_END(ctx);
467 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
468 _mesa_error(ctx, GL_INVALID_VALUE,
469 "glEnableVertexAttribArrayARB(index)");
473 ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib));
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);
483 _mesa_DisableVertexAttribArrayARB(GLuint index)
485 GET_CURRENT_CONTEXT(ctx);
486 ASSERT_OUTSIDE_BEGIN_END(ctx);
488 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
489 _mesa_error(ctx, GL_INVALID_VALUE,
490 "glDisableVertexAttribArrayARB(index)");
494 ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib));
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);
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.
509 get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname,
512 const struct gl_client_array *array;
514 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
515 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index);
519 ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib));
521 array = &ctx->Array.ArrayObj->VertexAttrib[index];
524 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
525 return array->Enabled;
526 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
528 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
529 return array->Stride;
530 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
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;
541 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB:
542 if (ctx->Extensions.ARB_instanced_arrays) {
543 return array->InstanceDivisor;
551 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname);
556 static const GLfloat *
557 get_current_attrib(struct gl_context *ctx, GLuint index, const char *function)
560 if (ctx->API != API_OPENGLES2) {
561 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function);
565 else if (index >= ctx->Const.VertexProgram.MaxAttribs) {
566 _mesa_error(ctx, GL_INVALID_VALUE,
567 "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function);
571 FLUSH_CURRENT(ctx, 0);
572 return ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index];
576 _mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params)
578 GET_CURRENT_CONTEXT(ctx);
579 ASSERT_OUTSIDE_BEGIN_END(ctx);
581 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
582 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv");
588 params[0] = (GLfloat) get_vertex_array_attrib(ctx, index, pname,
589 "glGetVertexAttribfv");
595 _mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params)
597 GET_CURRENT_CONTEXT(ctx);
598 ASSERT_OUTSIDE_BEGIN_END(ctx);
600 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
601 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv");
603 params[0] = (GLdouble) v[0];
604 params[1] = (GLdouble) v[1];
605 params[2] = (GLdouble) v[2];
606 params[3] = (GLdouble) v[3];
610 params[0] = (GLdouble) get_vertex_array_attrib(ctx, index, pname,
611 "glGetVertexAttribdv");
617 _mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params)
619 GET_CURRENT_CONTEXT(ctx);
620 ASSERT_OUTSIDE_BEGIN_END(ctx);
622 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
623 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv");
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];
633 params[0] = (GLint) get_vertex_array_attrib(ctx, index, pname,
634 "glGetVertexAttribiv");
641 _mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
643 GET_CURRENT_CONTEXT(ctx);
644 ASSERT_OUTSIDE_BEGIN_END(ctx);
646 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
648 get_current_attrib(ctx, index, "glGetVertexAttribIiv");
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];
658 params[0] = (GLint) get_vertex_array_attrib(ctx, index, pname,
659 "glGetVertexAttribIiv");
666 _mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
668 GET_CURRENT_CONTEXT(ctx);
669 ASSERT_OUTSIDE_BEGIN_END(ctx);
671 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
673 get_current_attrib(ctx, index, "glGetVertexAttribIuiv");
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];
683 params[0] = get_vertex_array_attrib(ctx, index, pname,
684 "glGetVertexAttribIuiv");
690 _mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
692 GET_CURRENT_CONTEXT(ctx);
693 ASSERT_OUTSIDE_BEGIN_END(ctx);
695 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
696 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
700 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
701 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
705 ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib));
707 *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[index].Ptr;
712 _mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
713 GLsizei count, const GLvoid *ptr)
716 _mesa_VertexPointer(size, type, stride, ptr);
721 _mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
725 _mesa_NormalPointer(type, stride, ptr);
730 _mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
734 _mesa_ColorPointer(size, type, stride, ptr);
739 _mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
743 _mesa_IndexPointer(type, stride, ptr);
748 _mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
749 GLsizei count, const GLvoid *ptr)
752 _mesa_TexCoordPointer(size, type, stride, ptr);
757 _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
760 _mesa_EdgeFlagPointer(stride, ptr);
765 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
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 */
776 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
779 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
782 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
788 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
789 tcomps = 0; ccomps = 0; vcomps = 2;
794 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
795 tcomps = 0; ccomps = 0; vcomps = 3;
800 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
801 tcomps = 0; ccomps = 4; vcomps = 2;
802 ctype = GL_UNSIGNED_BYTE;
808 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
809 tcomps = 0; ccomps = 4; vcomps = 3;
810 ctype = GL_UNSIGNED_BYTE;
816 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
817 tcomps = 0; ccomps = 3; vcomps = 3;
824 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
825 tcomps = 0; ccomps = 0; vcomps = 3;
831 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
832 tcomps = 0; ccomps = 4; vcomps = 3;
840 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
841 tcomps = 2; ccomps = 0; vcomps = 3;
846 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
847 tcomps = 4; ccomps = 0; vcomps = 4;
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;
860 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
861 tcomps = 2; ccomps = 3; vcomps = 3;
868 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
869 tcomps = 2; ccomps = 0; vcomps = 3;
874 case GL_T2F_C4F_N3F_V3F:
875 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
876 tcomps = 2; ccomps = 4; vcomps = 3;
883 case GL_T4F_C4F_N3F_V4F:
884 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
885 tcomps = 4; ccomps = 4; vcomps = 4;
893 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
901 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
902 _mesa_DisableClientState( GL_INDEX_ARRAY );
903 /* XXX also disable secondary color and generic arrays? */
907 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
908 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
909 (GLubyte *) pointer + toffset );
912 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
917 _mesa_EnableClientState( GL_COLOR_ARRAY );
918 _mesa_ColorPointer( ccomps, ctype, stride,
919 (GLubyte *) pointer + coffset );
922 _mesa_DisableClientState( GL_COLOR_ARRAY );
928 _mesa_EnableClientState( GL_NORMAL_ARRAY );
929 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset );
932 _mesa_DisableClientState( GL_NORMAL_ARRAY );
936 _mesa_EnableClientState( GL_VERTEX_ARRAY );
937 _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
938 (GLubyte *) pointer + voffset );
943 _mesa_LockArraysEXT(GLint first, GLsizei count)
945 GET_CURRENT_CONTEXT(ctx);
946 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
948 if (MESA_VERBOSE & VERBOSE_API)
949 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
952 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" );
956 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" );
959 if (ctx->Array.LockCount != 0) {
960 _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" );
964 ctx->Array.LockFirst = first;
965 ctx->Array.LockCount = count;
967 ctx->NewState |= _NEW_ARRAY;
968 ctx->Array.NewState |= _NEW_ARRAY_ALL;
973 _mesa_UnlockArraysEXT( void )
975 GET_CURRENT_CONTEXT(ctx);
976 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
978 if (MESA_VERBOSE & VERBOSE_API)
979 _mesa_debug(ctx, "glUnlockArrays\n");
981 if (ctx->Array.LockCount == 0) {
982 _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" );
986 ctx->Array.LockFirst = 0;
987 ctx->Array.LockCount = 0;
988 ctx->NewState |= _NEW_ARRAY;
989 ctx->Array.NewState |= _NEW_ARRAY_ALL;
993 /* GL_EXT_multi_draw_arrays */
995 _mesa_MultiDrawArraysEXT( GLenum mode, const GLint *first,
996 const GLsizei *count, GLsizei primcount )
998 GET_CURRENT_CONTEXT(ctx);
1001 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1003 for (i = 0; i < primcount; i++) {
1005 CALL_DrawArrays(ctx->Exec, (mode, first[i], count[i]));
1011 /* GL_IBM_multimode_draw_arrays */
1013 _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
1014 const GLsizei * count,
1015 GLsizei primcount, GLint modestride )
1017 GET_CURRENT_CONTEXT(ctx);
1020 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
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] ));
1031 /* GL_IBM_multimode_draw_arrays */
1033 _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
1034 GLenum type, const GLvoid * const * indices,
1035 GLsizei primcount, GLint modestride )
1037 GET_CURRENT_CONTEXT(ctx);
1040 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1042 /* XXX not sure about ARB_vertex_buffer_object handling here */
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] ));
1054 * GL_NV_primitive_restart and GL 3.1
1057 _mesa_PrimitiveRestartIndex(GLuint index)
1059 GET_CURRENT_CONTEXT(ctx);
1061 if (!ctx->Extensions.NV_primitive_restart &&
1062 ctx->VersionMajor * 10 + ctx->VersionMinor < 31) {
1063 _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()");
1067 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1069 FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
1071 ctx->Array.RestartIndex = index;
1076 * See GL_ARB_instanced_arrays.
1077 * Note that the instance divisor only applies to generic arrays, not
1078 * the legacy vertex arrays.
1081 _mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
1083 GET_CURRENT_CONTEXT(ctx);
1084 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1086 if (!ctx->Extensions.ARB_instanced_arrays) {
1087 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
1091 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
1092 _mesa_error(ctx, GL_INVALID_ENUM, "glVertexAttribDivisor(index = %u)",
1097 ctx->Array.ArrayObj->VertexAttrib[index].InstanceDivisor = divisor;
1103 * Copy one client vertex array to another.
1106 _mesa_copy_client_array(struct gl_context *ctx,
1107 struct gl_client_array *dst,
1108 struct gl_client_array *src)
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;
1128 * Print vertex array's fields.
1131 print_array(const char *name, GLint index, const struct gl_client_array *array)
1134 printf(" %s[%d]: ", name, index);
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);
1146 * Print current vertex object/array info. For debug.
1149 _mesa_print_arrays(struct gl_context *ctx)
1151 struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
1154 _mesa_update_array_object_max_element(ctx, arrayObj);
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);
1174 * Initialize vertex array state for given context.
1177 _mesa_init_varray(struct gl_context *ctx)
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 */
1184 ctx->Array.Objects = _mesa_NewHashTable();
1189 * Callback for deleting an array object. Called by _mesa_HashDeleteAll().
1192 delete_arrayobj_cb(GLuint id, void *data, void *userData)
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);
1201 * Free vertex array state for given context.
1204 _mesa_free_varray_data(struct gl_context *ctx)
1206 _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx);
1207 _mesa_DeleteHashTable(ctx->Array.Objects);