mesa: Refactor enable_vertex_array_attrib to make _mesa_enable_vertex_array_attrib
[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 void
774 _mesa_enable_vertex_array_attrib(struct gl_context *ctx,
775 struct gl_vertex_array_object *vao,
776 unsigned attrib)
777 {
778 assert(attrib < ARRAY_SIZE(vao->VertexAttrib));
779
780 if (!vao->VertexAttrib[attrib].Enabled) {
781 /* was disabled, now being enabled */
782 FLUSH_VERTICES(ctx, _NEW_ARRAY);
783 vao->VertexAttrib[attrib].Enabled = GL_TRUE;
784 vao->_Enabled |= VERT_BIT(attrib);
785 vao->NewArrays |= VERT_BIT(attrib);
786 }
787 }
788
789 static void
790 enable_vertex_array_attrib(struct gl_context *ctx,
791 struct gl_vertex_array_object *vao,
792 GLuint index,
793 const char *func)
794 {
795 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
796 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
797 return;
798 }
799
800 _mesa_enable_vertex_array_attrib(ctx, vao, VERT_ATTRIB_GENERIC(index));
801 }
802
803
804 void GLAPIENTRY
805 _mesa_EnableVertexAttribArray(GLuint index)
806 {
807 GET_CURRENT_CONTEXT(ctx);
808 enable_vertex_array_attrib(ctx, ctx->Array.VAO, index,
809 "glEnableVertexAttribArray");
810 }
811
812
813 void GLAPIENTRY
814 _mesa_EnableVertexArrayAttrib(GLuint vaobj, GLuint index)
815 {
816 GET_CURRENT_CONTEXT(ctx);
817 struct gl_vertex_array_object *vao;
818
819 /* The ARB_direct_state_access specification says:
820 *
821 * "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib
822 * and DisableVertexArrayAttrib if <vaobj> is not
823 * [compatibility profile: zero or] the name of an existing vertex
824 * array object."
825 */
826 vao = _mesa_lookup_vao_err(ctx, vaobj, "glEnableVertexArrayAttrib");
827 if (!vao)
828 return;
829
830 enable_vertex_array_attrib(ctx, vao, index, "glEnableVertexArrayAttrib");
831 }
832
833
834 static void
835 disable_vertex_array_attrib(struct gl_context *ctx,
836 struct gl_vertex_array_object *vao,
837 GLuint index,
838 const char *func)
839 {
840 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
841 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
842 return;
843 }
844
845 assert(VERT_ATTRIB_GENERIC(index) < ARRAY_SIZE(vao->VertexAttrib));
846
847 if (vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled) {
848 /* was enabled, now being disabled */
849 FLUSH_VERTICES(ctx, _NEW_ARRAY);
850 vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_FALSE;
851 vao->_Enabled &= ~VERT_BIT_GENERIC(index);
852 vao->NewArrays |= VERT_BIT_GENERIC(index);
853 }
854 }
855
856
857 void GLAPIENTRY
858 _mesa_DisableVertexAttribArray(GLuint index)
859 {
860 GET_CURRENT_CONTEXT(ctx);
861 disable_vertex_array_attrib(ctx, ctx->Array.VAO, index,
862 "glDisableVertexAttribArray");
863 }
864
865
866 void GLAPIENTRY
867 _mesa_DisableVertexArrayAttrib(GLuint vaobj, GLuint index)
868 {
869 GET_CURRENT_CONTEXT(ctx);
870 struct gl_vertex_array_object *vao;
871
872 /* The ARB_direct_state_access specification says:
873 *
874 * "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib
875 * and DisableVertexArrayAttrib if <vaobj> is not
876 * [compatibility profile: zero or] the name of an existing vertex
877 * array object."
878 */
879 vao = _mesa_lookup_vao_err(ctx, vaobj, "glDisableVertexArrayAttrib");
880 if (!vao)
881 return;
882
883 disable_vertex_array_attrib(ctx, vao, index, "glDisableVertexArrayAttrib");
884 }
885
886
887 /**
888 * Return info for a vertex attribute array (no alias with legacy
889 * vertex attributes (pos, normal, color, etc)). This function does
890 * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query.
891 */
892 static GLuint
893 get_vertex_array_attrib(struct gl_context *ctx,
894 const struct gl_vertex_array_object *vao,
895 GLuint index, GLenum pname,
896 const char *caller)
897 {
898 const struct gl_vertex_attrib_array *array;
899
900 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
901 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index);
902 return 0;
903 }
904
905 assert(VERT_ATTRIB_GENERIC(index) < ARRAY_SIZE(vao->VertexAttrib));
906
907 array = &vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)];
908
909 switch (pname) {
910 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
911 return array->Enabled;
912 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
913 return (array->Format == GL_BGRA) ? GL_BGRA : array->Size;
914 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
915 return array->Stride;
916 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
917 return array->Type;
918 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
919 return array->Normalized;
920 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
921 return vao->VertexBinding[array->VertexBinding].BufferObj->Name;
922 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
923 if ((_mesa_is_desktop_gl(ctx)
924 && (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))
925 || _mesa_is_gles3(ctx)) {
926 return array->Integer;
927 }
928 goto error;
929 case GL_VERTEX_ATTRIB_ARRAY_LONG:
930 if (_mesa_is_desktop_gl(ctx)) {
931 return array->Doubles;
932 }
933 goto error;
934 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB:
935 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_instanced_arrays)
936 || _mesa_is_gles3(ctx)) {
937 return vao->VertexBinding[array->VertexBinding].InstanceDivisor;
938 }
939 goto error;
940 case GL_VERTEX_ATTRIB_BINDING:
941 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
942 return array->VertexBinding - VERT_ATTRIB_GENERIC0;
943 }
944 goto error;
945 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
946 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
947 return array->RelativeOffset;
948 }
949 goto error;
950 default:
951 ; /* fall-through */
952 }
953
954 error:
955 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname);
956 return 0;
957 }
958
959
960 static const GLfloat *
961 get_current_attrib(struct gl_context *ctx, GLuint index, const char *function)
962 {
963 if (index == 0) {
964 if (_mesa_attr_zero_aliases_vertex(ctx)) {
965 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function);
966 return NULL;
967 }
968 }
969 else if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
970 _mesa_error(ctx, GL_INVALID_VALUE,
971 "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function);
972 return NULL;
973 }
974
975 assert(VERT_ATTRIB_GENERIC(index) <
976 ARRAY_SIZE(ctx->Array.VAO->VertexAttrib));
977
978 FLUSH_CURRENT(ctx, 0);
979 return ctx->Current.Attrib[VERT_ATTRIB_GENERIC(index)];
980 }
981
982 void GLAPIENTRY
983 _mesa_GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
984 {
985 GET_CURRENT_CONTEXT(ctx);
986
987 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
988 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv");
989 if (v != NULL) {
990 COPY_4V(params, v);
991 }
992 }
993 else {
994 params[0] = (GLfloat) get_vertex_array_attrib(ctx, ctx->Array.VAO,
995 index, pname,
996 "glGetVertexAttribfv");
997 }
998 }
999
1000
1001 void GLAPIENTRY
1002 _mesa_GetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params)
1003 {
1004 GET_CURRENT_CONTEXT(ctx);
1005
1006 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1007 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv");
1008 if (v != NULL) {
1009 params[0] = (GLdouble) v[0];
1010 params[1] = (GLdouble) v[1];
1011 params[2] = (GLdouble) v[2];
1012 params[3] = (GLdouble) v[3];
1013 }
1014 }
1015 else {
1016 params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1017 index, pname,
1018 "glGetVertexAttribdv");
1019 }
1020 }
1021
1022 void GLAPIENTRY
1023 _mesa_GetVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params)
1024 {
1025 GET_CURRENT_CONTEXT(ctx);
1026
1027 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1028 const GLdouble *v =
1029 (const GLdouble *)get_current_attrib(ctx, index,
1030 "glGetVertexAttribLdv");
1031 if (v != NULL) {
1032 params[0] = v[0];
1033 params[1] = v[1];
1034 params[2] = v[2];
1035 params[3] = v[3];
1036 }
1037 }
1038 else {
1039 params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1040 index, pname,
1041 "glGetVertexAttribLdv");
1042 }
1043 }
1044
1045 void GLAPIENTRY
1046 _mesa_GetVertexAttribiv(GLuint index, GLenum pname, GLint *params)
1047 {
1048 GET_CURRENT_CONTEXT(ctx);
1049
1050 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1051 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv");
1052 if (v != NULL) {
1053 /* XXX should floats in[0,1] be scaled to full int range? */
1054 params[0] = (GLint) v[0];
1055 params[1] = (GLint) v[1];
1056 params[2] = (GLint) v[2];
1057 params[3] = (GLint) v[3];
1058 }
1059 }
1060 else {
1061 params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1062 index, pname,
1063 "glGetVertexAttribiv");
1064 }
1065 }
1066
1067
1068 /** GL 3.0 */
1069 void GLAPIENTRY
1070 _mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
1071 {
1072 GET_CURRENT_CONTEXT(ctx);
1073
1074 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1075 const GLint *v = (const GLint *)
1076 get_current_attrib(ctx, index, "glGetVertexAttribIiv");
1077 if (v != NULL) {
1078 COPY_4V(params, v);
1079 }
1080 }
1081 else {
1082 params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1083 index, pname,
1084 "glGetVertexAttribIiv");
1085 }
1086 }
1087
1088
1089 /** GL 3.0 */
1090 void GLAPIENTRY
1091 _mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
1092 {
1093 GET_CURRENT_CONTEXT(ctx);
1094
1095 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1096 const GLuint *v = (const GLuint *)
1097 get_current_attrib(ctx, index, "glGetVertexAttribIuiv");
1098 if (v != NULL) {
1099 COPY_4V(params, v);
1100 }
1101 }
1102 else {
1103 params[0] = get_vertex_array_attrib(ctx, ctx->Array.VAO,
1104 index, pname,
1105 "glGetVertexAttribIuiv");
1106 }
1107 }
1108
1109
1110 void GLAPIENTRY
1111 _mesa_GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
1112 {
1113 GET_CURRENT_CONTEXT(ctx);
1114
1115 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1116 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
1117 return;
1118 }
1119
1120 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
1121 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
1122 return;
1123 }
1124
1125 assert(VERT_ATTRIB_GENERIC(index) <
1126 ARRAY_SIZE(ctx->Array.VAO->VertexAttrib));
1127
1128 *pointer = (GLvoid *)
1129 ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr;
1130 }
1131
1132
1133 /** ARB_direct_state_access */
1134 void GLAPIENTRY
1135 _mesa_GetVertexArrayIndexediv(GLuint vaobj, GLuint index,
1136 GLenum pname, GLint *params)
1137 {
1138 GET_CURRENT_CONTEXT(ctx);
1139 struct gl_vertex_array_object *vao;
1140
1141 /* The ARB_direct_state_access specification says:
1142 *
1143 * "An INVALID_OPERATION error is generated if <vaobj> is not
1144 * [compatibility profile: zero or] the name of an existing
1145 * vertex array object."
1146 */
1147 vao = _mesa_lookup_vao_err(ctx, vaobj, "glGetVertexArrayIndexediv");
1148 if (!vao)
1149 return;
1150
1151 /* The ARB_direct_state_access specification says:
1152 *
1153 * "For GetVertexArrayIndexediv, <pname> must be one of
1154 * VERTEX_ATTRIB_ARRAY_ENABLED, VERTEX_ATTRIB_ARRAY_SIZE,
1155 * VERTEX_ATTRIB_ARRAY_STRIDE, VERTEX_ATTRIB_ARRAY_TYPE,
1156 * VERTEX_ATTRIB_ARRAY_NORMALIZED, VERTEX_ATTRIB_ARRAY_INTEGER,
1157 * VERTEX_ATTRIB_ARRAY_LONG, VERTEX_ATTRIB_ARRAY_DIVISOR, or
1158 * VERTEX_ATTRIB_RELATIVE_OFFSET."
1159 *
1160 * and:
1161 *
1162 * "Add GetVertexArrayIndexediv in 'Get Command' for
1163 * VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
1164 * VERTEX_ATTRIB_BINDING,
1165 * VERTEX_ATTRIB_RELATIVE_OFFSET,
1166 * VERTEX_BINDING_OFFSET, and
1167 * VERTEX_BINDING_STRIDE states"
1168 *
1169 * The only parameter name common to both lists is
1170 * VERTEX_ATTRIB_RELATIVE_OFFSET. Also note that VERTEX_BINDING_BUFFER
1171 * and VERTEX_BINDING_DIVISOR are missing from both lists. It seems
1172 * pretty clear however that the intent is that it should be possible
1173 * to query all vertex attrib and binding states that can be set with
1174 * a DSA function.
1175 */
1176 switch (pname) {
1177 case GL_VERTEX_BINDING_OFFSET:
1178 params[0] = vao->VertexBinding[VERT_ATTRIB_GENERIC(index)].Offset;
1179 break;
1180 case GL_VERTEX_BINDING_STRIDE:
1181 params[0] = vao->VertexBinding[VERT_ATTRIB_GENERIC(index)].Stride;
1182 break;
1183 case GL_VERTEX_BINDING_DIVISOR:
1184 params[0] = vao->VertexBinding[VERT_ATTRIB_GENERIC(index)].InstanceDivisor;
1185 break;
1186 case GL_VERTEX_BINDING_BUFFER:
1187 params[0] = vao->VertexBinding[VERT_ATTRIB_GENERIC(index)].BufferObj->Name;
1188 break;
1189 default:
1190 params[0] = get_vertex_array_attrib(ctx, vao, index, pname,
1191 "glGetVertexArrayIndexediv");
1192 break;
1193 }
1194 }
1195
1196
1197 void GLAPIENTRY
1198 _mesa_GetVertexArrayIndexed64iv(GLuint vaobj, GLuint index,
1199 GLenum pname, GLint64 *params)
1200 {
1201 GET_CURRENT_CONTEXT(ctx);
1202 struct gl_vertex_array_object *vao;
1203
1204 /* The ARB_direct_state_access specification says:
1205 *
1206 * "An INVALID_OPERATION error is generated if <vaobj> is not
1207 * [compatibility profile: zero or] the name of an existing
1208 * vertex array object."
1209 */
1210 vao = _mesa_lookup_vao_err(ctx, vaobj, "glGetVertexArrayIndexed64iv");
1211 if (!vao)
1212 return;
1213
1214 /* The ARB_direct_state_access specification says:
1215 *
1216 * "For GetVertexArrayIndexed64iv, <pname> must be
1217 * VERTEX_BINDING_OFFSET."
1218 *
1219 * and:
1220 *
1221 * "An INVALID_ENUM error is generated if <pname> is not one of
1222 * the valid values listed above for the corresponding command."
1223 */
1224 if (pname != GL_VERTEX_BINDING_OFFSET) {
1225 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayIndexed64iv("
1226 "pname != GL_VERTEX_BINDING_OFFSET)");
1227 return;
1228 }
1229
1230 /* The ARB_direct_state_access specification says:
1231 *
1232 * "An INVALID_VALUE error is generated if <index> is greater than
1233 * or equal to the value of MAX_VERTEX_ATTRIBS."
1234 *
1235 * Since the index refers to a buffer binding in this case, the intended
1236 * limit must be MAX_VERTEX_ATTRIB_BINDINGS. Both limits are currently
1237 * required to be the same, so in practice this doesn't matter.
1238 */
1239 if (index >= ctx->Const.MaxVertexAttribBindings) {
1240 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexArrayIndexed64iv(index"
1241 "%d >= the value of GL_MAX_VERTEX_ATTRIB_BINDINGS (%d))",
1242 index, ctx->Const.MaxVertexAttribBindings);
1243 return;
1244 }
1245
1246 params[0] = vao->VertexBinding[VERT_ATTRIB_GENERIC(index)].Offset;
1247 }
1248
1249
1250 void GLAPIENTRY
1251 _mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
1252 GLsizei count, const GLvoid *ptr)
1253 {
1254 (void) count;
1255 _mesa_VertexPointer(size, type, stride, ptr);
1256 }
1257
1258
1259 void GLAPIENTRY
1260 _mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
1261 const GLvoid *ptr)
1262 {
1263 (void) count;
1264 _mesa_NormalPointer(type, stride, ptr);
1265 }
1266
1267
1268 void GLAPIENTRY
1269 _mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
1270 const GLvoid *ptr)
1271 {
1272 (void) count;
1273 _mesa_ColorPointer(size, type, stride, ptr);
1274 }
1275
1276
1277 void GLAPIENTRY
1278 _mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
1279 const GLvoid *ptr)
1280 {
1281 (void) count;
1282 _mesa_IndexPointer(type, stride, ptr);
1283 }
1284
1285
1286 void GLAPIENTRY
1287 _mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
1288 GLsizei count, const GLvoid *ptr)
1289 {
1290 (void) count;
1291 _mesa_TexCoordPointer(size, type, stride, ptr);
1292 }
1293
1294
1295 void GLAPIENTRY
1296 _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
1297 {
1298 (void) count;
1299 _mesa_EdgeFlagPointer(stride, ptr);
1300 }
1301
1302
1303 void GLAPIENTRY
1304 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
1305 {
1306 GET_CURRENT_CONTEXT(ctx);
1307 GLboolean tflag, cflag, nflag; /* enable/disable flags */
1308 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
1309 GLenum ctype = 0; /* color type */
1310 GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
1311 const GLint toffset = 0; /* always zero */
1312 GLint defstride; /* default stride */
1313 GLint c, f;
1314
1315 FLUSH_VERTICES(ctx, 0);
1316
1317 f = sizeof(GLfloat);
1318 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
1319
1320 if (stride < 0) {
1321 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
1322 return;
1323 }
1324
1325 switch (format) {
1326 case GL_V2F:
1327 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1328 tcomps = 0; ccomps = 0; vcomps = 2;
1329 voffset = 0;
1330 defstride = 2*f;
1331 break;
1332 case GL_V3F:
1333 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1334 tcomps = 0; ccomps = 0; vcomps = 3;
1335 voffset = 0;
1336 defstride = 3*f;
1337 break;
1338 case GL_C4UB_V2F:
1339 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1340 tcomps = 0; ccomps = 4; vcomps = 2;
1341 ctype = GL_UNSIGNED_BYTE;
1342 coffset = 0;
1343 voffset = c;
1344 defstride = c + 2*f;
1345 break;
1346 case GL_C4UB_V3F:
1347 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1348 tcomps = 0; ccomps = 4; vcomps = 3;
1349 ctype = GL_UNSIGNED_BYTE;
1350 coffset = 0;
1351 voffset = c;
1352 defstride = c + 3*f;
1353 break;
1354 case GL_C3F_V3F:
1355 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1356 tcomps = 0; ccomps = 3; vcomps = 3;
1357 ctype = GL_FLOAT;
1358 coffset = 0;
1359 voffset = 3*f;
1360 defstride = 6*f;
1361 break;
1362 case GL_N3F_V3F:
1363 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
1364 tcomps = 0; ccomps = 0; vcomps = 3;
1365 noffset = 0;
1366 voffset = 3*f;
1367 defstride = 6*f;
1368 break;
1369 case GL_C4F_N3F_V3F:
1370 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
1371 tcomps = 0; ccomps = 4; vcomps = 3;
1372 ctype = GL_FLOAT;
1373 coffset = 0;
1374 noffset = 4*f;
1375 voffset = 7*f;
1376 defstride = 10*f;
1377 break;
1378 case GL_T2F_V3F:
1379 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1380 tcomps = 2; ccomps = 0; vcomps = 3;
1381 voffset = 2*f;
1382 defstride = 5*f;
1383 break;
1384 case GL_T4F_V4F:
1385 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1386 tcomps = 4; ccomps = 0; vcomps = 4;
1387 voffset = 4*f;
1388 defstride = 8*f;
1389 break;
1390 case GL_T2F_C4UB_V3F:
1391 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1392 tcomps = 2; ccomps = 4; vcomps = 3;
1393 ctype = GL_UNSIGNED_BYTE;
1394 coffset = 2*f;
1395 voffset = c+2*f;
1396 defstride = c+5*f;
1397 break;
1398 case GL_T2F_C3F_V3F:
1399 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1400 tcomps = 2; ccomps = 3; vcomps = 3;
1401 ctype = GL_FLOAT;
1402 coffset = 2*f;
1403 voffset = 5*f;
1404 defstride = 8*f;
1405 break;
1406 case GL_T2F_N3F_V3F:
1407 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
1408 tcomps = 2; ccomps = 0; vcomps = 3;
1409 noffset = 2*f;
1410 voffset = 5*f;
1411 defstride = 8*f;
1412 break;
1413 case GL_T2F_C4F_N3F_V3F:
1414 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1415 tcomps = 2; ccomps = 4; vcomps = 3;
1416 ctype = GL_FLOAT;
1417 coffset = 2*f;
1418 noffset = 6*f;
1419 voffset = 9*f;
1420 defstride = 12*f;
1421 break;
1422 case GL_T4F_C4F_N3F_V4F:
1423 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1424 tcomps = 4; ccomps = 4; vcomps = 4;
1425 ctype = GL_FLOAT;
1426 coffset = 4*f;
1427 noffset = 8*f;
1428 voffset = 11*f;
1429 defstride = 15*f;
1430 break;
1431 default:
1432 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
1433 return;
1434 }
1435
1436 if (stride==0) {
1437 stride = defstride;
1438 }
1439
1440 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
1441 _mesa_DisableClientState( GL_INDEX_ARRAY );
1442 /* XXX also disable secondary color and generic arrays? */
1443
1444 /* Texcoords */
1445 if (tflag) {
1446 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
1447 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
1448 (GLubyte *) pointer + toffset );
1449 }
1450 else {
1451 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
1452 }
1453
1454 /* Color */
1455 if (cflag) {
1456 _mesa_EnableClientState( GL_COLOR_ARRAY );
1457 _mesa_ColorPointer( ccomps, ctype, stride,
1458 (GLubyte *) pointer + coffset );
1459 }
1460 else {
1461 _mesa_DisableClientState( GL_COLOR_ARRAY );
1462 }
1463
1464
1465 /* Normals */
1466 if (nflag) {
1467 _mesa_EnableClientState( GL_NORMAL_ARRAY );
1468 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset );
1469 }
1470 else {
1471 _mesa_DisableClientState( GL_NORMAL_ARRAY );
1472 }
1473
1474 /* Vertices */
1475 _mesa_EnableClientState( GL_VERTEX_ARRAY );
1476 _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
1477 (GLubyte *) pointer + voffset );
1478 }
1479
1480
1481 void GLAPIENTRY
1482 _mesa_LockArraysEXT(GLint first, GLsizei count)
1483 {
1484 GET_CURRENT_CONTEXT(ctx);
1485
1486 FLUSH_VERTICES(ctx, 0);
1487
1488 if (MESA_VERBOSE & VERBOSE_API)
1489 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
1490
1491 if (first < 0) {
1492 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" );
1493 return;
1494 }
1495 if (count <= 0) {
1496 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" );
1497 return;
1498 }
1499 if (ctx->Array.LockCount != 0) {
1500 _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" );
1501 return;
1502 }
1503
1504 ctx->Array.LockFirst = first;
1505 ctx->Array.LockCount = count;
1506
1507 ctx->NewState |= _NEW_ARRAY;
1508 }
1509
1510
1511 void GLAPIENTRY
1512 _mesa_UnlockArraysEXT( void )
1513 {
1514 GET_CURRENT_CONTEXT(ctx);
1515
1516 FLUSH_VERTICES(ctx, 0);
1517
1518 if (MESA_VERBOSE & VERBOSE_API)
1519 _mesa_debug(ctx, "glUnlockArrays\n");
1520
1521 if (ctx->Array.LockCount == 0) {
1522 _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" );
1523 return;
1524 }
1525
1526 ctx->Array.LockFirst = 0;
1527 ctx->Array.LockCount = 0;
1528 ctx->NewState |= _NEW_ARRAY;
1529 }
1530
1531
1532 /* GL_EXT_multi_draw_arrays */
1533 void GLAPIENTRY
1534 _mesa_MultiDrawArrays( GLenum mode, const GLint *first,
1535 const GLsizei *count, GLsizei primcount )
1536 {
1537 GET_CURRENT_CONTEXT(ctx);
1538 GLint i;
1539
1540 FLUSH_VERTICES(ctx, 0);
1541
1542 for (i = 0; i < primcount; i++) {
1543 if (count[i] > 0) {
1544 CALL_DrawArrays(ctx->CurrentDispatch, (mode, first[i], count[i]));
1545 }
1546 }
1547 }
1548
1549
1550 /* GL_IBM_multimode_draw_arrays */
1551 void GLAPIENTRY
1552 _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
1553 const GLsizei * count,
1554 GLsizei primcount, GLint modestride )
1555 {
1556 GET_CURRENT_CONTEXT(ctx);
1557 GLint i;
1558
1559 FLUSH_VERTICES(ctx, 0);
1560
1561 for ( i = 0 ; i < primcount ; i++ ) {
1562 if ( count[i] > 0 ) {
1563 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1564 CALL_DrawArrays(ctx->CurrentDispatch, ( m, first[i], count[i] ));
1565 }
1566 }
1567 }
1568
1569
1570 /* GL_IBM_multimode_draw_arrays */
1571 void GLAPIENTRY
1572 _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
1573 GLenum type, const GLvoid * const * indices,
1574 GLsizei primcount, GLint modestride )
1575 {
1576 GET_CURRENT_CONTEXT(ctx);
1577 GLint i;
1578
1579 FLUSH_VERTICES(ctx, 0);
1580
1581 /* XXX not sure about ARB_vertex_buffer_object handling here */
1582
1583 for ( i = 0 ; i < primcount ; i++ ) {
1584 if ( count[i] > 0 ) {
1585 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1586 CALL_DrawElements(ctx->CurrentDispatch, ( m, count[i], type,
1587 indices[i] ));
1588 }
1589 }
1590 }
1591
1592
1593 /**
1594 * GL_NV_primitive_restart and GL 3.1
1595 */
1596 void GLAPIENTRY
1597 _mesa_PrimitiveRestartIndex(GLuint index)
1598 {
1599 GET_CURRENT_CONTEXT(ctx);
1600
1601 if (!ctx->Extensions.NV_primitive_restart && ctx->Version < 31) {
1602 _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()");
1603 return;
1604 }
1605
1606 if (ctx->Array.RestartIndex != index) {
1607 FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
1608 ctx->Array.RestartIndex = index;
1609 }
1610 }
1611
1612
1613 /**
1614 * See GL_ARB_instanced_arrays.
1615 * Note that the instance divisor only applies to generic arrays, not
1616 * the legacy vertex arrays.
1617 */
1618 void GLAPIENTRY
1619 _mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
1620 {
1621 GET_CURRENT_CONTEXT(ctx);
1622
1623 const GLuint genericIndex = VERT_ATTRIB_GENERIC(index);
1624 struct gl_vertex_array_object * const vao = ctx->Array.VAO;
1625
1626 if (!ctx->Extensions.ARB_instanced_arrays) {
1627 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
1628 return;
1629 }
1630
1631 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1632 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribDivisor(index = %u)",
1633 index);
1634 return;
1635 }
1636
1637 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
1638
1639 /* The ARB_vertex_attrib_binding spec says:
1640 *
1641 * "The command
1642 *
1643 * void VertexAttribDivisor(uint index, uint divisor);
1644 *
1645 * is equivalent to (assuming no errors are generated):
1646 *
1647 * VertexAttribBinding(index, index);
1648 * VertexBindingDivisor(index, divisor);"
1649 */
1650 vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
1651 vertex_binding_divisor(ctx, vao, genericIndex, divisor);
1652 }
1653
1654
1655 unsigned
1656 _mesa_primitive_restart_index(const struct gl_context *ctx, GLenum ib_type)
1657 {
1658 /* From the OpenGL 4.3 core specification, page 302:
1659 * "If both PRIMITIVE_RESTART and PRIMITIVE_RESTART_FIXED_INDEX are
1660 * enabled, the index value determined by PRIMITIVE_RESTART_FIXED_INDEX
1661 * is used."
1662 */
1663 if (ctx->Array.PrimitiveRestartFixedIndex) {
1664 switch (ib_type) {
1665 case GL_UNSIGNED_BYTE:
1666 return 0xff;
1667 case GL_UNSIGNED_SHORT:
1668 return 0xffff;
1669 case GL_UNSIGNED_INT:
1670 return 0xffffffff;
1671 default:
1672 assert(!"_mesa_primitive_restart_index: Invalid index buffer type.");
1673 }
1674 }
1675
1676 return ctx->Array.RestartIndex;
1677 }
1678
1679
1680 /**
1681 * GL_ARB_vertex_attrib_binding
1682 */
1683 static void
1684 vertex_array_vertex_buffer(struct gl_context *ctx,
1685 struct gl_vertex_array_object *vao,
1686 GLuint bindingIndex, GLuint buffer, GLintptr offset,
1687 GLsizei stride, const char *func)
1688 {
1689 struct gl_buffer_object *vbo;
1690
1691 ASSERT_OUTSIDE_BEGIN_END(ctx);
1692
1693 /* The ARB_vertex_attrib_binding spec says:
1694 *
1695 * "An INVALID_VALUE error is generated if <bindingindex> is greater than
1696 * the value of MAX_VERTEX_ATTRIB_BINDINGS."
1697 */
1698 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
1699 _mesa_error(ctx, GL_INVALID_VALUE,
1700 "%s(bindingindex=%u > "
1701 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
1702 func, bindingIndex);
1703 return;
1704 }
1705
1706 /* The ARB_vertex_attrib_binding spec says:
1707 *
1708 * "The error INVALID_VALUE is generated if <stride> or <offset>
1709 * are negative."
1710 */
1711 if (offset < 0) {
1712 _mesa_error(ctx, GL_INVALID_VALUE,
1713 "%s(offset=%" PRId64 " < 0)",
1714 func, (int64_t) offset);
1715 return;
1716 }
1717
1718 if (stride < 0) {
1719 _mesa_error(ctx, GL_INVALID_VALUE,
1720 "%s(stride=%d < 0)", func, stride);
1721 return;
1722 }
1723
1724 if (((ctx->API == API_OPENGL_CORE && ctx->Version >= 44) || _mesa_is_gles31(ctx)) &&
1725 stride > ctx->Const.MaxVertexAttribStride) {
1726 _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > "
1727 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride);
1728 return;
1729 }
1730
1731 if (buffer ==
1732 vao->VertexBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj->Name) {
1733 vbo = vao->VertexBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj;
1734 } else if (buffer != 0) {
1735 vbo = _mesa_lookup_bufferobj(ctx, buffer);
1736
1737 /* From the GL_ARB_vertex_attrib_array spec:
1738 *
1739 * "[Core profile only:]
1740 * An INVALID_OPERATION error is generated if buffer is not zero or a
1741 * name returned from a previous call to GenBuffers, or if such a name
1742 * has since been deleted with DeleteBuffers.
1743 *
1744 * Otherwise, we fall back to the same compat profile behavior as other
1745 * object references (automatically gen it).
1746 */
1747 if (!_mesa_handle_bind_buffer_gen(ctx, buffer, &vbo, func))
1748 return;
1749 } else {
1750 /* The ARB_vertex_attrib_binding spec says:
1751 *
1752 * "If <buffer> is zero, any buffer object attached to this
1753 * bindpoint is detached."
1754 */
1755 vbo = ctx->Shared->NullBufferObj;
1756 }
1757
1758 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex),
1759 vbo, offset, stride);
1760 }
1761
1762
1763 void GLAPIENTRY
1764 _mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset,
1765 GLsizei stride)
1766 {
1767 GET_CURRENT_CONTEXT(ctx);
1768
1769 /* The ARB_vertex_attrib_binding spec says:
1770 *
1771 * "An INVALID_OPERATION error is generated if no vertex array object
1772 * is bound."
1773 */
1774 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
1775 ctx->Array.VAO == ctx->Array.DefaultVAO) {
1776 _mesa_error(ctx, GL_INVALID_OPERATION,
1777 "glBindVertexBuffer(No array object bound)");
1778 return;
1779 }
1780
1781 vertex_array_vertex_buffer(ctx, ctx->Array.VAO, bindingIndex,
1782 buffer, offset, stride, "glBindVertexBuffer");
1783 }
1784
1785
1786 void GLAPIENTRY
1787 _mesa_VertexArrayVertexBuffer(GLuint vaobj, GLuint bindingIndex, GLuint buffer,
1788 GLintptr offset, GLsizei stride)
1789 {
1790 GET_CURRENT_CONTEXT(ctx);
1791 struct gl_vertex_array_object *vao;
1792
1793 /* The ARB_direct_state_access specification says:
1794 *
1795 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
1796 * if <vaobj> is not [compatibility profile: zero or] the name of an
1797 * existing vertex array object."
1798 */
1799 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffer");
1800 if (!vao)
1801 return;
1802
1803 vertex_array_vertex_buffer(ctx, vao, bindingIndex,
1804 buffer, offset, stride,
1805 "glVertexArrayVertexBuffer");
1806 }
1807
1808
1809 static void
1810 vertex_array_vertex_buffers(struct gl_context *ctx,
1811 struct gl_vertex_array_object *vao,
1812 GLuint first, GLsizei count, const GLuint *buffers,
1813 const GLintptr *offsets, const GLsizei *strides,
1814 const char *func)
1815 {
1816 GLuint i;
1817
1818 ASSERT_OUTSIDE_BEGIN_END(ctx);
1819
1820 /* The ARB_multi_bind spec says:
1821 *
1822 * "An INVALID_OPERATION error is generated if <first> + <count>
1823 * is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS."
1824 */
1825 if (first + count > ctx->Const.MaxVertexAttribBindings) {
1826 _mesa_error(ctx, GL_INVALID_OPERATION,
1827 "%s(first=%u + count=%d > the value of "
1828 "GL_MAX_VERTEX_ATTRIB_BINDINGS=%u)",
1829 func, first, count, ctx->Const.MaxVertexAttribBindings);
1830 return;
1831 }
1832
1833 if (!buffers) {
1834 /**
1835 * The ARB_multi_bind spec says:
1836 *
1837 * "If <buffers> is NULL, each affected vertex buffer binding point
1838 * from <first> through <first>+<count>-1 will be reset to have no
1839 * bound buffer object. In this case, the offsets and strides
1840 * associated with the binding points are set to default values,
1841 * ignoring <offsets> and <strides>."
1842 */
1843 struct gl_buffer_object *vbo = ctx->Shared->NullBufferObj;
1844
1845 for (i = 0; i < count; i++)
1846 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
1847 vbo, 0, 16);
1848
1849 return;
1850 }
1851
1852 /* Note that the error semantics for multi-bind commands differ from
1853 * those of other GL commands.
1854 *
1855 * The Issues section in the ARB_multi_bind spec says:
1856 *
1857 * "(11) Typically, OpenGL specifies that if an error is generated by
1858 * a command, that command has no effect. This is somewhat
1859 * unfortunate for multi-bind commands, because it would require
1860 * a first pass to scan the entire list of bound objects for
1861 * errors and then a second pass to actually perform the
1862 * bindings. Should we have different error semantics?
1863 *
1864 * RESOLVED: Yes. In this specification, when the parameters for
1865 * one of the <count> binding points are invalid, that binding
1866 * point is not updated and an error will be generated. However,
1867 * other binding points in the same command will be updated if
1868 * their parameters are valid and no other error occurs."
1869 */
1870
1871 _mesa_begin_bufferobj_lookups(ctx);
1872
1873 for (i = 0; i < count; i++) {
1874 struct gl_buffer_object *vbo;
1875
1876 /* The ARB_multi_bind spec says:
1877 *
1878 * "An INVALID_VALUE error is generated if any value in
1879 * <offsets> or <strides> is negative (per binding)."
1880 */
1881 if (offsets[i] < 0) {
1882 _mesa_error(ctx, GL_INVALID_VALUE,
1883 "%s(offsets[%u]=%" PRId64 " < 0)",
1884 func, i, (int64_t) offsets[i]);
1885 continue;
1886 }
1887
1888 if (strides[i] < 0) {
1889 _mesa_error(ctx, GL_INVALID_VALUE,
1890 "%s(strides[%u]=%d < 0)",
1891 func, i, strides[i]);
1892 continue;
1893 }
1894
1895 if (ctx->API == API_OPENGL_CORE && ctx->Version >= 44 &&
1896 strides[i] > ctx->Const.MaxVertexAttribStride) {
1897 _mesa_error(ctx, GL_INVALID_VALUE,
1898 "%s(strides[%u]=%d > "
1899 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, i, strides[i]);
1900 continue;
1901 }
1902
1903 if (buffers[i]) {
1904 struct gl_vertex_buffer_binding *binding =
1905 &vao->VertexBinding[VERT_ATTRIB_GENERIC(first + i)];
1906
1907 if (buffers[i] == binding->BufferObj->Name)
1908 vbo = binding->BufferObj;
1909 else
1910 vbo = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, func);
1911
1912 if (!vbo)
1913 continue;
1914 } else {
1915 vbo = ctx->Shared->NullBufferObj;
1916 }
1917
1918 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
1919 vbo, offsets[i], strides[i]);
1920 }
1921
1922 _mesa_end_bufferobj_lookups(ctx);
1923 }
1924
1925
1926 void GLAPIENTRY
1927 _mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers,
1928 const GLintptr *offsets, const GLsizei *strides)
1929 {
1930 GET_CURRENT_CONTEXT(ctx);
1931
1932 /* The ARB_vertex_attrib_binding spec says:
1933 *
1934 * "An INVALID_OPERATION error is generated if no
1935 * vertex array object is bound."
1936 */
1937 if (ctx->API == API_OPENGL_CORE &&
1938 ctx->Array.VAO == ctx->Array.DefaultVAO) {
1939 _mesa_error(ctx, GL_INVALID_OPERATION,
1940 "glBindVertexBuffers(No array object bound)");
1941 return;
1942 }
1943
1944 vertex_array_vertex_buffers(ctx, ctx->Array.VAO, first, count,
1945 buffers, offsets, strides,
1946 "glBindVertexBuffers");
1947 }
1948
1949
1950 void GLAPIENTRY
1951 _mesa_VertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count,
1952 const GLuint *buffers,
1953 const GLintptr *offsets, const GLsizei *strides)
1954 {
1955 GET_CURRENT_CONTEXT(ctx);
1956 struct gl_vertex_array_object *vao;
1957
1958 /* The ARB_direct_state_access specification says:
1959 *
1960 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
1961 * if <vaobj> is not [compatibility profile: zero or] the name of an
1962 * existing vertex array object."
1963 */
1964 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffers");
1965 if (!vao)
1966 return;
1967
1968 vertex_array_vertex_buffers(ctx, vao, first, count,
1969 buffers, offsets, strides,
1970 "glVertexArrayVertexBuffers");
1971 }
1972
1973
1974 static void
1975 vertex_attrib_format(GLuint attribIndex, GLint size, GLenum type,
1976 GLboolean normalized, GLboolean integer,
1977 GLboolean doubles, GLbitfield legalTypes,
1978 GLsizei maxSize, GLuint relativeOffset,
1979 const char *func)
1980 {
1981 GET_CURRENT_CONTEXT(ctx);
1982 ASSERT_OUTSIDE_BEGIN_END(ctx);
1983
1984 /* The ARB_vertex_attrib_binding spec says:
1985 *
1986 * "An INVALID_OPERATION error is generated under any of the following
1987 * conditions:
1988 * - if no vertex array object is currently bound (see section 2.10);
1989 * - ..."
1990 *
1991 * This error condition only applies to VertexAttribFormat and
1992 * VertexAttribIFormat in the extension spec, but we assume that this
1993 * is an oversight. In the OpenGL 4.3 (Core Profile) spec, it applies
1994 * to all three functions.
1995 */
1996 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
1997 ctx->Array.VAO == ctx->Array.DefaultVAO) {
1998 _mesa_error(ctx, GL_INVALID_OPERATION,
1999 "%s(No array object bound)", func);
2000 return;
2001 }
2002
2003 /* The ARB_vertex_attrib_binding spec says:
2004 *
2005 * "The error INVALID_VALUE is generated if index is greater than or equal
2006 * to the value of MAX_VERTEX_ATTRIBS."
2007 */
2008 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2009 _mesa_error(ctx, GL_INVALID_VALUE,
2010 "%s(attribindex=%u > "
2011 "GL_MAX_VERTEX_ATTRIBS)",
2012 func, attribIndex);
2013 return;
2014 }
2015
2016 FLUSH_VERTICES(ctx, 0);
2017
2018 update_array_format(ctx, func, ctx->Array.VAO,
2019 VERT_ATTRIB_GENERIC(attribIndex),
2020 legalTypes, 1, maxSize, size, type,
2021 normalized, integer, doubles, relativeOffset);
2022 }
2023
2024
2025 void GLAPIENTRY
2026 _mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type,
2027 GLboolean normalized, GLuint relativeOffset)
2028 {
2029 vertex_attrib_format(attribIndex, size, type, normalized,
2030 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
2031 BGRA_OR_4, relativeOffset,
2032 "glVertexAttribFormat");
2033 }
2034
2035
2036 void GLAPIENTRY
2037 _mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type,
2038 GLuint relativeOffset)
2039 {
2040 vertex_attrib_format(attribIndex, size, type, GL_FALSE,
2041 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK, 4,
2042 relativeOffset, "glVertexAttribIFormat");
2043 }
2044
2045
2046 void GLAPIENTRY
2047 _mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type,
2048 GLuint relativeOffset)
2049 {
2050 vertex_attrib_format(attribIndex, size, type, GL_FALSE, GL_FALSE,
2051 GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK, 4,
2052 relativeOffset, "glVertexAttribLFormat");
2053 }
2054
2055
2056 static void
2057 vertex_array_attrib_format(GLuint vaobj, GLuint attribIndex, GLint size,
2058 GLenum type, GLboolean normalized,
2059 GLboolean integer, GLboolean doubles,
2060 GLbitfield legalTypes, GLsizei maxSize,
2061 GLuint relativeOffset, const char *func)
2062 {
2063 GET_CURRENT_CONTEXT(ctx);
2064 struct gl_vertex_array_object *vao;
2065
2066 ASSERT_OUTSIDE_BEGIN_END(ctx);
2067
2068 /* The ARB_direct_state_access spec says:
2069 *
2070 * "An INVALID_OPERATION error is generated by VertexArrayAttrib*Format
2071 * if <vaobj> is not [compatibility profile: zero or] the name of an
2072 * existing vertex array object."
2073 */
2074 vao = _mesa_lookup_vao_err(ctx, vaobj, func);
2075 if (!vao)
2076 return;
2077
2078 /* The ARB_vertex_attrib_binding spec says:
2079 *
2080 * "The error INVALID_VALUE is generated if index is greater than or equal
2081 * to the value of MAX_VERTEX_ATTRIBS."
2082 */
2083 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2084 _mesa_error(ctx, GL_INVALID_VALUE,
2085 "%s(attribindex=%u > GL_MAX_VERTEX_ATTRIBS)",
2086 func, attribIndex);
2087 return;
2088 }
2089
2090 FLUSH_VERTICES(ctx, 0);
2091
2092 update_array_format(ctx, func, vao,
2093 VERT_ATTRIB_GENERIC(attribIndex),
2094 legalTypes, 1, maxSize, size, type, normalized,
2095 integer, doubles, relativeOffset);
2096 }
2097
2098
2099 void GLAPIENTRY
2100 _mesa_VertexArrayAttribFormat(GLuint vaobj, GLuint attribIndex, GLint size,
2101 GLenum type, GLboolean normalized,
2102 GLuint relativeOffset)
2103 {
2104 vertex_array_attrib_format(vaobj, attribIndex, size, type, normalized,
2105 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
2106 BGRA_OR_4, relativeOffset,
2107 "glVertexArrayAttribFormat");
2108 }
2109
2110
2111 void GLAPIENTRY
2112 _mesa_VertexArrayAttribIFormat(GLuint vaobj, GLuint attribIndex,
2113 GLint size, GLenum type,
2114 GLuint relativeOffset)
2115 {
2116 vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE,
2117 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK,
2118 4, relativeOffset,
2119 "glVertexArrayAttribIFormat");
2120 }
2121
2122
2123 void GLAPIENTRY
2124 _mesa_VertexArrayAttribLFormat(GLuint vaobj, GLuint attribIndex,
2125 GLint size, GLenum type,
2126 GLuint relativeOffset)
2127 {
2128 vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE,
2129 GL_FALSE, GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK,
2130 4, relativeOffset,
2131 "glVertexArrayAttribLFormat");
2132 }
2133
2134
2135 static void
2136 vertex_array_attrib_binding(struct gl_context *ctx,
2137 struct gl_vertex_array_object *vao,
2138 GLuint attribIndex, GLuint bindingIndex,
2139 const char *func)
2140 {
2141 ASSERT_OUTSIDE_BEGIN_END(ctx);
2142
2143 /* The ARB_vertex_attrib_binding spec says:
2144 *
2145 * "<attribindex> must be less than the value of MAX_VERTEX_ATTRIBS and
2146 * <bindingindex> must be less than the value of
2147 * MAX_VERTEX_ATTRIB_BINDINGS, otherwise the error INVALID_VALUE
2148 * is generated."
2149 */
2150 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2151 _mesa_error(ctx, GL_INVALID_VALUE,
2152 "%s(attribindex=%u >= "
2153 "GL_MAX_VERTEX_ATTRIBS)",
2154 func, attribIndex);
2155 return;
2156 }
2157
2158 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2159 _mesa_error(ctx, GL_INVALID_VALUE,
2160 "%s(bindingindex=%u >= "
2161 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2162 func, bindingIndex);
2163 return;
2164 }
2165
2166 assert(VERT_ATTRIB_GENERIC(attribIndex) < ARRAY_SIZE(vao->VertexAttrib));
2167
2168 vertex_attrib_binding(ctx, vao,
2169 VERT_ATTRIB_GENERIC(attribIndex),
2170 VERT_ATTRIB_GENERIC(bindingIndex));
2171 }
2172
2173
2174 void GLAPIENTRY
2175 _mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
2176 {
2177 GET_CURRENT_CONTEXT(ctx);
2178
2179 /* The ARB_vertex_attrib_binding spec says:
2180 *
2181 * "An INVALID_OPERATION error is generated if no vertex array object
2182 * is bound."
2183 */
2184 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2185 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2186 _mesa_error(ctx, GL_INVALID_OPERATION,
2187 "glVertexAttribBinding(No array object bound)");
2188 return;
2189 }
2190
2191 vertex_array_attrib_binding(ctx, ctx->Array.VAO,
2192 attribIndex, bindingIndex,
2193 "glVertexAttribBinding");
2194 }
2195
2196
2197 void GLAPIENTRY
2198 _mesa_VertexArrayAttribBinding(GLuint vaobj, GLuint attribIndex, GLuint bindingIndex)
2199 {
2200 GET_CURRENT_CONTEXT(ctx);
2201 struct gl_vertex_array_object *vao;
2202
2203 /* The ARB_direct_state_access specification says:
2204 *
2205 * "An INVALID_OPERATION error is generated by VertexArrayAttribBinding
2206 * if <vaobj> is not [compatibility profile: zero or] the name of an
2207 * existing vertex array object."
2208 */
2209 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayAttribBinding");
2210 if (!vao)
2211 return;
2212
2213 vertex_array_attrib_binding(ctx, vao, attribIndex, bindingIndex,
2214 "glVertexArrayAttribBinding");
2215 }
2216
2217
2218 static void
2219 vertex_array_binding_divisor(struct gl_context *ctx,
2220 struct gl_vertex_array_object *vao,
2221 GLuint bindingIndex, GLuint divisor,
2222 const char *func)
2223 {
2224 ASSERT_OUTSIDE_BEGIN_END(ctx);
2225
2226 if (!ctx->Extensions.ARB_instanced_arrays) {
2227 _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", func);
2228 return;
2229 }
2230
2231 /* The ARB_vertex_attrib_binding spec says:
2232 *
2233 * "An INVALID_VALUE error is generated if <bindingindex> is greater
2234 * than or equal to the value of MAX_VERTEX_ATTRIB_BINDINGS."
2235 */
2236 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2237 _mesa_error(ctx, GL_INVALID_VALUE,
2238 "%s(bindingindex=%u > "
2239 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2240 func, bindingIndex);
2241 return;
2242 }
2243
2244 vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2245 }
2246
2247
2248 void GLAPIENTRY
2249 _mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
2250 {
2251 GET_CURRENT_CONTEXT(ctx);
2252
2253 /* The ARB_vertex_attrib_binding spec says:
2254 *
2255 * "An INVALID_OPERATION error is generated if no vertex array object
2256 * is bound."
2257 */
2258 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2259 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2260 _mesa_error(ctx, GL_INVALID_OPERATION,
2261 "glVertexBindingDivisor(No array object bound)");
2262 return;
2263 }
2264
2265 vertex_array_binding_divisor(ctx, ctx->Array.VAO,
2266 bindingIndex, divisor,
2267 "glVertexBindingDivisor");
2268 }
2269
2270
2271 void GLAPIENTRY
2272 _mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex,
2273 GLuint divisor)
2274 {
2275 struct gl_vertex_array_object *vao;
2276 GET_CURRENT_CONTEXT(ctx);
2277
2278 /* The ARB_direct_state_access specification says:
2279 *
2280 * "An INVALID_OPERATION error is generated by VertexArrayBindingDivisor
2281 * if <vaobj> is not [compatibility profile: zero or] the name of an
2282 * existing vertex array object."
2283 */
2284 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayBindingDivisor");
2285 if (!vao)
2286 return;
2287
2288 vertex_array_binding_divisor(ctx, vao, bindingIndex, divisor,
2289 "glVertexArrayBindingDivisor");
2290 }
2291
2292
2293 /**
2294 * Copy one client vertex array to another.
2295 */
2296 void
2297 _mesa_copy_client_array(struct gl_context *ctx,
2298 struct gl_client_array *dst,
2299 struct gl_client_array *src)
2300 {
2301 dst->Size = src->Size;
2302 dst->Type = src->Type;
2303 dst->Format = src->Format;
2304 dst->Stride = src->Stride;
2305 dst->StrideB = src->StrideB;
2306 dst->Ptr = src->Ptr;
2307 dst->Enabled = src->Enabled;
2308 dst->Normalized = src->Normalized;
2309 dst->Integer = src->Integer;
2310 dst->Doubles = src->Doubles;
2311 dst->InstanceDivisor = src->InstanceDivisor;
2312 dst->_ElementSize = src->_ElementSize;
2313 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
2314 }
2315
2316 void
2317 _mesa_copy_vertex_attrib_array(struct gl_context *ctx,
2318 struct gl_vertex_attrib_array *dst,
2319 const struct gl_vertex_attrib_array *src)
2320 {
2321 dst->Size = src->Size;
2322 dst->Type = src->Type;
2323 dst->Format = src->Format;
2324 dst->VertexBinding = src->VertexBinding;
2325 dst->RelativeOffset = src->RelativeOffset;
2326 dst->Format = src->Format;
2327 dst->Integer = src->Integer;
2328 dst->Doubles = src->Doubles;
2329 dst->Normalized = src->Normalized;
2330 dst->Ptr = src->Ptr;
2331 dst->Enabled = src->Enabled;
2332 dst->_ElementSize = src->_ElementSize;
2333 }
2334
2335 void
2336 _mesa_copy_vertex_buffer_binding(struct gl_context *ctx,
2337 struct gl_vertex_buffer_binding *dst,
2338 const struct gl_vertex_buffer_binding *src)
2339 {
2340 dst->Offset = src->Offset;
2341 dst->Stride = src->Stride;
2342 dst->InstanceDivisor = src->InstanceDivisor;
2343 dst->_BoundArrays = src->_BoundArrays;
2344
2345 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
2346 }
2347
2348 /**
2349 * Print vertex array's fields.
2350 */
2351 static void
2352 print_array(const char *name, GLint index, const struct gl_client_array *array)
2353 {
2354 if (index >= 0)
2355 fprintf(stderr, " %s[%d]: ", name, index);
2356 else
2357 fprintf(stderr, " %s: ", name);
2358 fprintf(stderr, "Ptr=%p, Type=%s, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %lu)\n",
2359 array->Ptr, _mesa_enum_to_string(array->Type), array->Size,
2360 array->_ElementSize, array->StrideB, array->BufferObj->Name,
2361 (unsigned long) array->BufferObj->Size);
2362 }
2363
2364
2365 /**
2366 * Print current vertex object/array info. For debug.
2367 */
2368 void
2369 _mesa_print_arrays(struct gl_context *ctx)
2370 {
2371 struct gl_vertex_array_object *vao = ctx->Array.VAO;
2372 GLuint i;
2373
2374 printf("Array Object %u\n", vao->Name);
2375 if (vao->_VertexAttrib[VERT_ATTRIB_POS].Enabled)
2376 print_array("Vertex", -1, &vao->_VertexAttrib[VERT_ATTRIB_POS]);
2377 if (vao->_VertexAttrib[VERT_ATTRIB_NORMAL].Enabled)
2378 print_array("Normal", -1, &vao->_VertexAttrib[VERT_ATTRIB_NORMAL]);
2379 if (vao->_VertexAttrib[VERT_ATTRIB_COLOR0].Enabled)
2380 print_array("Color", -1, &vao->_VertexAttrib[VERT_ATTRIB_COLOR0]);
2381 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
2382 if (vao->_VertexAttrib[VERT_ATTRIB_TEX(i)].Enabled)
2383 print_array("TexCoord", i, &vao->_VertexAttrib[VERT_ATTRIB_TEX(i)]);
2384 for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++)
2385 if (vao->_VertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
2386 print_array("Attrib", i, &vao->_VertexAttrib[VERT_ATTRIB_GENERIC(i)]);
2387 }
2388
2389
2390 /**
2391 * Initialize vertex array state for given context.
2392 */
2393 void
2394 _mesa_init_varray(struct gl_context *ctx)
2395 {
2396 ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0);
2397 _mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO);
2398 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
2399
2400 ctx->Array.Objects = _mesa_NewHashTable();
2401 }
2402
2403
2404 /**
2405 * Callback for deleting an array object. Called by _mesa_HashDeleteAll().
2406 */
2407 static void
2408 delete_arrayobj_cb(GLuint id, void *data, void *userData)
2409 {
2410 struct gl_vertex_array_object *vao = (struct gl_vertex_array_object *) data;
2411 struct gl_context *ctx = (struct gl_context *) userData;
2412 _mesa_delete_vao(ctx, vao);
2413 }
2414
2415
2416 /**
2417 * Free vertex array state for given context.
2418 */
2419 void
2420 _mesa_free_varray_data(struct gl_context *ctx)
2421 {
2422 _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx);
2423 _mesa_DeleteHashTable(ctx->Array.Objects);
2424 }