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