90b874aa49a897799e1f49824da833613793965d
[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, bool flush_vertices)
1095 {
1096 assert(attrib < ARRAY_SIZE(vao->VertexAttrib));
1097
1098 if (!vao->VertexAttrib[attrib].Enabled) {
1099 /* was disabled, now being enabled */
1100 if (flush_vertices) {
1101 FLUSH_VERTICES(ctx, _NEW_ARRAY);
1102 }
1103
1104 vao->VertexAttrib[attrib].Enabled = GL_TRUE;
1105 const GLbitfield array_bit = VERT_BIT(attrib);
1106 vao->_Enabled |= array_bit;
1107 vao->NewArrays |= array_bit;
1108
1109 /* Update the map mode if needed */
1110 if (array_bit & (VERT_BIT_POS|VERT_BIT_GENERIC0))
1111 update_attribute_map_mode(ctx, vao);
1112 }
1113 }
1114
1115 static void
1116 enable_vertex_array_attrib(struct gl_context *ctx,
1117 struct gl_vertex_array_object *vao,
1118 GLuint index,
1119 const char *func)
1120 {
1121 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1122 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
1123 return;
1124 }
1125
1126 _mesa_enable_vertex_array_attrib(ctx, vao,
1127 VERT_ATTRIB_GENERIC(index), true);
1128 }
1129
1130
1131 void GLAPIENTRY
1132 _mesa_EnableVertexAttribArray(GLuint index)
1133 {
1134 GET_CURRENT_CONTEXT(ctx);
1135 enable_vertex_array_attrib(ctx, ctx->Array.VAO, index,
1136 "glEnableVertexAttribArray");
1137 }
1138
1139
1140 void GLAPIENTRY
1141 _mesa_EnableVertexAttribArray_no_error(GLuint index)
1142 {
1143 GET_CURRENT_CONTEXT(ctx);
1144 _mesa_enable_vertex_array_attrib(ctx, ctx->Array.VAO,
1145 VERT_ATTRIB_GENERIC(index), true);
1146 }
1147
1148
1149 void GLAPIENTRY
1150 _mesa_EnableVertexArrayAttrib(GLuint vaobj, GLuint index)
1151 {
1152 GET_CURRENT_CONTEXT(ctx);
1153 struct gl_vertex_array_object *vao;
1154
1155 /* The ARB_direct_state_access specification says:
1156 *
1157 * "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib
1158 * and DisableVertexArrayAttrib if <vaobj> is not
1159 * [compatibility profile: zero or] the name of an existing vertex
1160 * array object."
1161 */
1162 vao = _mesa_lookup_vao_err(ctx, vaobj, "glEnableVertexArrayAttrib");
1163 if (!vao)
1164 return;
1165
1166 enable_vertex_array_attrib(ctx, vao, index, "glEnableVertexArrayAttrib");
1167 }
1168
1169
1170 void GLAPIENTRY
1171 _mesa_EnableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index)
1172 {
1173 GET_CURRENT_CONTEXT(ctx);
1174 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
1175 _mesa_enable_vertex_array_attrib(ctx, vao,
1176 VERT_ATTRIB_GENERIC(index), true);
1177 }
1178
1179
1180 void
1181 _mesa_disable_vertex_array_attrib(struct gl_context *ctx,
1182 struct gl_vertex_array_object *vao,
1183 gl_vert_attrib attrib, bool flush_vertices)
1184 {
1185 assert(attrib < ARRAY_SIZE(vao->VertexAttrib));
1186
1187 if (vao->VertexAttrib[attrib].Enabled) {
1188 /* was enabled, now being disabled */
1189 if (flush_vertices) {
1190 FLUSH_VERTICES(ctx, _NEW_ARRAY);
1191 }
1192
1193 vao->VertexAttrib[attrib].Enabled = GL_FALSE;
1194 const GLbitfield array_bit = VERT_BIT(attrib);
1195 vao->_Enabled &= ~array_bit;
1196 vao->NewArrays |= array_bit;
1197
1198 /* Update the map mode if needed */
1199 if (array_bit & (VERT_BIT_POS|VERT_BIT_GENERIC0))
1200 update_attribute_map_mode(ctx, vao);
1201 }
1202 }
1203
1204
1205 void GLAPIENTRY
1206 _mesa_DisableVertexAttribArray(GLuint index)
1207 {
1208 GET_CURRENT_CONTEXT(ctx);
1209
1210 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1211 _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexAttribArray(index)");
1212 return;
1213 }
1214
1215 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1216 _mesa_disable_vertex_array_attrib(ctx, ctx->Array.VAO, attrib, true);
1217 }
1218
1219
1220 void GLAPIENTRY
1221 _mesa_DisableVertexAttribArray_no_error(GLuint index)
1222 {
1223 GET_CURRENT_CONTEXT(ctx);
1224 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1225 _mesa_disable_vertex_array_attrib(ctx, ctx->Array.VAO, attrib, true);
1226 }
1227
1228
1229 void GLAPIENTRY
1230 _mesa_DisableVertexArrayAttrib(GLuint vaobj, GLuint index)
1231 {
1232 GET_CURRENT_CONTEXT(ctx);
1233 struct gl_vertex_array_object *vao;
1234
1235 /* The ARB_direct_state_access specification says:
1236 *
1237 * "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib
1238 * and DisableVertexArrayAttrib if <vaobj> is not
1239 * [compatibility profile: zero or] the name of an existing vertex
1240 * array object."
1241 */
1242 vao = _mesa_lookup_vao_err(ctx, vaobj, "glDisableVertexArrayAttrib");
1243 if (!vao)
1244 return;
1245
1246 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1247 _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexArrayAttrib(index)");
1248 return;
1249 }
1250
1251 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1252 _mesa_disable_vertex_array_attrib(ctx, vao, attrib, true);
1253 }
1254
1255
1256 void GLAPIENTRY
1257 _mesa_DisableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index)
1258 {
1259 GET_CURRENT_CONTEXT(ctx);
1260 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
1261 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1262 _mesa_disable_vertex_array_attrib(ctx, vao, attrib, true);
1263 }
1264
1265
1266 /**
1267 * Return info for a vertex attribute array (no alias with legacy
1268 * vertex attributes (pos, normal, color, etc)). This function does
1269 * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query.
1270 */
1271 static GLuint
1272 get_vertex_array_attrib(struct gl_context *ctx,
1273 const struct gl_vertex_array_object *vao,
1274 GLuint index, GLenum pname,
1275 const char *caller)
1276 {
1277 const struct gl_array_attributes *array;
1278
1279 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1280 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index);
1281 return 0;
1282 }
1283
1284 assert(VERT_ATTRIB_GENERIC(index) < ARRAY_SIZE(vao->VertexAttrib));
1285
1286 array = &vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)];
1287
1288 switch (pname) {
1289 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
1290 return array->Enabled;
1291 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
1292 return (array->Format == GL_BGRA) ? GL_BGRA : array->Size;
1293 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
1294 return array->Stride;
1295 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
1296 return array->Type;
1297 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
1298 return array->Normalized;
1299 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
1300 return vao->BufferBinding[array->BufferBindingIndex].BufferObj->Name;
1301 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
1302 if ((_mesa_is_desktop_gl(ctx)
1303 && (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))
1304 || _mesa_is_gles3(ctx)) {
1305 return array->Integer;
1306 }
1307 goto error;
1308 case GL_VERTEX_ATTRIB_ARRAY_LONG:
1309 if (_mesa_is_desktop_gl(ctx)) {
1310 return array->Doubles;
1311 }
1312 goto error;
1313 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB:
1314 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_instanced_arrays)
1315 || _mesa_is_gles3(ctx)) {
1316 return vao->BufferBinding[array->BufferBindingIndex].InstanceDivisor;
1317 }
1318 goto error;
1319 case GL_VERTEX_ATTRIB_BINDING:
1320 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
1321 return array->BufferBindingIndex - VERT_ATTRIB_GENERIC0;
1322 }
1323 goto error;
1324 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
1325 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
1326 return array->RelativeOffset;
1327 }
1328 goto error;
1329 default:
1330 ; /* fall-through */
1331 }
1332
1333 error:
1334 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname);
1335 return 0;
1336 }
1337
1338
1339 static const GLfloat *
1340 get_current_attrib(struct gl_context *ctx, GLuint index, const char *function)
1341 {
1342 if (index == 0) {
1343 if (_mesa_attr_zero_aliases_vertex(ctx)) {
1344 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function);
1345 return NULL;
1346 }
1347 }
1348 else if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1349 _mesa_error(ctx, GL_INVALID_VALUE,
1350 "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function);
1351 return NULL;
1352 }
1353
1354 assert(VERT_ATTRIB_GENERIC(index) <
1355 ARRAY_SIZE(ctx->Array.VAO->VertexAttrib));
1356
1357 FLUSH_CURRENT(ctx, 0);
1358 return ctx->Current.Attrib[VERT_ATTRIB_GENERIC(index)];
1359 }
1360
1361 void GLAPIENTRY
1362 _mesa_GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
1363 {
1364 GET_CURRENT_CONTEXT(ctx);
1365
1366 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1367 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv");
1368 if (v != NULL) {
1369 COPY_4V(params, v);
1370 }
1371 }
1372 else {
1373 params[0] = (GLfloat) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1374 index, pname,
1375 "glGetVertexAttribfv");
1376 }
1377 }
1378
1379
1380 void GLAPIENTRY
1381 _mesa_GetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params)
1382 {
1383 GET_CURRENT_CONTEXT(ctx);
1384
1385 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1386 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv");
1387 if (v != NULL) {
1388 params[0] = (GLdouble) v[0];
1389 params[1] = (GLdouble) v[1];
1390 params[2] = (GLdouble) v[2];
1391 params[3] = (GLdouble) v[3];
1392 }
1393 }
1394 else {
1395 params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1396 index, pname,
1397 "glGetVertexAttribdv");
1398 }
1399 }
1400
1401 void GLAPIENTRY
1402 _mesa_GetVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params)
1403 {
1404 GET_CURRENT_CONTEXT(ctx);
1405
1406 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1407 const GLdouble *v =
1408 (const GLdouble *)get_current_attrib(ctx, index,
1409 "glGetVertexAttribLdv");
1410 if (v != NULL) {
1411 params[0] = v[0];
1412 params[1] = v[1];
1413 params[2] = v[2];
1414 params[3] = v[3];
1415 }
1416 }
1417 else {
1418 params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1419 index, pname,
1420 "glGetVertexAttribLdv");
1421 }
1422 }
1423
1424 void GLAPIENTRY
1425 _mesa_GetVertexAttribiv(GLuint index, GLenum pname, GLint *params)
1426 {
1427 GET_CURRENT_CONTEXT(ctx);
1428
1429 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1430 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv");
1431 if (v != NULL) {
1432 /* XXX should floats in[0,1] be scaled to full int range? */
1433 params[0] = (GLint) v[0];
1434 params[1] = (GLint) v[1];
1435 params[2] = (GLint) v[2];
1436 params[3] = (GLint) v[3];
1437 }
1438 }
1439 else {
1440 params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1441 index, pname,
1442 "glGetVertexAttribiv");
1443 }
1444 }
1445
1446 void GLAPIENTRY
1447 _mesa_GetVertexAttribLui64vARB(GLuint index, GLenum pname, GLuint64EXT *params)
1448 {
1449 GET_CURRENT_CONTEXT(ctx);
1450
1451 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1452 const GLuint64 *v =
1453 (const GLuint64 *)get_current_attrib(ctx, index,
1454 "glGetVertexAttribLui64vARB");
1455 if (v != NULL) {
1456 params[0] = v[0];
1457 params[1] = v[1];
1458 params[2] = v[2];
1459 params[3] = v[3];
1460 }
1461 }
1462 else {
1463 params[0] = (GLuint64) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1464 index, pname,
1465 "glGetVertexAttribLui64vARB");
1466 }
1467 }
1468
1469
1470 /** GL 3.0 */
1471 void GLAPIENTRY
1472 _mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
1473 {
1474 GET_CURRENT_CONTEXT(ctx);
1475
1476 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1477 const GLint *v = (const GLint *)
1478 get_current_attrib(ctx, index, "glGetVertexAttribIiv");
1479 if (v != NULL) {
1480 COPY_4V(params, v);
1481 }
1482 }
1483 else {
1484 params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1485 index, pname,
1486 "glGetVertexAttribIiv");
1487 }
1488 }
1489
1490
1491 /** GL 3.0 */
1492 void GLAPIENTRY
1493 _mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
1494 {
1495 GET_CURRENT_CONTEXT(ctx);
1496
1497 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1498 const GLuint *v = (const GLuint *)
1499 get_current_attrib(ctx, index, "glGetVertexAttribIuiv");
1500 if (v != NULL) {
1501 COPY_4V(params, v);
1502 }
1503 }
1504 else {
1505 params[0] = get_vertex_array_attrib(ctx, ctx->Array.VAO,
1506 index, pname,
1507 "glGetVertexAttribIuiv");
1508 }
1509 }
1510
1511
1512 void GLAPIENTRY
1513 _mesa_GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
1514 {
1515 GET_CURRENT_CONTEXT(ctx);
1516
1517 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1518 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
1519 return;
1520 }
1521
1522 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
1523 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
1524 return;
1525 }
1526
1527 assert(VERT_ATTRIB_GENERIC(index) <
1528 ARRAY_SIZE(ctx->Array.VAO->VertexAttrib));
1529
1530 *pointer = (GLvoid *)
1531 ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr;
1532 }
1533
1534
1535 /** ARB_direct_state_access */
1536 void GLAPIENTRY
1537 _mesa_GetVertexArrayIndexediv(GLuint vaobj, GLuint index,
1538 GLenum pname, GLint *params)
1539 {
1540 GET_CURRENT_CONTEXT(ctx);
1541 struct gl_vertex_array_object *vao;
1542
1543 /* The ARB_direct_state_access specification says:
1544 *
1545 * "An INVALID_OPERATION error is generated if <vaobj> is not
1546 * [compatibility profile: zero or] the name of an existing
1547 * vertex array object."
1548 */
1549 vao = _mesa_lookup_vao_err(ctx, vaobj, "glGetVertexArrayIndexediv");
1550 if (!vao)
1551 return;
1552
1553 /* The ARB_direct_state_access specification says:
1554 *
1555 * "For GetVertexArrayIndexediv, <pname> must be one of
1556 * VERTEX_ATTRIB_ARRAY_ENABLED, VERTEX_ATTRIB_ARRAY_SIZE,
1557 * VERTEX_ATTRIB_ARRAY_STRIDE, VERTEX_ATTRIB_ARRAY_TYPE,
1558 * VERTEX_ATTRIB_ARRAY_NORMALIZED, VERTEX_ATTRIB_ARRAY_INTEGER,
1559 * VERTEX_ATTRIB_ARRAY_LONG, VERTEX_ATTRIB_ARRAY_DIVISOR, or
1560 * VERTEX_ATTRIB_RELATIVE_OFFSET."
1561 *
1562 * and:
1563 *
1564 * "Add GetVertexArrayIndexediv in 'Get Command' for
1565 * VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
1566 * VERTEX_ATTRIB_BINDING,
1567 * VERTEX_ATTRIB_RELATIVE_OFFSET,
1568 * VERTEX_BINDING_OFFSET, and
1569 * VERTEX_BINDING_STRIDE states"
1570 *
1571 * The only parameter name common to both lists is
1572 * VERTEX_ATTRIB_RELATIVE_OFFSET. Also note that VERTEX_BINDING_BUFFER
1573 * and VERTEX_BINDING_DIVISOR are missing from both lists. It seems
1574 * pretty clear however that the intent is that it should be possible
1575 * to query all vertex attrib and binding states that can be set with
1576 * a DSA function.
1577 */
1578 switch (pname) {
1579 case GL_VERTEX_BINDING_OFFSET:
1580 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Offset;
1581 break;
1582 case GL_VERTEX_BINDING_STRIDE:
1583 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Stride;
1584 break;
1585 case GL_VERTEX_BINDING_DIVISOR:
1586 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].InstanceDivisor;
1587 break;
1588 case GL_VERTEX_BINDING_BUFFER:
1589 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].BufferObj->Name;
1590 break;
1591 default:
1592 params[0] = get_vertex_array_attrib(ctx, vao, index, pname,
1593 "glGetVertexArrayIndexediv");
1594 break;
1595 }
1596 }
1597
1598
1599 void GLAPIENTRY
1600 _mesa_GetVertexArrayIndexed64iv(GLuint vaobj, GLuint index,
1601 GLenum pname, GLint64 *params)
1602 {
1603 GET_CURRENT_CONTEXT(ctx);
1604 struct gl_vertex_array_object *vao;
1605
1606 /* The ARB_direct_state_access specification says:
1607 *
1608 * "An INVALID_OPERATION error is generated if <vaobj> is not
1609 * [compatibility profile: zero or] the name of an existing
1610 * vertex array object."
1611 */
1612 vao = _mesa_lookup_vao_err(ctx, vaobj, "glGetVertexArrayIndexed64iv");
1613 if (!vao)
1614 return;
1615
1616 /* The ARB_direct_state_access specification says:
1617 *
1618 * "For GetVertexArrayIndexed64iv, <pname> must be
1619 * VERTEX_BINDING_OFFSET."
1620 *
1621 * and:
1622 *
1623 * "An INVALID_ENUM error is generated if <pname> is not one of
1624 * the valid values listed above for the corresponding command."
1625 */
1626 if (pname != GL_VERTEX_BINDING_OFFSET) {
1627 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayIndexed64iv("
1628 "pname != GL_VERTEX_BINDING_OFFSET)");
1629 return;
1630 }
1631
1632 /* The ARB_direct_state_access specification says:
1633 *
1634 * "An INVALID_VALUE error is generated if <index> is greater than
1635 * or equal to the value of MAX_VERTEX_ATTRIBS."
1636 *
1637 * Since the index refers to a buffer binding in this case, the intended
1638 * limit must be MAX_VERTEX_ATTRIB_BINDINGS. Both limits are currently
1639 * required to be the same, so in practice this doesn't matter.
1640 */
1641 if (index >= ctx->Const.MaxVertexAttribBindings) {
1642 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexArrayIndexed64iv(index"
1643 "%d >= the value of GL_MAX_VERTEX_ATTRIB_BINDINGS (%d))",
1644 index, ctx->Const.MaxVertexAttribBindings);
1645 return;
1646 }
1647
1648 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Offset;
1649 }
1650
1651
1652 void GLAPIENTRY
1653 _mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
1654 GLsizei count, const GLvoid *ptr)
1655 {
1656 (void) count;
1657 _mesa_VertexPointer(size, type, stride, ptr);
1658 }
1659
1660
1661 void GLAPIENTRY
1662 _mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
1663 const GLvoid *ptr)
1664 {
1665 (void) count;
1666 _mesa_NormalPointer(type, stride, ptr);
1667 }
1668
1669
1670 void GLAPIENTRY
1671 _mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
1672 const GLvoid *ptr)
1673 {
1674 (void) count;
1675 _mesa_ColorPointer(size, type, stride, ptr);
1676 }
1677
1678
1679 void GLAPIENTRY
1680 _mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
1681 const GLvoid *ptr)
1682 {
1683 (void) count;
1684 _mesa_IndexPointer(type, stride, ptr);
1685 }
1686
1687
1688 void GLAPIENTRY
1689 _mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
1690 GLsizei count, const GLvoid *ptr)
1691 {
1692 (void) count;
1693 _mesa_TexCoordPointer(size, type, stride, ptr);
1694 }
1695
1696
1697 void GLAPIENTRY
1698 _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
1699 {
1700 (void) count;
1701 _mesa_EdgeFlagPointer(stride, ptr);
1702 }
1703
1704
1705 void GLAPIENTRY
1706 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
1707 {
1708 GET_CURRENT_CONTEXT(ctx);
1709 GLboolean tflag, cflag, nflag; /* enable/disable flags */
1710 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
1711 GLenum ctype = 0; /* color type */
1712 GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
1713 const GLint toffset = 0; /* always zero */
1714 GLint defstride; /* default stride */
1715 GLint c, f;
1716
1717 FLUSH_VERTICES(ctx, 0);
1718
1719 f = sizeof(GLfloat);
1720 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
1721
1722 if (stride < 0) {
1723 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
1724 return;
1725 }
1726
1727 switch (format) {
1728 case GL_V2F:
1729 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1730 tcomps = 0; ccomps = 0; vcomps = 2;
1731 voffset = 0;
1732 defstride = 2*f;
1733 break;
1734 case GL_V3F:
1735 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1736 tcomps = 0; ccomps = 0; vcomps = 3;
1737 voffset = 0;
1738 defstride = 3*f;
1739 break;
1740 case GL_C4UB_V2F:
1741 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1742 tcomps = 0; ccomps = 4; vcomps = 2;
1743 ctype = GL_UNSIGNED_BYTE;
1744 coffset = 0;
1745 voffset = c;
1746 defstride = c + 2*f;
1747 break;
1748 case GL_C4UB_V3F:
1749 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1750 tcomps = 0; ccomps = 4; vcomps = 3;
1751 ctype = GL_UNSIGNED_BYTE;
1752 coffset = 0;
1753 voffset = c;
1754 defstride = c + 3*f;
1755 break;
1756 case GL_C3F_V3F:
1757 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1758 tcomps = 0; ccomps = 3; vcomps = 3;
1759 ctype = GL_FLOAT;
1760 coffset = 0;
1761 voffset = 3*f;
1762 defstride = 6*f;
1763 break;
1764 case GL_N3F_V3F:
1765 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
1766 tcomps = 0; ccomps = 0; vcomps = 3;
1767 noffset = 0;
1768 voffset = 3*f;
1769 defstride = 6*f;
1770 break;
1771 case GL_C4F_N3F_V3F:
1772 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
1773 tcomps = 0; ccomps = 4; vcomps = 3;
1774 ctype = GL_FLOAT;
1775 coffset = 0;
1776 noffset = 4*f;
1777 voffset = 7*f;
1778 defstride = 10*f;
1779 break;
1780 case GL_T2F_V3F:
1781 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1782 tcomps = 2; ccomps = 0; vcomps = 3;
1783 voffset = 2*f;
1784 defstride = 5*f;
1785 break;
1786 case GL_T4F_V4F:
1787 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1788 tcomps = 4; ccomps = 0; vcomps = 4;
1789 voffset = 4*f;
1790 defstride = 8*f;
1791 break;
1792 case GL_T2F_C4UB_V3F:
1793 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1794 tcomps = 2; ccomps = 4; vcomps = 3;
1795 ctype = GL_UNSIGNED_BYTE;
1796 coffset = 2*f;
1797 voffset = c+2*f;
1798 defstride = c+5*f;
1799 break;
1800 case GL_T2F_C3F_V3F:
1801 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1802 tcomps = 2; ccomps = 3; vcomps = 3;
1803 ctype = GL_FLOAT;
1804 coffset = 2*f;
1805 voffset = 5*f;
1806 defstride = 8*f;
1807 break;
1808 case GL_T2F_N3F_V3F:
1809 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
1810 tcomps = 2; ccomps = 0; vcomps = 3;
1811 noffset = 2*f;
1812 voffset = 5*f;
1813 defstride = 8*f;
1814 break;
1815 case GL_T2F_C4F_N3F_V3F:
1816 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1817 tcomps = 2; ccomps = 4; vcomps = 3;
1818 ctype = GL_FLOAT;
1819 coffset = 2*f;
1820 noffset = 6*f;
1821 voffset = 9*f;
1822 defstride = 12*f;
1823 break;
1824 case GL_T4F_C4F_N3F_V4F:
1825 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1826 tcomps = 4; ccomps = 4; vcomps = 4;
1827 ctype = GL_FLOAT;
1828 coffset = 4*f;
1829 noffset = 8*f;
1830 voffset = 11*f;
1831 defstride = 15*f;
1832 break;
1833 default:
1834 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
1835 return;
1836 }
1837
1838 if (stride==0) {
1839 stride = defstride;
1840 }
1841
1842 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
1843 _mesa_DisableClientState( GL_INDEX_ARRAY );
1844 /* XXX also disable secondary color and generic arrays? */
1845
1846 /* Texcoords */
1847 if (tflag) {
1848 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
1849 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
1850 (GLubyte *) pointer + toffset );
1851 }
1852 else {
1853 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
1854 }
1855
1856 /* Color */
1857 if (cflag) {
1858 _mesa_EnableClientState( GL_COLOR_ARRAY );
1859 _mesa_ColorPointer( ccomps, ctype, stride,
1860 (GLubyte *) pointer + coffset );
1861 }
1862 else {
1863 _mesa_DisableClientState( GL_COLOR_ARRAY );
1864 }
1865
1866
1867 /* Normals */
1868 if (nflag) {
1869 _mesa_EnableClientState( GL_NORMAL_ARRAY );
1870 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset );
1871 }
1872 else {
1873 _mesa_DisableClientState( GL_NORMAL_ARRAY );
1874 }
1875
1876 /* Vertices */
1877 _mesa_EnableClientState( GL_VERTEX_ARRAY );
1878 _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
1879 (GLubyte *) pointer + voffset );
1880 }
1881
1882
1883 void GLAPIENTRY
1884 _mesa_LockArraysEXT(GLint first, GLsizei count)
1885 {
1886 GET_CURRENT_CONTEXT(ctx);
1887
1888 FLUSH_VERTICES(ctx, 0);
1889
1890 if (MESA_VERBOSE & VERBOSE_API)
1891 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
1892
1893 if (first < 0) {
1894 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" );
1895 return;
1896 }
1897 if (count <= 0) {
1898 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" );
1899 return;
1900 }
1901 if (ctx->Array.LockCount != 0) {
1902 _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" );
1903 return;
1904 }
1905
1906 ctx->Array.LockFirst = first;
1907 ctx->Array.LockCount = count;
1908
1909 ctx->NewState |= _NEW_ARRAY;
1910 }
1911
1912
1913 void GLAPIENTRY
1914 _mesa_UnlockArraysEXT( void )
1915 {
1916 GET_CURRENT_CONTEXT(ctx);
1917
1918 FLUSH_VERTICES(ctx, 0);
1919
1920 if (MESA_VERBOSE & VERBOSE_API)
1921 _mesa_debug(ctx, "glUnlockArrays\n");
1922
1923 if (ctx->Array.LockCount == 0) {
1924 _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" );
1925 return;
1926 }
1927
1928 ctx->Array.LockFirst = 0;
1929 ctx->Array.LockCount = 0;
1930 ctx->NewState |= _NEW_ARRAY;
1931 }
1932
1933
1934 /* GL_IBM_multimode_draw_arrays */
1935 void GLAPIENTRY
1936 _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
1937 const GLsizei * count,
1938 GLsizei primcount, GLint modestride )
1939 {
1940 GET_CURRENT_CONTEXT(ctx);
1941 GLint i;
1942
1943 FLUSH_VERTICES(ctx, 0);
1944
1945 for ( i = 0 ; i < primcount ; i++ ) {
1946 if ( count[i] > 0 ) {
1947 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1948 CALL_DrawArrays(ctx->CurrentServerDispatch, ( m, first[i], count[i] ));
1949 }
1950 }
1951 }
1952
1953
1954 /* GL_IBM_multimode_draw_arrays */
1955 void GLAPIENTRY
1956 _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
1957 GLenum type, const GLvoid * const * indices,
1958 GLsizei primcount, GLint modestride )
1959 {
1960 GET_CURRENT_CONTEXT(ctx);
1961 GLint i;
1962
1963 FLUSH_VERTICES(ctx, 0);
1964
1965 /* XXX not sure about ARB_vertex_buffer_object handling here */
1966
1967 for ( i = 0 ; i < primcount ; i++ ) {
1968 if ( count[i] > 0 ) {
1969 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1970 CALL_DrawElements(ctx->CurrentServerDispatch, ( m, count[i], type,
1971 indices[i] ));
1972 }
1973 }
1974 }
1975
1976
1977 static void
1978 primitive_restart_index(struct gl_context *ctx, GLuint index)
1979 {
1980 if (ctx->Array.RestartIndex != index) {
1981 FLUSH_VERTICES(ctx, 0);
1982 ctx->Array.RestartIndex = index;
1983 }
1984 }
1985
1986
1987 /**
1988 * GL_NV_primitive_restart and GL 3.1
1989 */
1990 void GLAPIENTRY
1991 _mesa_PrimitiveRestartIndex_no_error(GLuint index)
1992 {
1993 GET_CURRENT_CONTEXT(ctx);
1994 primitive_restart_index(ctx, index);
1995 }
1996
1997
1998 void GLAPIENTRY
1999 _mesa_PrimitiveRestartIndex(GLuint index)
2000 {
2001 GET_CURRENT_CONTEXT(ctx);
2002
2003 if (!ctx->Extensions.NV_primitive_restart && ctx->Version < 31) {
2004 _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()");
2005 return;
2006 }
2007
2008 primitive_restart_index(ctx, index);
2009 }
2010
2011
2012 void GLAPIENTRY
2013 _mesa_VertexAttribDivisor_no_error(GLuint index, GLuint divisor)
2014 {
2015 GET_CURRENT_CONTEXT(ctx);
2016
2017 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index);
2018 struct gl_vertex_array_object * const vao = ctx->Array.VAO;
2019
2020 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
2021
2022 /* The ARB_vertex_attrib_binding spec says:
2023 *
2024 * "The command
2025 *
2026 * void VertexAttribDivisor(uint index, uint divisor);
2027 *
2028 * is equivalent to (assuming no errors are generated):
2029 *
2030 * VertexAttribBinding(index, index);
2031 * VertexBindingDivisor(index, divisor);"
2032 */
2033 vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
2034 vertex_binding_divisor(ctx, vao, genericIndex, divisor);
2035 }
2036
2037
2038 /**
2039 * See GL_ARB_instanced_arrays.
2040 * Note that the instance divisor only applies to generic arrays, not
2041 * the legacy vertex arrays.
2042 */
2043 void GLAPIENTRY
2044 _mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
2045 {
2046 GET_CURRENT_CONTEXT(ctx);
2047
2048 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index);
2049 struct gl_vertex_array_object * const vao = ctx->Array.VAO;
2050
2051 if (!ctx->Extensions.ARB_instanced_arrays) {
2052 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
2053 return;
2054 }
2055
2056 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2057 _mesa_error(ctx, GL_INVALID_VALUE,
2058 "glVertexAttribDivisor(index = %u)", index);
2059 return;
2060 }
2061
2062 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
2063
2064 /* The ARB_vertex_attrib_binding spec says:
2065 *
2066 * "The command
2067 *
2068 * void VertexAttribDivisor(uint index, uint divisor);
2069 *
2070 * is equivalent to (assuming no errors are generated):
2071 *
2072 * VertexAttribBinding(index, index);
2073 * VertexBindingDivisor(index, divisor);"
2074 */
2075 vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
2076 vertex_binding_divisor(ctx, vao, genericIndex, divisor);
2077 }
2078
2079
2080 static ALWAYS_INLINE void
2081 vertex_array_vertex_buffer(struct gl_context *ctx,
2082 struct gl_vertex_array_object *vao,
2083 GLuint bindingIndex, GLuint buffer, GLintptr offset,
2084 GLsizei stride, bool no_error, const char *func)
2085 {
2086 struct gl_buffer_object *vbo;
2087 if (buffer ==
2088 vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj->Name) {
2089 vbo = vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj;
2090 } else if (buffer != 0) {
2091 vbo = _mesa_lookup_bufferobj(ctx, buffer);
2092
2093 if (!no_error && !vbo && _mesa_is_gles31(ctx)) {
2094 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", func);
2095 return;
2096 }
2097 /* From the GL_ARB_vertex_attrib_array spec:
2098 *
2099 * "[Core profile only:]
2100 * An INVALID_OPERATION error is generated if buffer is not zero or a
2101 * name returned from a previous call to GenBuffers, or if such a name
2102 * has since been deleted with DeleteBuffers.
2103 *
2104 * Otherwise, we fall back to the same compat profile behavior as other
2105 * object references (automatically gen it).
2106 */
2107 if (!_mesa_handle_bind_buffer_gen(ctx, buffer, &vbo, func))
2108 return;
2109 } else {
2110 /* The ARB_vertex_attrib_binding spec says:
2111 *
2112 * "If <buffer> is zero, any buffer object attached to this
2113 * bindpoint is detached."
2114 */
2115 vbo = ctx->Shared->NullBufferObj;
2116 }
2117
2118 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex),
2119 vbo, offset, stride);
2120 }
2121
2122
2123 /**
2124 * GL_ARB_vertex_attrib_binding
2125 */
2126 static void
2127 vertex_array_vertex_buffer_err(struct gl_context *ctx,
2128 struct gl_vertex_array_object *vao,
2129 GLuint bindingIndex, GLuint buffer,
2130 GLintptr offset, GLsizei stride,
2131 const char *func)
2132 {
2133 ASSERT_OUTSIDE_BEGIN_END(ctx);
2134
2135 /* The ARB_vertex_attrib_binding spec says:
2136 *
2137 * "An INVALID_VALUE error is generated if <bindingindex> is greater than
2138 * the value of MAX_VERTEX_ATTRIB_BINDINGS."
2139 */
2140 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2141 _mesa_error(ctx, GL_INVALID_VALUE,
2142 "%s(bindingindex=%u > "
2143 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2144 func, bindingIndex);
2145 return;
2146 }
2147
2148 /* The ARB_vertex_attrib_binding spec says:
2149 *
2150 * "The error INVALID_VALUE is generated if <stride> or <offset>
2151 * are negative."
2152 */
2153 if (offset < 0) {
2154 _mesa_error(ctx, GL_INVALID_VALUE,
2155 "%s(offset=%" PRId64 " < 0)",
2156 func, (int64_t) offset);
2157 return;
2158 }
2159
2160 if (stride < 0) {
2161 _mesa_error(ctx, GL_INVALID_VALUE,
2162 "%s(stride=%d < 0)", func, stride);
2163 return;
2164 }
2165
2166 if (((ctx->API == API_OPENGL_CORE && ctx->Version >= 44) || _mesa_is_gles31(ctx)) &&
2167 stride > ctx->Const.MaxVertexAttribStride) {
2168 _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > "
2169 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride);
2170 return;
2171 }
2172
2173 vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset,
2174 stride, false, func);
2175 }
2176
2177
2178 void GLAPIENTRY
2179 _mesa_BindVertexBuffer_no_error(GLuint bindingIndex, GLuint buffer,
2180 GLintptr offset, GLsizei stride)
2181 {
2182 GET_CURRENT_CONTEXT(ctx);
2183 vertex_array_vertex_buffer(ctx, ctx->Array.VAO, bindingIndex,
2184 buffer, offset, stride, true,
2185 "glBindVertexBuffer");
2186 }
2187
2188
2189 void GLAPIENTRY
2190 _mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset,
2191 GLsizei stride)
2192 {
2193 GET_CURRENT_CONTEXT(ctx);
2194
2195 /* The ARB_vertex_attrib_binding spec says:
2196 *
2197 * "An INVALID_OPERATION error is generated if no vertex array object
2198 * is bound."
2199 */
2200 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2201 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2202 _mesa_error(ctx, GL_INVALID_OPERATION,
2203 "glBindVertexBuffer(No array object bound)");
2204 return;
2205 }
2206
2207 vertex_array_vertex_buffer_err(ctx, ctx->Array.VAO, bindingIndex,
2208 buffer, offset, stride,
2209 "glBindVertexBuffer");
2210 }
2211
2212
2213 void GLAPIENTRY
2214 _mesa_VertexArrayVertexBuffer_no_error(GLuint vaobj, GLuint bindingIndex,
2215 GLuint buffer, GLintptr offset,
2216 GLsizei stride)
2217 {
2218 GET_CURRENT_CONTEXT(ctx);
2219
2220 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2221 vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset,
2222 stride, true, "glVertexArrayVertexBuffer");
2223 }
2224
2225
2226 void GLAPIENTRY
2227 _mesa_VertexArrayVertexBuffer(GLuint vaobj, GLuint bindingIndex, GLuint buffer,
2228 GLintptr offset, GLsizei stride)
2229 {
2230 GET_CURRENT_CONTEXT(ctx);
2231 struct gl_vertex_array_object *vao;
2232
2233 /* The ARB_direct_state_access specification says:
2234 *
2235 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
2236 * if <vaobj> is not [compatibility profile: zero or] the name of an
2237 * existing vertex array object."
2238 */
2239 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffer");
2240 if (!vao)
2241 return;
2242
2243 vertex_array_vertex_buffer_err(ctx, vao, bindingIndex, buffer, offset,
2244 stride, "glVertexArrayVertexBuffer");
2245 }
2246
2247
2248 static ALWAYS_INLINE void
2249 vertex_array_vertex_buffers(struct gl_context *ctx,
2250 struct gl_vertex_array_object *vao,
2251 GLuint first, GLsizei count, const GLuint *buffers,
2252 const GLintptr *offsets, const GLsizei *strides,
2253 bool no_error, const char *func)
2254 {
2255 GLint i;
2256
2257 if (!buffers) {
2258 /**
2259 * The ARB_multi_bind spec says:
2260 *
2261 * "If <buffers> is NULL, each affected vertex buffer binding point
2262 * from <first> through <first>+<count>-1 will be reset to have no
2263 * bound buffer object. In this case, the offsets and strides
2264 * associated with the binding points are set to default values,
2265 * ignoring <offsets> and <strides>."
2266 */
2267 struct gl_buffer_object *vbo = ctx->Shared->NullBufferObj;
2268
2269 for (i = 0; i < count; i++)
2270 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
2271 vbo, 0, 16);
2272
2273 return;
2274 }
2275
2276 /* Note that the error semantics for multi-bind commands differ from
2277 * those of other GL commands.
2278 *
2279 * The Issues section in the ARB_multi_bind spec says:
2280 *
2281 * "(11) Typically, OpenGL specifies that if an error is generated by
2282 * a command, that command has no effect. This is somewhat
2283 * unfortunate for multi-bind commands, because it would require
2284 * a first pass to scan the entire list of bound objects for
2285 * errors and then a second pass to actually perform the
2286 * bindings. Should we have different error semantics?
2287 *
2288 * RESOLVED: Yes. In this specification, when the parameters for
2289 * one of the <count> binding points are invalid, that binding
2290 * point is not updated and an error will be generated. However,
2291 * other binding points in the same command will be updated if
2292 * their parameters are valid and no other error occurs."
2293 */
2294
2295 _mesa_HashLockMutex(ctx->Shared->BufferObjects);
2296
2297 for (i = 0; i < count; i++) {
2298 struct gl_buffer_object *vbo;
2299
2300 if (!no_error) {
2301 /* The ARB_multi_bind spec says:
2302 *
2303 * "An INVALID_VALUE error is generated if any value in
2304 * <offsets> or <strides> is negative (per binding)."
2305 */
2306 if (offsets[i] < 0) {
2307 _mesa_error(ctx, GL_INVALID_VALUE,
2308 "%s(offsets[%u]=%" PRId64 " < 0)",
2309 func, i, (int64_t) offsets[i]);
2310 continue;
2311 }
2312
2313 if (strides[i] < 0) {
2314 _mesa_error(ctx, GL_INVALID_VALUE,
2315 "%s(strides[%u]=%d < 0)",
2316 func, i, strides[i]);
2317 continue;
2318 }
2319
2320 if (ctx->API == API_OPENGL_CORE && ctx->Version >= 44 &&
2321 strides[i] > ctx->Const.MaxVertexAttribStride) {
2322 _mesa_error(ctx, GL_INVALID_VALUE,
2323 "%s(strides[%u]=%d > "
2324 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, i, strides[i]);
2325 continue;
2326 }
2327 }
2328
2329 if (buffers[i]) {
2330 struct gl_vertex_buffer_binding *binding =
2331 &vao->BufferBinding[VERT_ATTRIB_GENERIC(first + i)];
2332
2333 if (buffers[i] == binding->BufferObj->Name)
2334 vbo = binding->BufferObj;
2335 else
2336 vbo = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, func);
2337
2338 if (!vbo)
2339 continue;
2340 } else {
2341 vbo = ctx->Shared->NullBufferObj;
2342 }
2343
2344 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
2345 vbo, offsets[i], strides[i]);
2346 }
2347
2348 _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
2349 }
2350
2351
2352 static void
2353 vertex_array_vertex_buffers_err(struct gl_context *ctx,
2354 struct gl_vertex_array_object *vao,
2355 GLuint first, GLsizei count,
2356 const GLuint *buffers, const GLintptr *offsets,
2357 const GLsizei *strides, const char *func)
2358 {
2359 ASSERT_OUTSIDE_BEGIN_END(ctx);
2360
2361 /* The ARB_multi_bind spec says:
2362 *
2363 * "An INVALID_OPERATION error is generated if <first> + <count>
2364 * is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS."
2365 */
2366 if (first + count > ctx->Const.MaxVertexAttribBindings) {
2367 _mesa_error(ctx, GL_INVALID_OPERATION,
2368 "%s(first=%u + count=%d > the value of "
2369 "GL_MAX_VERTEX_ATTRIB_BINDINGS=%u)",
2370 func, first, count, ctx->Const.MaxVertexAttribBindings);
2371 return;
2372 }
2373
2374 vertex_array_vertex_buffers(ctx, vao, first, count, buffers, offsets,
2375 strides, false, func);
2376 }
2377
2378
2379 void GLAPIENTRY
2380 _mesa_BindVertexBuffers_no_error(GLuint first, GLsizei count,
2381 const GLuint *buffers, const GLintptr *offsets,
2382 const GLsizei *strides)
2383 {
2384 GET_CURRENT_CONTEXT(ctx);
2385
2386 vertex_array_vertex_buffers(ctx, ctx->Array.VAO, first, count,
2387 buffers, offsets, strides, true,
2388 "glBindVertexBuffers");
2389 }
2390
2391
2392 void GLAPIENTRY
2393 _mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers,
2394 const GLintptr *offsets, const GLsizei *strides)
2395 {
2396 GET_CURRENT_CONTEXT(ctx);
2397
2398 /* The ARB_vertex_attrib_binding spec says:
2399 *
2400 * "An INVALID_OPERATION error is generated if no
2401 * vertex array object is bound."
2402 */
2403 if (ctx->API == API_OPENGL_CORE &&
2404 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2405 _mesa_error(ctx, GL_INVALID_OPERATION,
2406 "glBindVertexBuffers(No array object bound)");
2407 return;
2408 }
2409
2410 vertex_array_vertex_buffers_err(ctx, ctx->Array.VAO, first, count,
2411 buffers, offsets, strides,
2412 "glBindVertexBuffers");
2413 }
2414
2415
2416 void GLAPIENTRY
2417 _mesa_VertexArrayVertexBuffers_no_error(GLuint vaobj, GLuint first,
2418 GLsizei count, const GLuint *buffers,
2419 const GLintptr *offsets,
2420 const GLsizei *strides)
2421 {
2422 GET_CURRENT_CONTEXT(ctx);
2423
2424 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2425 vertex_array_vertex_buffers(ctx, vao, first, count,
2426 buffers, offsets, strides, true,
2427 "glVertexArrayVertexBuffers");
2428 }
2429
2430
2431 void GLAPIENTRY
2432 _mesa_VertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count,
2433 const GLuint *buffers,
2434 const GLintptr *offsets, const GLsizei *strides)
2435 {
2436 GET_CURRENT_CONTEXT(ctx);
2437 struct gl_vertex_array_object *vao;
2438
2439 /* The ARB_direct_state_access specification says:
2440 *
2441 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
2442 * if <vaobj> is not [compatibility profile: zero or] the name of an
2443 * existing vertex array object."
2444 */
2445 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffers");
2446 if (!vao)
2447 return;
2448
2449 vertex_array_vertex_buffers_err(ctx, vao, first, count,
2450 buffers, offsets, strides,
2451 "glVertexArrayVertexBuffers");
2452 }
2453
2454
2455 static void
2456 vertex_attrib_format(GLuint attribIndex, GLint size, GLenum type,
2457 GLboolean normalized, GLboolean integer,
2458 GLboolean doubles, GLbitfield legalTypes,
2459 GLsizei sizeMax, GLuint relativeOffset,
2460 const char *func)
2461 {
2462 GET_CURRENT_CONTEXT(ctx);
2463 ASSERT_OUTSIDE_BEGIN_END(ctx);
2464
2465 GLenum format = get_array_format(ctx, sizeMax, &size);
2466
2467 if (!_mesa_is_no_error_enabled(ctx)) {
2468 /* The ARB_vertex_attrib_binding spec says:
2469 *
2470 * "An INVALID_OPERATION error is generated under any of the
2471 * following conditions:
2472 * - if no vertex array object is currently bound (see section
2473 * 2.10);
2474 * - ..."
2475 *
2476 * This error condition only applies to VertexAttribFormat and
2477 * VertexAttribIFormat in the extension spec, but we assume that this
2478 * is an oversight. In the OpenGL 4.3 (Core Profile) spec, it applies
2479 * to all three functions.
2480 */
2481 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2482 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2483 _mesa_error(ctx, GL_INVALID_OPERATION,
2484 "%s(No array object bound)", func);
2485 return;
2486 }
2487
2488 /* The ARB_vertex_attrib_binding spec says:
2489 *
2490 * "The error INVALID_VALUE is generated if index is greater than or
2491 * equal to the value of MAX_VERTEX_ATTRIBS."
2492 */
2493 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2494 _mesa_error(ctx, GL_INVALID_VALUE,
2495 "%s(attribindex=%u > "
2496 "GL_MAX_VERTEX_ATTRIBS)",
2497 func, attribIndex);
2498 return;
2499 }
2500
2501 if (!validate_array_format(ctx, func, ctx->Array.VAO,
2502 VERT_ATTRIB_GENERIC(attribIndex),
2503 legalTypes, 1, sizeMax, size, type,
2504 normalized, integer, doubles, relativeOffset,
2505 format)) {
2506 return;
2507 }
2508 }
2509
2510 FLUSH_VERTICES(ctx, 0);
2511
2512 _mesa_update_array_format(ctx, ctx->Array.VAO,
2513 VERT_ATTRIB_GENERIC(attribIndex), size, type,
2514 format, normalized, integer, doubles,
2515 relativeOffset);
2516 }
2517
2518
2519 void GLAPIENTRY
2520 _mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type,
2521 GLboolean normalized, GLuint relativeOffset)
2522 {
2523 vertex_attrib_format(attribIndex, size, type, normalized,
2524 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
2525 BGRA_OR_4, relativeOffset,
2526 "glVertexAttribFormat");
2527 }
2528
2529
2530 void GLAPIENTRY
2531 _mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type,
2532 GLuint relativeOffset)
2533 {
2534 vertex_attrib_format(attribIndex, size, type, GL_FALSE,
2535 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK, 4,
2536 relativeOffset, "glVertexAttribIFormat");
2537 }
2538
2539
2540 void GLAPIENTRY
2541 _mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type,
2542 GLuint relativeOffset)
2543 {
2544 vertex_attrib_format(attribIndex, size, type, GL_FALSE, GL_FALSE,
2545 GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK, 4,
2546 relativeOffset, "glVertexAttribLFormat");
2547 }
2548
2549
2550 static void
2551 vertex_array_attrib_format(GLuint vaobj, GLuint attribIndex, GLint size,
2552 GLenum type, GLboolean normalized,
2553 GLboolean integer, GLboolean doubles,
2554 GLbitfield legalTypes, GLsizei sizeMax,
2555 GLuint relativeOffset, const char *func)
2556 {
2557 GET_CURRENT_CONTEXT(ctx);
2558 struct gl_vertex_array_object *vao;
2559
2560 ASSERT_OUTSIDE_BEGIN_END(ctx);
2561
2562 GLenum format = get_array_format(ctx, sizeMax, &size);
2563
2564 if (_mesa_is_no_error_enabled(ctx)) {
2565 vao = _mesa_lookup_vao(ctx, vaobj);
2566 if (!vao)
2567 return;
2568 } else {
2569 /* The ARB_direct_state_access spec says:
2570 *
2571 * "An INVALID_OPERATION error is generated by
2572 * VertexArrayAttrib*Format if <vaobj> is not [compatibility profile:
2573 * zero or] the name of an existing vertex array object."
2574 */
2575 vao = _mesa_lookup_vao_err(ctx, vaobj, func);
2576 if (!vao)
2577 return;
2578
2579 /* The ARB_vertex_attrib_binding spec says:
2580 *
2581 * "The error INVALID_VALUE is generated if index is greater than or
2582 * equal to the value of MAX_VERTEX_ATTRIBS."
2583 */
2584 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2585 _mesa_error(ctx, GL_INVALID_VALUE,
2586 "%s(attribindex=%u > GL_MAX_VERTEX_ATTRIBS)",
2587 func, attribIndex);
2588 return;
2589 }
2590
2591 if (!validate_array_format(ctx, func, vao,
2592 VERT_ATTRIB_GENERIC(attribIndex),
2593 legalTypes, 1, sizeMax, size, type,
2594 normalized, integer, doubles, relativeOffset,
2595 format)) {
2596 return;
2597 }
2598 }
2599
2600 FLUSH_VERTICES(ctx, 0);
2601
2602 _mesa_update_array_format(ctx, vao, VERT_ATTRIB_GENERIC(attribIndex), size,
2603 type, format, normalized, integer, doubles,
2604 relativeOffset);
2605 }
2606
2607
2608 void GLAPIENTRY
2609 _mesa_VertexArrayAttribFormat(GLuint vaobj, GLuint attribIndex, GLint size,
2610 GLenum type, GLboolean normalized,
2611 GLuint relativeOffset)
2612 {
2613 vertex_array_attrib_format(vaobj, attribIndex, size, type, normalized,
2614 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
2615 BGRA_OR_4, relativeOffset,
2616 "glVertexArrayAttribFormat");
2617 }
2618
2619
2620 void GLAPIENTRY
2621 _mesa_VertexArrayAttribIFormat(GLuint vaobj, GLuint attribIndex,
2622 GLint size, GLenum type,
2623 GLuint relativeOffset)
2624 {
2625 vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE,
2626 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK,
2627 4, relativeOffset,
2628 "glVertexArrayAttribIFormat");
2629 }
2630
2631
2632 void GLAPIENTRY
2633 _mesa_VertexArrayAttribLFormat(GLuint vaobj, GLuint attribIndex,
2634 GLint size, GLenum type,
2635 GLuint relativeOffset)
2636 {
2637 vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE,
2638 GL_FALSE, GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK,
2639 4, relativeOffset,
2640 "glVertexArrayAttribLFormat");
2641 }
2642
2643
2644 static void
2645 vertex_array_attrib_binding(struct gl_context *ctx,
2646 struct gl_vertex_array_object *vao,
2647 GLuint attribIndex, GLuint bindingIndex,
2648 const char *func)
2649 {
2650 ASSERT_OUTSIDE_BEGIN_END(ctx);
2651
2652 /* The ARB_vertex_attrib_binding spec says:
2653 *
2654 * "<attribindex> must be less than the value of MAX_VERTEX_ATTRIBS and
2655 * <bindingindex> must be less than the value of
2656 * MAX_VERTEX_ATTRIB_BINDINGS, otherwise the error INVALID_VALUE
2657 * is generated."
2658 */
2659 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2660 _mesa_error(ctx, GL_INVALID_VALUE,
2661 "%s(attribindex=%u >= "
2662 "GL_MAX_VERTEX_ATTRIBS)",
2663 func, attribIndex);
2664 return;
2665 }
2666
2667 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2668 _mesa_error(ctx, GL_INVALID_VALUE,
2669 "%s(bindingindex=%u >= "
2670 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2671 func, bindingIndex);
2672 return;
2673 }
2674
2675 assert(VERT_ATTRIB_GENERIC(attribIndex) < ARRAY_SIZE(vao->VertexAttrib));
2676
2677 vertex_attrib_binding(ctx, vao,
2678 VERT_ATTRIB_GENERIC(attribIndex),
2679 VERT_ATTRIB_GENERIC(bindingIndex));
2680 }
2681
2682
2683 void GLAPIENTRY
2684 _mesa_VertexAttribBinding_no_error(GLuint attribIndex, GLuint bindingIndex)
2685 {
2686 GET_CURRENT_CONTEXT(ctx);
2687 vertex_attrib_binding(ctx, ctx->Array.VAO,
2688 VERT_ATTRIB_GENERIC(attribIndex),
2689 VERT_ATTRIB_GENERIC(bindingIndex));
2690 }
2691
2692
2693 void GLAPIENTRY
2694 _mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
2695 {
2696 GET_CURRENT_CONTEXT(ctx);
2697
2698 /* The ARB_vertex_attrib_binding spec says:
2699 *
2700 * "An INVALID_OPERATION error is generated if no vertex array object
2701 * is bound."
2702 */
2703 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2704 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2705 _mesa_error(ctx, GL_INVALID_OPERATION,
2706 "glVertexAttribBinding(No array object bound)");
2707 return;
2708 }
2709
2710 vertex_array_attrib_binding(ctx, ctx->Array.VAO,
2711 attribIndex, bindingIndex,
2712 "glVertexAttribBinding");
2713 }
2714
2715
2716 void GLAPIENTRY
2717 _mesa_VertexArrayAttribBinding_no_error(GLuint vaobj, GLuint attribIndex,
2718 GLuint bindingIndex)
2719 {
2720 GET_CURRENT_CONTEXT(ctx);
2721
2722 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2723 vertex_attrib_binding(ctx, vao,
2724 VERT_ATTRIB_GENERIC(attribIndex),
2725 VERT_ATTRIB_GENERIC(bindingIndex));
2726 }
2727
2728
2729 void GLAPIENTRY
2730 _mesa_VertexArrayAttribBinding(GLuint vaobj, GLuint attribIndex, GLuint bindingIndex)
2731 {
2732 GET_CURRENT_CONTEXT(ctx);
2733 struct gl_vertex_array_object *vao;
2734
2735 /* The ARB_direct_state_access specification says:
2736 *
2737 * "An INVALID_OPERATION error is generated by VertexArrayAttribBinding
2738 * if <vaobj> is not [compatibility profile: zero or] the name of an
2739 * existing vertex array object."
2740 */
2741 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayAttribBinding");
2742 if (!vao)
2743 return;
2744
2745 vertex_array_attrib_binding(ctx, vao, attribIndex, bindingIndex,
2746 "glVertexArrayAttribBinding");
2747 }
2748
2749
2750 static void
2751 vertex_array_binding_divisor(struct gl_context *ctx,
2752 struct gl_vertex_array_object *vao,
2753 GLuint bindingIndex, GLuint divisor,
2754 const char *func)
2755 {
2756 ASSERT_OUTSIDE_BEGIN_END(ctx);
2757
2758 if (!ctx->Extensions.ARB_instanced_arrays) {
2759 _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", func);
2760 return;
2761 }
2762
2763 /* The ARB_vertex_attrib_binding spec says:
2764 *
2765 * "An INVALID_VALUE error is generated if <bindingindex> is greater
2766 * than or equal to the value of MAX_VERTEX_ATTRIB_BINDINGS."
2767 */
2768 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2769 _mesa_error(ctx, GL_INVALID_VALUE,
2770 "%s(bindingindex=%u > "
2771 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2772 func, bindingIndex);
2773 return;
2774 }
2775
2776 vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2777 }
2778
2779
2780 void GLAPIENTRY
2781 _mesa_VertexBindingDivisor_no_error(GLuint bindingIndex, GLuint divisor)
2782 {
2783 GET_CURRENT_CONTEXT(ctx);
2784 vertex_binding_divisor(ctx, ctx->Array.VAO,
2785 VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2786 }
2787
2788
2789 void GLAPIENTRY
2790 _mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
2791 {
2792 GET_CURRENT_CONTEXT(ctx);
2793
2794 /* The ARB_vertex_attrib_binding spec says:
2795 *
2796 * "An INVALID_OPERATION error is generated if no vertex array object
2797 * is bound."
2798 */
2799 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2800 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2801 _mesa_error(ctx, GL_INVALID_OPERATION,
2802 "glVertexBindingDivisor(No array object bound)");
2803 return;
2804 }
2805
2806 vertex_array_binding_divisor(ctx, ctx->Array.VAO,
2807 bindingIndex, divisor,
2808 "glVertexBindingDivisor");
2809 }
2810
2811
2812 void GLAPIENTRY
2813 _mesa_VertexArrayBindingDivisor_no_error(GLuint vaobj, GLuint bindingIndex,
2814 GLuint divisor)
2815 {
2816 GET_CURRENT_CONTEXT(ctx);
2817
2818 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2819 vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2820 }
2821
2822
2823 void GLAPIENTRY
2824 _mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex,
2825 GLuint divisor)
2826 {
2827 struct gl_vertex_array_object *vao;
2828 GET_CURRENT_CONTEXT(ctx);
2829
2830 /* The ARB_direct_state_access specification says:
2831 *
2832 * "An INVALID_OPERATION error is generated by VertexArrayBindingDivisor
2833 * if <vaobj> is not [compatibility profile: zero or] the name of an
2834 * existing vertex array object."
2835 */
2836 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayBindingDivisor");
2837 if (!vao)
2838 return;
2839
2840 vertex_array_binding_divisor(ctx, vao, bindingIndex, divisor,
2841 "glVertexArrayBindingDivisor");
2842 }
2843
2844
2845 /**
2846 * Copy one vertex array to another.
2847 */
2848 void
2849 _mesa_copy_vertex_array(struct gl_context *ctx,
2850 struct gl_vertex_array *dst,
2851 struct gl_vertex_array *src)
2852 {
2853 dst->Size = src->Size;
2854 dst->Type = src->Type;
2855 dst->Format = src->Format;
2856 dst->StrideB = src->StrideB;
2857 dst->Ptr = src->Ptr;
2858 dst->Normalized = src->Normalized;
2859 dst->Integer = src->Integer;
2860 dst->Doubles = src->Doubles;
2861 dst->InstanceDivisor = src->InstanceDivisor;
2862 dst->_ElementSize = src->_ElementSize;
2863 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
2864 }
2865
2866 void
2867 _mesa_copy_vertex_attrib_array(struct gl_context *ctx,
2868 struct gl_array_attributes *dst,
2869 const struct gl_array_attributes *src)
2870 {
2871 dst->Size = src->Size;
2872 dst->Type = src->Type;
2873 dst->Format = src->Format;
2874 dst->BufferBindingIndex = src->BufferBindingIndex;
2875 dst->RelativeOffset = src->RelativeOffset;
2876 dst->Format = src->Format;
2877 dst->Integer = src->Integer;
2878 dst->Doubles = src->Doubles;
2879 dst->Normalized = src->Normalized;
2880 dst->Ptr = src->Ptr;
2881 dst->Enabled = src->Enabled;
2882 dst->_ElementSize = src->_ElementSize;
2883 }
2884
2885 void
2886 _mesa_copy_vertex_buffer_binding(struct gl_context *ctx,
2887 struct gl_vertex_buffer_binding *dst,
2888 const struct gl_vertex_buffer_binding *src)
2889 {
2890 dst->Offset = src->Offset;
2891 dst->Stride = src->Stride;
2892 dst->InstanceDivisor = src->InstanceDivisor;
2893 dst->_BoundArrays = src->_BoundArrays;
2894
2895 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
2896 }
2897
2898 /**
2899 * Print current vertex object/array info. For debug.
2900 */
2901 void
2902 _mesa_print_arrays(struct gl_context *ctx)
2903 {
2904 const struct gl_vertex_array_object *vao = ctx->Array.VAO;
2905
2906 fprintf(stderr, "Array Object %u\n", vao->Name);
2907
2908 gl_vert_attrib i;
2909 for (i = 0; i < VERT_ATTRIB_MAX; ++i) {
2910 const struct gl_array_attributes *array = &vao->VertexAttrib[i];
2911 if (!array->Enabled)
2912 continue;
2913
2914 const struct gl_vertex_buffer_binding *binding =
2915 &vao->BufferBinding[array->BufferBindingIndex];
2916 const struct gl_buffer_object *bo = binding->BufferObj;
2917
2918 fprintf(stderr, " %s: Ptr=%p, Type=%s, Size=%d, ElemSize=%u, "
2919 "Stride=%d, Buffer=%u(Size %lu)\n",
2920 gl_vert_attrib_name((gl_vert_attrib)i),
2921 array->Ptr, _mesa_enum_to_string(array->Type), array->Size,
2922 array->_ElementSize, binding->Stride, bo->Name,
2923 (unsigned long) bo->Size);
2924 }
2925 }
2926
2927
2928 /**
2929 * Initialize vertex array state for given context.
2930 */
2931 void
2932 _mesa_init_varray(struct gl_context *ctx)
2933 {
2934 ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0);
2935 _mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO);
2936 ctx->Array._EmptyVAO = _mesa_new_vao(ctx, ~0u);
2937 _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, ctx->Array._EmptyVAO);
2938 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
2939
2940 ctx->Array.Objects = _mesa_NewHashTable();
2941 }
2942
2943
2944 /**
2945 * Callback for deleting an array object. Called by _mesa_HashDeleteAll().
2946 */
2947 static void
2948 delete_arrayobj_cb(GLuint id, void *data, void *userData)
2949 {
2950 struct gl_vertex_array_object *vao = (struct gl_vertex_array_object *) data;
2951 struct gl_context *ctx = (struct gl_context *) userData;
2952 _mesa_delete_vao(ctx, vao);
2953 }
2954
2955
2956 /**
2957 * Free vertex array state for given context.
2958 */
2959 void
2960 _mesa_free_varray_data(struct gl_context *ctx)
2961 {
2962 _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx);
2963 _mesa_DeleteHashTable(ctx->Array.Objects);
2964 }