mesa: Only update enabled VAO gl_vertex_array entries.
[mesa.git] / src / mesa / main / varray.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27 #include <stdio.h>
28 #include <inttypes.h> /* for PRId64 macro */
29
30 #include "glheader.h"
31 #include "imports.h"
32 #include "bufferobj.h"
33 #include "context.h"
34 #include "enable.h"
35 #include "enums.h"
36 #include "hash.h"
37 #include "image.h"
38 #include "macros.h"
39 #include "mtypes.h"
40 #include "varray.h"
41 #include "arrayobj.h"
42 #include "main/dispatch.h"
43
44
45 /** Used to do error checking for GL_EXT_vertex_array_bgra */
46 #define BGRA_OR_4 5
47
48
49 /** Used to indicate which GL datatypes are accepted by each of the
50 * glVertex/Color/Attrib/EtcPointer() functions.
51 */
52 #define BOOL_BIT (1 << 0)
53 #define BYTE_BIT (1 << 1)
54 #define UNSIGNED_BYTE_BIT (1 << 2)
55 #define SHORT_BIT (1 << 3)
56 #define UNSIGNED_SHORT_BIT (1 << 4)
57 #define INT_BIT (1 << 5)
58 #define UNSIGNED_INT_BIT (1 << 6)
59 #define HALF_BIT (1 << 7)
60 #define FLOAT_BIT (1 << 8)
61 #define DOUBLE_BIT (1 << 9)
62 #define FIXED_ES_BIT (1 << 10)
63 #define FIXED_GL_BIT (1 << 11)
64 #define UNSIGNED_INT_2_10_10_10_REV_BIT (1 << 12)
65 #define INT_2_10_10_10_REV_BIT (1 << 13)
66 #define UNSIGNED_INT_10F_11F_11F_REV_BIT (1 << 14)
67 #define ALL_TYPE_BITS ((1 << 15) - 1)
68
69 #define ATTRIB_FORMAT_TYPES_MASK (BYTE_BIT | UNSIGNED_BYTE_BIT | \
70 SHORT_BIT | UNSIGNED_SHORT_BIT | \
71 INT_BIT | UNSIGNED_INT_BIT | \
72 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | \
73 FIXED_GL_BIT | \
74 UNSIGNED_INT_2_10_10_10_REV_BIT | \
75 INT_2_10_10_10_REV_BIT | \
76 UNSIGNED_INT_10F_11F_11F_REV_BIT)
77
78 #define ATTRIB_IFORMAT_TYPES_MASK (BYTE_BIT | UNSIGNED_BYTE_BIT | \
79 SHORT_BIT | UNSIGNED_SHORT_BIT | \
80 INT_BIT | UNSIGNED_INT_BIT)
81
82 #define ATTRIB_LFORMAT_TYPES_MASK DOUBLE_BIT
83
84
85 /** Convert GL datatype enum into a <type>_BIT value seen above */
86 static GLbitfield
87 type_to_bit(const struct gl_context *ctx, GLenum type)
88 {
89 switch (type) {
90 case GL_BOOL:
91 return BOOL_BIT;
92 case GL_BYTE:
93 return BYTE_BIT;
94 case GL_UNSIGNED_BYTE:
95 return UNSIGNED_BYTE_BIT;
96 case GL_SHORT:
97 return SHORT_BIT;
98 case GL_UNSIGNED_SHORT:
99 return UNSIGNED_SHORT_BIT;
100 case GL_INT:
101 return INT_BIT;
102 case GL_UNSIGNED_INT:
103 return UNSIGNED_INT_BIT;
104 case GL_HALF_FLOAT:
105 case GL_HALF_FLOAT_OES:
106 if (ctx->Extensions.ARB_half_float_vertex)
107 return HALF_BIT;
108 else
109 return 0x0;
110 case GL_FLOAT:
111 return FLOAT_BIT;
112 case GL_DOUBLE:
113 return DOUBLE_BIT;
114 case GL_FIXED:
115 return _mesa_is_desktop_gl(ctx) ? FIXED_GL_BIT : FIXED_ES_BIT;
116 case GL_UNSIGNED_INT_2_10_10_10_REV:
117 return UNSIGNED_INT_2_10_10_10_REV_BIT;
118 case GL_INT_2_10_10_10_REV:
119 return INT_2_10_10_10_REV_BIT;
120 case GL_UNSIGNED_INT_10F_11F_11F_REV:
121 return UNSIGNED_INT_10F_11F_11F_REV_BIT;
122 default:
123 return 0;
124 }
125 }
126
127
128 /**
129 * Depending on the position and generic0 attributes enable flags select
130 * the one that is used for both attributes.
131 * The generic0 attribute takes precedence.
132 */
133 static inline void
134 update_attribute_map_mode(const struct gl_context *ctx,
135 struct gl_vertex_array_object *vao)
136 {
137 /*
138 * There is no need to change the mapping away from the
139 * identity mapping if we are not in compat mode.
140 */
141 if (ctx->API != API_OPENGL_COMPAT)
142 return;
143 /* The generic0 attribute superseeds the position attribute */
144 const GLbitfield enabled = vao->_Enabled;
145 if (enabled & VERT_BIT_GENERIC0)
146 vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_GENERIC0;
147 else if (enabled & VERT_BIT_POS)
148 vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_POSITION;
149 else
150 vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_IDENTITY;
151 }
152
153
154 /**
155 * Sets the BufferBindingIndex field for the vertex attribute given by
156 * attribIndex.
157 */
158 static void
159 vertex_attrib_binding(struct gl_context *ctx,
160 struct gl_vertex_array_object *vao,
161 gl_vert_attrib attribIndex,
162 GLuint bindingIndex)
163 {
164 struct gl_array_attributes *array = &vao->VertexAttrib[attribIndex];
165
166 if (array->BufferBindingIndex != bindingIndex) {
167 const GLbitfield array_bit = VERT_BIT(attribIndex);
168
169 if (_mesa_is_bufferobj(vao->BufferBinding[bindingIndex].BufferObj))
170 vao->VertexAttribBufferMask |= array_bit;
171 else
172 vao->VertexAttribBufferMask &= ~array_bit;
173
174 FLUSH_VERTICES(ctx, _NEW_ARRAY);
175
176 vao->BufferBinding[array->BufferBindingIndex]._BoundArrays &= ~array_bit;
177 vao->BufferBinding[bindingIndex]._BoundArrays |= array_bit;
178
179 array->BufferBindingIndex = bindingIndex;
180
181 vao->NewArrays |= vao->_Enabled & array_bit;
182 }
183 }
184
185
186 /**
187 * Binds a buffer object to the vertex buffer binding point given by index,
188 * and sets the Offset and Stride fields.
189 */
190 void
191 _mesa_bind_vertex_buffer(struct gl_context *ctx,
192 struct gl_vertex_array_object *vao,
193 GLuint index,
194 struct gl_buffer_object *vbo,
195 GLintptr offset, GLsizei stride)
196 {
197 assert(index < ARRAY_SIZE(vao->BufferBinding));
198 struct gl_vertex_buffer_binding *binding = &vao->BufferBinding[index];
199
200 if (binding->BufferObj != vbo ||
201 binding->Offset != offset ||
202 binding->Stride != stride) {
203
204 FLUSH_VERTICES(ctx, _NEW_ARRAY);
205
206 _mesa_reference_buffer_object(ctx, &binding->BufferObj, vbo);
207
208 binding->Offset = offset;
209 binding->Stride = stride;
210
211 if (!_mesa_is_bufferobj(vbo))
212 vao->VertexAttribBufferMask &= ~binding->_BoundArrays;
213 else
214 vao->VertexAttribBufferMask |= binding->_BoundArrays;
215
216 vao->NewArrays |= vao->_Enabled & binding->_BoundArrays;
217 }
218 }
219
220
221 /**
222 * Sets the InstanceDivisor field in the vertex buffer binding point
223 * given by bindingIndex.
224 */
225 static void
226 vertex_binding_divisor(struct gl_context *ctx,
227 struct gl_vertex_array_object *vao,
228 GLuint bindingIndex,
229 GLuint divisor)
230 {
231 struct gl_vertex_buffer_binding *binding =
232 &vao->BufferBinding[bindingIndex];
233
234 if (binding->InstanceDivisor != divisor) {
235 FLUSH_VERTICES(ctx, _NEW_ARRAY);
236 binding->InstanceDivisor = divisor;
237 vao->NewArrays |= vao->_Enabled & binding->_BoundArrays;
238 }
239 }
240
241
242 /**
243 * Examine the API profile and extensions to determine which types are legal
244 * for vertex arrays. This is called once from update_array_format().
245 */
246 static GLbitfield
247 get_legal_types_mask(const struct gl_context *ctx)
248 {
249 GLbitfield legalTypesMask = ALL_TYPE_BITS;
250
251 if (_mesa_is_gles(ctx)) {
252 legalTypesMask &= ~(FIXED_GL_BIT |
253 DOUBLE_BIT |
254 UNSIGNED_INT_10F_11F_11F_REV_BIT);
255
256 /* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until
257 * 3.0. The 2_10_10_10 types are added in OpenGL ES 3.0 or
258 * GL_OES_vertex_type_10_10_10_2. GL_HALF_FLOAT data is not allowed
259 * until 3.0 or with the GL_OES_vertex_half float extension, which isn't
260 * quite as trivial as we'd like because it uses a different enum value
261 * for GL_HALF_FLOAT_OES.
262 */
263 if (ctx->Version < 30) {
264 legalTypesMask &= ~(UNSIGNED_INT_BIT |
265 INT_BIT |
266 UNSIGNED_INT_2_10_10_10_REV_BIT |
267 INT_2_10_10_10_REV_BIT);
268
269 if (!_mesa_has_OES_vertex_half_float(ctx))
270 legalTypesMask &= ~HALF_BIT;
271 }
272 }
273 else {
274 legalTypesMask &= ~FIXED_ES_BIT;
275
276 if (!ctx->Extensions.ARB_ES2_compatibility)
277 legalTypesMask &= ~FIXED_GL_BIT;
278
279 if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev)
280 legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT |
281 INT_2_10_10_10_REV_BIT);
282
283 if (!ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev)
284 legalTypesMask &= ~UNSIGNED_INT_10F_11F_11F_REV_BIT;
285 }
286
287 return legalTypesMask;
288 }
289
290 static GLenum
291 get_array_format(const struct gl_context *ctx, GLint sizeMax, GLint *size)
292 {
293 GLenum format = GL_RGBA;
294
295 /* Do size parameter checking.
296 * If sizeMax = BGRA_OR_4 it means that size = GL_BGRA is legal and
297 * must be handled specially.
298 */
299 if (ctx->Extensions.EXT_vertex_array_bgra && sizeMax == BGRA_OR_4 &&
300 *size == GL_BGRA) {
301 format = GL_BGRA;
302 *size = 4;
303 }
304
305 return format;
306 }
307
308
309 /**
310 * \param attrib The index of the attribute array
311 * \param size Components per element (1, 2, 3 or 4)
312 * \param type Datatype of each component (GL_FLOAT, GL_INT, etc)
313 * \param format Either GL_RGBA or GL_BGRA.
314 * \param normalized Whether integer types are converted to floats in [-1, 1]
315 * \param integer Integer-valued values (will not be normalized to [-1, 1])
316 * \param doubles Double values not reduced to floats
317 * \param relativeOffset Offset of the first element relative to the binding
318 * offset.
319 * \param flush_verties Should \c FLUSH_VERTICES be invoked before updating
320 * state?
321 */
322 void
323 _mesa_update_array_format(struct gl_context *ctx,
324 struct gl_vertex_array_object *vao,
325 gl_vert_attrib attrib, GLint size, GLenum type,
326 GLenum format, GLboolean normalized,
327 GLboolean integer, GLboolean doubles,
328 GLuint relativeOffset)
329 {
330 struct gl_array_attributes *const array = &vao->VertexAttrib[attrib];
331 GLint elementSize;
332
333 assert(size <= 4);
334
335 elementSize = _mesa_bytes_per_vertex_attrib(size, type);
336 assert(elementSize != -1);
337
338 array->Size = size;
339 array->Type = type;
340 array->Format = format;
341 array->Normalized = normalized;
342 array->Integer = integer;
343 array->Doubles = doubles;
344 array->RelativeOffset = relativeOffset;
345 array->_ElementSize = elementSize;
346
347 vao->NewArrays |= vao->_Enabled & VERT_BIT(attrib);
348 ctx->NewState |= _NEW_ARRAY;
349 }
350
351 /**
352 * Does error checking of the format in an attrib array.
353 *
354 * Called by *Pointer() and VertexAttrib*Format().
355 *
356 * \param func Name of calling function used for error reporting
357 * \param attrib The index of the attribute array
358 * \param legalTypes Bitmask of *_BIT above indicating legal datatypes
359 * \param sizeMin Min allowable size value
360 * \param sizeMax Max allowable size value (may also be BGRA_OR_4)
361 * \param size Components per element (1, 2, 3 or 4)
362 * \param type Datatype of each component (GL_FLOAT, GL_INT, etc)
363 * \param normalized Whether integer types are converted to floats in [-1, 1]
364 * \param integer Integer-valued values (will not be normalized to [-1, 1])
365 * \param doubles Double values not reduced to floats
366 * \param relativeOffset Offset of the first element relative to the binding offset.
367 * \return bool True if validation is successful, False otherwise.
368 */
369 static bool
370 validate_array_format(struct gl_context *ctx, const char *func,
371 struct gl_vertex_array_object *vao,
372 GLuint attrib, GLbitfield legalTypesMask,
373 GLint sizeMin, GLint sizeMax,
374 GLint size, GLenum type, GLboolean normalized,
375 GLboolean integer, GLboolean doubles,
376 GLuint relativeOffset, GLenum format)
377 {
378 GLbitfield typeBit;
379
380 /* at most, one of these bools can be true */
381 assert((int) normalized + (int) integer + (int) doubles <= 1);
382
383 if (ctx->Array.LegalTypesMask == 0 || ctx->Array.LegalTypesMaskAPI != ctx->API) {
384 /* Compute the LegalTypesMask only once, unless the context API has
385 * changed, in which case we want to compute it again. We can't do this
386 * in _mesa_init_varrays() below because extensions are not yet enabled
387 * at that point.
388 */
389 ctx->Array.LegalTypesMask = get_legal_types_mask(ctx);
390 ctx->Array.LegalTypesMaskAPI = ctx->API;
391 }
392
393 legalTypesMask &= ctx->Array.LegalTypesMask;
394
395 if (_mesa_is_gles(ctx) && sizeMax == BGRA_OR_4) {
396 /* BGRA ordering is not supported in ES contexts.
397 */
398 sizeMax = 4;
399 }
400
401 typeBit = type_to_bit(ctx, type);
402 if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) {
403 _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)",
404 func, _mesa_enum_to_string(type));
405 return false;
406 }
407
408 if (format == GL_BGRA) {
409 /* Page 298 of the PDF of the OpenGL 4.3 (Core Profile) spec says:
410 *
411 * "An INVALID_OPERATION error is generated under any of the following
412 * conditions:
413 * ...
414 * • size is BGRA and type is not UNSIGNED_BYTE, INT_2_10_10_10_REV
415 * or UNSIGNED_INT_2_10_10_10_REV;
416 * ...
417 * • size is BGRA and normalized is FALSE;"
418 */
419 bool bgra_error = false;
420
421 if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) {
422 if (type != GL_UNSIGNED_INT_2_10_10_10_REV &&
423 type != GL_INT_2_10_10_10_REV &&
424 type != GL_UNSIGNED_BYTE)
425 bgra_error = true;
426 } else if (type != GL_UNSIGNED_BYTE)
427 bgra_error = true;
428
429 if (bgra_error) {
430 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=GL_BGRA and type=%s)",
431 func, _mesa_enum_to_string(type));
432 return false;
433 }
434
435 if (!normalized) {
436 _mesa_error(ctx, GL_INVALID_OPERATION,
437 "%s(size=GL_BGRA and normalized=GL_FALSE)", func);
438 return false;
439 }
440 }
441 else if (size < sizeMin || size > sizeMax || size > 4) {
442 _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size);
443 return false;
444 }
445
446 if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev &&
447 (type == GL_UNSIGNED_INT_2_10_10_10_REV ||
448 type == GL_INT_2_10_10_10_REV) && size != 4) {
449 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size);
450 return false;
451 }
452
453 /* The ARB_vertex_attrib_binding_spec says:
454 *
455 * An INVALID_VALUE error is generated if <relativeoffset> is larger than
456 * the value of MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.
457 */
458 if (relativeOffset > ctx->Const.MaxVertexAttribRelativeOffset) {
459 _mesa_error(ctx, GL_INVALID_VALUE,
460 "%s(relativeOffset=%d > "
461 "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET)",
462 func, relativeOffset);
463 return false;
464 }
465
466 if (ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev &&
467 type == GL_UNSIGNED_INT_10F_11F_11F_REV && size != 3) {
468 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size);
469 return false;
470 }
471
472 return true;
473 }
474
475 /**
476 * Do error checking for glVertex/Color/TexCoord/...Pointer functions.
477 *
478 * \param func name of calling function used for error reporting
479 * \param attrib the attribute array index to update
480 * \param legalTypes bitmask of *_BIT above indicating legal datatypes
481 * \param sizeMin min allowable size value
482 * \param sizeMax max allowable size value (may also be BGRA_OR_4)
483 * \param size components per element (1, 2, 3 or 4)
484 * \param type datatype of each component (GL_FLOAT, GL_INT, etc)
485 * \param stride stride between elements, in elements
486 * \param normalized are integer types converted to floats in [-1, 1]?
487 * \param integer integer-valued values (will not be normalized to [-1,1])
488 * \param doubles Double values not reduced to floats
489 * \param ptr the address (or offset inside VBO) of the array data
490 */
491 static void
492 validate_array(struct gl_context *ctx, const char *func,
493 GLuint attrib, GLbitfield legalTypesMask,
494 GLint sizeMin, GLint sizeMax,
495 GLint size, GLenum type, GLsizei stride,
496 GLboolean normalized, GLboolean integer, GLboolean doubles,
497 const GLvoid *ptr)
498 {
499 struct gl_vertex_array_object *vao = ctx->Array.VAO;
500
501 /* Page 407 (page 423 of the PDF) of the OpenGL 3.0 spec says:
502 *
503 * "Client vertex arrays - all vertex array attribute pointers must
504 * refer to buffer objects (section 2.9.2). The default vertex array
505 * object (the name zero) is also deprecated. Calling
506 * VertexAttribPointer when no buffer object or no vertex array object
507 * is bound will generate an INVALID_OPERATION error..."
508 *
509 * The check for VBOs is handled below.
510 */
511 if (ctx->API == API_OPENGL_CORE && (vao == ctx->Array.DefaultVAO)) {
512 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no array object bound)",
513 func);
514 return;
515 }
516
517 if (stride < 0) {
518 _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride );
519 return;
520 }
521
522 if (ctx->API == API_OPENGL_CORE && ctx->Version >= 44 &&
523 stride > ctx->Const.MaxVertexAttribStride) {
524 _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > "
525 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride);
526 return;
527 }
528
529 /* Page 29 (page 44 of the PDF) of the OpenGL 3.3 spec says:
530 *
531 * "An INVALID_OPERATION error is generated under any of the following
532 * conditions:
533 *
534 * ...
535 *
536 * * any of the *Pointer commands specifying the location and
537 * organization of vertex array data are called while zero is bound
538 * to the ARRAY_BUFFER buffer object binding point (see section
539 * 2.9.6), and the pointer argument is not NULL."
540 */
541 if (ptr != NULL && vao != ctx->Array.DefaultVAO &&
542 !_mesa_is_bufferobj(ctx->Array.ArrayBufferObj)) {
543 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func);
544 return;
545 }
546 }
547
548
549 static bool
550 validate_array_and_format(struct gl_context *ctx, const char *func,
551 GLuint attrib, GLbitfield legalTypes,
552 GLint sizeMin, GLint sizeMax,
553 GLint size, GLenum type, GLsizei stride,
554 GLboolean normalized, GLboolean integer,
555 GLboolean doubles, GLenum format, const GLvoid *ptr,
556 struct gl_vertex_array_object *vao)
557 {
558 validate_array(ctx, func, attrib, legalTypes, sizeMin, sizeMax, size,
559 type, stride, normalized, integer, doubles, ptr);
560
561 return validate_array_format(ctx, func, vao, attrib, legalTypes, sizeMin,
562 sizeMax, size, type, normalized, integer,
563 doubles, 0, format);
564 }
565
566
567 /**
568 * Update state for glVertex/Color/TexCoord/...Pointer functions.
569 *
570 * \param attrib the attribute array index to update
571 * \param format Either GL_RGBA or GL_BGRA.
572 * \param sizeMax max allowable size value (may also be BGRA_OR_4)
573 * \param size components per element (1, 2, 3 or 4)
574 * \param type datatype of each component (GL_FLOAT, GL_INT, etc)
575 * \param stride stride between elements, in elements
576 * \param normalized are integer types converted to floats in [-1, 1]?
577 * \param integer integer-valued values (will not be normalized to [-1,1])
578 * \param doubles Double values not reduced to floats
579 * \param ptr the address (or offset inside VBO) of the array data
580 */
581 static void
582 update_array(struct gl_context *ctx,
583 GLuint attrib, GLenum format,
584 GLint sizeMax,
585 GLint size, GLenum type, GLsizei stride,
586 GLboolean normalized, GLboolean integer, GLboolean doubles,
587 const GLvoid *ptr)
588 {
589 struct gl_vertex_array_object *vao = ctx->Array.VAO;
590
591 _mesa_update_array_format(ctx, vao, attrib, size, type, format,
592 normalized, integer, doubles, 0);
593
594 /* Reset the vertex attrib binding */
595 vertex_attrib_binding(ctx, vao, attrib, attrib);
596
597 /* The Stride and Ptr fields are not set by update_array_format() */
598 struct gl_array_attributes *array = &vao->VertexAttrib[attrib];
599 array->Stride = stride;
600 array->Ptr = ptr;
601
602 /* Update the vertex buffer binding */
603 GLsizei effectiveStride = stride != 0 ? stride : array->_ElementSize;
604 _mesa_bind_vertex_buffer(ctx, vao, attrib,
605 ctx->Array.ArrayBufferObj, (GLintptr) ptr,
606 effectiveStride);
607 }
608
609 void GLAPIENTRY
610 _mesa_VertexPointer_no_error(GLint size, GLenum type, GLsizei stride,
611 const GLvoid *ptr)
612 {
613 GET_CURRENT_CONTEXT(ctx);
614 FLUSH_VERTICES(ctx, 0);
615
616 update_array(ctx, VERT_ATTRIB_POS, GL_RGBA, 4, size, type, stride,
617 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
618 }
619
620
621 void GLAPIENTRY
622 _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
623 {
624 GET_CURRENT_CONTEXT(ctx);
625
626 FLUSH_VERTICES(ctx, 0);
627
628 GLenum format = GL_RGBA;
629 GLbitfield legalTypes = (ctx->API == API_OPENGLES)
630 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
631 : (SHORT_BIT | INT_BIT | FLOAT_BIT |
632 DOUBLE_BIT | HALF_BIT |
633 UNSIGNED_INT_2_10_10_10_REV_BIT |
634 INT_2_10_10_10_REV_BIT);
635
636 if (!validate_array_and_format(ctx, "glVertexPointer", VERT_ATTRIB_POS,
637 legalTypes, 2, 4, size, type, stride,
638 GL_FALSE, GL_FALSE, GL_FALSE, format,
639 ptr, ctx->Array.VAO))
640 return;
641
642 update_array(ctx, VERT_ATTRIB_POS, format, 4, size, type, stride,
643 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
644 }
645
646
647 void GLAPIENTRY
648 _mesa_NormalPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr )
649 {
650 GET_CURRENT_CONTEXT(ctx);
651 FLUSH_VERTICES(ctx, 0);
652
653 update_array(ctx, VERT_ATTRIB_NORMAL, GL_RGBA, 3, 3, type, stride, GL_TRUE,
654 GL_FALSE, GL_FALSE, ptr);
655 }
656
657
658 void GLAPIENTRY
659 _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
660 {
661 GET_CURRENT_CONTEXT(ctx);
662
663 FLUSH_VERTICES(ctx, 0);
664
665 GLenum format = GL_RGBA;
666 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
667 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
668 : (BYTE_BIT | SHORT_BIT | INT_BIT |
669 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
670 UNSIGNED_INT_2_10_10_10_REV_BIT |
671 INT_2_10_10_10_REV_BIT);
672
673 if (!validate_array_and_format(ctx, "glNormalPointer",
674 VERT_ATTRIB_NORMAL, legalTypes, 3, 3, 3,
675 type, stride, GL_TRUE, GL_FALSE,
676 GL_FALSE, format, ptr, ctx->Array.VAO))
677 return;
678
679 update_array(ctx, VERT_ATTRIB_NORMAL, format, 3, 3, type, stride, GL_TRUE,
680 GL_FALSE, GL_FALSE, ptr);
681 }
682
683
684 void GLAPIENTRY
685 _mesa_ColorPointer_no_error(GLint size, GLenum type, GLsizei stride,
686 const GLvoid *ptr)
687 {
688 GET_CURRENT_CONTEXT(ctx);
689 FLUSH_VERTICES(ctx, 0);
690
691 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
692 update_array(ctx, VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size,
693 type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
694 }
695
696
697 void GLAPIENTRY
698 _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
699 {
700 GET_CURRENT_CONTEXT(ctx);
701 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 4 : 3;
702
703 FLUSH_VERTICES(ctx, 0);
704
705 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
706 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
707 ? (UNSIGNED_BYTE_BIT | HALF_BIT | FLOAT_BIT | FIXED_ES_BIT)
708 : (BYTE_BIT | UNSIGNED_BYTE_BIT |
709 SHORT_BIT | UNSIGNED_SHORT_BIT |
710 INT_BIT | UNSIGNED_INT_BIT |
711 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
712 UNSIGNED_INT_2_10_10_10_REV_BIT |
713 INT_2_10_10_10_REV_BIT);
714
715 if (!validate_array_and_format(ctx, "glColorPointer",
716 VERT_ATTRIB_COLOR0, legalTypes, sizeMin,
717 BGRA_OR_4, size, type, stride, GL_TRUE,
718 GL_FALSE, GL_FALSE, format, ptr,
719 ctx->Array.VAO))
720 return;
721
722 update_array(ctx, VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size,
723 type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
724 }
725
726
727 void GLAPIENTRY
728 _mesa_FogCoordPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr)
729 {
730 GET_CURRENT_CONTEXT(ctx);
731 FLUSH_VERTICES(ctx, 0);
732
733 update_array(ctx, VERT_ATTRIB_FOG, GL_RGBA, 1, 1, type, stride, GL_FALSE,
734 GL_FALSE, GL_FALSE, ptr);
735 }
736
737
738 void GLAPIENTRY
739 _mesa_FogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
740 {
741 GET_CURRENT_CONTEXT(ctx);
742
743 FLUSH_VERTICES(ctx, 0);
744
745 GLenum format = GL_RGBA;
746 const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT);
747
748 if (!validate_array_and_format(ctx, "glFogCoordPointer",
749 VERT_ATTRIB_FOG, legalTypes, 1, 1, 1,
750 type, stride, GL_FALSE, GL_FALSE,
751 GL_FALSE, format, ptr, ctx->Array.VAO))
752 return;
753
754 update_array(ctx, VERT_ATTRIB_FOG, format, 1, 1, type, stride, GL_FALSE,
755 GL_FALSE, GL_FALSE, ptr);
756 }
757
758
759 void GLAPIENTRY
760 _mesa_IndexPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr)
761 {
762 GET_CURRENT_CONTEXT(ctx);
763 FLUSH_VERTICES(ctx, 0);
764
765 update_array(ctx, VERT_ATTRIB_COLOR_INDEX, GL_RGBA, 1, 1, type, stride,
766 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
767 }
768
769
770 void GLAPIENTRY
771 _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
772 {
773 GET_CURRENT_CONTEXT(ctx);
774
775 FLUSH_VERTICES(ctx, 0);
776
777 GLenum format = GL_RGBA;
778 const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT |
779 FLOAT_BIT | DOUBLE_BIT);
780
781 if (!validate_array_and_format(ctx, "glIndexPointer",
782 VERT_ATTRIB_COLOR_INDEX,
783 legalTypes, 1, 1, 1, type, stride,
784 GL_FALSE, GL_FALSE, GL_FALSE, format,
785 ptr, ctx->Array.VAO))
786 return;
787
788 update_array(ctx, VERT_ATTRIB_COLOR_INDEX, format, 1, 1, type, stride,
789 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
790 }
791
792
793 void GLAPIENTRY
794 _mesa_SecondaryColorPointer_no_error(GLint size, GLenum type,
795 GLsizei stride, const GLvoid *ptr)
796 {
797 GET_CURRENT_CONTEXT(ctx);
798 FLUSH_VERTICES(ctx, 0);
799
800 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
801 update_array(ctx, VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type,
802 stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
803 }
804
805
806 void GLAPIENTRY
807 _mesa_SecondaryColorPointer(GLint size, GLenum type,
808 GLsizei stride, const GLvoid *ptr)
809 {
810 GET_CURRENT_CONTEXT(ctx);
811
812 FLUSH_VERTICES(ctx, 0);
813
814 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
815 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
816 SHORT_BIT | UNSIGNED_SHORT_BIT |
817 INT_BIT | UNSIGNED_INT_BIT |
818 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
819 UNSIGNED_INT_2_10_10_10_REV_BIT |
820 INT_2_10_10_10_REV_BIT);
821
822 if (!validate_array_and_format(ctx, "glSecondaryColorPointer",
823 VERT_ATTRIB_COLOR1, legalTypes, 3,
824 BGRA_OR_4, size, type, stride,
825 GL_TRUE, GL_FALSE, GL_FALSE, format, ptr,
826 ctx->Array.VAO))
827 return;
828
829 update_array(ctx, VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type,
830 stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
831 }
832
833
834 void GLAPIENTRY
835 _mesa_TexCoordPointer_no_error(GLint size, GLenum type, GLsizei stride,
836 const GLvoid *ptr)
837 {
838 GET_CURRENT_CONTEXT(ctx);
839 const GLuint unit = ctx->Array.ActiveTexture;
840 FLUSH_VERTICES(ctx, 0);
841
842 update_array(ctx, VERT_ATTRIB_TEX(unit), GL_RGBA, 4, size, type,
843 stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr);
844 }
845
846
847 void GLAPIENTRY
848 _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
849 const GLvoid *ptr)
850 {
851 GET_CURRENT_CONTEXT(ctx);
852 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1;
853 const GLuint unit = ctx->Array.ActiveTexture;
854
855 FLUSH_VERTICES(ctx, 0);
856
857 GLenum format = GL_RGBA;
858 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
859 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
860 : (SHORT_BIT | INT_BIT |
861 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
862 UNSIGNED_INT_2_10_10_10_REV_BIT |
863 INT_2_10_10_10_REV_BIT);
864
865 if (!validate_array_and_format(ctx, "glTexCoordPointer",
866 VERT_ATTRIB_TEX(unit), legalTypes,
867 sizeMin, 4, size, type, stride,
868 GL_FALSE, GL_FALSE, GL_FALSE, format, ptr,
869 ctx->Array.VAO))
870 return;
871
872 update_array(ctx, VERT_ATTRIB_TEX(unit), format, 4, size, type,
873 stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr);
874 }
875
876
877 void GLAPIENTRY
878 _mesa_EdgeFlagPointer_no_error(GLsizei stride, const GLvoid *ptr)
879 {
880 /* this is the same type that glEdgeFlag uses */
881 const GLboolean integer = GL_FALSE;
882 GET_CURRENT_CONTEXT(ctx);
883 FLUSH_VERTICES(ctx, 0);
884
885 update_array(ctx, VERT_ATTRIB_EDGEFLAG, GL_RGBA, 1, 1, GL_UNSIGNED_BYTE,
886 stride, GL_FALSE, integer, GL_FALSE, ptr);
887 }
888
889
890 void GLAPIENTRY
891 _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
892 {
893 /* this is the same type that glEdgeFlag uses */
894 const GLboolean integer = GL_FALSE;
895 GET_CURRENT_CONTEXT(ctx);
896
897 FLUSH_VERTICES(ctx, 0);
898
899 GLenum format = GL_RGBA;
900 const GLbitfield legalTypes = UNSIGNED_BYTE_BIT;
901
902 if (!validate_array_and_format(ctx, "glEdgeFlagPointer",
903 VERT_ATTRIB_EDGEFLAG, legalTypes,
904 1, 1, 1, GL_UNSIGNED_BYTE, stride,
905 GL_FALSE, integer, GL_FALSE, format, ptr,
906 ctx->Array.VAO))
907 return;
908
909 update_array(ctx, VERT_ATTRIB_EDGEFLAG, format, 1, 1, GL_UNSIGNED_BYTE,
910 stride, GL_FALSE, integer, GL_FALSE, ptr);
911 }
912
913
914 void GLAPIENTRY
915 _mesa_PointSizePointerOES_no_error(GLenum type, GLsizei stride,
916 const GLvoid *ptr)
917 {
918 GET_CURRENT_CONTEXT(ctx);
919 FLUSH_VERTICES(ctx, 0);
920
921 update_array(ctx, VERT_ATTRIB_POINT_SIZE, GL_RGBA, 1, 1, type, stride,
922 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
923 }
924
925
926 void GLAPIENTRY
927 _mesa_PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *ptr)
928 {
929 GET_CURRENT_CONTEXT(ctx);
930
931 FLUSH_VERTICES(ctx, 0);
932
933 GLenum format = GL_RGBA;
934 if (ctx->API != API_OPENGLES) {
935 _mesa_error(ctx, GL_INVALID_OPERATION,
936 "glPointSizePointer(ES 1.x only)");
937 return;
938 }
939
940 const GLbitfield legalTypes = (FLOAT_BIT | FIXED_ES_BIT);
941
942 if (!validate_array_and_format(ctx, "glPointSizePointer",
943 VERT_ATTRIB_POINT_SIZE, legalTypes,
944 1, 1, 1, type, stride, GL_FALSE, GL_FALSE,
945 GL_FALSE, format, ptr, ctx->Array.VAO))
946 return;
947
948 update_array(ctx, VERT_ATTRIB_POINT_SIZE, format, 1, 1, type, stride,
949 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
950 }
951
952
953 void GLAPIENTRY
954 _mesa_VertexAttribPointer_no_error(GLuint index, GLint size, GLenum type,
955 GLboolean normalized,
956 GLsizei stride, const GLvoid *ptr)
957 {
958 GET_CURRENT_CONTEXT(ctx);
959
960 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
961 update_array(ctx, VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4,
962 size, type, stride, normalized, GL_FALSE, GL_FALSE, ptr);
963 }
964
965
966 /**
967 * Set a generic vertex attribute array.
968 * Note that these arrays DO NOT alias the conventional GL vertex arrays
969 * (position, normal, color, fog, texcoord, etc).
970 */
971 void GLAPIENTRY
972 _mesa_VertexAttribPointer(GLuint index, GLint size, GLenum type,
973 GLboolean normalized,
974 GLsizei stride, const GLvoid *ptr)
975 {
976 GET_CURRENT_CONTEXT(ctx);
977
978 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
979 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
980 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(idx)");
981 return;
982 }
983
984 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
985 SHORT_BIT | UNSIGNED_SHORT_BIT |
986 INT_BIT | UNSIGNED_INT_BIT |
987 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
988 FIXED_ES_BIT | FIXED_GL_BIT |
989 UNSIGNED_INT_2_10_10_10_REV_BIT |
990 INT_2_10_10_10_REV_BIT |
991 UNSIGNED_INT_10F_11F_11F_REV_BIT);
992
993 if (!validate_array_and_format(ctx, "glVertexAttribPointer",
994 VERT_ATTRIB_GENERIC(index), legalTypes,
995 1, BGRA_OR_4, size, type, stride,
996 normalized, GL_FALSE, GL_FALSE, format,
997 ptr, ctx->Array.VAO))
998 return;
999
1000 update_array(ctx, VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4,
1001 size, type, stride, normalized, GL_FALSE, GL_FALSE, ptr);
1002 }
1003
1004
1005 void GLAPIENTRY
1006 _mesa_VertexAttribIPointer_no_error(GLuint index, GLint size, GLenum type,
1007 GLsizei stride, const GLvoid *ptr)
1008 {
1009 const GLboolean normalized = GL_FALSE;
1010 const GLboolean integer = GL_TRUE;
1011 GET_CURRENT_CONTEXT(ctx);
1012
1013 update_array(ctx, VERT_ATTRIB_GENERIC(index), GL_RGBA, 4, size, type,
1014 stride, normalized, integer, GL_FALSE, ptr);
1015 }
1016
1017
1018 /**
1019 * GL_EXT_gpu_shader4 / GL 3.0.
1020 * Set an integer-valued vertex attribute array.
1021 * Note that these arrays DO NOT alias the conventional GL vertex arrays
1022 * (position, normal, color, fog, texcoord, etc).
1023 */
1024 void GLAPIENTRY
1025 _mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type,
1026 GLsizei stride, const GLvoid *ptr)
1027 {
1028 const GLboolean normalized = GL_FALSE;
1029 const GLboolean integer = GL_TRUE;
1030 GET_CURRENT_CONTEXT(ctx);
1031
1032 GLenum format = GL_RGBA;
1033 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1034 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIPointer(index)");
1035 return;
1036 }
1037
1038 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
1039 SHORT_BIT | UNSIGNED_SHORT_BIT |
1040 INT_BIT | UNSIGNED_INT_BIT);
1041
1042 if (!validate_array_and_format(ctx, "glVertexAttribIPointer",
1043 VERT_ATTRIB_GENERIC(index), legalTypes,
1044 1, 4, size, type, stride,
1045 normalized, integer, GL_FALSE, format,
1046 ptr, ctx->Array.VAO))
1047 return;
1048
1049 update_array(ctx, VERT_ATTRIB_GENERIC(index), format, 4, size, type,
1050 stride, normalized, integer, GL_FALSE, ptr);
1051 }
1052
1053
1054 void GLAPIENTRY
1055 _mesa_VertexAttribLPointer_no_error(GLuint index, GLint size, GLenum type,
1056 GLsizei stride, const GLvoid *ptr)
1057 {
1058 GET_CURRENT_CONTEXT(ctx);
1059
1060 update_array(ctx, VERT_ATTRIB_GENERIC(index), GL_RGBA, 4, size, type,
1061 stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr);
1062 }
1063
1064
1065 void GLAPIENTRY
1066 _mesa_VertexAttribLPointer(GLuint index, GLint size, GLenum type,
1067 GLsizei stride, const GLvoid *ptr)
1068 {
1069 GET_CURRENT_CONTEXT(ctx);
1070
1071 GLenum format = GL_RGBA;
1072 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1073 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribLPointer(index)");
1074 return;
1075 }
1076
1077 const GLbitfield legalTypes = DOUBLE_BIT;
1078
1079 if (!validate_array_and_format(ctx, "glVertexAttribLPointer",
1080 VERT_ATTRIB_GENERIC(index), legalTypes,
1081 1, 4, size, type, stride,
1082 GL_FALSE, GL_FALSE, GL_TRUE, format,
1083 ptr, ctx->Array.VAO))
1084 return;
1085
1086 update_array(ctx, VERT_ATTRIB_GENERIC(index), format, 4, size, type,
1087 stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr);
1088 }
1089
1090
1091 void
1092 _mesa_enable_vertex_array_attrib(struct gl_context *ctx,
1093 struct gl_vertex_array_object *vao,
1094 gl_vert_attrib attrib)
1095 {
1096 assert(attrib < ARRAY_SIZE(vao->VertexAttrib));
1097
1098 if (!vao->VertexAttrib[attrib].Enabled) {
1099 /* was disabled, now being enabled */
1100 FLUSH_VERTICES(ctx, _NEW_ARRAY);
1101 vao->VertexAttrib[attrib].Enabled = GL_TRUE;
1102 const GLbitfield array_bit = VERT_BIT(attrib);
1103 vao->_Enabled |= array_bit;
1104 vao->NewArrays |= array_bit;
1105
1106 /* Update the map mode if needed */
1107 if (array_bit & (VERT_BIT_POS|VERT_BIT_GENERIC0))
1108 update_attribute_map_mode(ctx, vao);
1109 }
1110 }
1111
1112 static void
1113 enable_vertex_array_attrib(struct gl_context *ctx,
1114 struct gl_vertex_array_object *vao,
1115 GLuint index,
1116 const char *func)
1117 {
1118 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1119 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
1120 return;
1121 }
1122
1123 _mesa_enable_vertex_array_attrib(ctx, vao, VERT_ATTRIB_GENERIC(index));
1124 }
1125
1126
1127 void GLAPIENTRY
1128 _mesa_EnableVertexAttribArray(GLuint index)
1129 {
1130 GET_CURRENT_CONTEXT(ctx);
1131 enable_vertex_array_attrib(ctx, ctx->Array.VAO, index,
1132 "glEnableVertexAttribArray");
1133 }
1134
1135
1136 void GLAPIENTRY
1137 _mesa_EnableVertexAttribArray_no_error(GLuint index)
1138 {
1139 GET_CURRENT_CONTEXT(ctx);
1140 _mesa_enable_vertex_array_attrib(ctx, ctx->Array.VAO,
1141 VERT_ATTRIB_GENERIC(index));
1142 }
1143
1144
1145 void GLAPIENTRY
1146 _mesa_EnableVertexArrayAttrib(GLuint vaobj, GLuint index)
1147 {
1148 GET_CURRENT_CONTEXT(ctx);
1149 struct gl_vertex_array_object *vao;
1150
1151 /* The ARB_direct_state_access specification says:
1152 *
1153 * "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib
1154 * and DisableVertexArrayAttrib if <vaobj> is not
1155 * [compatibility profile: zero or] the name of an existing vertex
1156 * array object."
1157 */
1158 vao = _mesa_lookup_vao_err(ctx, vaobj, "glEnableVertexArrayAttrib");
1159 if (!vao)
1160 return;
1161
1162 enable_vertex_array_attrib(ctx, vao, index, "glEnableVertexArrayAttrib");
1163 }
1164
1165
1166 void GLAPIENTRY
1167 _mesa_EnableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index)
1168 {
1169 GET_CURRENT_CONTEXT(ctx);
1170 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
1171 _mesa_enable_vertex_array_attrib(ctx, vao, VERT_ATTRIB_GENERIC(index));
1172 }
1173
1174
1175 void
1176 _mesa_disable_vertex_array_attrib(struct gl_context *ctx,
1177 struct gl_vertex_array_object *vao,
1178 gl_vert_attrib attrib)
1179 {
1180 assert(attrib < ARRAY_SIZE(vao->VertexAttrib));
1181
1182 if (vao->VertexAttrib[attrib].Enabled) {
1183 /* was enabled, now being disabled */
1184 FLUSH_VERTICES(ctx, _NEW_ARRAY);
1185 vao->VertexAttrib[attrib].Enabled = GL_FALSE;
1186 const GLbitfield array_bit = VERT_BIT(attrib);
1187 vao->_Enabled &= ~array_bit;
1188 vao->NewArrays |= array_bit;
1189
1190 /* Update the map mode if needed */
1191 if (array_bit & (VERT_BIT_POS|VERT_BIT_GENERIC0))
1192 update_attribute_map_mode(ctx, vao);
1193 }
1194 }
1195
1196
1197 void GLAPIENTRY
1198 _mesa_DisableVertexAttribArray(GLuint index)
1199 {
1200 GET_CURRENT_CONTEXT(ctx);
1201
1202 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1203 _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexAttribArray(index)");
1204 return;
1205 }
1206
1207 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1208 _mesa_disable_vertex_array_attrib(ctx, ctx->Array.VAO, attrib);
1209 }
1210
1211
1212 void GLAPIENTRY
1213 _mesa_DisableVertexAttribArray_no_error(GLuint index)
1214 {
1215 GET_CURRENT_CONTEXT(ctx);
1216 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1217 _mesa_disable_vertex_array_attrib(ctx, ctx->Array.VAO, attrib);
1218 }
1219
1220
1221 void GLAPIENTRY
1222 _mesa_DisableVertexArrayAttrib(GLuint vaobj, GLuint index)
1223 {
1224 GET_CURRENT_CONTEXT(ctx);
1225 struct gl_vertex_array_object *vao;
1226
1227 /* The ARB_direct_state_access specification says:
1228 *
1229 * "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib
1230 * and DisableVertexArrayAttrib if <vaobj> is not
1231 * [compatibility profile: zero or] the name of an existing vertex
1232 * array object."
1233 */
1234 vao = _mesa_lookup_vao_err(ctx, vaobj, "glDisableVertexArrayAttrib");
1235 if (!vao)
1236 return;
1237
1238 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1239 _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexArrayAttrib(index)");
1240 return;
1241 }
1242
1243 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1244 _mesa_disable_vertex_array_attrib(ctx, vao, attrib);
1245 }
1246
1247
1248 void GLAPIENTRY
1249 _mesa_DisableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index)
1250 {
1251 GET_CURRENT_CONTEXT(ctx);
1252 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
1253 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1254 _mesa_disable_vertex_array_attrib(ctx, vao, attrib);
1255 }
1256
1257
1258 /**
1259 * Return info for a vertex attribute array (no alias with legacy
1260 * vertex attributes (pos, normal, color, etc)). This function does
1261 * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query.
1262 */
1263 static GLuint
1264 get_vertex_array_attrib(struct gl_context *ctx,
1265 const struct gl_vertex_array_object *vao,
1266 GLuint index, GLenum pname,
1267 const char *caller)
1268 {
1269 const struct gl_array_attributes *array;
1270
1271 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1272 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index);
1273 return 0;
1274 }
1275
1276 assert(VERT_ATTRIB_GENERIC(index) < ARRAY_SIZE(vao->VertexAttrib));
1277
1278 array = &vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)];
1279
1280 switch (pname) {
1281 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
1282 return array->Enabled;
1283 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
1284 return (array->Format == GL_BGRA) ? GL_BGRA : array->Size;
1285 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
1286 return array->Stride;
1287 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
1288 return array->Type;
1289 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
1290 return array->Normalized;
1291 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
1292 return vao->BufferBinding[array->BufferBindingIndex].BufferObj->Name;
1293 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
1294 if ((_mesa_is_desktop_gl(ctx)
1295 && (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))
1296 || _mesa_is_gles3(ctx)) {
1297 return array->Integer;
1298 }
1299 goto error;
1300 case GL_VERTEX_ATTRIB_ARRAY_LONG:
1301 if (_mesa_is_desktop_gl(ctx)) {
1302 return array->Doubles;
1303 }
1304 goto error;
1305 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB:
1306 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_instanced_arrays)
1307 || _mesa_is_gles3(ctx)) {
1308 return vao->BufferBinding[array->BufferBindingIndex].InstanceDivisor;
1309 }
1310 goto error;
1311 case GL_VERTEX_ATTRIB_BINDING:
1312 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
1313 return array->BufferBindingIndex - VERT_ATTRIB_GENERIC0;
1314 }
1315 goto error;
1316 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
1317 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
1318 return array->RelativeOffset;
1319 }
1320 goto error;
1321 default:
1322 ; /* fall-through */
1323 }
1324
1325 error:
1326 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname);
1327 return 0;
1328 }
1329
1330
1331 static const GLfloat *
1332 get_current_attrib(struct gl_context *ctx, GLuint index, const char *function)
1333 {
1334 if (index == 0) {
1335 if (_mesa_attr_zero_aliases_vertex(ctx)) {
1336 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function);
1337 return NULL;
1338 }
1339 }
1340 else if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1341 _mesa_error(ctx, GL_INVALID_VALUE,
1342 "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function);
1343 return NULL;
1344 }
1345
1346 assert(VERT_ATTRIB_GENERIC(index) <
1347 ARRAY_SIZE(ctx->Array.VAO->VertexAttrib));
1348
1349 FLUSH_CURRENT(ctx, 0);
1350 return ctx->Current.Attrib[VERT_ATTRIB_GENERIC(index)];
1351 }
1352
1353 void GLAPIENTRY
1354 _mesa_GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
1355 {
1356 GET_CURRENT_CONTEXT(ctx);
1357
1358 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1359 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv");
1360 if (v != NULL) {
1361 COPY_4V(params, v);
1362 }
1363 }
1364 else {
1365 params[0] = (GLfloat) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1366 index, pname,
1367 "glGetVertexAttribfv");
1368 }
1369 }
1370
1371
1372 void GLAPIENTRY
1373 _mesa_GetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params)
1374 {
1375 GET_CURRENT_CONTEXT(ctx);
1376
1377 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1378 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv");
1379 if (v != NULL) {
1380 params[0] = (GLdouble) v[0];
1381 params[1] = (GLdouble) v[1];
1382 params[2] = (GLdouble) v[2];
1383 params[3] = (GLdouble) v[3];
1384 }
1385 }
1386 else {
1387 params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1388 index, pname,
1389 "glGetVertexAttribdv");
1390 }
1391 }
1392
1393 void GLAPIENTRY
1394 _mesa_GetVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params)
1395 {
1396 GET_CURRENT_CONTEXT(ctx);
1397
1398 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1399 const GLdouble *v =
1400 (const GLdouble *)get_current_attrib(ctx, index,
1401 "glGetVertexAttribLdv");
1402 if (v != NULL) {
1403 params[0] = v[0];
1404 params[1] = v[1];
1405 params[2] = v[2];
1406 params[3] = v[3];
1407 }
1408 }
1409 else {
1410 params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1411 index, pname,
1412 "glGetVertexAttribLdv");
1413 }
1414 }
1415
1416 void GLAPIENTRY
1417 _mesa_GetVertexAttribiv(GLuint index, GLenum pname, GLint *params)
1418 {
1419 GET_CURRENT_CONTEXT(ctx);
1420
1421 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1422 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv");
1423 if (v != NULL) {
1424 /* XXX should floats in[0,1] be scaled to full int range? */
1425 params[0] = (GLint) v[0];
1426 params[1] = (GLint) v[1];
1427 params[2] = (GLint) v[2];
1428 params[3] = (GLint) v[3];
1429 }
1430 }
1431 else {
1432 params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1433 index, pname,
1434 "glGetVertexAttribiv");
1435 }
1436 }
1437
1438 void GLAPIENTRY
1439 _mesa_GetVertexAttribLui64vARB(GLuint index, GLenum pname, GLuint64EXT *params)
1440 {
1441 GET_CURRENT_CONTEXT(ctx);
1442
1443 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1444 const GLuint64 *v =
1445 (const GLuint64 *)get_current_attrib(ctx, index,
1446 "glGetVertexAttribLui64vARB");
1447 if (v != NULL) {
1448 params[0] = v[0];
1449 params[1] = v[1];
1450 params[2] = v[2];
1451 params[3] = v[3];
1452 }
1453 }
1454 else {
1455 params[0] = (GLuint64) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1456 index, pname,
1457 "glGetVertexAttribLui64vARB");
1458 }
1459 }
1460
1461
1462 /** GL 3.0 */
1463 void GLAPIENTRY
1464 _mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
1465 {
1466 GET_CURRENT_CONTEXT(ctx);
1467
1468 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1469 const GLint *v = (const GLint *)
1470 get_current_attrib(ctx, index, "glGetVertexAttribIiv");
1471 if (v != NULL) {
1472 COPY_4V(params, v);
1473 }
1474 }
1475 else {
1476 params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1477 index, pname,
1478 "glGetVertexAttribIiv");
1479 }
1480 }
1481
1482
1483 /** GL 3.0 */
1484 void GLAPIENTRY
1485 _mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
1486 {
1487 GET_CURRENT_CONTEXT(ctx);
1488
1489 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1490 const GLuint *v = (const GLuint *)
1491 get_current_attrib(ctx, index, "glGetVertexAttribIuiv");
1492 if (v != NULL) {
1493 COPY_4V(params, v);
1494 }
1495 }
1496 else {
1497 params[0] = get_vertex_array_attrib(ctx, ctx->Array.VAO,
1498 index, pname,
1499 "glGetVertexAttribIuiv");
1500 }
1501 }
1502
1503
1504 void GLAPIENTRY
1505 _mesa_GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
1506 {
1507 GET_CURRENT_CONTEXT(ctx);
1508
1509 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1510 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
1511 return;
1512 }
1513
1514 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
1515 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
1516 return;
1517 }
1518
1519 assert(VERT_ATTRIB_GENERIC(index) <
1520 ARRAY_SIZE(ctx->Array.VAO->VertexAttrib));
1521
1522 *pointer = (GLvoid *)
1523 ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr;
1524 }
1525
1526
1527 /** ARB_direct_state_access */
1528 void GLAPIENTRY
1529 _mesa_GetVertexArrayIndexediv(GLuint vaobj, GLuint index,
1530 GLenum pname, GLint *params)
1531 {
1532 GET_CURRENT_CONTEXT(ctx);
1533 struct gl_vertex_array_object *vao;
1534
1535 /* The ARB_direct_state_access specification says:
1536 *
1537 * "An INVALID_OPERATION error is generated if <vaobj> is not
1538 * [compatibility profile: zero or] the name of an existing
1539 * vertex array object."
1540 */
1541 vao = _mesa_lookup_vao_err(ctx, vaobj, "glGetVertexArrayIndexediv");
1542 if (!vao)
1543 return;
1544
1545 /* The ARB_direct_state_access specification says:
1546 *
1547 * "For GetVertexArrayIndexediv, <pname> must be one of
1548 * VERTEX_ATTRIB_ARRAY_ENABLED, VERTEX_ATTRIB_ARRAY_SIZE,
1549 * VERTEX_ATTRIB_ARRAY_STRIDE, VERTEX_ATTRIB_ARRAY_TYPE,
1550 * VERTEX_ATTRIB_ARRAY_NORMALIZED, VERTEX_ATTRIB_ARRAY_INTEGER,
1551 * VERTEX_ATTRIB_ARRAY_LONG, VERTEX_ATTRIB_ARRAY_DIVISOR, or
1552 * VERTEX_ATTRIB_RELATIVE_OFFSET."
1553 *
1554 * and:
1555 *
1556 * "Add GetVertexArrayIndexediv in 'Get Command' for
1557 * VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
1558 * VERTEX_ATTRIB_BINDING,
1559 * VERTEX_ATTRIB_RELATIVE_OFFSET,
1560 * VERTEX_BINDING_OFFSET, and
1561 * VERTEX_BINDING_STRIDE states"
1562 *
1563 * The only parameter name common to both lists is
1564 * VERTEX_ATTRIB_RELATIVE_OFFSET. Also note that VERTEX_BINDING_BUFFER
1565 * and VERTEX_BINDING_DIVISOR are missing from both lists. It seems
1566 * pretty clear however that the intent is that it should be possible
1567 * to query all vertex attrib and binding states that can be set with
1568 * a DSA function.
1569 */
1570 switch (pname) {
1571 case GL_VERTEX_BINDING_OFFSET:
1572 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Offset;
1573 break;
1574 case GL_VERTEX_BINDING_STRIDE:
1575 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Stride;
1576 break;
1577 case GL_VERTEX_BINDING_DIVISOR:
1578 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].InstanceDivisor;
1579 break;
1580 case GL_VERTEX_BINDING_BUFFER:
1581 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].BufferObj->Name;
1582 break;
1583 default:
1584 params[0] = get_vertex_array_attrib(ctx, vao, index, pname,
1585 "glGetVertexArrayIndexediv");
1586 break;
1587 }
1588 }
1589
1590
1591 void GLAPIENTRY
1592 _mesa_GetVertexArrayIndexed64iv(GLuint vaobj, GLuint index,
1593 GLenum pname, GLint64 *params)
1594 {
1595 GET_CURRENT_CONTEXT(ctx);
1596 struct gl_vertex_array_object *vao;
1597
1598 /* The ARB_direct_state_access specification says:
1599 *
1600 * "An INVALID_OPERATION error is generated if <vaobj> is not
1601 * [compatibility profile: zero or] the name of an existing
1602 * vertex array object."
1603 */
1604 vao = _mesa_lookup_vao_err(ctx, vaobj, "glGetVertexArrayIndexed64iv");
1605 if (!vao)
1606 return;
1607
1608 /* The ARB_direct_state_access specification says:
1609 *
1610 * "For GetVertexArrayIndexed64iv, <pname> must be
1611 * VERTEX_BINDING_OFFSET."
1612 *
1613 * and:
1614 *
1615 * "An INVALID_ENUM error is generated if <pname> is not one of
1616 * the valid values listed above for the corresponding command."
1617 */
1618 if (pname != GL_VERTEX_BINDING_OFFSET) {
1619 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayIndexed64iv("
1620 "pname != GL_VERTEX_BINDING_OFFSET)");
1621 return;
1622 }
1623
1624 /* The ARB_direct_state_access specification says:
1625 *
1626 * "An INVALID_VALUE error is generated if <index> is greater than
1627 * or equal to the value of MAX_VERTEX_ATTRIBS."
1628 *
1629 * Since the index refers to a buffer binding in this case, the intended
1630 * limit must be MAX_VERTEX_ATTRIB_BINDINGS. Both limits are currently
1631 * required to be the same, so in practice this doesn't matter.
1632 */
1633 if (index >= ctx->Const.MaxVertexAttribBindings) {
1634 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexArrayIndexed64iv(index"
1635 "%d >= the value of GL_MAX_VERTEX_ATTRIB_BINDINGS (%d))",
1636 index, ctx->Const.MaxVertexAttribBindings);
1637 return;
1638 }
1639
1640 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Offset;
1641 }
1642
1643
1644 void GLAPIENTRY
1645 _mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
1646 GLsizei count, const GLvoid *ptr)
1647 {
1648 (void) count;
1649 _mesa_VertexPointer(size, type, stride, ptr);
1650 }
1651
1652
1653 void GLAPIENTRY
1654 _mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
1655 const GLvoid *ptr)
1656 {
1657 (void) count;
1658 _mesa_NormalPointer(type, stride, ptr);
1659 }
1660
1661
1662 void GLAPIENTRY
1663 _mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
1664 const GLvoid *ptr)
1665 {
1666 (void) count;
1667 _mesa_ColorPointer(size, type, stride, ptr);
1668 }
1669
1670
1671 void GLAPIENTRY
1672 _mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
1673 const GLvoid *ptr)
1674 {
1675 (void) count;
1676 _mesa_IndexPointer(type, stride, ptr);
1677 }
1678
1679
1680 void GLAPIENTRY
1681 _mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
1682 GLsizei count, const GLvoid *ptr)
1683 {
1684 (void) count;
1685 _mesa_TexCoordPointer(size, type, stride, ptr);
1686 }
1687
1688
1689 void GLAPIENTRY
1690 _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
1691 {
1692 (void) count;
1693 _mesa_EdgeFlagPointer(stride, ptr);
1694 }
1695
1696
1697 void GLAPIENTRY
1698 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
1699 {
1700 GET_CURRENT_CONTEXT(ctx);
1701 GLboolean tflag, cflag, nflag; /* enable/disable flags */
1702 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
1703 GLenum ctype = 0; /* color type */
1704 GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
1705 const GLint toffset = 0; /* always zero */
1706 GLint defstride; /* default stride */
1707 GLint c, f;
1708
1709 FLUSH_VERTICES(ctx, 0);
1710
1711 f = sizeof(GLfloat);
1712 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
1713
1714 if (stride < 0) {
1715 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
1716 return;
1717 }
1718
1719 switch (format) {
1720 case GL_V2F:
1721 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1722 tcomps = 0; ccomps = 0; vcomps = 2;
1723 voffset = 0;
1724 defstride = 2*f;
1725 break;
1726 case GL_V3F:
1727 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1728 tcomps = 0; ccomps = 0; vcomps = 3;
1729 voffset = 0;
1730 defstride = 3*f;
1731 break;
1732 case GL_C4UB_V2F:
1733 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1734 tcomps = 0; ccomps = 4; vcomps = 2;
1735 ctype = GL_UNSIGNED_BYTE;
1736 coffset = 0;
1737 voffset = c;
1738 defstride = c + 2*f;
1739 break;
1740 case GL_C4UB_V3F:
1741 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1742 tcomps = 0; ccomps = 4; vcomps = 3;
1743 ctype = GL_UNSIGNED_BYTE;
1744 coffset = 0;
1745 voffset = c;
1746 defstride = c + 3*f;
1747 break;
1748 case GL_C3F_V3F:
1749 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1750 tcomps = 0; ccomps = 3; vcomps = 3;
1751 ctype = GL_FLOAT;
1752 coffset = 0;
1753 voffset = 3*f;
1754 defstride = 6*f;
1755 break;
1756 case GL_N3F_V3F:
1757 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
1758 tcomps = 0; ccomps = 0; vcomps = 3;
1759 noffset = 0;
1760 voffset = 3*f;
1761 defstride = 6*f;
1762 break;
1763 case GL_C4F_N3F_V3F:
1764 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
1765 tcomps = 0; ccomps = 4; vcomps = 3;
1766 ctype = GL_FLOAT;
1767 coffset = 0;
1768 noffset = 4*f;
1769 voffset = 7*f;
1770 defstride = 10*f;
1771 break;
1772 case GL_T2F_V3F:
1773 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1774 tcomps = 2; ccomps = 0; vcomps = 3;
1775 voffset = 2*f;
1776 defstride = 5*f;
1777 break;
1778 case GL_T4F_V4F:
1779 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1780 tcomps = 4; ccomps = 0; vcomps = 4;
1781 voffset = 4*f;
1782 defstride = 8*f;
1783 break;
1784 case GL_T2F_C4UB_V3F:
1785 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1786 tcomps = 2; ccomps = 4; vcomps = 3;
1787 ctype = GL_UNSIGNED_BYTE;
1788 coffset = 2*f;
1789 voffset = c+2*f;
1790 defstride = c+5*f;
1791 break;
1792 case GL_T2F_C3F_V3F:
1793 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1794 tcomps = 2; ccomps = 3; vcomps = 3;
1795 ctype = GL_FLOAT;
1796 coffset = 2*f;
1797 voffset = 5*f;
1798 defstride = 8*f;
1799 break;
1800 case GL_T2F_N3F_V3F:
1801 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
1802 tcomps = 2; ccomps = 0; vcomps = 3;
1803 noffset = 2*f;
1804 voffset = 5*f;
1805 defstride = 8*f;
1806 break;
1807 case GL_T2F_C4F_N3F_V3F:
1808 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1809 tcomps = 2; ccomps = 4; vcomps = 3;
1810 ctype = GL_FLOAT;
1811 coffset = 2*f;
1812 noffset = 6*f;
1813 voffset = 9*f;
1814 defstride = 12*f;
1815 break;
1816 case GL_T4F_C4F_N3F_V4F:
1817 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1818 tcomps = 4; ccomps = 4; vcomps = 4;
1819 ctype = GL_FLOAT;
1820 coffset = 4*f;
1821 noffset = 8*f;
1822 voffset = 11*f;
1823 defstride = 15*f;
1824 break;
1825 default:
1826 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
1827 return;
1828 }
1829
1830 if (stride==0) {
1831 stride = defstride;
1832 }
1833
1834 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
1835 _mesa_DisableClientState( GL_INDEX_ARRAY );
1836 /* XXX also disable secondary color and generic arrays? */
1837
1838 /* Texcoords */
1839 if (tflag) {
1840 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
1841 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
1842 (GLubyte *) pointer + toffset );
1843 }
1844 else {
1845 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
1846 }
1847
1848 /* Color */
1849 if (cflag) {
1850 _mesa_EnableClientState( GL_COLOR_ARRAY );
1851 _mesa_ColorPointer( ccomps, ctype, stride,
1852 (GLubyte *) pointer + coffset );
1853 }
1854 else {
1855 _mesa_DisableClientState( GL_COLOR_ARRAY );
1856 }
1857
1858
1859 /* Normals */
1860 if (nflag) {
1861 _mesa_EnableClientState( GL_NORMAL_ARRAY );
1862 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset );
1863 }
1864 else {
1865 _mesa_DisableClientState( GL_NORMAL_ARRAY );
1866 }
1867
1868 /* Vertices */
1869 _mesa_EnableClientState( GL_VERTEX_ARRAY );
1870 _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
1871 (GLubyte *) pointer + voffset );
1872 }
1873
1874
1875 void GLAPIENTRY
1876 _mesa_LockArraysEXT(GLint first, GLsizei count)
1877 {
1878 GET_CURRENT_CONTEXT(ctx);
1879
1880 FLUSH_VERTICES(ctx, 0);
1881
1882 if (MESA_VERBOSE & VERBOSE_API)
1883 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
1884
1885 if (first < 0) {
1886 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" );
1887 return;
1888 }
1889 if (count <= 0) {
1890 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" );
1891 return;
1892 }
1893 if (ctx->Array.LockCount != 0) {
1894 _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" );
1895 return;
1896 }
1897
1898 ctx->Array.LockFirst = first;
1899 ctx->Array.LockCount = count;
1900
1901 ctx->NewState |= _NEW_ARRAY;
1902 }
1903
1904
1905 void GLAPIENTRY
1906 _mesa_UnlockArraysEXT( void )
1907 {
1908 GET_CURRENT_CONTEXT(ctx);
1909
1910 FLUSH_VERTICES(ctx, 0);
1911
1912 if (MESA_VERBOSE & VERBOSE_API)
1913 _mesa_debug(ctx, "glUnlockArrays\n");
1914
1915 if (ctx->Array.LockCount == 0) {
1916 _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" );
1917 return;
1918 }
1919
1920 ctx->Array.LockFirst = 0;
1921 ctx->Array.LockCount = 0;
1922 ctx->NewState |= _NEW_ARRAY;
1923 }
1924
1925
1926 /* GL_IBM_multimode_draw_arrays */
1927 void GLAPIENTRY
1928 _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
1929 const GLsizei * count,
1930 GLsizei primcount, GLint modestride )
1931 {
1932 GET_CURRENT_CONTEXT(ctx);
1933 GLint i;
1934
1935 FLUSH_VERTICES(ctx, 0);
1936
1937 for ( i = 0 ; i < primcount ; i++ ) {
1938 if ( count[i] > 0 ) {
1939 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1940 CALL_DrawArrays(ctx->CurrentServerDispatch, ( m, first[i], count[i] ));
1941 }
1942 }
1943 }
1944
1945
1946 /* GL_IBM_multimode_draw_arrays */
1947 void GLAPIENTRY
1948 _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
1949 GLenum type, const GLvoid * const * indices,
1950 GLsizei primcount, GLint modestride )
1951 {
1952 GET_CURRENT_CONTEXT(ctx);
1953 GLint i;
1954
1955 FLUSH_VERTICES(ctx, 0);
1956
1957 /* XXX not sure about ARB_vertex_buffer_object handling here */
1958
1959 for ( i = 0 ; i < primcount ; i++ ) {
1960 if ( count[i] > 0 ) {
1961 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1962 CALL_DrawElements(ctx->CurrentServerDispatch, ( m, count[i], type,
1963 indices[i] ));
1964 }
1965 }
1966 }
1967
1968
1969 static void
1970 primitive_restart_index(struct gl_context *ctx, GLuint index)
1971 {
1972 if (ctx->Array.RestartIndex != index) {
1973 FLUSH_VERTICES(ctx, 0);
1974 ctx->Array.RestartIndex = index;
1975 }
1976 }
1977
1978
1979 /**
1980 * GL_NV_primitive_restart and GL 3.1
1981 */
1982 void GLAPIENTRY
1983 _mesa_PrimitiveRestartIndex_no_error(GLuint index)
1984 {
1985 GET_CURRENT_CONTEXT(ctx);
1986 primitive_restart_index(ctx, index);
1987 }
1988
1989
1990 void GLAPIENTRY
1991 _mesa_PrimitiveRestartIndex(GLuint index)
1992 {
1993 GET_CURRENT_CONTEXT(ctx);
1994
1995 if (!ctx->Extensions.NV_primitive_restart && ctx->Version < 31) {
1996 _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()");
1997 return;
1998 }
1999
2000 primitive_restart_index(ctx, index);
2001 }
2002
2003
2004 void GLAPIENTRY
2005 _mesa_VertexAttribDivisor_no_error(GLuint index, GLuint divisor)
2006 {
2007 GET_CURRENT_CONTEXT(ctx);
2008
2009 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index);
2010 struct gl_vertex_array_object * const vao = ctx->Array.VAO;
2011
2012 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
2013
2014 /* The ARB_vertex_attrib_binding spec says:
2015 *
2016 * "The command
2017 *
2018 * void VertexAttribDivisor(uint index, uint divisor);
2019 *
2020 * is equivalent to (assuming no errors are generated):
2021 *
2022 * VertexAttribBinding(index, index);
2023 * VertexBindingDivisor(index, divisor);"
2024 */
2025 vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
2026 vertex_binding_divisor(ctx, vao, genericIndex, divisor);
2027 }
2028
2029
2030 /**
2031 * See GL_ARB_instanced_arrays.
2032 * Note that the instance divisor only applies to generic arrays, not
2033 * the legacy vertex arrays.
2034 */
2035 void GLAPIENTRY
2036 _mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
2037 {
2038 GET_CURRENT_CONTEXT(ctx);
2039
2040 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index);
2041 struct gl_vertex_array_object * const vao = ctx->Array.VAO;
2042
2043 if (!ctx->Extensions.ARB_instanced_arrays) {
2044 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
2045 return;
2046 }
2047
2048 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2049 _mesa_error(ctx, GL_INVALID_VALUE,
2050 "glVertexAttribDivisor(index = %u)", index);
2051 return;
2052 }
2053
2054 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
2055
2056 /* The ARB_vertex_attrib_binding spec says:
2057 *
2058 * "The command
2059 *
2060 * void VertexAttribDivisor(uint index, uint divisor);
2061 *
2062 * is equivalent to (assuming no errors are generated):
2063 *
2064 * VertexAttribBinding(index, index);
2065 * VertexBindingDivisor(index, divisor);"
2066 */
2067 vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
2068 vertex_binding_divisor(ctx, vao, genericIndex, divisor);
2069 }
2070
2071
2072 static ALWAYS_INLINE void
2073 vertex_array_vertex_buffer(struct gl_context *ctx,
2074 struct gl_vertex_array_object *vao,
2075 GLuint bindingIndex, GLuint buffer, GLintptr offset,
2076 GLsizei stride, bool no_error, const char *func)
2077 {
2078 struct gl_buffer_object *vbo;
2079 if (buffer ==
2080 vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj->Name) {
2081 vbo = vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj;
2082 } else if (buffer != 0) {
2083 vbo = _mesa_lookup_bufferobj(ctx, buffer);
2084
2085 if (!no_error && !vbo && _mesa_is_gles31(ctx)) {
2086 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", func);
2087 return;
2088 }
2089 /* From the GL_ARB_vertex_attrib_array spec:
2090 *
2091 * "[Core profile only:]
2092 * An INVALID_OPERATION error is generated if buffer is not zero or a
2093 * name returned from a previous call to GenBuffers, or if such a name
2094 * has since been deleted with DeleteBuffers.
2095 *
2096 * Otherwise, we fall back to the same compat profile behavior as other
2097 * object references (automatically gen it).
2098 */
2099 if (!_mesa_handle_bind_buffer_gen(ctx, buffer, &vbo, func))
2100 return;
2101 } else {
2102 /* The ARB_vertex_attrib_binding spec says:
2103 *
2104 * "If <buffer> is zero, any buffer object attached to this
2105 * bindpoint is detached."
2106 */
2107 vbo = ctx->Shared->NullBufferObj;
2108 }
2109
2110 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex),
2111 vbo, offset, stride);
2112 }
2113
2114
2115 /**
2116 * GL_ARB_vertex_attrib_binding
2117 */
2118 static void
2119 vertex_array_vertex_buffer_err(struct gl_context *ctx,
2120 struct gl_vertex_array_object *vao,
2121 GLuint bindingIndex, GLuint buffer,
2122 GLintptr offset, GLsizei stride,
2123 const char *func)
2124 {
2125 ASSERT_OUTSIDE_BEGIN_END(ctx);
2126
2127 /* The ARB_vertex_attrib_binding spec says:
2128 *
2129 * "An INVALID_VALUE error is generated if <bindingindex> is greater than
2130 * the value of MAX_VERTEX_ATTRIB_BINDINGS."
2131 */
2132 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2133 _mesa_error(ctx, GL_INVALID_VALUE,
2134 "%s(bindingindex=%u > "
2135 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2136 func, bindingIndex);
2137 return;
2138 }
2139
2140 /* The ARB_vertex_attrib_binding spec says:
2141 *
2142 * "The error INVALID_VALUE is generated if <stride> or <offset>
2143 * are negative."
2144 */
2145 if (offset < 0) {
2146 _mesa_error(ctx, GL_INVALID_VALUE,
2147 "%s(offset=%" PRId64 " < 0)",
2148 func, (int64_t) offset);
2149 return;
2150 }
2151
2152 if (stride < 0) {
2153 _mesa_error(ctx, GL_INVALID_VALUE,
2154 "%s(stride=%d < 0)", func, stride);
2155 return;
2156 }
2157
2158 if (((ctx->API == API_OPENGL_CORE && ctx->Version >= 44) || _mesa_is_gles31(ctx)) &&
2159 stride > ctx->Const.MaxVertexAttribStride) {
2160 _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > "
2161 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride);
2162 return;
2163 }
2164
2165 vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset,
2166 stride, false, func);
2167 }
2168
2169
2170 void GLAPIENTRY
2171 _mesa_BindVertexBuffer_no_error(GLuint bindingIndex, GLuint buffer,
2172 GLintptr offset, GLsizei stride)
2173 {
2174 GET_CURRENT_CONTEXT(ctx);
2175 vertex_array_vertex_buffer(ctx, ctx->Array.VAO, bindingIndex,
2176 buffer, offset, stride, true,
2177 "glBindVertexBuffer");
2178 }
2179
2180
2181 void GLAPIENTRY
2182 _mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset,
2183 GLsizei stride)
2184 {
2185 GET_CURRENT_CONTEXT(ctx);
2186
2187 /* The ARB_vertex_attrib_binding spec says:
2188 *
2189 * "An INVALID_OPERATION error is generated if no vertex array object
2190 * is bound."
2191 */
2192 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2193 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2194 _mesa_error(ctx, GL_INVALID_OPERATION,
2195 "glBindVertexBuffer(No array object bound)");
2196 return;
2197 }
2198
2199 vertex_array_vertex_buffer_err(ctx, ctx->Array.VAO, bindingIndex,
2200 buffer, offset, stride,
2201 "glBindVertexBuffer");
2202 }
2203
2204
2205 void GLAPIENTRY
2206 _mesa_VertexArrayVertexBuffer_no_error(GLuint vaobj, GLuint bindingIndex,
2207 GLuint buffer, GLintptr offset,
2208 GLsizei stride)
2209 {
2210 GET_CURRENT_CONTEXT(ctx);
2211
2212 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2213 vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset,
2214 stride, true, "glVertexArrayVertexBuffer");
2215 }
2216
2217
2218 void GLAPIENTRY
2219 _mesa_VertexArrayVertexBuffer(GLuint vaobj, GLuint bindingIndex, GLuint buffer,
2220 GLintptr offset, GLsizei stride)
2221 {
2222 GET_CURRENT_CONTEXT(ctx);
2223 struct gl_vertex_array_object *vao;
2224
2225 /* The ARB_direct_state_access specification says:
2226 *
2227 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
2228 * if <vaobj> is not [compatibility profile: zero or] the name of an
2229 * existing vertex array object."
2230 */
2231 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffer");
2232 if (!vao)
2233 return;
2234
2235 vertex_array_vertex_buffer_err(ctx, vao, bindingIndex, buffer, offset,
2236 stride, "glVertexArrayVertexBuffer");
2237 }
2238
2239
2240 static ALWAYS_INLINE void
2241 vertex_array_vertex_buffers(struct gl_context *ctx,
2242 struct gl_vertex_array_object *vao,
2243 GLuint first, GLsizei count, const GLuint *buffers,
2244 const GLintptr *offsets, const GLsizei *strides,
2245 bool no_error, const char *func)
2246 {
2247 GLint i;
2248
2249 if (!buffers) {
2250 /**
2251 * The ARB_multi_bind spec says:
2252 *
2253 * "If <buffers> is NULL, each affected vertex buffer binding point
2254 * from <first> through <first>+<count>-1 will be reset to have no
2255 * bound buffer object. In this case, the offsets and strides
2256 * associated with the binding points are set to default values,
2257 * ignoring <offsets> and <strides>."
2258 */
2259 struct gl_buffer_object *vbo = ctx->Shared->NullBufferObj;
2260
2261 for (i = 0; i < count; i++)
2262 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
2263 vbo, 0, 16);
2264
2265 return;
2266 }
2267
2268 /* Note that the error semantics for multi-bind commands differ from
2269 * those of other GL commands.
2270 *
2271 * The Issues section in the ARB_multi_bind spec says:
2272 *
2273 * "(11) Typically, OpenGL specifies that if an error is generated by
2274 * a command, that command has no effect. This is somewhat
2275 * unfortunate for multi-bind commands, because it would require
2276 * a first pass to scan the entire list of bound objects for
2277 * errors and then a second pass to actually perform the
2278 * bindings. Should we have different error semantics?
2279 *
2280 * RESOLVED: Yes. In this specification, when the parameters for
2281 * one of the <count> binding points are invalid, that binding
2282 * point is not updated and an error will be generated. However,
2283 * other binding points in the same command will be updated if
2284 * their parameters are valid and no other error occurs."
2285 */
2286
2287 _mesa_HashLockMutex(ctx->Shared->BufferObjects);
2288
2289 for (i = 0; i < count; i++) {
2290 struct gl_buffer_object *vbo;
2291
2292 if (!no_error) {
2293 /* The ARB_multi_bind spec says:
2294 *
2295 * "An INVALID_VALUE error is generated if any value in
2296 * <offsets> or <strides> is negative (per binding)."
2297 */
2298 if (offsets[i] < 0) {
2299 _mesa_error(ctx, GL_INVALID_VALUE,
2300 "%s(offsets[%u]=%" PRId64 " < 0)",
2301 func, i, (int64_t) offsets[i]);
2302 continue;
2303 }
2304
2305 if (strides[i] < 0) {
2306 _mesa_error(ctx, GL_INVALID_VALUE,
2307 "%s(strides[%u]=%d < 0)",
2308 func, i, strides[i]);
2309 continue;
2310 }
2311
2312 if (ctx->API == API_OPENGL_CORE && ctx->Version >= 44 &&
2313 strides[i] > ctx->Const.MaxVertexAttribStride) {
2314 _mesa_error(ctx, GL_INVALID_VALUE,
2315 "%s(strides[%u]=%d > "
2316 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, i, strides[i]);
2317 continue;
2318 }
2319 }
2320
2321 if (buffers[i]) {
2322 struct gl_vertex_buffer_binding *binding =
2323 &vao->BufferBinding[VERT_ATTRIB_GENERIC(first + i)];
2324
2325 if (buffers[i] == binding->BufferObj->Name)
2326 vbo = binding->BufferObj;
2327 else
2328 vbo = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, func);
2329
2330 if (!vbo)
2331 continue;
2332 } else {
2333 vbo = ctx->Shared->NullBufferObj;
2334 }
2335
2336 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
2337 vbo, offsets[i], strides[i]);
2338 }
2339
2340 _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
2341 }
2342
2343
2344 static void
2345 vertex_array_vertex_buffers_err(struct gl_context *ctx,
2346 struct gl_vertex_array_object *vao,
2347 GLuint first, GLsizei count,
2348 const GLuint *buffers, const GLintptr *offsets,
2349 const GLsizei *strides, const char *func)
2350 {
2351 ASSERT_OUTSIDE_BEGIN_END(ctx);
2352
2353 /* The ARB_multi_bind spec says:
2354 *
2355 * "An INVALID_OPERATION error is generated if <first> + <count>
2356 * is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS."
2357 */
2358 if (first + count > ctx->Const.MaxVertexAttribBindings) {
2359 _mesa_error(ctx, GL_INVALID_OPERATION,
2360 "%s(first=%u + count=%d > the value of "
2361 "GL_MAX_VERTEX_ATTRIB_BINDINGS=%u)",
2362 func, first, count, ctx->Const.MaxVertexAttribBindings);
2363 return;
2364 }
2365
2366 vertex_array_vertex_buffers(ctx, vao, first, count, buffers, offsets,
2367 strides, false, func);
2368 }
2369
2370
2371 void GLAPIENTRY
2372 _mesa_BindVertexBuffers_no_error(GLuint first, GLsizei count,
2373 const GLuint *buffers, const GLintptr *offsets,
2374 const GLsizei *strides)
2375 {
2376 GET_CURRENT_CONTEXT(ctx);
2377
2378 vertex_array_vertex_buffers(ctx, ctx->Array.VAO, first, count,
2379 buffers, offsets, strides, true,
2380 "glBindVertexBuffers");
2381 }
2382
2383
2384 void GLAPIENTRY
2385 _mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers,
2386 const GLintptr *offsets, const GLsizei *strides)
2387 {
2388 GET_CURRENT_CONTEXT(ctx);
2389
2390 /* The ARB_vertex_attrib_binding spec says:
2391 *
2392 * "An INVALID_OPERATION error is generated if no
2393 * vertex array object is bound."
2394 */
2395 if (ctx->API == API_OPENGL_CORE &&
2396 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2397 _mesa_error(ctx, GL_INVALID_OPERATION,
2398 "glBindVertexBuffers(No array object bound)");
2399 return;
2400 }
2401
2402 vertex_array_vertex_buffers_err(ctx, ctx->Array.VAO, first, count,
2403 buffers, offsets, strides,
2404 "glBindVertexBuffers");
2405 }
2406
2407
2408 void GLAPIENTRY
2409 _mesa_VertexArrayVertexBuffers_no_error(GLuint vaobj, GLuint first,
2410 GLsizei count, const GLuint *buffers,
2411 const GLintptr *offsets,
2412 const GLsizei *strides)
2413 {
2414 GET_CURRENT_CONTEXT(ctx);
2415
2416 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2417 vertex_array_vertex_buffers(ctx, vao, first, count,
2418 buffers, offsets, strides, true,
2419 "glVertexArrayVertexBuffers");
2420 }
2421
2422
2423 void GLAPIENTRY
2424 _mesa_VertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count,
2425 const GLuint *buffers,
2426 const GLintptr *offsets, const GLsizei *strides)
2427 {
2428 GET_CURRENT_CONTEXT(ctx);
2429 struct gl_vertex_array_object *vao;
2430
2431 /* The ARB_direct_state_access specification says:
2432 *
2433 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
2434 * if <vaobj> is not [compatibility profile: zero or] the name of an
2435 * existing vertex array object."
2436 */
2437 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffers");
2438 if (!vao)
2439 return;
2440
2441 vertex_array_vertex_buffers_err(ctx, vao, first, count,
2442 buffers, offsets, strides,
2443 "glVertexArrayVertexBuffers");
2444 }
2445
2446
2447 static void
2448 vertex_attrib_format(GLuint attribIndex, GLint size, GLenum type,
2449 GLboolean normalized, GLboolean integer,
2450 GLboolean doubles, GLbitfield legalTypes,
2451 GLsizei sizeMax, GLuint relativeOffset,
2452 const char *func)
2453 {
2454 GET_CURRENT_CONTEXT(ctx);
2455 ASSERT_OUTSIDE_BEGIN_END(ctx);
2456
2457 GLenum format = get_array_format(ctx, sizeMax, &size);
2458
2459 if (!_mesa_is_no_error_enabled(ctx)) {
2460 /* The ARB_vertex_attrib_binding spec says:
2461 *
2462 * "An INVALID_OPERATION error is generated under any of the
2463 * following conditions:
2464 * - if no vertex array object is currently bound (see section
2465 * 2.10);
2466 * - ..."
2467 *
2468 * This error condition only applies to VertexAttribFormat and
2469 * VertexAttribIFormat in the extension spec, but we assume that this
2470 * is an oversight. In the OpenGL 4.3 (Core Profile) spec, it applies
2471 * to all three functions.
2472 */
2473 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2474 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2475 _mesa_error(ctx, GL_INVALID_OPERATION,
2476 "%s(No array object bound)", func);
2477 return;
2478 }
2479
2480 /* The ARB_vertex_attrib_binding spec says:
2481 *
2482 * "The error INVALID_VALUE is generated if index is greater than or
2483 * equal to the value of MAX_VERTEX_ATTRIBS."
2484 */
2485 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2486 _mesa_error(ctx, GL_INVALID_VALUE,
2487 "%s(attribindex=%u > "
2488 "GL_MAX_VERTEX_ATTRIBS)",
2489 func, attribIndex);
2490 return;
2491 }
2492
2493 if (!validate_array_format(ctx, func, ctx->Array.VAO,
2494 VERT_ATTRIB_GENERIC(attribIndex),
2495 legalTypes, 1, sizeMax, size, type,
2496 normalized, integer, doubles, relativeOffset,
2497 format)) {
2498 return;
2499 }
2500 }
2501
2502 FLUSH_VERTICES(ctx, 0);
2503
2504 _mesa_update_array_format(ctx, ctx->Array.VAO,
2505 VERT_ATTRIB_GENERIC(attribIndex), size, type,
2506 format, normalized, integer, doubles,
2507 relativeOffset);
2508 }
2509
2510
2511 void GLAPIENTRY
2512 _mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type,
2513 GLboolean normalized, GLuint relativeOffset)
2514 {
2515 vertex_attrib_format(attribIndex, size, type, normalized,
2516 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
2517 BGRA_OR_4, relativeOffset,
2518 "glVertexAttribFormat");
2519 }
2520
2521
2522 void GLAPIENTRY
2523 _mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type,
2524 GLuint relativeOffset)
2525 {
2526 vertex_attrib_format(attribIndex, size, type, GL_FALSE,
2527 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK, 4,
2528 relativeOffset, "glVertexAttribIFormat");
2529 }
2530
2531
2532 void GLAPIENTRY
2533 _mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type,
2534 GLuint relativeOffset)
2535 {
2536 vertex_attrib_format(attribIndex, size, type, GL_FALSE, GL_FALSE,
2537 GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK, 4,
2538 relativeOffset, "glVertexAttribLFormat");
2539 }
2540
2541
2542 static void
2543 vertex_array_attrib_format(GLuint vaobj, GLuint attribIndex, GLint size,
2544 GLenum type, GLboolean normalized,
2545 GLboolean integer, GLboolean doubles,
2546 GLbitfield legalTypes, GLsizei sizeMax,
2547 GLuint relativeOffset, const char *func)
2548 {
2549 GET_CURRENT_CONTEXT(ctx);
2550 struct gl_vertex_array_object *vao;
2551
2552 ASSERT_OUTSIDE_BEGIN_END(ctx);
2553
2554 GLenum format = get_array_format(ctx, sizeMax, &size);
2555
2556 if (_mesa_is_no_error_enabled(ctx)) {
2557 vao = _mesa_lookup_vao(ctx, vaobj);
2558 if (!vao)
2559 return;
2560 } else {
2561 /* The ARB_direct_state_access spec says:
2562 *
2563 * "An INVALID_OPERATION error is generated by
2564 * VertexArrayAttrib*Format if <vaobj> is not [compatibility profile:
2565 * zero or] the name of an existing vertex array object."
2566 */
2567 vao = _mesa_lookup_vao_err(ctx, vaobj, func);
2568 if (!vao)
2569 return;
2570
2571 /* The ARB_vertex_attrib_binding spec says:
2572 *
2573 * "The error INVALID_VALUE is generated if index is greater than or
2574 * equal to the value of MAX_VERTEX_ATTRIBS."
2575 */
2576 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2577 _mesa_error(ctx, GL_INVALID_VALUE,
2578 "%s(attribindex=%u > GL_MAX_VERTEX_ATTRIBS)",
2579 func, attribIndex);
2580 return;
2581 }
2582
2583 if (!validate_array_format(ctx, func, vao,
2584 VERT_ATTRIB_GENERIC(attribIndex),
2585 legalTypes, 1, sizeMax, size, type,
2586 normalized, integer, doubles, relativeOffset,
2587 format)) {
2588 return;
2589 }
2590 }
2591
2592 FLUSH_VERTICES(ctx, 0);
2593
2594 _mesa_update_array_format(ctx, vao, VERT_ATTRIB_GENERIC(attribIndex), size,
2595 type, format, normalized, integer, doubles,
2596 relativeOffset);
2597 }
2598
2599
2600 void GLAPIENTRY
2601 _mesa_VertexArrayAttribFormat(GLuint vaobj, GLuint attribIndex, GLint size,
2602 GLenum type, GLboolean normalized,
2603 GLuint relativeOffset)
2604 {
2605 vertex_array_attrib_format(vaobj, attribIndex, size, type, normalized,
2606 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
2607 BGRA_OR_4, relativeOffset,
2608 "glVertexArrayAttribFormat");
2609 }
2610
2611
2612 void GLAPIENTRY
2613 _mesa_VertexArrayAttribIFormat(GLuint vaobj, GLuint attribIndex,
2614 GLint size, GLenum type,
2615 GLuint relativeOffset)
2616 {
2617 vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE,
2618 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK,
2619 4, relativeOffset,
2620 "glVertexArrayAttribIFormat");
2621 }
2622
2623
2624 void GLAPIENTRY
2625 _mesa_VertexArrayAttribLFormat(GLuint vaobj, GLuint attribIndex,
2626 GLint size, GLenum type,
2627 GLuint relativeOffset)
2628 {
2629 vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE,
2630 GL_FALSE, GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK,
2631 4, relativeOffset,
2632 "glVertexArrayAttribLFormat");
2633 }
2634
2635
2636 static void
2637 vertex_array_attrib_binding(struct gl_context *ctx,
2638 struct gl_vertex_array_object *vao,
2639 GLuint attribIndex, GLuint bindingIndex,
2640 const char *func)
2641 {
2642 ASSERT_OUTSIDE_BEGIN_END(ctx);
2643
2644 /* The ARB_vertex_attrib_binding spec says:
2645 *
2646 * "<attribindex> must be less than the value of MAX_VERTEX_ATTRIBS and
2647 * <bindingindex> must be less than the value of
2648 * MAX_VERTEX_ATTRIB_BINDINGS, otherwise the error INVALID_VALUE
2649 * is generated."
2650 */
2651 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2652 _mesa_error(ctx, GL_INVALID_VALUE,
2653 "%s(attribindex=%u >= "
2654 "GL_MAX_VERTEX_ATTRIBS)",
2655 func, attribIndex);
2656 return;
2657 }
2658
2659 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2660 _mesa_error(ctx, GL_INVALID_VALUE,
2661 "%s(bindingindex=%u >= "
2662 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2663 func, bindingIndex);
2664 return;
2665 }
2666
2667 assert(VERT_ATTRIB_GENERIC(attribIndex) < ARRAY_SIZE(vao->VertexAttrib));
2668
2669 vertex_attrib_binding(ctx, vao,
2670 VERT_ATTRIB_GENERIC(attribIndex),
2671 VERT_ATTRIB_GENERIC(bindingIndex));
2672 }
2673
2674
2675 void GLAPIENTRY
2676 _mesa_VertexAttribBinding_no_error(GLuint attribIndex, GLuint bindingIndex)
2677 {
2678 GET_CURRENT_CONTEXT(ctx);
2679 vertex_attrib_binding(ctx, ctx->Array.VAO,
2680 VERT_ATTRIB_GENERIC(attribIndex),
2681 VERT_ATTRIB_GENERIC(bindingIndex));
2682 }
2683
2684
2685 void GLAPIENTRY
2686 _mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
2687 {
2688 GET_CURRENT_CONTEXT(ctx);
2689
2690 /* The ARB_vertex_attrib_binding spec says:
2691 *
2692 * "An INVALID_OPERATION error is generated if no vertex array object
2693 * is bound."
2694 */
2695 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2696 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2697 _mesa_error(ctx, GL_INVALID_OPERATION,
2698 "glVertexAttribBinding(No array object bound)");
2699 return;
2700 }
2701
2702 vertex_array_attrib_binding(ctx, ctx->Array.VAO,
2703 attribIndex, bindingIndex,
2704 "glVertexAttribBinding");
2705 }
2706
2707
2708 void GLAPIENTRY
2709 _mesa_VertexArrayAttribBinding_no_error(GLuint vaobj, GLuint attribIndex,
2710 GLuint bindingIndex)
2711 {
2712 GET_CURRENT_CONTEXT(ctx);
2713
2714 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2715 vertex_attrib_binding(ctx, vao,
2716 VERT_ATTRIB_GENERIC(attribIndex),
2717 VERT_ATTRIB_GENERIC(bindingIndex));
2718 }
2719
2720
2721 void GLAPIENTRY
2722 _mesa_VertexArrayAttribBinding(GLuint vaobj, GLuint attribIndex, GLuint bindingIndex)
2723 {
2724 GET_CURRENT_CONTEXT(ctx);
2725 struct gl_vertex_array_object *vao;
2726
2727 /* The ARB_direct_state_access specification says:
2728 *
2729 * "An INVALID_OPERATION error is generated by VertexArrayAttribBinding
2730 * if <vaobj> is not [compatibility profile: zero or] the name of an
2731 * existing vertex array object."
2732 */
2733 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayAttribBinding");
2734 if (!vao)
2735 return;
2736
2737 vertex_array_attrib_binding(ctx, vao, attribIndex, bindingIndex,
2738 "glVertexArrayAttribBinding");
2739 }
2740
2741
2742 static void
2743 vertex_array_binding_divisor(struct gl_context *ctx,
2744 struct gl_vertex_array_object *vao,
2745 GLuint bindingIndex, GLuint divisor,
2746 const char *func)
2747 {
2748 ASSERT_OUTSIDE_BEGIN_END(ctx);
2749
2750 if (!ctx->Extensions.ARB_instanced_arrays) {
2751 _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", func);
2752 return;
2753 }
2754
2755 /* The ARB_vertex_attrib_binding spec says:
2756 *
2757 * "An INVALID_VALUE error is generated if <bindingindex> is greater
2758 * than or equal to the value of MAX_VERTEX_ATTRIB_BINDINGS."
2759 */
2760 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2761 _mesa_error(ctx, GL_INVALID_VALUE,
2762 "%s(bindingindex=%u > "
2763 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2764 func, bindingIndex);
2765 return;
2766 }
2767
2768 vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2769 }
2770
2771
2772 void GLAPIENTRY
2773 _mesa_VertexBindingDivisor_no_error(GLuint bindingIndex, GLuint divisor)
2774 {
2775 GET_CURRENT_CONTEXT(ctx);
2776 vertex_binding_divisor(ctx, ctx->Array.VAO,
2777 VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2778 }
2779
2780
2781 void GLAPIENTRY
2782 _mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
2783 {
2784 GET_CURRENT_CONTEXT(ctx);
2785
2786 /* The ARB_vertex_attrib_binding spec says:
2787 *
2788 * "An INVALID_OPERATION error is generated if no vertex array object
2789 * is bound."
2790 */
2791 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2792 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2793 _mesa_error(ctx, GL_INVALID_OPERATION,
2794 "glVertexBindingDivisor(No array object bound)");
2795 return;
2796 }
2797
2798 vertex_array_binding_divisor(ctx, ctx->Array.VAO,
2799 bindingIndex, divisor,
2800 "glVertexBindingDivisor");
2801 }
2802
2803
2804 void GLAPIENTRY
2805 _mesa_VertexArrayBindingDivisor_no_error(GLuint vaobj, GLuint bindingIndex,
2806 GLuint divisor)
2807 {
2808 GET_CURRENT_CONTEXT(ctx);
2809
2810 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2811 vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2812 }
2813
2814
2815 void GLAPIENTRY
2816 _mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex,
2817 GLuint divisor)
2818 {
2819 struct gl_vertex_array_object *vao;
2820 GET_CURRENT_CONTEXT(ctx);
2821
2822 /* The ARB_direct_state_access specification says:
2823 *
2824 * "An INVALID_OPERATION error is generated by VertexArrayBindingDivisor
2825 * if <vaobj> is not [compatibility profile: zero or] the name of an
2826 * existing vertex array object."
2827 */
2828 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayBindingDivisor");
2829 if (!vao)
2830 return;
2831
2832 vertex_array_binding_divisor(ctx, vao, bindingIndex, divisor,
2833 "glVertexArrayBindingDivisor");
2834 }
2835
2836
2837 /**
2838 * Copy one vertex array to another.
2839 */
2840 void
2841 _mesa_copy_vertex_array(struct gl_context *ctx,
2842 struct gl_vertex_array *dst,
2843 struct gl_vertex_array *src)
2844 {
2845 dst->Size = src->Size;
2846 dst->Type = src->Type;
2847 dst->Format = src->Format;
2848 dst->StrideB = src->StrideB;
2849 dst->Ptr = src->Ptr;
2850 dst->Normalized = src->Normalized;
2851 dst->Integer = src->Integer;
2852 dst->Doubles = src->Doubles;
2853 dst->InstanceDivisor = src->InstanceDivisor;
2854 dst->_ElementSize = src->_ElementSize;
2855 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
2856 }
2857
2858 void
2859 _mesa_copy_vertex_attrib_array(struct gl_context *ctx,
2860 struct gl_array_attributes *dst,
2861 const struct gl_array_attributes *src)
2862 {
2863 dst->Size = src->Size;
2864 dst->Type = src->Type;
2865 dst->Format = src->Format;
2866 dst->BufferBindingIndex = src->BufferBindingIndex;
2867 dst->RelativeOffset = src->RelativeOffset;
2868 dst->Format = src->Format;
2869 dst->Integer = src->Integer;
2870 dst->Doubles = src->Doubles;
2871 dst->Normalized = src->Normalized;
2872 dst->Ptr = src->Ptr;
2873 dst->Enabled = src->Enabled;
2874 dst->_ElementSize = src->_ElementSize;
2875 }
2876
2877 void
2878 _mesa_copy_vertex_buffer_binding(struct gl_context *ctx,
2879 struct gl_vertex_buffer_binding *dst,
2880 const struct gl_vertex_buffer_binding *src)
2881 {
2882 dst->Offset = src->Offset;
2883 dst->Stride = src->Stride;
2884 dst->InstanceDivisor = src->InstanceDivisor;
2885 dst->_BoundArrays = src->_BoundArrays;
2886
2887 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
2888 }
2889
2890 /**
2891 * Print current vertex object/array info. For debug.
2892 */
2893 void
2894 _mesa_print_arrays(struct gl_context *ctx)
2895 {
2896 const struct gl_vertex_array_object *vao = ctx->Array.VAO;
2897
2898 fprintf(stderr, "Array Object %u\n", vao->Name);
2899
2900 gl_vert_attrib i;
2901 for (i = 0; i < VERT_ATTRIB_MAX; ++i) {
2902 const struct gl_array_attributes *array = &vao->VertexAttrib[i];
2903 if (!array->Enabled)
2904 continue;
2905
2906 const struct gl_vertex_buffer_binding *binding =
2907 &vao->BufferBinding[array->BufferBindingIndex];
2908 const struct gl_buffer_object *bo = binding->BufferObj;
2909
2910 fprintf(stderr, " %s: Ptr=%p, Type=%s, Size=%d, ElemSize=%u, "
2911 "Stride=%d, Buffer=%u(Size %lu)\n",
2912 gl_vert_attrib_name((gl_vert_attrib)i),
2913 array->Ptr, _mesa_enum_to_string(array->Type), array->Size,
2914 array->_ElementSize, binding->Stride, bo->Name,
2915 (unsigned long) bo->Size);
2916 }
2917 }
2918
2919
2920 /**
2921 * Initialize vertex array state for given context.
2922 */
2923 void
2924 _mesa_init_varray(struct gl_context *ctx)
2925 {
2926 ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0);
2927 _mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO);
2928 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
2929
2930 ctx->Array.Objects = _mesa_NewHashTable();
2931 }
2932
2933
2934 /**
2935 * Callback for deleting an array object. Called by _mesa_HashDeleteAll().
2936 */
2937 static void
2938 delete_arrayobj_cb(GLuint id, void *data, void *userData)
2939 {
2940 struct gl_vertex_array_object *vao = (struct gl_vertex_array_object *) data;
2941 struct gl_context *ctx = (struct gl_context *) userData;
2942 _mesa_delete_vao(ctx, vao);
2943 }
2944
2945
2946 /**
2947 * Free vertex array state for given context.
2948 */
2949 void
2950 _mesa_free_varray_data(struct gl_context *ctx)
2951 {
2952 _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx);
2953 _mesa_DeleteHashTable(ctx->Array.Objects);
2954 }