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