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"
38 #include "main/dispatch.h"
42 * Set the fields of a vertex array.
43 * Also do an error check for GL_ARB_vertex_array_object: check that
44 * all arrays reside in VBOs when using a vertex array object.
46 * \param array the array to update
47 * \param dirtyBit which bit to set in ctx->Array.NewState for this array
48 * \param elementSize size of each array element, in bytes
49 * \param size components per element (1, 2, 3 or 4)
50 * \param type datatype of each component (GL_FLOAT, GL_INT, etc)
51 * \param format either GL_RGBA or GL_BGRA
52 * \param stride stride between elements, in elements
53 * \param normalized are integer types converted to floats in [-1, 1]?
54 * \param integer integer-valued values (will not be normalized to [-1,1])
55 * \param ptr the address (or offset inside VBO) of the array data
58 update_array(struct gl_context
*ctx
, struct gl_client_array
*array
,
59 GLbitfield dirtyBit
, GLsizei elementSize
,
60 GLint size
, GLenum type
, GLenum format
,
61 GLsizei stride
, GLboolean normalized
, GLboolean integer
,
64 ASSERT(format
== GL_RGBA
|| format
== GL_BGRA
);
66 if (ctx
->Array
.ArrayObj
->VBOonly
&&
67 ctx
->Array
.ArrayBufferObj
->Name
== 0) {
68 /* GL_ARB_vertex_array_object requires that all arrays reside in VBOs.
69 * Generate GL_INVALID_OPERATION if that's not true.
71 _mesa_error(ctx
, GL_INVALID_OPERATION
,
72 "glVertex/Normal/EtcPointer(non-VBO array)");
78 array
->Format
= format
;
79 array
->Stride
= stride
;
80 array
->StrideB
= stride
? stride
: elementSize
;
81 array
->Normalized
= normalized
;
82 array
->Ptr
= (const GLubyte
*) ptr
;
83 array
->_ElementSize
= elementSize
;
85 _mesa_reference_buffer_object(ctx
, &array
->BufferObj
,
86 ctx
->Array
.ArrayBufferObj
);
88 ctx
->NewState
|= _NEW_ARRAY
;
89 ctx
->Array
.NewState
|= dirtyBit
;
94 _mesa_VertexPointer(GLint size
, GLenum type
, GLsizei stride
, const GLvoid
*ptr
)
97 GET_CURRENT_CONTEXT(ctx
);
98 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
100 if (size
< 2 || size
> 4) {
101 _mesa_error( ctx
, GL_INVALID_VALUE
, "glVertexPointer(size)" );
105 _mesa_error( ctx
, GL_INVALID_VALUE
, "glVertexPointer(stride)" );
109 if (MESA_VERBOSE
&(VERBOSE_VARRAY
|VERBOSE_API
))
110 _mesa_debug(ctx
, "glVertexPointer( sz %d type %s stride %d )\n", size
,
111 _mesa_lookup_enum_by_nr( type
), stride
);
113 /* always need to check that <type> is legal */
116 elementSize
= size
* sizeof(GLshort
);
119 elementSize
= size
* sizeof(GLint
);
122 elementSize
= size
* sizeof(GLfloat
);
125 elementSize
= size
* sizeof(GLdouble
);
128 elementSize
= size
* sizeof(GLhalfARB
);
132 elementSize
= size
* sizeof(GLfixed
);
135 #if FEATURE_vertex_array_byte
137 elementSize
= size
* sizeof(GLbyte
);
141 _mesa_error( ctx
, GL_INVALID_ENUM
, "glVertexPointer(type=%s)",
142 _mesa_lookup_enum_by_nr(type
));
146 update_array(ctx
, &ctx
->Array
.ArrayObj
->Vertex
, _NEW_ARRAY_VERTEX
,
147 elementSize
, size
, type
, GL_RGBA
, stride
, GL_FALSE
,
153 _mesa_NormalPointer(GLenum type
, GLsizei stride
, const GLvoid
*ptr
)
156 GET_CURRENT_CONTEXT(ctx
);
157 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
160 _mesa_error( ctx
, GL_INVALID_VALUE
, "glNormalPointer(stride)" );
164 if (MESA_VERBOSE
&(VERBOSE_VARRAY
|VERBOSE_API
))
165 _mesa_debug(ctx
, "glNormalPointer( type %s stride %d )\n",
166 _mesa_lookup_enum_by_nr( type
), stride
);
170 elementSize
= 3 * sizeof(GLbyte
);
173 elementSize
= 3 * sizeof(GLshort
);
176 elementSize
= 3 * sizeof(GLint
);
179 elementSize
= 3 * sizeof(GLfloat
);
182 elementSize
= 3 * sizeof(GLdouble
);
185 elementSize
= 3 * sizeof(GLhalfARB
);
189 elementSize
= 3 * sizeof(GLfixed
);
193 _mesa_error( ctx
, GL_INVALID_ENUM
, "glNormalPointer(type=%s)",
194 _mesa_lookup_enum_by_nr(type
));
198 update_array(ctx
, &ctx
->Array
.ArrayObj
->Normal
, _NEW_ARRAY_NORMAL
,
199 elementSize
, 3, type
, GL_RGBA
, stride
, GL_TRUE
, GL_FALSE
, ptr
);
204 _mesa_ColorPointer(GLint size
, GLenum type
, GLsizei stride
, const GLvoid
*ptr
)
208 GET_CURRENT_CONTEXT(ctx
);
209 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
211 if (size
< 3 || size
> 4) {
212 if (!ctx
->Extensions
.EXT_vertex_array_bgra
|| size
!= GL_BGRA
) {
213 _mesa_error(ctx
, GL_INVALID_VALUE
, "glColorPointer(size)");
218 _mesa_error( ctx
, GL_INVALID_VALUE
, "glColorPointer(stride)" );
222 if (MESA_VERBOSE
&(VERBOSE_VARRAY
|VERBOSE_API
))
223 _mesa_debug(ctx
, "glColorPointer( sz %d type %s stride %d )\n", size
,
224 _mesa_lookup_enum_by_nr( type
), stride
);
226 if (size
== GL_BGRA
) {
227 if (type
!= GL_UNSIGNED_BYTE
) {
228 _mesa_error(ctx
, GL_INVALID_VALUE
, "glColorPointer(GL_BGRA/GLubyte)");
240 elementSize
= size
* sizeof(GLbyte
);
242 case GL_UNSIGNED_BYTE
:
243 elementSize
= size
* sizeof(GLubyte
);
246 elementSize
= size
* sizeof(GLshort
);
248 case GL_UNSIGNED_SHORT
:
249 elementSize
= size
* sizeof(GLushort
);
252 elementSize
= size
* sizeof(GLint
);
254 case GL_UNSIGNED_INT
:
255 elementSize
= size
* sizeof(GLuint
);
258 elementSize
= size
* sizeof(GLfloat
);
261 elementSize
= size
* sizeof(GLdouble
);
264 elementSize
= size
* sizeof(GLhalfARB
);
268 elementSize
= size
* sizeof(GLfixed
);
272 _mesa_error( ctx
, GL_INVALID_ENUM
, "glColorPointer(type=%s)",
273 _mesa_lookup_enum_by_nr(type
));
277 update_array(ctx
, &ctx
->Array
.ArrayObj
->Color
, _NEW_ARRAY_COLOR0
,
278 elementSize
, size
, type
, format
, stride
, GL_TRUE
, GL_FALSE
,
284 _mesa_FogCoordPointerEXT(GLenum type
, GLsizei stride
, const GLvoid
*ptr
)
287 GET_CURRENT_CONTEXT(ctx
);
288 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
291 _mesa_error( ctx
, GL_INVALID_VALUE
, "glFogCoordPointer(stride)" );
297 elementSize
= sizeof(GLfloat
);
300 elementSize
= sizeof(GLdouble
);
303 elementSize
= sizeof(GLhalfARB
);
306 _mesa_error( ctx
, GL_INVALID_ENUM
, "glFogCoordPointer(type)" );
310 update_array(ctx
, &ctx
->Array
.ArrayObj
->FogCoord
, _NEW_ARRAY_FOGCOORD
,
311 elementSize
, 1, type
, GL_RGBA
, stride
, GL_FALSE
, GL_FALSE
,
317 _mesa_IndexPointer(GLenum type
, GLsizei stride
, const GLvoid
*ptr
)
320 GET_CURRENT_CONTEXT(ctx
);
321 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
324 _mesa_error( ctx
, GL_INVALID_VALUE
, "glIndexPointer(stride)" );
329 case GL_UNSIGNED_BYTE
:
330 elementSize
= sizeof(GLubyte
);
333 elementSize
= sizeof(GLshort
);
336 elementSize
= sizeof(GLint
);
339 elementSize
= sizeof(GLfloat
);
342 elementSize
= sizeof(GLdouble
);
345 _mesa_error( ctx
, GL_INVALID_ENUM
, "glIndexPointer(type)" );
349 update_array(ctx
, &ctx
->Array
.ArrayObj
->Index
, _NEW_ARRAY_INDEX
,
350 elementSize
, 1, type
, GL_RGBA
, stride
, GL_FALSE
, GL_FALSE
,
356 _mesa_SecondaryColorPointerEXT(GLint size
, GLenum type
,
357 GLsizei stride
, const GLvoid
*ptr
)
361 GET_CURRENT_CONTEXT(ctx
);
362 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
364 if (size
!= 3 && size
!= 4) {
365 if (!ctx
->Extensions
.EXT_vertex_array_bgra
|| size
!= GL_BGRA
) {
366 _mesa_error(ctx
, GL_INVALID_VALUE
, "glSecondaryColorPointer(size)");
371 _mesa_error( ctx
, GL_INVALID_VALUE
, "glSecondaryColorPointer(stride)" );
375 if (MESA_VERBOSE
&(VERBOSE_VARRAY
|VERBOSE_API
))
376 _mesa_debug(ctx
, "glSecondaryColorPointer( sz %d type %s stride %d )\n",
377 size
, _mesa_lookup_enum_by_nr( type
), stride
);
379 if (size
== GL_BGRA
) {
380 if (type
!= GL_UNSIGNED_BYTE
) {
381 _mesa_error(ctx
, GL_INVALID_VALUE
, "glColorPointer(GL_BGRA/GLubyte)");
393 elementSize
= size
* sizeof(GLbyte
);
395 case GL_UNSIGNED_BYTE
:
396 elementSize
= size
* sizeof(GLubyte
);
399 elementSize
= size
* sizeof(GLshort
);
401 case GL_UNSIGNED_SHORT
:
402 elementSize
= size
* sizeof(GLushort
);
405 elementSize
= size
* sizeof(GLint
);
407 case GL_UNSIGNED_INT
:
408 elementSize
= size
* sizeof(GLuint
);
411 elementSize
= size
* sizeof(GLfloat
);
414 elementSize
= size
* sizeof(GLdouble
);
417 elementSize
= size
* sizeof(GLhalfARB
);
420 _mesa_error( ctx
, GL_INVALID_ENUM
, "glSecondaryColorPointer(type=%s)",
421 _mesa_lookup_enum_by_nr(type
));
425 update_array(ctx
, &ctx
->Array
.ArrayObj
->SecondaryColor
, _NEW_ARRAY_COLOR1
,
426 elementSize
, size
, type
, format
, stride
, GL_TRUE
, GL_FALSE
,
432 _mesa_TexCoordPointer(GLint size
, GLenum type
, GLsizei stride
,
436 GET_CURRENT_CONTEXT(ctx
);
437 const GLuint unit
= ctx
->Array
.ActiveTexture
;
438 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
440 if (size
< 1 || size
> 4) {
441 _mesa_error( ctx
, GL_INVALID_VALUE
, "glTexCoordPointer(size)" );
445 _mesa_error( ctx
, GL_INVALID_VALUE
, "glTexCoordPointer(stride)" );
449 if (MESA_VERBOSE
&(VERBOSE_VARRAY
|VERBOSE_API
))
450 _mesa_debug(ctx
, "glTexCoordPointer(unit %u sz %d type %s stride %d)\n",
451 unit
, size
, _mesa_lookup_enum_by_nr( type
), stride
);
453 /* always need to check that <type> is legal */
456 elementSize
= size
* sizeof(GLshort
);
459 elementSize
= size
* sizeof(GLint
);
462 elementSize
= size
* sizeof(GLfloat
);
465 elementSize
= size
* sizeof(GLdouble
);
468 elementSize
= size
* sizeof(GLhalfARB
);
472 elementSize
= size
* sizeof(GLfixed
);
475 #if FEATURE_vertex_array_byte
477 elementSize
= size
* sizeof(GLbyte
);
481 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexCoordPointer(type=%s)",
482 _mesa_lookup_enum_by_nr(type
));
486 ASSERT(unit
< Elements(ctx
->Array
.ArrayObj
->TexCoord
));
488 update_array(ctx
, &ctx
->Array
.ArrayObj
->TexCoord
[unit
],
489 _NEW_ARRAY_TEXCOORD(unit
),
490 elementSize
, size
, type
, GL_RGBA
, stride
, GL_FALSE
, GL_FALSE
,
496 _mesa_EdgeFlagPointer(GLsizei stride
, const GLvoid
*ptr
)
498 /* see table 2.4 edits in GL_EXT_gpu_shader4 spec: */
499 const GLboolean integer
= GL_TRUE
;
500 GET_CURRENT_CONTEXT(ctx
);
501 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
504 _mesa_error( ctx
, GL_INVALID_VALUE
, "glEdgeFlagPointer(stride)" );
508 update_array(ctx
, &ctx
->Array
.ArrayObj
->EdgeFlag
, _NEW_ARRAY_EDGEFLAG
,
509 sizeof(GLboolean
), 1, GL_UNSIGNED_BYTE
, GL_RGBA
,
510 stride
, GL_FALSE
, integer
, ptr
);
515 _mesa_PointSizePointer(GLenum type
, GLsizei stride
, const GLvoid
*ptr
)
518 GET_CURRENT_CONTEXT(ctx
);
519 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
522 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPointSizePointer(stride)" );
528 elementSize
= sizeof(GLfloat
);
532 elementSize
= sizeof(GLfixed
);
536 _mesa_error( ctx
, GL_INVALID_ENUM
, "glPointSizePointer(type)" );
540 update_array(ctx
, &ctx
->Array
.ArrayObj
->PointSize
, _NEW_ARRAY_POINT_SIZE
,
541 elementSize
, 1, type
, GL_RGBA
, stride
, GL_FALSE
, GL_FALSE
,
546 #if FEATURE_NV_vertex_program
548 * Set a vertex attribute array.
549 * Note that these arrays DO alias the conventional GL vertex arrays
550 * (position, normal, color, fog, texcoord, etc).
551 * The generic attribute slots at #16 and above are not touched.
554 _mesa_VertexAttribPointerNV(GLuint index
, GLint size
, GLenum type
,
555 GLsizei stride
, const GLvoid
*ptr
)
557 GLboolean normalized
= GL_FALSE
;
560 GET_CURRENT_CONTEXT(ctx
);
561 ASSERT_OUTSIDE_BEGIN_END(ctx
);
563 if (index
>= MAX_NV_VERTEX_PROGRAM_INPUTS
) {
564 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribPointerNV(index)");
568 if (size
< 1 || size
> 4) {
569 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribPointerNV(size)");
574 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribPointerNV(stride)");
578 if (type
== GL_UNSIGNED_BYTE
&& size
!= 4) {
579 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribPointerNV(size!=4)");
583 if (size
== GL_BGRA
) {
584 if (type
!= GL_UNSIGNED_BYTE
) {
585 _mesa_error(ctx
, GL_INVALID_VALUE
,
586 "glVertexAttribPointerNV(GL_BGRA/type)");
592 normalized
= GL_TRUE
;
598 /* check for valid 'type' and compute StrideB right away */
600 case GL_UNSIGNED_BYTE
:
601 normalized
= GL_TRUE
;
602 elementSize
= size
* sizeof(GLubyte
);
605 elementSize
= size
* sizeof(GLshort
);
608 elementSize
= size
* sizeof(GLfloat
);
611 elementSize
= size
* sizeof(GLdouble
);
614 _mesa_error( ctx
, GL_INVALID_ENUM
, "glVertexAttribPointerNV(type=%s)",
615 _mesa_lookup_enum_by_nr(type
));
619 update_array(ctx
, &ctx
->Array
.ArrayObj
->VertexAttrib
[index
],
620 _NEW_ARRAY_ATTRIB(index
),
621 elementSize
, size
, type
, format
, stride
, normalized
, GL_FALSE
,
627 #if FEATURE_ARB_vertex_program
629 * Set a generic vertex attribute array.
630 * Note that these arrays DO NOT alias the conventional GL vertex arrays
631 * (position, normal, color, fog, texcoord, etc).
634 _mesa_VertexAttribPointerARB(GLuint index
, GLint size
, GLenum type
,
635 GLboolean normalized
,
636 GLsizei stride
, const GLvoid
*ptr
)
640 GET_CURRENT_CONTEXT(ctx
);
641 ASSERT_OUTSIDE_BEGIN_END(ctx
);
643 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
644 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribPointerARB(index)");
648 if (size
< 1 || size
> 4) {
649 if (!ctx
->Extensions
.EXT_vertex_array_bgra
|| size
!= GL_BGRA
) {
650 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribPointerARB(size)");
656 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribPointerARB(stride)");
660 if (size
== GL_BGRA
) {
661 if (type
!= GL_UNSIGNED_BYTE
) {
662 _mesa_error(ctx
, GL_INVALID_VALUE
,
663 "glVertexAttribPointerARB(GL_BGRA/type)");
666 if (normalized
!= GL_TRUE
) {
667 _mesa_error(ctx
, GL_INVALID_VALUE
,
668 "glVertexAttribPointerARB(GL_BGRA/normalized)");
679 /* check for valid 'type' and compute StrideB right away */
680 /* NOTE: more types are supported here than in the NV extension */
683 elementSize
= size
* sizeof(GLbyte
);
685 case GL_UNSIGNED_BYTE
:
686 elementSize
= size
* sizeof(GLubyte
);
689 elementSize
= size
* sizeof(GLshort
);
691 case GL_UNSIGNED_SHORT
:
692 elementSize
= size
* sizeof(GLushort
);
695 elementSize
= size
* sizeof(GLint
);
697 case GL_UNSIGNED_INT
:
698 elementSize
= size
* sizeof(GLuint
);
701 elementSize
= size
* sizeof(GLfloat
);
704 elementSize
= size
* sizeof(GLdouble
);
707 elementSize
= size
* sizeof(GLhalfARB
);
711 elementSize
= size
* sizeof(GLfixed
);
715 _mesa_error( ctx
, GL_INVALID_ENUM
, "glVertexAttribPointerARB(type)" );
719 update_array(ctx
, &ctx
->Array
.ArrayObj
->VertexAttrib
[index
],
720 _NEW_ARRAY_ATTRIB(index
),
721 elementSize
, size
, type
, format
, stride
, normalized
, GL_FALSE
,
728 * GL_EXT_gpu_shader4 / GL 3.0.
729 * Set an integer-valued vertex attribute array.
730 * Note that these arrays DO NOT alias the conventional GL vertex arrays
731 * (position, normal, color, fog, texcoord, etc).
734 _mesa_VertexAttribIPointer(GLuint index
, GLint size
, GLenum type
,
735 GLsizei stride
, const GLvoid
*ptr
)
737 const GLboolean normalized
= GL_FALSE
;
738 const GLboolean integer
= GL_TRUE
;
739 const GLenum format
= GL_RGBA
;
741 GET_CURRENT_CONTEXT(ctx
);
742 ASSERT_OUTSIDE_BEGIN_END(ctx
);
744 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
745 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribIPointer(index)");
749 if (size
< 1 || size
> 4) {
750 if (!ctx
->Extensions
.EXT_vertex_array_bgra
|| size
!= GL_BGRA
) {
751 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribIPointer(size)");
757 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribIPointer(stride)");
761 /* check for valid 'type' and compute StrideB right away */
762 /* NOTE: more types are supported here than in the NV extension */
765 elementSize
= size
* sizeof(GLbyte
);
767 case GL_UNSIGNED_BYTE
:
768 elementSize
= size
* sizeof(GLubyte
);
771 elementSize
= size
* sizeof(GLshort
);
773 case GL_UNSIGNED_SHORT
:
774 elementSize
= size
* sizeof(GLushort
);
777 elementSize
= size
* sizeof(GLint
);
779 case GL_UNSIGNED_INT
:
780 elementSize
= size
* sizeof(GLuint
);
783 _mesa_error( ctx
, GL_INVALID_ENUM
, "glVertexAttribIPointer(type)" );
787 update_array(ctx
, &ctx
->Array
.ArrayObj
->VertexAttrib
[index
],
788 _NEW_ARRAY_ATTRIB(index
),
789 elementSize
, size
, type
, format
, stride
,
790 normalized
, integer
, ptr
);
796 _mesa_EnableVertexAttribArrayARB(GLuint index
)
798 GET_CURRENT_CONTEXT(ctx
);
799 ASSERT_OUTSIDE_BEGIN_END(ctx
);
801 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
802 _mesa_error(ctx
, GL_INVALID_VALUE
,
803 "glEnableVertexAttribArrayARB(index)");
807 ASSERT(index
< Elements(ctx
->Array
.ArrayObj
->VertexAttrib
));
809 FLUSH_VERTICES(ctx
, _NEW_ARRAY
);
810 ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Enabled
= GL_TRUE
;
811 ctx
->Array
.ArrayObj
->_Enabled
|= _NEW_ARRAY_ATTRIB(index
);
812 ctx
->Array
.NewState
|= _NEW_ARRAY_ATTRIB(index
);
817 _mesa_DisableVertexAttribArrayARB(GLuint index
)
819 GET_CURRENT_CONTEXT(ctx
);
820 ASSERT_OUTSIDE_BEGIN_END(ctx
);
822 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
823 _mesa_error(ctx
, GL_INVALID_VALUE
,
824 "glEnableVertexAttribArrayARB(index)");
828 ASSERT(index
< Elements(ctx
->Array
.ArrayObj
->VertexAttrib
));
830 FLUSH_VERTICES(ctx
, _NEW_ARRAY
);
831 ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Enabled
= GL_FALSE
;
832 ctx
->Array
.ArrayObj
->_Enabled
&= ~_NEW_ARRAY_ATTRIB(index
);
833 ctx
->Array
.NewState
|= _NEW_ARRAY_ATTRIB(index
);
838 * Return info for a vertex attribute array (no alias with legacy
839 * vertex attributes (pos, normal, color, etc)). This function does
840 * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query.
843 get_vertex_array_attrib(struct gl_context
*ctx
, GLuint index
, GLenum pname
,
846 const struct gl_client_array
*array
;
848 if (index
>= MAX_VERTEX_GENERIC_ATTRIBS
) {
849 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(index=%u)", caller
, index
);
853 ASSERT(index
< Elements(ctx
->Array
.ArrayObj
->VertexAttrib
));
855 array
= &ctx
->Array
.ArrayObj
->VertexAttrib
[index
];
858 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB
:
859 return array
->Enabled
;
860 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB
:
862 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB
:
863 return array
->Stride
;
864 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB
:
866 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB
:
867 return array
->Normalized
;
868 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB
:
869 return array
->BufferObj
->Name
;
870 case GL_VERTEX_ATTRIB_ARRAY_INTEGER
:
871 if (ctx
->Extensions
.EXT_gpu_shader4
) {
872 return array
->Integer
;
876 _mesa_error(ctx
, GL_INVALID_ENUM
, "%s(pname=0x%x)", caller
, pname
);
883 _mesa_GetVertexAttribfvARB(GLuint index
, GLenum pname
, GLfloat
*params
)
885 GET_CURRENT_CONTEXT(ctx
);
886 ASSERT_OUTSIDE_BEGIN_END(ctx
);
888 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
890 _mesa_error(ctx
, GL_INVALID_OPERATION
,
891 "glGetVertexAttribfv(index==0)");
894 const GLfloat
*v
= ctx
->Current
.Attrib
[VERT_ATTRIB_GENERIC0
+ index
];
895 FLUSH_CURRENT(ctx
, 0);
900 params
[0] = (GLfloat
) get_vertex_array_attrib(ctx
, index
, pname
,
901 "glGetVertexAttribfv");
907 _mesa_GetVertexAttribdvARB(GLuint index
, GLenum pname
, GLdouble
*params
)
909 GET_CURRENT_CONTEXT(ctx
);
910 ASSERT_OUTSIDE_BEGIN_END(ctx
);
912 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
914 _mesa_error(ctx
, GL_INVALID_OPERATION
,
915 "glGetVertexAttribdv(index==0)");
918 const GLfloat
*v
= ctx
->Current
.Attrib
[VERT_ATTRIB_GENERIC0
+ index
];
919 FLUSH_CURRENT(ctx
, 0);
920 params
[0] = (GLdouble
) v
[0];
921 params
[1] = (GLdouble
) v
[1];
922 params
[2] = (GLdouble
) v
[2];
923 params
[3] = (GLdouble
) v
[3];
927 params
[0] = (GLdouble
) get_vertex_array_attrib(ctx
, index
, pname
,
928 "glGetVertexAttribdv");
934 _mesa_GetVertexAttribivARB(GLuint index
, GLenum pname
, GLint
*params
)
936 GET_CURRENT_CONTEXT(ctx
);
937 ASSERT_OUTSIDE_BEGIN_END(ctx
);
939 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
941 _mesa_error(ctx
, GL_INVALID_OPERATION
,
942 "glGetVertexAttribiv(index==0)");
945 const GLfloat
*v
= ctx
->Current
.Attrib
[VERT_ATTRIB_GENERIC0
+ index
];
946 FLUSH_CURRENT(ctx
, 0);
947 /* XXX should floats in[0,1] be scaled to full int range? */
948 params
[0] = (GLint
) v
[0];
949 params
[1] = (GLint
) v
[1];
950 params
[2] = (GLint
) v
[2];
951 params
[3] = (GLint
) v
[3];
955 params
[0] = (GLint
) get_vertex_array_attrib(ctx
, index
, pname
,
956 "glGetVertexAttribiv");
963 _mesa_GetVertexAttribIiv(GLuint index
, GLenum pname
, GLint
*params
)
965 GET_CURRENT_CONTEXT(ctx
);
966 ASSERT_OUTSIDE_BEGIN_END(ctx
);
968 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
970 _mesa_error(ctx
, GL_INVALID_OPERATION
,
971 "glGetVertexAttribIiv(index==0)");
974 const GLfloat
*v
= ctx
->Current
.Attrib
[VERT_ATTRIB_GENERIC0
+ index
];
975 FLUSH_CURRENT(ctx
, 0);
976 /* XXX we don't have true integer-valued vertex attribs yet */
977 params
[0] = (GLint
) v
[0];
978 params
[1] = (GLint
) v
[1];
979 params
[2] = (GLint
) v
[2];
980 params
[3] = (GLint
) v
[3];
984 params
[0] = (GLint
) get_vertex_array_attrib(ctx
, index
, pname
,
985 "glGetVertexAttribIiv");
992 _mesa_GetVertexAttribIuiv(GLuint index
, GLenum pname
, GLuint
*params
)
994 GET_CURRENT_CONTEXT(ctx
);
995 ASSERT_OUTSIDE_BEGIN_END(ctx
);
997 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
999 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1000 "glGetVertexAttribIuiv(index==0)");
1003 const GLfloat
*v
= ctx
->Current
.Attrib
[VERT_ATTRIB_GENERIC0
+ index
];
1004 FLUSH_CURRENT(ctx
, 0);
1005 /* XXX we don't have true integer-valued vertex attribs yet */
1006 params
[0] = (GLuint
) v
[0];
1007 params
[1] = (GLuint
) v
[1];
1008 params
[2] = (GLuint
) v
[2];
1009 params
[3] = (GLuint
) v
[3];
1013 params
[0] = get_vertex_array_attrib(ctx
, index
, pname
,
1014 "glGetVertexAttribIuiv");
1020 _mesa_GetVertexAttribPointervARB(GLuint index
, GLenum pname
, GLvoid
**pointer
)
1022 GET_CURRENT_CONTEXT(ctx
);
1023 ASSERT_OUTSIDE_BEGIN_END(ctx
);
1025 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
1026 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribPointerARB(index)");
1030 if (pname
!= GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB
) {
1031 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribPointerARB(pname)");
1035 ASSERT(index
< Elements(ctx
->Array
.ArrayObj
->VertexAttrib
));
1037 *pointer
= (GLvoid
*) ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Ptr
;
1042 _mesa_VertexPointerEXT(GLint size
, GLenum type
, GLsizei stride
,
1043 GLsizei count
, const GLvoid
*ptr
)
1046 _mesa_VertexPointer(size
, type
, stride
, ptr
);
1051 _mesa_NormalPointerEXT(GLenum type
, GLsizei stride
, GLsizei count
,
1055 _mesa_NormalPointer(type
, stride
, ptr
);
1060 _mesa_ColorPointerEXT(GLint size
, GLenum type
, GLsizei stride
, GLsizei count
,
1064 _mesa_ColorPointer(size
, type
, stride
, ptr
);
1069 _mesa_IndexPointerEXT(GLenum type
, GLsizei stride
, GLsizei count
,
1073 _mesa_IndexPointer(type
, stride
, ptr
);
1078 _mesa_TexCoordPointerEXT(GLint size
, GLenum type
, GLsizei stride
,
1079 GLsizei count
, const GLvoid
*ptr
)
1082 _mesa_TexCoordPointer(size
, type
, stride
, ptr
);
1087 _mesa_EdgeFlagPointerEXT(GLsizei stride
, GLsizei count
, const GLboolean
*ptr
)
1090 _mesa_EdgeFlagPointer(stride
, ptr
);
1095 _mesa_InterleavedArrays(GLenum format
, GLsizei stride
, const GLvoid
*pointer
)
1097 GET_CURRENT_CONTEXT(ctx
);
1098 GLboolean tflag
, cflag
, nflag
; /* enable/disable flags */
1099 GLint tcomps
, ccomps
, vcomps
; /* components per texcoord, color, vertex */
1100 GLenum ctype
= 0; /* color type */
1101 GLint coffset
= 0, noffset
= 0, voffset
;/* color, normal, vertex offsets */
1102 const GLint toffset
= 0; /* always zero */
1103 GLint defstride
; /* default stride */
1106 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1108 f
= sizeof(GLfloat
);
1109 c
= f
* ((4 * sizeof(GLubyte
) + (f
- 1)) / f
);
1112 _mesa_error( ctx
, GL_INVALID_VALUE
, "glInterleavedArrays(stride)" );
1118 tflag
= GL_FALSE
; cflag
= GL_FALSE
; nflag
= GL_FALSE
;
1119 tcomps
= 0; ccomps
= 0; vcomps
= 2;
1124 tflag
= GL_FALSE
; cflag
= GL_FALSE
; nflag
= GL_FALSE
;
1125 tcomps
= 0; ccomps
= 0; vcomps
= 3;
1130 tflag
= GL_FALSE
; cflag
= GL_TRUE
; nflag
= GL_FALSE
;
1131 tcomps
= 0; ccomps
= 4; vcomps
= 2;
1132 ctype
= GL_UNSIGNED_BYTE
;
1135 defstride
= c
+ 2*f
;
1138 tflag
= GL_FALSE
; cflag
= GL_TRUE
; nflag
= GL_FALSE
;
1139 tcomps
= 0; ccomps
= 4; vcomps
= 3;
1140 ctype
= GL_UNSIGNED_BYTE
;
1143 defstride
= c
+ 3*f
;
1146 tflag
= GL_FALSE
; cflag
= GL_TRUE
; nflag
= GL_FALSE
;
1147 tcomps
= 0; ccomps
= 3; vcomps
= 3;
1154 tflag
= GL_FALSE
; cflag
= GL_FALSE
; nflag
= GL_TRUE
;
1155 tcomps
= 0; ccomps
= 0; vcomps
= 3;
1160 case GL_C4F_N3F_V3F
:
1161 tflag
= GL_FALSE
; cflag
= GL_TRUE
; nflag
= GL_TRUE
;
1162 tcomps
= 0; ccomps
= 4; vcomps
= 3;
1170 tflag
= GL_TRUE
; cflag
= GL_FALSE
; nflag
= GL_FALSE
;
1171 tcomps
= 2; ccomps
= 0; vcomps
= 3;
1176 tflag
= GL_TRUE
; cflag
= GL_FALSE
; nflag
= GL_FALSE
;
1177 tcomps
= 4; ccomps
= 0; vcomps
= 4;
1181 case GL_T2F_C4UB_V3F
:
1182 tflag
= GL_TRUE
; cflag
= GL_TRUE
; nflag
= GL_FALSE
;
1183 tcomps
= 2; ccomps
= 4; vcomps
= 3;
1184 ctype
= GL_UNSIGNED_BYTE
;
1189 case GL_T2F_C3F_V3F
:
1190 tflag
= GL_TRUE
; cflag
= GL_TRUE
; nflag
= GL_FALSE
;
1191 tcomps
= 2; ccomps
= 3; vcomps
= 3;
1197 case GL_T2F_N3F_V3F
:
1198 tflag
= GL_TRUE
; cflag
= GL_FALSE
; nflag
= GL_TRUE
;
1199 tcomps
= 2; ccomps
= 0; vcomps
= 3;
1204 case GL_T2F_C4F_N3F_V3F
:
1205 tflag
= GL_TRUE
; cflag
= GL_TRUE
; nflag
= GL_TRUE
;
1206 tcomps
= 2; ccomps
= 4; vcomps
= 3;
1213 case GL_T4F_C4F_N3F_V4F
:
1214 tflag
= GL_TRUE
; cflag
= GL_TRUE
; nflag
= GL_TRUE
;
1215 tcomps
= 4; ccomps
= 4; vcomps
= 4;
1223 _mesa_error( ctx
, GL_INVALID_ENUM
, "glInterleavedArrays(format)" );
1231 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY
);
1232 _mesa_DisableClientState( GL_INDEX_ARRAY
);
1233 /* XXX also disable secondary color and generic arrays? */
1237 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY
);
1238 _mesa_TexCoordPointer( tcomps
, GL_FLOAT
, stride
,
1239 (GLubyte
*) pointer
+ toffset
);
1242 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY
);
1247 _mesa_EnableClientState( GL_COLOR_ARRAY
);
1248 _mesa_ColorPointer( ccomps
, ctype
, stride
,
1249 (GLubyte
*) pointer
+ coffset
);
1252 _mesa_DisableClientState( GL_COLOR_ARRAY
);
1258 _mesa_EnableClientState( GL_NORMAL_ARRAY
);
1259 _mesa_NormalPointer( GL_FLOAT
, stride
, (GLubyte
*) pointer
+ noffset
);
1262 _mesa_DisableClientState( GL_NORMAL_ARRAY
);
1266 _mesa_EnableClientState( GL_VERTEX_ARRAY
);
1267 _mesa_VertexPointer( vcomps
, GL_FLOAT
, stride
,
1268 (GLubyte
*) pointer
+ voffset
);
1273 _mesa_LockArraysEXT(GLint first
, GLsizei count
)
1275 GET_CURRENT_CONTEXT(ctx
);
1276 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1278 if (MESA_VERBOSE
& VERBOSE_API
)
1279 _mesa_debug(ctx
, "glLockArrays %d %d\n", first
, count
);
1282 _mesa_error( ctx
, GL_INVALID_VALUE
, "glLockArraysEXT(first)" );
1286 _mesa_error( ctx
, GL_INVALID_VALUE
, "glLockArraysEXT(count)" );
1289 if (ctx
->Array
.LockCount
!= 0) {
1290 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glLockArraysEXT(reentry)" );
1294 ctx
->Array
.LockFirst
= first
;
1295 ctx
->Array
.LockCount
= count
;
1297 ctx
->NewState
|= _NEW_ARRAY
;
1298 ctx
->Array
.NewState
|= _NEW_ARRAY_ALL
;
1303 _mesa_UnlockArraysEXT( void )
1305 GET_CURRENT_CONTEXT(ctx
);
1306 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1308 if (MESA_VERBOSE
& VERBOSE_API
)
1309 _mesa_debug(ctx
, "glUnlockArrays\n");
1311 if (ctx
->Array
.LockCount
== 0) {
1312 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glUnlockArraysEXT(reexit)" );
1316 ctx
->Array
.LockFirst
= 0;
1317 ctx
->Array
.LockCount
= 0;
1318 ctx
->NewState
|= _NEW_ARRAY
;
1319 ctx
->Array
.NewState
|= _NEW_ARRAY_ALL
;
1323 /* GL_EXT_multi_draw_arrays */
1324 /* Somebody forgot to spec the first and count parameters as const! <sigh> */
1326 _mesa_MultiDrawArraysEXT( GLenum mode
, const GLint
*first
,
1327 const GLsizei
*count
, GLsizei primcount
)
1329 GET_CURRENT_CONTEXT(ctx
);
1332 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1334 for (i
= 0; i
< primcount
; i
++) {
1336 CALL_DrawArrays(ctx
->Exec
, (mode
, first
[i
], count
[i
]));
1342 /* GL_IBM_multimode_draw_arrays */
1344 _mesa_MultiModeDrawArraysIBM( const GLenum
* mode
, const GLint
* first
,
1345 const GLsizei
* count
,
1346 GLsizei primcount
, GLint modestride
)
1348 GET_CURRENT_CONTEXT(ctx
);
1351 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1353 for ( i
= 0 ; i
< primcount
; i
++ ) {
1354 if ( count
[i
] > 0 ) {
1355 GLenum m
= *((GLenum
*) ((GLubyte
*) mode
+ i
* modestride
));
1356 CALL_DrawArrays(ctx
->Exec
, ( m
, first
[i
], count
[i
] ));
1362 /* GL_IBM_multimode_draw_arrays */
1364 _mesa_MultiModeDrawElementsIBM( const GLenum
* mode
, const GLsizei
* count
,
1365 GLenum type
, const GLvoid
* const * indices
,
1366 GLsizei primcount
, GLint modestride
)
1368 GET_CURRENT_CONTEXT(ctx
);
1371 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1373 /* XXX not sure about ARB_vertex_buffer_object handling here */
1375 for ( i
= 0 ; i
< primcount
; i
++ ) {
1376 if ( count
[i
] > 0 ) {
1377 GLenum m
= *((GLenum
*) ((GLubyte
*) mode
+ i
* modestride
));
1378 CALL_DrawElements(ctx
->Exec
, ( m
, count
[i
], type
, indices
[i
] ));
1385 * GL_NV_primitive_restart and GL 3.1
1388 _mesa_PrimitiveRestartIndex(GLuint index
)
1390 GET_CURRENT_CONTEXT(ctx
);
1392 if (!ctx
->Extensions
.NV_primitive_restart
&&
1393 ctx
->VersionMajor
* 10 + ctx
->VersionMinor
< 31) {
1394 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glPrimitiveRestartIndexNV()");
1398 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1400 FLUSH_VERTICES(ctx
, _NEW_TRANSFORM
);
1402 ctx
->Array
.RestartIndex
= index
;
1407 * Copy one client vertex array to another.
1410 _mesa_copy_client_array(struct gl_context
*ctx
,
1411 struct gl_client_array
*dst
,
1412 struct gl_client_array
*src
)
1414 dst
->Size
= src
->Size
;
1415 dst
->Type
= src
->Type
;
1416 dst
->Format
= src
->Format
;
1417 dst
->Stride
= src
->Stride
;
1418 dst
->StrideB
= src
->StrideB
;
1419 dst
->Ptr
= src
->Ptr
;
1420 dst
->Enabled
= src
->Enabled
;
1421 dst
->Normalized
= src
->Normalized
;
1422 dst
->Integer
= src
->Integer
;
1423 dst
->_ElementSize
= src
->_ElementSize
;
1424 _mesa_reference_buffer_object(ctx
, &dst
->BufferObj
, src
->BufferObj
);
1425 dst
->_MaxElement
= src
->_MaxElement
;
1431 * Print vertex array's fields.
1434 print_array(const char *name
, GLint index
, const struct gl_client_array
*array
)
1437 printf(" %s[%d]: ", name
, index
);
1439 printf(" %s: ", name
);
1440 printf("Ptr=%p, Type=0x%x, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %lu), MaxElem=%u\n",
1441 array
->Ptr
, array
->Type
, array
->Size
,
1442 array
->_ElementSize
, array
->StrideB
,
1443 array
->BufferObj
->Name
, (unsigned long) array
->BufferObj
->Size
,
1444 array
->_MaxElement
);
1449 * Print current vertex object/array info. For debug.
1452 _mesa_print_arrays(struct gl_context
*ctx
)
1454 struct gl_array_object
*arrayObj
= ctx
->Array
.ArrayObj
;
1457 _mesa_update_array_object_max_element(ctx
, arrayObj
);
1459 printf("Array Object %u\n", arrayObj
->Name
);
1460 if (arrayObj
->Vertex
.Enabled
)
1461 print_array("Vertex", -1, &arrayObj
->Vertex
);
1462 if (arrayObj
->Normal
.Enabled
)
1463 print_array("Normal", -1, &arrayObj
->Normal
);
1464 if (arrayObj
->Color
.Enabled
)
1465 print_array("Color", -1, &arrayObj
->Color
);
1466 for (i
= 0; i
< Elements(arrayObj
->TexCoord
); i
++)
1467 if (arrayObj
->TexCoord
[i
].Enabled
)
1468 print_array("TexCoord", i
, &arrayObj
->TexCoord
[i
]);
1469 for (i
= 0; i
< Elements(arrayObj
->VertexAttrib
); i
++)
1470 if (arrayObj
->VertexAttrib
[i
].Enabled
)
1471 print_array("Attrib", i
, &arrayObj
->VertexAttrib
[i
]);
1472 printf(" _MaxElement = %u\n", arrayObj
->_MaxElement
);
1477 * Initialize vertex array state for given context.
1480 _mesa_init_varray(struct gl_context
*ctx
)
1482 ctx
->Array
.DefaultArrayObj
= _mesa_new_array_object(ctx
, 0);
1483 _mesa_reference_array_object(ctx
, &ctx
->Array
.ArrayObj
,
1484 ctx
->Array
.DefaultArrayObj
);
1485 ctx
->Array
.ActiveTexture
= 0; /* GL_ARB_multitexture */
1487 ctx
->Array
.Objects
= _mesa_NewHashTable();
1492 * Callback for deleting an array object. Called by _mesa_HashDeleteAll().
1495 delete_arrayobj_cb(GLuint id
, void *data
, void *userData
)
1497 struct gl_array_object
*arrayObj
= (struct gl_array_object
*) data
;
1498 struct gl_context
*ctx
= (struct gl_context
*) userData
;
1499 _mesa_delete_array_object(ctx
, arrayObj
);
1504 * Free vertex array state for given context.
1507 _mesa_free_varray_data(struct gl_context
*ctx
)
1509 _mesa_HashDeleteAll(ctx
->Array
.Objects
, delete_arrayobj_cb
, ctx
);
1510 _mesa_DeleteHashTable(ctx
->Array
.Objects
);