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