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