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