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