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