mesa: add vao/vbo lookup helper for EXT_dsa
[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 "glformats.h"
37 #include "hash.h"
38 #include "image.h"
39 #include "macros.h"
40 #include "mtypes.h"
41 #include "varray.h"
42 #include "arrayobj.h"
43 #include "main/dispatch.h"
44
45
46 /** Used to do error checking for GL_EXT_vertex_array_bgra */
47 #define BGRA_OR_4 5
48
49
50 /** Used to indicate which GL datatypes are accepted by each of the
51 * glVertex/Color/Attrib/EtcPointer() functions.
52 */
53 #define BOOL_BIT (1 << 0)
54 #define BYTE_BIT (1 << 1)
55 #define UNSIGNED_BYTE_BIT (1 << 2)
56 #define SHORT_BIT (1 << 3)
57 #define UNSIGNED_SHORT_BIT (1 << 4)
58 #define INT_BIT (1 << 5)
59 #define UNSIGNED_INT_BIT (1 << 6)
60 #define HALF_BIT (1 << 7)
61 #define FLOAT_BIT (1 << 8)
62 #define DOUBLE_BIT (1 << 9)
63 #define FIXED_ES_BIT (1 << 10)
64 #define FIXED_GL_BIT (1 << 11)
65 #define UNSIGNED_INT_2_10_10_10_REV_BIT (1 << 12)
66 #define INT_2_10_10_10_REV_BIT (1 << 13)
67 #define UNSIGNED_INT_10F_11F_11F_REV_BIT (1 << 14)
68 #define ALL_TYPE_BITS ((1 << 15) - 1)
69
70 #define ATTRIB_FORMAT_TYPES_MASK (BYTE_BIT | UNSIGNED_BYTE_BIT | \
71 SHORT_BIT | UNSIGNED_SHORT_BIT | \
72 INT_BIT | UNSIGNED_INT_BIT | \
73 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | \
74 FIXED_GL_BIT | \
75 UNSIGNED_INT_2_10_10_10_REV_BIT | \
76 INT_2_10_10_10_REV_BIT | \
77 UNSIGNED_INT_10F_11F_11F_REV_BIT)
78
79 #define ATTRIB_IFORMAT_TYPES_MASK (BYTE_BIT | UNSIGNED_BYTE_BIT | \
80 SHORT_BIT | UNSIGNED_SHORT_BIT | \
81 INT_BIT | UNSIGNED_INT_BIT)
82
83 #define ATTRIB_LFORMAT_TYPES_MASK DOUBLE_BIT
84
85
86 /** Convert GL datatype enum into a <type>_BIT value seen above */
87 static GLbitfield
88 type_to_bit(const struct gl_context *ctx, GLenum type)
89 {
90 switch (type) {
91 case GL_BOOL:
92 return BOOL_BIT;
93 case GL_BYTE:
94 return BYTE_BIT;
95 case GL_UNSIGNED_BYTE:
96 return UNSIGNED_BYTE_BIT;
97 case GL_SHORT:
98 return SHORT_BIT;
99 case GL_UNSIGNED_SHORT:
100 return UNSIGNED_SHORT_BIT;
101 case GL_INT:
102 return INT_BIT;
103 case GL_UNSIGNED_INT:
104 return UNSIGNED_INT_BIT;
105 case GL_HALF_FLOAT:
106 case GL_HALF_FLOAT_OES:
107 if (ctx->Extensions.ARB_half_float_vertex)
108 return HALF_BIT;
109 else
110 return 0x0;
111 case GL_FLOAT:
112 return FLOAT_BIT;
113 case GL_DOUBLE:
114 return DOUBLE_BIT;
115 case GL_FIXED:
116 return _mesa_is_desktop_gl(ctx) ? FIXED_GL_BIT : FIXED_ES_BIT;
117 case GL_UNSIGNED_INT_2_10_10_10_REV:
118 return UNSIGNED_INT_2_10_10_10_REV_BIT;
119 case GL_INT_2_10_10_10_REV:
120 return INT_2_10_10_10_REV_BIT;
121 case GL_UNSIGNED_INT_10F_11F_11F_REV:
122 return UNSIGNED_INT_10F_11F_11F_REV_BIT;
123 default:
124 return 0;
125 }
126 }
127
128
129 /**
130 * Depending on the position and generic0 attributes enable flags select
131 * the one that is used for both attributes.
132 * The generic0 attribute takes precedence.
133 */
134 static inline void
135 update_attribute_map_mode(const struct gl_context *ctx,
136 struct gl_vertex_array_object *vao)
137 {
138 /*
139 * There is no need to change the mapping away from the
140 * identity mapping if we are not in compat mode.
141 */
142 if (ctx->API != API_OPENGL_COMPAT)
143 return;
144 /* The generic0 attribute superseeds the position attribute */
145 const GLbitfield enabled = vao->Enabled;
146 if (enabled & VERT_BIT_GENERIC0)
147 vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_GENERIC0;
148 else if (enabled & VERT_BIT_POS)
149 vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_POSITION;
150 else
151 vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_IDENTITY;
152 }
153
154
155 /**
156 * Sets the BufferBindingIndex field for the vertex attribute given by
157 * attribIndex.
158 */
159 void
160 _mesa_vertex_attrib_binding(struct gl_context *ctx,
161 struct gl_vertex_array_object *vao,
162 gl_vert_attrib attribIndex,
163 GLuint bindingIndex)
164 {
165 struct gl_array_attributes *array = &vao->VertexAttrib[attribIndex];
166 assert(!vao->SharedAndImmutable);
167
168 if (array->BufferBindingIndex != bindingIndex) {
169 const GLbitfield array_bit = VERT_BIT(attribIndex);
170
171 if (_mesa_is_bufferobj(vao->BufferBinding[bindingIndex].BufferObj))
172 vao->VertexAttribBufferMask |= array_bit;
173 else
174 vao->VertexAttribBufferMask &= ~array_bit;
175
176 vao->BufferBinding[array->BufferBindingIndex]._BoundArrays &= ~array_bit;
177 vao->BufferBinding[bindingIndex]._BoundArrays |= array_bit;
178
179 array->BufferBindingIndex = bindingIndex;
180
181 vao->NewArrays |= vao->Enabled & array_bit;
182 }
183 }
184
185
186 /**
187 * Binds a buffer object to the vertex buffer binding point given by index,
188 * and sets the Offset and Stride fields.
189 */
190 void
191 _mesa_bind_vertex_buffer(struct gl_context *ctx,
192 struct gl_vertex_array_object *vao,
193 GLuint index,
194 struct gl_buffer_object *vbo,
195 GLintptr offset, GLsizei stride)
196 {
197 assert(index < ARRAY_SIZE(vao->BufferBinding));
198 assert(!vao->SharedAndImmutable);
199 struct gl_vertex_buffer_binding *binding = &vao->BufferBinding[index];
200
201 if (binding->BufferObj != vbo ||
202 binding->Offset != offset ||
203 binding->Stride != stride) {
204
205 _mesa_reference_buffer_object(ctx, &binding->BufferObj, vbo);
206
207 binding->Offset = offset;
208 binding->Stride = stride;
209
210 if (!_mesa_is_bufferobj(vbo)) {
211 vao->VertexAttribBufferMask &= ~binding->_BoundArrays;
212 } else {
213 vao->VertexAttribBufferMask |= binding->_BoundArrays;
214 vbo->UsageHistory |= USAGE_ARRAY_BUFFER;
215 }
216
217 vao->NewArrays |= vao->Enabled & binding->_BoundArrays;
218 }
219 }
220
221
222 /**
223 * Sets the InstanceDivisor field in the vertex buffer binding point
224 * given by bindingIndex.
225 */
226 static void
227 vertex_binding_divisor(struct gl_context *ctx,
228 struct gl_vertex_array_object *vao,
229 GLuint bindingIndex,
230 GLuint divisor)
231 {
232 struct gl_vertex_buffer_binding *binding =
233 &vao->BufferBinding[bindingIndex];
234 assert(!vao->SharedAndImmutable);
235
236 if (binding->InstanceDivisor != divisor) {
237 binding->InstanceDivisor = divisor;
238 vao->NewArrays |= vao->Enabled & binding->_BoundArrays;
239 }
240 }
241
242
243 void
244 _mesa_set_vertex_format(struct gl_vertex_format *vertex_format,
245 GLubyte size, GLenum16 type, GLenum16 format,
246 GLboolean normalized, GLboolean integer,
247 GLboolean doubles)
248 {
249 assert(size <= 4);
250 vertex_format->Type = type;
251 vertex_format->Format = format;
252 vertex_format->Size = size;
253 vertex_format->Normalized = normalized;
254 vertex_format->Integer = integer;
255 vertex_format->Doubles = doubles;
256 vertex_format->_ElementSize = _mesa_bytes_per_vertex_attrib(size, type);
257 assert(vertex_format->_ElementSize <= 4*sizeof(double));
258 }
259
260
261 /**
262 * Examine the API profile and extensions to determine which types are legal
263 * for vertex arrays. This is called once from update_array_format().
264 */
265 static GLbitfield
266 get_legal_types_mask(const struct gl_context *ctx)
267 {
268 GLbitfield legalTypesMask = ALL_TYPE_BITS;
269
270 if (_mesa_is_gles(ctx)) {
271 legalTypesMask &= ~(FIXED_GL_BIT |
272 DOUBLE_BIT |
273 UNSIGNED_INT_10F_11F_11F_REV_BIT);
274
275 /* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until
276 * 3.0. The 2_10_10_10 types are added in OpenGL ES 3.0 or
277 * GL_OES_vertex_type_10_10_10_2. GL_HALF_FLOAT data is not allowed
278 * until 3.0 or with the GL_OES_vertex_half float extension, which isn't
279 * quite as trivial as we'd like because it uses a different enum value
280 * for GL_HALF_FLOAT_OES.
281 */
282 if (ctx->Version < 30) {
283 legalTypesMask &= ~(UNSIGNED_INT_BIT |
284 INT_BIT |
285 UNSIGNED_INT_2_10_10_10_REV_BIT |
286 INT_2_10_10_10_REV_BIT);
287
288 if (!_mesa_has_OES_vertex_half_float(ctx))
289 legalTypesMask &= ~HALF_BIT;
290 }
291 }
292 else {
293 legalTypesMask &= ~FIXED_ES_BIT;
294
295 if (!ctx->Extensions.ARB_ES2_compatibility)
296 legalTypesMask &= ~FIXED_GL_BIT;
297
298 if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev)
299 legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT |
300 INT_2_10_10_10_REV_BIT);
301
302 if (!ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev)
303 legalTypesMask &= ~UNSIGNED_INT_10F_11F_11F_REV_BIT;
304 }
305
306 return legalTypesMask;
307 }
308
309 static GLenum
310 get_array_format(const struct gl_context *ctx, GLint sizeMax, GLint *size)
311 {
312 GLenum format = GL_RGBA;
313
314 /* Do size parameter checking.
315 * If sizeMax = BGRA_OR_4 it means that size = GL_BGRA is legal and
316 * must be handled specially.
317 */
318 if (ctx->Extensions.EXT_vertex_array_bgra && sizeMax == BGRA_OR_4 &&
319 *size == GL_BGRA) {
320 format = GL_BGRA;
321 *size = 4;
322 }
323
324 return format;
325 }
326
327
328 /**
329 * \param attrib The index of the attribute array
330 * \param size Components per element (1, 2, 3 or 4)
331 * \param type Datatype of each component (GL_FLOAT, GL_INT, etc)
332 * \param format Either GL_RGBA or GL_BGRA.
333 * \param normalized Whether integer types are converted to floats in [-1, 1]
334 * \param integer Integer-valued values (will not be normalized to [-1, 1])
335 * \param doubles Double values not reduced to floats
336 * \param relativeOffset Offset of the first element relative to the binding
337 * offset.
338 */
339 void
340 _mesa_update_array_format(struct gl_context *ctx,
341 struct gl_vertex_array_object *vao,
342 gl_vert_attrib attrib, GLint size, GLenum type,
343 GLenum format, GLboolean normalized,
344 GLboolean integer, GLboolean doubles,
345 GLuint relativeOffset)
346 {
347 struct gl_array_attributes *const array = &vao->VertexAttrib[attrib];
348
349 assert(!vao->SharedAndImmutable);
350 assert(size <= 4);
351
352 array->RelativeOffset = relativeOffset;
353 _mesa_set_vertex_format(&array->Format, size, type, format,
354 normalized, integer, doubles);
355
356 vao->NewArrays |= vao->Enabled & VERT_BIT(attrib);
357 }
358
359 /**
360 * Does error checking of the format in an attrib array.
361 *
362 * Called by *Pointer() and VertexAttrib*Format().
363 *
364 * \param func Name of calling function used for error reporting
365 * \param attrib The index of the attribute array
366 * \param legalTypes Bitmask of *_BIT above indicating legal datatypes
367 * \param sizeMin Min allowable size value
368 * \param sizeMax Max allowable size value (may also be BGRA_OR_4)
369 * \param size Components per element (1, 2, 3 or 4)
370 * \param type Datatype of each component (GL_FLOAT, GL_INT, etc)
371 * \param normalized Whether integer types are converted to floats in [-1, 1]
372 * \param integer Integer-valued values (will not be normalized to [-1, 1])
373 * \param doubles Double values not reduced to floats
374 * \param relativeOffset Offset of the first element relative to the binding offset.
375 * \return bool True if validation is successful, False otherwise.
376 */
377 static bool
378 validate_array_format(struct gl_context *ctx, const char *func,
379 struct gl_vertex_array_object *vao,
380 GLuint attrib, GLbitfield legalTypesMask,
381 GLint sizeMin, GLint sizeMax,
382 GLint size, GLenum type, GLboolean normalized,
383 GLboolean integer, GLboolean doubles,
384 GLuint relativeOffset, GLenum format)
385 {
386 GLbitfield typeBit;
387
388 /* at most, one of these bools can be true */
389 assert((int) normalized + (int) integer + (int) doubles <= 1);
390
391 if (ctx->Array.LegalTypesMask == 0 || ctx->Array.LegalTypesMaskAPI != ctx->API) {
392 /* Compute the LegalTypesMask only once, unless the context API has
393 * changed, in which case we want to compute it again. We can't do this
394 * in _mesa_init_varrays() below because extensions are not yet enabled
395 * at that point.
396 */
397 ctx->Array.LegalTypesMask = get_legal_types_mask(ctx);
398 ctx->Array.LegalTypesMaskAPI = ctx->API;
399 }
400
401 legalTypesMask &= ctx->Array.LegalTypesMask;
402
403 if (_mesa_is_gles(ctx) && sizeMax == BGRA_OR_4) {
404 /* BGRA ordering is not supported in ES contexts.
405 */
406 sizeMax = 4;
407 }
408
409 typeBit = type_to_bit(ctx, type);
410 if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) {
411 _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)",
412 func, _mesa_enum_to_string(type));
413 return false;
414 }
415
416 if (format == GL_BGRA) {
417 /* Page 298 of the PDF of the OpenGL 4.3 (Core Profile) spec says:
418 *
419 * "An INVALID_OPERATION error is generated under any of the following
420 * conditions:
421 * ...
422 * • size is BGRA and type is not UNSIGNED_BYTE, INT_2_10_10_10_REV
423 * or UNSIGNED_INT_2_10_10_10_REV;
424 * ...
425 * • size is BGRA and normalized is FALSE;"
426 */
427 bool bgra_error = false;
428
429 if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) {
430 if (type != GL_UNSIGNED_INT_2_10_10_10_REV &&
431 type != GL_INT_2_10_10_10_REV &&
432 type != GL_UNSIGNED_BYTE)
433 bgra_error = true;
434 } else if (type != GL_UNSIGNED_BYTE)
435 bgra_error = true;
436
437 if (bgra_error) {
438 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=GL_BGRA and type=%s)",
439 func, _mesa_enum_to_string(type));
440 return false;
441 }
442
443 if (!normalized) {
444 _mesa_error(ctx, GL_INVALID_OPERATION,
445 "%s(size=GL_BGRA and normalized=GL_FALSE)", func);
446 return false;
447 }
448 }
449 else if (size < sizeMin || size > sizeMax || size > 4) {
450 _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size);
451 return false;
452 }
453
454 if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev &&
455 (type == GL_UNSIGNED_INT_2_10_10_10_REV ||
456 type == GL_INT_2_10_10_10_REV) && size != 4) {
457 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size);
458 return false;
459 }
460
461 /* The ARB_vertex_attrib_binding_spec says:
462 *
463 * An INVALID_VALUE error is generated if <relativeoffset> is larger than
464 * the value of MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.
465 */
466 if (relativeOffset > ctx->Const.MaxVertexAttribRelativeOffset) {
467 _mesa_error(ctx, GL_INVALID_VALUE,
468 "%s(relativeOffset=%d > "
469 "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET)",
470 func, relativeOffset);
471 return false;
472 }
473
474 if (ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev &&
475 type == GL_UNSIGNED_INT_10F_11F_11F_REV && size != 3) {
476 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size);
477 return false;
478 }
479
480 return true;
481 }
482
483 /**
484 * Do error checking for glVertex/Color/TexCoord/...Pointer functions.
485 *
486 * \param func name of calling function used for error reporting
487 * \param vao the vao to update
488 * \param obj the bound buffer object
489 * \param attrib the attribute array index to update
490 * \param legalTypes bitmask of *_BIT above indicating legal datatypes
491 * \param sizeMin min allowable size value
492 * \param sizeMax max allowable size value (may also be BGRA_OR_4)
493 * \param size components per element (1, 2, 3 or 4)
494 * \param type datatype of each component (GL_FLOAT, GL_INT, etc)
495 * \param stride stride between elements, in elements
496 * \param normalized are integer types converted to floats in [-1, 1]?
497 * \param integer integer-valued values (will not be normalized to [-1,1])
498 * \param doubles Double values not reduced to floats
499 * \param ptr the address (or offset inside VBO) of the array data
500 */
501 static void
502 validate_array(struct gl_context *ctx, const char *func,
503 struct gl_vertex_array_object *vao,
504 struct gl_buffer_object *obj,
505 GLuint attrib, GLbitfield legalTypesMask,
506 GLint sizeMin, GLint sizeMax,
507 GLint size, GLenum type, GLsizei stride,
508 GLboolean normalized, GLboolean integer, GLboolean doubles,
509 const GLvoid *ptr)
510 {
511 /* Page 407 (page 423 of the PDF) of the OpenGL 3.0 spec says:
512 *
513 * "Client vertex arrays - all vertex array attribute pointers must
514 * refer to buffer objects (section 2.9.2). The default vertex array
515 * object (the name zero) is also deprecated. Calling
516 * VertexAttribPointer when no buffer object or no vertex array object
517 * is bound will generate an INVALID_OPERATION error..."
518 *
519 * The check for VBOs is handled below.
520 */
521 if (ctx->API == API_OPENGL_CORE && (vao == ctx->Array.DefaultVAO)) {
522 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no array object bound)",
523 func);
524 return;
525 }
526
527 if (stride < 0) {
528 _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride );
529 return;
530 }
531
532 if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 44 &&
533 stride > ctx->Const.MaxVertexAttribStride) {
534 _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > "
535 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride);
536 return;
537 }
538
539 /* Page 29 (page 44 of the PDF) of the OpenGL 3.3 spec says:
540 *
541 * "An INVALID_OPERATION error is generated under any of the following
542 * conditions:
543 *
544 * ...
545 *
546 * * any of the *Pointer commands specifying the location and
547 * organization of vertex array data are called while zero is bound
548 * to the ARRAY_BUFFER buffer object binding point (see section
549 * 2.9.6), and the pointer argument is not NULL."
550 */
551 if (ptr != NULL && vao != ctx->Array.DefaultVAO &&
552 !_mesa_is_bufferobj(obj)) {
553 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func);
554 return;
555 }
556 }
557
558
559 static bool
560 validate_array_and_format(struct gl_context *ctx, const char *func,
561 struct gl_vertex_array_object *vao,
562 struct gl_buffer_object *obj,
563 GLuint attrib, GLbitfield legalTypes,
564 GLint sizeMin, GLint sizeMax,
565 GLint size, GLenum type, GLsizei stride,
566 GLboolean normalized, GLboolean integer,
567 GLboolean doubles, GLenum format, const GLvoid *ptr)
568 {
569 validate_array(ctx, func, vao, obj, attrib, legalTypes, sizeMin, sizeMax,
570 size, type, stride, normalized, integer, doubles, ptr);
571
572 return validate_array_format(ctx, func, vao, attrib, legalTypes, sizeMin,
573 sizeMax, size, type, normalized, integer,
574 doubles, 0, format);
575 }
576
577
578 /**
579 * Update state for glVertex/Color/TexCoord/...Pointer functions.
580 *
581 * \param vao the vao to update
582 * \param obj the bound buffer object
583 * \param attrib the attribute array index to update
584 * \param format Either GL_RGBA or GL_BGRA.
585 * \param sizeMax max allowable size value (may also be BGRA_OR_4)
586 * \param size components per element (1, 2, 3 or 4)
587 * \param type datatype of each component (GL_FLOAT, GL_INT, etc)
588 * \param stride stride between elements, in elements
589 * \param normalized are integer types converted to floats in [-1, 1]?
590 * \param integer integer-valued values (will not be normalized to [-1,1])
591 * \param doubles Double values not reduced to floats
592 * \param ptr the address (or offset inside VBO) of the array data
593 */
594 static void
595 update_array(struct gl_context *ctx,
596 struct gl_vertex_array_object *vao,
597 struct gl_buffer_object *obj,
598 GLuint attrib, GLenum format,
599 GLint sizeMax,
600 GLint size, GLenum type, GLsizei stride,
601 GLboolean normalized, GLboolean integer, GLboolean doubles,
602 const GLvoid *ptr)
603 {
604 _mesa_update_array_format(ctx, vao, attrib, size, type, format,
605 normalized, integer, doubles, 0);
606
607 /* Reset the vertex attrib binding */
608 _mesa_vertex_attrib_binding(ctx, vao, attrib, attrib);
609
610 /* The Stride and Ptr fields are not set by update_array_format() */
611 struct gl_array_attributes *array = &vao->VertexAttrib[attrib];
612 array->Stride = stride;
613 /* For updating the pointer we would need to add the vao->NewArrays flag
614 * to the VAO. But but that is done already unconditionally in
615 * _mesa_update_array_format called above.
616 */
617 assert((vao->NewArrays | ~vao->Enabled) & VERT_BIT(attrib));
618 array->Ptr = ptr;
619
620 /* Update the vertex buffer binding */
621 GLsizei effectiveStride = stride != 0 ?
622 stride : array->Format._ElementSize;
623 _mesa_bind_vertex_buffer(ctx, vao, attrib,
624 obj, (GLintptr) ptr,
625 effectiveStride);
626 }
627
628
629 /* Helper function for all EXT_direct_state_access glVertexArray* functions */
630 static bool
631 _lookup_vao_and_vbo_dsa(struct gl_context *ctx,
632 GLuint vaobj, GLuint buffer,
633 GLintptr offset,
634 struct gl_vertex_array_object** vao,
635 struct gl_buffer_object** vbo,
636 const char* caller)
637 {
638 *vao = _mesa_lookup_vao_err(ctx, vaobj, true, caller);
639 if (!(*vao))
640 return false;
641
642 if (buffer != 0) {
643 *vbo = _mesa_lookup_bufferobj(ctx, buffer);
644 if (!_mesa_handle_bind_buffer_gen(ctx, buffer, vbo, caller))
645 return false;
646
647 if (offset < 0) {
648 _mesa_error(ctx, GL_INVALID_VALUE,
649 "%s(negative offset with non-0 buffer)", caller);
650 return false;
651 }
652 } else {
653 *vbo = ctx->Shared->NullBufferObj;
654 }
655
656 return true;
657 }
658
659
660 void GLAPIENTRY
661 _mesa_VertexPointer_no_error(GLint size, GLenum type, GLsizei stride,
662 const GLvoid *ptr)
663 {
664 GET_CURRENT_CONTEXT(ctx);
665
666 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
667 VERT_ATTRIB_POS, GL_RGBA, 4, size, type, stride,
668 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
669 }
670
671
672 void GLAPIENTRY
673 _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
674 {
675 GET_CURRENT_CONTEXT(ctx);
676
677 GLenum format = GL_RGBA;
678 GLbitfield legalTypes = (ctx->API == API_OPENGLES)
679 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
680 : (SHORT_BIT | INT_BIT | FLOAT_BIT |
681 DOUBLE_BIT | HALF_BIT |
682 UNSIGNED_INT_2_10_10_10_REV_BIT |
683 INT_2_10_10_10_REV_BIT);
684
685 if (!validate_array_and_format(ctx, "glVertexPointer",
686 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
687 VERT_ATTRIB_POS, legalTypes, 2, 4, size,
688 type, stride, GL_FALSE, GL_FALSE, GL_FALSE,
689 format, ptr))
690 return;
691
692 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
693 VERT_ATTRIB_POS, format, 4, size, type, stride,
694 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
695 }
696
697
698 void GLAPIENTRY
699 _mesa_VertexArrayVertexOffsetEXT(GLuint vaobj, GLuint buffer, GLint size,
700 GLenum type, GLsizei stride, GLintptr offset)
701 {
702
703 }
704
705
706 void GLAPIENTRY
707 _mesa_NormalPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr )
708 {
709 GET_CURRENT_CONTEXT(ctx);
710
711 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
712 VERT_ATTRIB_NORMAL, GL_RGBA, 3, 3, type, stride, GL_TRUE,
713 GL_FALSE, GL_FALSE, ptr);
714 }
715
716
717 void GLAPIENTRY
718 _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
719 {
720 GET_CURRENT_CONTEXT(ctx);
721
722 GLenum format = GL_RGBA;
723 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
724 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
725 : (BYTE_BIT | SHORT_BIT | INT_BIT |
726 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
727 UNSIGNED_INT_2_10_10_10_REV_BIT |
728 INT_2_10_10_10_REV_BIT);
729
730 if (!validate_array_and_format(ctx, "glNormalPointer",
731 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
732 VERT_ATTRIB_NORMAL, legalTypes, 3, 3, 3,
733 type, stride, GL_TRUE, GL_FALSE,
734 GL_FALSE, format, ptr))
735 return;
736
737 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
738 VERT_ATTRIB_NORMAL, format, 3, 3, type, stride, GL_TRUE,
739 GL_FALSE, GL_FALSE, ptr);
740 }
741
742
743 void GLAPIENTRY
744 _mesa_VertexArrayNormalOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type,
745 GLsizei stride, GLintptr offset)
746 {
747
748 }
749
750
751 void GLAPIENTRY
752 _mesa_ColorPointer_no_error(GLint size, GLenum type, GLsizei stride,
753 const GLvoid *ptr)
754 {
755 GET_CURRENT_CONTEXT(ctx);
756
757 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
758 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
759 VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size,
760 type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
761 }
762
763
764 void GLAPIENTRY
765 _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
766 {
767 GET_CURRENT_CONTEXT(ctx);
768 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 4 : 3;
769
770 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
771 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
772 ? (UNSIGNED_BYTE_BIT | HALF_BIT | FLOAT_BIT | FIXED_ES_BIT)
773 : (BYTE_BIT | UNSIGNED_BYTE_BIT |
774 SHORT_BIT | UNSIGNED_SHORT_BIT |
775 INT_BIT | UNSIGNED_INT_BIT |
776 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
777 UNSIGNED_INT_2_10_10_10_REV_BIT |
778 INT_2_10_10_10_REV_BIT);
779
780 if (!validate_array_and_format(ctx, "glColorPointer",
781 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
782 VERT_ATTRIB_COLOR0, legalTypes, sizeMin,
783 BGRA_OR_4, size, type, stride, GL_TRUE,
784 GL_FALSE, GL_FALSE, format, ptr))
785 return;
786
787 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
788 VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size,
789 type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
790 }
791
792
793 void GLAPIENTRY
794 _mesa_VertexArrayColorOffsetEXT(GLuint vaobj, GLuint buffer, GLint size,
795 GLenum type, GLsizei stride, GLintptr offset)
796 {
797
798 }
799
800
801 void GLAPIENTRY
802 _mesa_FogCoordPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr)
803 {
804 GET_CURRENT_CONTEXT(ctx);
805
806 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
807 VERT_ATTRIB_FOG, GL_RGBA, 1, 1, type, stride, GL_FALSE,
808 GL_FALSE, GL_FALSE, ptr);
809 }
810
811
812 void GLAPIENTRY
813 _mesa_FogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
814 {
815 GET_CURRENT_CONTEXT(ctx);
816
817 GLenum format = GL_RGBA;
818 const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT);
819
820 if (!validate_array_and_format(ctx, "glFogCoordPointer",
821 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
822 VERT_ATTRIB_FOG, legalTypes, 1, 1, 1,
823 type, stride, GL_FALSE, GL_FALSE,
824 GL_FALSE, format, ptr))
825 return;
826
827 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
828 VERT_ATTRIB_FOG, format, 1, 1, type, stride, GL_FALSE,
829 GL_FALSE, GL_FALSE, ptr);
830 }
831
832
833 void GLAPIENTRY
834 _mesa_VertexArrayFogCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type,
835 GLsizei stride, GLintptr offset)
836 {
837
838 }
839
840
841 void GLAPIENTRY
842 _mesa_IndexPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr)
843 {
844 GET_CURRENT_CONTEXT(ctx);
845
846 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
847 VERT_ATTRIB_COLOR_INDEX, GL_RGBA, 1, 1, type, stride,
848 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
849 }
850
851
852 void GLAPIENTRY
853 _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
854 {
855 GET_CURRENT_CONTEXT(ctx);
856
857 GLenum format = GL_RGBA;
858 const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT |
859 FLOAT_BIT | DOUBLE_BIT);
860
861 if (!validate_array_and_format(ctx, "glIndexPointer",
862 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
863 VERT_ATTRIB_COLOR_INDEX,
864 legalTypes, 1, 1, 1, type, stride,
865 GL_FALSE, GL_FALSE, GL_FALSE, format, ptr))
866 return;
867
868 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
869 VERT_ATTRIB_COLOR_INDEX, format, 1, 1, type, stride,
870 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
871 }
872
873
874 void GLAPIENTRY
875 _mesa_VertexArrayIndexOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type,
876 GLsizei stride, GLintptr offset)
877 {
878
879 }
880
881
882 void GLAPIENTRY
883 _mesa_SecondaryColorPointer_no_error(GLint size, GLenum type,
884 GLsizei stride, const GLvoid *ptr)
885 {
886 GET_CURRENT_CONTEXT(ctx);
887
888 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
889 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
890 VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type,
891 stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
892 }
893
894
895 void GLAPIENTRY
896 _mesa_SecondaryColorPointer(GLint size, GLenum type,
897 GLsizei stride, const GLvoid *ptr)
898 {
899 GET_CURRENT_CONTEXT(ctx);
900
901 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
902 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
903 SHORT_BIT | UNSIGNED_SHORT_BIT |
904 INT_BIT | UNSIGNED_INT_BIT |
905 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
906 UNSIGNED_INT_2_10_10_10_REV_BIT |
907 INT_2_10_10_10_REV_BIT);
908
909 if (!validate_array_and_format(ctx, "glSecondaryColorPointer",
910 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
911 VERT_ATTRIB_COLOR1, legalTypes, 3,
912 BGRA_OR_4, size, type, stride,
913 GL_TRUE, GL_FALSE, GL_FALSE, format, ptr))
914 return;
915
916 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
917 VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type,
918 stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
919 }
920
921
922 void GLAPIENTRY
923 _mesa_VertexArraySecondaryColorOffsetEXT(GLuint vaobj, GLuint buffer, GLint size,
924 GLenum type, GLsizei stride, GLintptr offset)
925 {
926
927 }
928
929
930 void GLAPIENTRY
931 _mesa_TexCoordPointer_no_error(GLint size, GLenum type, GLsizei stride,
932 const GLvoid *ptr)
933 {
934 GET_CURRENT_CONTEXT(ctx);
935 const GLuint unit = ctx->Array.ActiveTexture;
936
937 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
938 VERT_ATTRIB_TEX(unit), GL_RGBA, 4, size, type,
939 stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr);
940 }
941
942
943 void GLAPIENTRY
944 _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
945 const GLvoid *ptr)
946 {
947 GET_CURRENT_CONTEXT(ctx);
948 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1;
949 const GLuint unit = ctx->Array.ActiveTexture;
950
951 GLenum format = GL_RGBA;
952 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
953 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
954 : (SHORT_BIT | INT_BIT |
955 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
956 UNSIGNED_INT_2_10_10_10_REV_BIT |
957 INT_2_10_10_10_REV_BIT);
958
959 if (!validate_array_and_format(ctx, "glTexCoordPointer",
960 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
961 VERT_ATTRIB_TEX(unit), legalTypes,
962 sizeMin, 4, size, type, stride,
963 GL_FALSE, GL_FALSE, GL_FALSE, format, ptr))
964 return;
965
966 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
967 VERT_ATTRIB_TEX(unit), format, 4, size, type,
968 stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr);
969 }
970
971
972 void GLAPIENTRY
973 _mesa_VertexArrayTexCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLint size,
974 GLenum type, GLsizei stride, GLintptr offset)
975 {
976
977 }
978
979
980 void GLAPIENTRY
981 _mesa_VertexArrayMultiTexCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLenum texunit,
982 GLint size, GLenum type, GLsizei stride,
983 GLintptr offset)
984 {
985
986 }
987
988
989 void GLAPIENTRY
990 _mesa_EdgeFlagPointer_no_error(GLsizei stride, const GLvoid *ptr)
991 {
992 /* this is the same type that glEdgeFlag uses */
993 const GLboolean integer = GL_FALSE;
994 GET_CURRENT_CONTEXT(ctx);
995
996 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
997 VERT_ATTRIB_EDGEFLAG, GL_RGBA, 1, 1, GL_UNSIGNED_BYTE,
998 stride, GL_FALSE, integer, GL_FALSE, ptr);
999 }
1000
1001
1002 void GLAPIENTRY
1003 _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
1004 {
1005 /* this is the same type that glEdgeFlag uses */
1006 const GLboolean integer = GL_FALSE;
1007 GET_CURRENT_CONTEXT(ctx);
1008
1009 GLenum format = GL_RGBA;
1010 const GLbitfield legalTypes = UNSIGNED_BYTE_BIT;
1011
1012 if (!validate_array_and_format(ctx, "glEdgeFlagPointer",
1013 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1014 VERT_ATTRIB_EDGEFLAG, legalTypes,
1015 1, 1, 1, GL_UNSIGNED_BYTE, stride,
1016 GL_FALSE, integer, GL_FALSE, format, ptr))
1017 return;
1018
1019 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1020 VERT_ATTRIB_EDGEFLAG, format, 1, 1, GL_UNSIGNED_BYTE,
1021 stride, GL_FALSE, integer, GL_FALSE, ptr);
1022 }
1023
1024
1025 void GLAPIENTRY
1026 _mesa_VertexArrayEdgeFlagOffsetEXT(GLuint vaobj, GLuint buffer, GLsizei stride,
1027 GLintptr offset)
1028 {
1029
1030 }
1031
1032
1033 void GLAPIENTRY
1034 _mesa_PointSizePointerOES_no_error(GLenum type, GLsizei stride,
1035 const GLvoid *ptr)
1036 {
1037 GET_CURRENT_CONTEXT(ctx);
1038
1039 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1040 VERT_ATTRIB_POINT_SIZE, GL_RGBA, 1, 1, type, stride,
1041 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
1042 }
1043
1044
1045 void GLAPIENTRY
1046 _mesa_PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *ptr)
1047 {
1048 GET_CURRENT_CONTEXT(ctx);
1049
1050 GLenum format = GL_RGBA;
1051 if (ctx->API != API_OPENGLES) {
1052 _mesa_error(ctx, GL_INVALID_OPERATION,
1053 "glPointSizePointer(ES 1.x only)");
1054 return;
1055 }
1056
1057 const GLbitfield legalTypes = (FLOAT_BIT | FIXED_ES_BIT);
1058
1059 if (!validate_array_and_format(ctx, "glPointSizePointer",
1060 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1061 VERT_ATTRIB_POINT_SIZE, legalTypes,
1062 1, 1, 1, type, stride, GL_FALSE, GL_FALSE,
1063 GL_FALSE, format, ptr))
1064 return;
1065
1066 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1067 VERT_ATTRIB_POINT_SIZE, format, 1, 1, type, stride,
1068 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
1069 }
1070
1071
1072 void GLAPIENTRY
1073 _mesa_VertexAttribPointer_no_error(GLuint index, GLint size, GLenum type,
1074 GLboolean normalized,
1075 GLsizei stride, const GLvoid *ptr)
1076 {
1077 GET_CURRENT_CONTEXT(ctx);
1078
1079 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
1080 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1081 VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4,
1082 size, type, stride, normalized, GL_FALSE, GL_FALSE, ptr);
1083 }
1084
1085
1086 /**
1087 * Set a generic vertex attribute array.
1088 * Note that these arrays DO NOT alias the conventional GL vertex arrays
1089 * (position, normal, color, fog, texcoord, etc).
1090 */
1091 void GLAPIENTRY
1092 _mesa_VertexAttribPointer(GLuint index, GLint size, GLenum type,
1093 GLboolean normalized,
1094 GLsizei stride, const GLvoid *ptr)
1095 {
1096 GET_CURRENT_CONTEXT(ctx);
1097
1098 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
1099 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1100 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(idx)");
1101 return;
1102 }
1103
1104 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
1105 SHORT_BIT | UNSIGNED_SHORT_BIT |
1106 INT_BIT | UNSIGNED_INT_BIT |
1107 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
1108 FIXED_ES_BIT | FIXED_GL_BIT |
1109 UNSIGNED_INT_2_10_10_10_REV_BIT |
1110 INT_2_10_10_10_REV_BIT |
1111 UNSIGNED_INT_10F_11F_11F_REV_BIT);
1112
1113 if (!validate_array_and_format(ctx, "glVertexAttribPointer",
1114 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1115 VERT_ATTRIB_GENERIC(index), legalTypes,
1116 1, BGRA_OR_4, size, type, stride,
1117 normalized, GL_FALSE, GL_FALSE, format, ptr))
1118 return;
1119
1120 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1121 VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4,
1122 size, type, stride, normalized, GL_FALSE, GL_FALSE, ptr);
1123 }
1124
1125
1126 void GLAPIENTRY
1127 _mesa_VertexArrayVertexAttribOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size,
1128 GLenum type, GLboolean normalized,
1129 GLsizei stride, GLintptr offset)
1130 {
1131
1132 }
1133
1134
1135 void GLAPIENTRY
1136 _mesa_VertexAttribIPointer_no_error(GLuint index, GLint size, GLenum type,
1137 GLsizei stride, const GLvoid *ptr)
1138 {
1139 const GLboolean normalized = GL_FALSE;
1140 const GLboolean integer = GL_TRUE;
1141 GET_CURRENT_CONTEXT(ctx);
1142
1143 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1144 VERT_ATTRIB_GENERIC(index), GL_RGBA, 4, size, type,
1145 stride, normalized, integer, GL_FALSE, ptr);
1146 }
1147
1148
1149 /**
1150 * GL_EXT_gpu_shader4 / GL 3.0.
1151 * Set an integer-valued vertex attribute array.
1152 * Note that these arrays DO NOT alias the conventional GL vertex arrays
1153 * (position, normal, color, fog, texcoord, etc).
1154 */
1155 void GLAPIENTRY
1156 _mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type,
1157 GLsizei stride, const GLvoid *ptr)
1158 {
1159 const GLboolean normalized = GL_FALSE;
1160 const GLboolean integer = GL_TRUE;
1161 GET_CURRENT_CONTEXT(ctx);
1162
1163 GLenum format = GL_RGBA;
1164 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1165 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIPointer(index)");
1166 return;
1167 }
1168
1169 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
1170 SHORT_BIT | UNSIGNED_SHORT_BIT |
1171 INT_BIT | UNSIGNED_INT_BIT);
1172
1173 if (!validate_array_and_format(ctx, "glVertexAttribIPointer",
1174 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1175 VERT_ATTRIB_GENERIC(index), legalTypes,
1176 1, 4, size, type, stride,
1177 normalized, integer, GL_FALSE, format, ptr))
1178 return;
1179
1180 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1181 VERT_ATTRIB_GENERIC(index), format, 4, size, type,
1182 stride, normalized, integer, GL_FALSE, ptr);
1183 }
1184
1185
1186 void GLAPIENTRY
1187 _mesa_VertexAttribLPointer_no_error(GLuint index, GLint size, GLenum type,
1188 GLsizei stride, const GLvoid *ptr)
1189 {
1190 GET_CURRENT_CONTEXT(ctx);
1191
1192 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1193 VERT_ATTRIB_GENERIC(index), GL_RGBA, 4, size, type,
1194 stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr);
1195 }
1196
1197
1198 void GLAPIENTRY
1199 _mesa_VertexArrayVertexAttribIOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size,
1200 GLenum type, GLsizei stride, GLintptr offset)
1201 {
1202
1203 }
1204
1205
1206 void GLAPIENTRY
1207 _mesa_VertexAttribLPointer(GLuint index, GLint size, GLenum type,
1208 GLsizei stride, const GLvoid *ptr)
1209 {
1210 GET_CURRENT_CONTEXT(ctx);
1211
1212 GLenum format = GL_RGBA;
1213 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1214 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribLPointer(index)");
1215 return;
1216 }
1217
1218 const GLbitfield legalTypes = DOUBLE_BIT;
1219
1220 if (!validate_array_and_format(ctx, "glVertexAttribLPointer",
1221 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1222 VERT_ATTRIB_GENERIC(index), legalTypes,
1223 1, 4, size, type, stride,
1224 GL_FALSE, GL_FALSE, GL_TRUE, format, ptr))
1225 return;
1226
1227 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1228 VERT_ATTRIB_GENERIC(index), format, 4, size, type,
1229 stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr);
1230 }
1231
1232
1233 void
1234 _mesa_enable_vertex_array_attribs(struct gl_context *ctx,
1235 struct gl_vertex_array_object *vao,
1236 GLbitfield attrib_bits)
1237 {
1238 assert((attrib_bits & ~VERT_BIT_ALL) == 0);
1239 assert(!vao->SharedAndImmutable);
1240
1241 /* Only work on bits that are disabled */
1242 attrib_bits &= ~vao->Enabled;
1243 if (attrib_bits) {
1244 /* was disabled, now being enabled */
1245 vao->Enabled |= attrib_bits;
1246 vao->NewArrays |= attrib_bits;
1247
1248 /* Update the map mode if needed */
1249 if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0))
1250 update_attribute_map_mode(ctx, vao);
1251 }
1252 }
1253
1254 static void
1255 enable_vertex_array_attrib(struct gl_context *ctx,
1256 struct gl_vertex_array_object *vao,
1257 GLuint index,
1258 const char *func)
1259 {
1260 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1261 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
1262 return;
1263 }
1264
1265 _mesa_enable_vertex_array_attrib(ctx, vao, VERT_ATTRIB_GENERIC(index));
1266 }
1267
1268
1269 void GLAPIENTRY
1270 _mesa_EnableVertexAttribArray(GLuint index)
1271 {
1272 GET_CURRENT_CONTEXT(ctx);
1273 enable_vertex_array_attrib(ctx, ctx->Array.VAO, index,
1274 "glEnableVertexAttribArray");
1275 }
1276
1277
1278 void GLAPIENTRY
1279 _mesa_EnableVertexAttribArray_no_error(GLuint index)
1280 {
1281 GET_CURRENT_CONTEXT(ctx);
1282 _mesa_enable_vertex_array_attrib(ctx, ctx->Array.VAO,
1283 VERT_ATTRIB_GENERIC(index));
1284 }
1285
1286
1287 void GLAPIENTRY
1288 _mesa_EnableVertexArrayAttrib(GLuint vaobj, GLuint index)
1289 {
1290 GET_CURRENT_CONTEXT(ctx);
1291 struct gl_vertex_array_object *vao;
1292
1293 /* The ARB_direct_state_access specification says:
1294 *
1295 * "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib
1296 * and DisableVertexArrayAttrib if <vaobj> is not
1297 * [compatibility profile: zero or] the name of an existing vertex
1298 * array object."
1299 */
1300 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glEnableVertexArrayAttrib");
1301 if (!vao)
1302 return;
1303
1304 enable_vertex_array_attrib(ctx, vao, index, "glEnableVertexArrayAttrib");
1305 }
1306
1307
1308 void GLAPIENTRY
1309 _mesa_EnableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index)
1310 {
1311 GET_CURRENT_CONTEXT(ctx);
1312 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
1313 _mesa_enable_vertex_array_attrib(ctx, vao, VERT_ATTRIB_GENERIC(index));
1314 }
1315
1316
1317 void
1318 _mesa_disable_vertex_array_attribs(struct gl_context *ctx,
1319 struct gl_vertex_array_object *vao,
1320 GLbitfield attrib_bits)
1321 {
1322 assert((attrib_bits & ~VERT_BIT_ALL) == 0);
1323 assert(!vao->SharedAndImmutable);
1324
1325 /* Only work on bits that are enabled */
1326 attrib_bits &= vao->Enabled;
1327 if (attrib_bits) {
1328 /* was enabled, now being disabled */
1329 vao->Enabled &= ~attrib_bits;
1330 vao->NewArrays |= attrib_bits;
1331
1332 /* Update the map mode if needed */
1333 if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0))
1334 update_attribute_map_mode(ctx, vao);
1335 }
1336 }
1337
1338
1339 void GLAPIENTRY
1340 _mesa_DisableVertexAttribArray(GLuint index)
1341 {
1342 GET_CURRENT_CONTEXT(ctx);
1343
1344 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1345 _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexAttribArray(index)");
1346 return;
1347 }
1348
1349 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1350 _mesa_disable_vertex_array_attrib(ctx, ctx->Array.VAO, attrib);
1351 }
1352
1353
1354 void GLAPIENTRY
1355 _mesa_DisableVertexAttribArray_no_error(GLuint index)
1356 {
1357 GET_CURRENT_CONTEXT(ctx);
1358 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1359 _mesa_disable_vertex_array_attrib(ctx, ctx->Array.VAO, attrib);
1360 }
1361
1362
1363 void GLAPIENTRY
1364 _mesa_DisableVertexArrayAttrib(GLuint vaobj, GLuint index)
1365 {
1366 GET_CURRENT_CONTEXT(ctx);
1367 struct gl_vertex_array_object *vao;
1368
1369 /* The ARB_direct_state_access specification says:
1370 *
1371 * "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib
1372 * and DisableVertexArrayAttrib if <vaobj> is not
1373 * [compatibility profile: zero or] the name of an existing vertex
1374 * array object."
1375 */
1376 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glDisableVertexArrayAttrib");
1377 if (!vao)
1378 return;
1379
1380 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1381 _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexArrayAttrib(index)");
1382 return;
1383 }
1384
1385 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1386 _mesa_disable_vertex_array_attrib(ctx, vao, attrib);
1387 }
1388
1389
1390 void GLAPIENTRY
1391 _mesa_DisableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index)
1392 {
1393 GET_CURRENT_CONTEXT(ctx);
1394 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
1395 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1396 _mesa_disable_vertex_array_attrib(ctx, vao, attrib);
1397 }
1398
1399
1400 /**
1401 * Return info for a vertex attribute array (no alias with legacy
1402 * vertex attributes (pos, normal, color, etc)). This function does
1403 * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query.
1404 */
1405 static GLuint
1406 get_vertex_array_attrib(struct gl_context *ctx,
1407 const struct gl_vertex_array_object *vao,
1408 GLuint index, GLenum pname,
1409 const char *caller)
1410 {
1411 const struct gl_array_attributes *array;
1412
1413 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1414 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index);
1415 return 0;
1416 }
1417
1418 assert(VERT_ATTRIB_GENERIC(index) < ARRAY_SIZE(vao->VertexAttrib));
1419
1420 array = &vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)];
1421
1422 switch (pname) {
1423 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
1424 return !!(vao->Enabled & VERT_BIT_GENERIC(index));
1425 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
1426 return (array->Format.Format == GL_BGRA) ? GL_BGRA : array->Format.Size;
1427 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
1428 return array->Stride;
1429 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
1430 return array->Format.Type;
1431 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
1432 return array->Format.Normalized;
1433 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
1434 return vao->BufferBinding[array->BufferBindingIndex].BufferObj->Name;
1435 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
1436 if ((_mesa_is_desktop_gl(ctx)
1437 && (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))
1438 || _mesa_is_gles3(ctx)) {
1439 return array->Format.Integer;
1440 }
1441 goto error;
1442 case GL_VERTEX_ATTRIB_ARRAY_LONG:
1443 if (_mesa_is_desktop_gl(ctx)) {
1444 return array->Format.Doubles;
1445 }
1446 goto error;
1447 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB:
1448 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_instanced_arrays)
1449 || _mesa_is_gles3(ctx)) {
1450 return vao->BufferBinding[array->BufferBindingIndex].InstanceDivisor;
1451 }
1452 goto error;
1453 case GL_VERTEX_ATTRIB_BINDING:
1454 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
1455 return array->BufferBindingIndex - VERT_ATTRIB_GENERIC0;
1456 }
1457 goto error;
1458 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
1459 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
1460 return array->RelativeOffset;
1461 }
1462 goto error;
1463 default:
1464 ; /* fall-through */
1465 }
1466
1467 error:
1468 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname);
1469 return 0;
1470 }
1471
1472
1473 static const GLfloat *
1474 get_current_attrib(struct gl_context *ctx, GLuint index, const char *function)
1475 {
1476 if (index == 0) {
1477 if (_mesa_attr_zero_aliases_vertex(ctx)) {
1478 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function);
1479 return NULL;
1480 }
1481 }
1482 else if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1483 _mesa_error(ctx, GL_INVALID_VALUE,
1484 "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function);
1485 return NULL;
1486 }
1487
1488 assert(VERT_ATTRIB_GENERIC(index) <
1489 ARRAY_SIZE(ctx->Array.VAO->VertexAttrib));
1490
1491 FLUSH_CURRENT(ctx, 0);
1492 return ctx->Current.Attrib[VERT_ATTRIB_GENERIC(index)];
1493 }
1494
1495 void GLAPIENTRY
1496 _mesa_GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
1497 {
1498 GET_CURRENT_CONTEXT(ctx);
1499
1500 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1501 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv");
1502 if (v != NULL) {
1503 COPY_4V(params, v);
1504 }
1505 }
1506 else {
1507 params[0] = (GLfloat) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1508 index, pname,
1509 "glGetVertexAttribfv");
1510 }
1511 }
1512
1513
1514 void GLAPIENTRY
1515 _mesa_GetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params)
1516 {
1517 GET_CURRENT_CONTEXT(ctx);
1518
1519 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1520 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv");
1521 if (v != NULL) {
1522 params[0] = (GLdouble) v[0];
1523 params[1] = (GLdouble) v[1];
1524 params[2] = (GLdouble) v[2];
1525 params[3] = (GLdouble) v[3];
1526 }
1527 }
1528 else {
1529 params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1530 index, pname,
1531 "glGetVertexAttribdv");
1532 }
1533 }
1534
1535 void GLAPIENTRY
1536 _mesa_GetVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params)
1537 {
1538 GET_CURRENT_CONTEXT(ctx);
1539
1540 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1541 const GLdouble *v =
1542 (const GLdouble *)get_current_attrib(ctx, index,
1543 "glGetVertexAttribLdv");
1544 if (v != NULL) {
1545 params[0] = v[0];
1546 params[1] = v[1];
1547 params[2] = v[2];
1548 params[3] = v[3];
1549 }
1550 }
1551 else {
1552 params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1553 index, pname,
1554 "glGetVertexAttribLdv");
1555 }
1556 }
1557
1558 void GLAPIENTRY
1559 _mesa_GetVertexAttribiv(GLuint index, GLenum pname, GLint *params)
1560 {
1561 GET_CURRENT_CONTEXT(ctx);
1562
1563 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1564 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv");
1565 if (v != NULL) {
1566 /* XXX should floats in[0,1] be scaled to full int range? */
1567 params[0] = (GLint) v[0];
1568 params[1] = (GLint) v[1];
1569 params[2] = (GLint) v[2];
1570 params[3] = (GLint) v[3];
1571 }
1572 }
1573 else {
1574 params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1575 index, pname,
1576 "glGetVertexAttribiv");
1577 }
1578 }
1579
1580 void GLAPIENTRY
1581 _mesa_GetVertexAttribLui64vARB(GLuint index, GLenum pname, GLuint64EXT *params)
1582 {
1583 GET_CURRENT_CONTEXT(ctx);
1584
1585 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1586 const GLuint64 *v =
1587 (const GLuint64 *)get_current_attrib(ctx, index,
1588 "glGetVertexAttribLui64vARB");
1589 if (v != NULL) {
1590 params[0] = v[0];
1591 params[1] = v[1];
1592 params[2] = v[2];
1593 params[3] = v[3];
1594 }
1595 }
1596 else {
1597 params[0] = (GLuint64) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1598 index, pname,
1599 "glGetVertexAttribLui64vARB");
1600 }
1601 }
1602
1603
1604 /** GL 3.0 */
1605 void GLAPIENTRY
1606 _mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
1607 {
1608 GET_CURRENT_CONTEXT(ctx);
1609
1610 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1611 const GLint *v = (const GLint *)
1612 get_current_attrib(ctx, index, "glGetVertexAttribIiv");
1613 if (v != NULL) {
1614 COPY_4V(params, v);
1615 }
1616 }
1617 else {
1618 params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1619 index, pname,
1620 "glGetVertexAttribIiv");
1621 }
1622 }
1623
1624
1625 /** GL 3.0 */
1626 void GLAPIENTRY
1627 _mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
1628 {
1629 GET_CURRENT_CONTEXT(ctx);
1630
1631 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1632 const GLuint *v = (const GLuint *)
1633 get_current_attrib(ctx, index, "glGetVertexAttribIuiv");
1634 if (v != NULL) {
1635 COPY_4V(params, v);
1636 }
1637 }
1638 else {
1639 params[0] = get_vertex_array_attrib(ctx, ctx->Array.VAO,
1640 index, pname,
1641 "glGetVertexAttribIuiv");
1642 }
1643 }
1644
1645
1646 void GLAPIENTRY
1647 _mesa_GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
1648 {
1649 GET_CURRENT_CONTEXT(ctx);
1650
1651 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1652 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
1653 return;
1654 }
1655
1656 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
1657 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
1658 return;
1659 }
1660
1661 assert(VERT_ATTRIB_GENERIC(index) <
1662 ARRAY_SIZE(ctx->Array.VAO->VertexAttrib));
1663
1664 *pointer = (GLvoid *)
1665 ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr;
1666 }
1667
1668
1669 /** ARB_direct_state_access */
1670 void GLAPIENTRY
1671 _mesa_GetVertexArrayIndexediv(GLuint vaobj, GLuint index,
1672 GLenum pname, GLint *params)
1673 {
1674 GET_CURRENT_CONTEXT(ctx);
1675 struct gl_vertex_array_object *vao;
1676
1677 /* The ARB_direct_state_access specification says:
1678 *
1679 * "An INVALID_OPERATION error is generated if <vaobj> is not
1680 * [compatibility profile: zero or] the name of an existing
1681 * vertex array object."
1682 */
1683 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glGetVertexArrayIndexediv");
1684 if (!vao)
1685 return;
1686
1687 /* The ARB_direct_state_access specification says:
1688 *
1689 * "For GetVertexArrayIndexediv, <pname> must be one of
1690 * VERTEX_ATTRIB_ARRAY_ENABLED, VERTEX_ATTRIB_ARRAY_SIZE,
1691 * VERTEX_ATTRIB_ARRAY_STRIDE, VERTEX_ATTRIB_ARRAY_TYPE,
1692 * VERTEX_ATTRIB_ARRAY_NORMALIZED, VERTEX_ATTRIB_ARRAY_INTEGER,
1693 * VERTEX_ATTRIB_ARRAY_LONG, VERTEX_ATTRIB_ARRAY_DIVISOR, or
1694 * VERTEX_ATTRIB_RELATIVE_OFFSET."
1695 *
1696 * and:
1697 *
1698 * "Add GetVertexArrayIndexediv in 'Get Command' for
1699 * VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
1700 * VERTEX_ATTRIB_BINDING,
1701 * VERTEX_ATTRIB_RELATIVE_OFFSET,
1702 * VERTEX_BINDING_OFFSET, and
1703 * VERTEX_BINDING_STRIDE states"
1704 *
1705 * The only parameter name common to both lists is
1706 * VERTEX_ATTRIB_RELATIVE_OFFSET. Also note that VERTEX_BINDING_BUFFER
1707 * and VERTEX_BINDING_DIVISOR are missing from both lists. It seems
1708 * pretty clear however that the intent is that it should be possible
1709 * to query all vertex attrib and binding states that can be set with
1710 * a DSA function.
1711 */
1712 switch (pname) {
1713 case GL_VERTEX_BINDING_OFFSET:
1714 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Offset;
1715 break;
1716 case GL_VERTEX_BINDING_STRIDE:
1717 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Stride;
1718 break;
1719 case GL_VERTEX_BINDING_DIVISOR:
1720 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].InstanceDivisor;
1721 break;
1722 case GL_VERTEX_BINDING_BUFFER:
1723 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].BufferObj->Name;
1724 break;
1725 default:
1726 params[0] = get_vertex_array_attrib(ctx, vao, index, pname,
1727 "glGetVertexArrayIndexediv");
1728 break;
1729 }
1730 }
1731
1732
1733 void GLAPIENTRY
1734 _mesa_GetVertexArrayIndexed64iv(GLuint vaobj, GLuint index,
1735 GLenum pname, GLint64 *params)
1736 {
1737 GET_CURRENT_CONTEXT(ctx);
1738 struct gl_vertex_array_object *vao;
1739
1740 /* The ARB_direct_state_access specification says:
1741 *
1742 * "An INVALID_OPERATION error is generated if <vaobj> is not
1743 * [compatibility profile: zero or] the name of an existing
1744 * vertex array object."
1745 */
1746 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glGetVertexArrayIndexed64iv");
1747 if (!vao)
1748 return;
1749
1750 /* The ARB_direct_state_access specification says:
1751 *
1752 * "For GetVertexArrayIndexed64iv, <pname> must be
1753 * VERTEX_BINDING_OFFSET."
1754 *
1755 * and:
1756 *
1757 * "An INVALID_ENUM error is generated if <pname> is not one of
1758 * the valid values listed above for the corresponding command."
1759 */
1760 if (pname != GL_VERTEX_BINDING_OFFSET) {
1761 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayIndexed64iv("
1762 "pname != GL_VERTEX_BINDING_OFFSET)");
1763 return;
1764 }
1765
1766 /* The ARB_direct_state_access specification says:
1767 *
1768 * "An INVALID_VALUE error is generated if <index> is greater than
1769 * or equal to the value of MAX_VERTEX_ATTRIBS."
1770 *
1771 * Since the index refers to a buffer binding in this case, the intended
1772 * limit must be MAX_VERTEX_ATTRIB_BINDINGS. Both limits are currently
1773 * required to be the same, so in practice this doesn't matter.
1774 */
1775 if (index >= ctx->Const.MaxVertexAttribBindings) {
1776 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexArrayIndexed64iv(index"
1777 "%d >= the value of GL_MAX_VERTEX_ATTRIB_BINDINGS (%d))",
1778 index, ctx->Const.MaxVertexAttribBindings);
1779 return;
1780 }
1781
1782 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Offset;
1783 }
1784
1785
1786 void GLAPIENTRY
1787 _mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
1788 GLsizei count, const GLvoid *ptr)
1789 {
1790 (void) count;
1791 _mesa_VertexPointer(size, type, stride, ptr);
1792 }
1793
1794
1795 void GLAPIENTRY
1796 _mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
1797 const GLvoid *ptr)
1798 {
1799 (void) count;
1800 _mesa_NormalPointer(type, stride, ptr);
1801 }
1802
1803
1804 void GLAPIENTRY
1805 _mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
1806 const GLvoid *ptr)
1807 {
1808 (void) count;
1809 _mesa_ColorPointer(size, type, stride, ptr);
1810 }
1811
1812
1813 void GLAPIENTRY
1814 _mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
1815 const GLvoid *ptr)
1816 {
1817 (void) count;
1818 _mesa_IndexPointer(type, stride, ptr);
1819 }
1820
1821
1822 void GLAPIENTRY
1823 _mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
1824 GLsizei count, const GLvoid *ptr)
1825 {
1826 (void) count;
1827 _mesa_TexCoordPointer(size, type, stride, ptr);
1828 }
1829
1830
1831 void GLAPIENTRY
1832 _mesa_MultiTexCoordPointerEXT(GLenum texunit, GLint size, GLenum type,
1833 GLsizei stride, const GLvoid *ptr)
1834 {
1835 GET_CURRENT_CONTEXT(ctx);
1836 const GLint sizeMin = 1;
1837 const GLuint unit = texunit - GL_TEXTURE0;
1838
1839 GLenum format = GL_RGBA;
1840 const GLbitfield legalTypes = (SHORT_BIT | INT_BIT |
1841 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
1842 UNSIGNED_INT_2_10_10_10_REV_BIT |
1843 INT_2_10_10_10_REV_BIT);
1844
1845 if (!validate_array_and_format(ctx, "glMultiTexCoordPointerEXT",
1846 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1847 VERT_ATTRIB_TEX(unit), legalTypes,
1848 sizeMin, 4, size, type, stride,
1849 GL_FALSE, GL_FALSE, GL_FALSE, format, ptr))
1850 return;
1851
1852 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1853 VERT_ATTRIB_TEX(unit), format, 4, size, type,
1854 stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr);
1855 }
1856
1857
1858 void GLAPIENTRY
1859 _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
1860 {
1861 (void) count;
1862 _mesa_EdgeFlagPointer(stride, ptr);
1863 }
1864
1865
1866 void GLAPIENTRY
1867 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
1868 {
1869 GET_CURRENT_CONTEXT(ctx);
1870 GLboolean tflag, cflag, nflag; /* enable/disable flags */
1871 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
1872 GLenum ctype = 0; /* color type */
1873 GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
1874 const GLint toffset = 0; /* always zero */
1875 GLint defstride; /* default stride */
1876 GLint c, f;
1877
1878 f = sizeof(GLfloat);
1879 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
1880
1881 if (stride < 0) {
1882 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
1883 return;
1884 }
1885
1886 switch (format) {
1887 case GL_V2F:
1888 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1889 tcomps = 0; ccomps = 0; vcomps = 2;
1890 voffset = 0;
1891 defstride = 2*f;
1892 break;
1893 case GL_V3F:
1894 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1895 tcomps = 0; ccomps = 0; vcomps = 3;
1896 voffset = 0;
1897 defstride = 3*f;
1898 break;
1899 case GL_C4UB_V2F:
1900 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1901 tcomps = 0; ccomps = 4; vcomps = 2;
1902 ctype = GL_UNSIGNED_BYTE;
1903 coffset = 0;
1904 voffset = c;
1905 defstride = c + 2*f;
1906 break;
1907 case GL_C4UB_V3F:
1908 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1909 tcomps = 0; ccomps = 4; vcomps = 3;
1910 ctype = GL_UNSIGNED_BYTE;
1911 coffset = 0;
1912 voffset = c;
1913 defstride = c + 3*f;
1914 break;
1915 case GL_C3F_V3F:
1916 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1917 tcomps = 0; ccomps = 3; vcomps = 3;
1918 ctype = GL_FLOAT;
1919 coffset = 0;
1920 voffset = 3*f;
1921 defstride = 6*f;
1922 break;
1923 case GL_N3F_V3F:
1924 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
1925 tcomps = 0; ccomps = 0; vcomps = 3;
1926 noffset = 0;
1927 voffset = 3*f;
1928 defstride = 6*f;
1929 break;
1930 case GL_C4F_N3F_V3F:
1931 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
1932 tcomps = 0; ccomps = 4; vcomps = 3;
1933 ctype = GL_FLOAT;
1934 coffset = 0;
1935 noffset = 4*f;
1936 voffset = 7*f;
1937 defstride = 10*f;
1938 break;
1939 case GL_T2F_V3F:
1940 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1941 tcomps = 2; ccomps = 0; vcomps = 3;
1942 voffset = 2*f;
1943 defstride = 5*f;
1944 break;
1945 case GL_T4F_V4F:
1946 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1947 tcomps = 4; ccomps = 0; vcomps = 4;
1948 voffset = 4*f;
1949 defstride = 8*f;
1950 break;
1951 case GL_T2F_C4UB_V3F:
1952 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1953 tcomps = 2; ccomps = 4; vcomps = 3;
1954 ctype = GL_UNSIGNED_BYTE;
1955 coffset = 2*f;
1956 voffset = c+2*f;
1957 defstride = c+5*f;
1958 break;
1959 case GL_T2F_C3F_V3F:
1960 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1961 tcomps = 2; ccomps = 3; vcomps = 3;
1962 ctype = GL_FLOAT;
1963 coffset = 2*f;
1964 voffset = 5*f;
1965 defstride = 8*f;
1966 break;
1967 case GL_T2F_N3F_V3F:
1968 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
1969 tcomps = 2; ccomps = 0; vcomps = 3;
1970 noffset = 2*f;
1971 voffset = 5*f;
1972 defstride = 8*f;
1973 break;
1974 case GL_T2F_C4F_N3F_V3F:
1975 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1976 tcomps = 2; ccomps = 4; vcomps = 3;
1977 ctype = GL_FLOAT;
1978 coffset = 2*f;
1979 noffset = 6*f;
1980 voffset = 9*f;
1981 defstride = 12*f;
1982 break;
1983 case GL_T4F_C4F_N3F_V4F:
1984 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1985 tcomps = 4; ccomps = 4; vcomps = 4;
1986 ctype = GL_FLOAT;
1987 coffset = 4*f;
1988 noffset = 8*f;
1989 voffset = 11*f;
1990 defstride = 15*f;
1991 break;
1992 default:
1993 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
1994 return;
1995 }
1996
1997 if (stride==0) {
1998 stride = defstride;
1999 }
2000
2001 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
2002 _mesa_DisableClientState( GL_INDEX_ARRAY );
2003 /* XXX also disable secondary color and generic arrays? */
2004
2005 /* Texcoords */
2006 if (tflag) {
2007 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
2008 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
2009 (GLubyte *) pointer + toffset );
2010 }
2011 else {
2012 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
2013 }
2014
2015 /* Color */
2016 if (cflag) {
2017 _mesa_EnableClientState( GL_COLOR_ARRAY );
2018 _mesa_ColorPointer( ccomps, ctype, stride,
2019 (GLubyte *) pointer + coffset );
2020 }
2021 else {
2022 _mesa_DisableClientState( GL_COLOR_ARRAY );
2023 }
2024
2025
2026 /* Normals */
2027 if (nflag) {
2028 _mesa_EnableClientState( GL_NORMAL_ARRAY );
2029 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset );
2030 }
2031 else {
2032 _mesa_DisableClientState( GL_NORMAL_ARRAY );
2033 }
2034
2035 /* Vertices */
2036 _mesa_EnableClientState( GL_VERTEX_ARRAY );
2037 _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
2038 (GLubyte *) pointer + voffset );
2039 }
2040
2041
2042 void GLAPIENTRY
2043 _mesa_LockArraysEXT(GLint first, GLsizei count)
2044 {
2045 GET_CURRENT_CONTEXT(ctx);
2046
2047 if (MESA_VERBOSE & VERBOSE_API)
2048 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
2049
2050 if (first < 0) {
2051 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" );
2052 return;
2053 }
2054 if (count <= 0) {
2055 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" );
2056 return;
2057 }
2058 if (ctx->Array.LockCount != 0) {
2059 _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" );
2060 return;
2061 }
2062
2063 ctx->Array.LockFirst = first;
2064 ctx->Array.LockCount = count;
2065 }
2066
2067
2068 void GLAPIENTRY
2069 _mesa_UnlockArraysEXT( void )
2070 {
2071 GET_CURRENT_CONTEXT(ctx);
2072
2073 if (MESA_VERBOSE & VERBOSE_API)
2074 _mesa_debug(ctx, "glUnlockArrays\n");
2075
2076 if (ctx->Array.LockCount == 0) {
2077 _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" );
2078 return;
2079 }
2080
2081 ctx->Array.LockFirst = 0;
2082 ctx->Array.LockCount = 0;
2083 }
2084
2085
2086 static void
2087 primitive_restart_index(struct gl_context *ctx, GLuint index)
2088 {
2089 ctx->Array.RestartIndex = index;
2090 }
2091
2092
2093 /**
2094 * GL_NV_primitive_restart and GL 3.1
2095 */
2096 void GLAPIENTRY
2097 _mesa_PrimitiveRestartIndex_no_error(GLuint index)
2098 {
2099 GET_CURRENT_CONTEXT(ctx);
2100 primitive_restart_index(ctx, index);
2101 }
2102
2103
2104 void GLAPIENTRY
2105 _mesa_PrimitiveRestartIndex(GLuint index)
2106 {
2107 GET_CURRENT_CONTEXT(ctx);
2108
2109 if (!ctx->Extensions.NV_primitive_restart && ctx->Version < 31) {
2110 _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()");
2111 return;
2112 }
2113
2114 primitive_restart_index(ctx, index);
2115 }
2116
2117
2118 void GLAPIENTRY
2119 _mesa_VertexAttribDivisor_no_error(GLuint index, GLuint divisor)
2120 {
2121 GET_CURRENT_CONTEXT(ctx);
2122
2123 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index);
2124 struct gl_vertex_array_object * const vao = ctx->Array.VAO;
2125
2126 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
2127
2128 /* The ARB_vertex_attrib_binding spec says:
2129 *
2130 * "The command
2131 *
2132 * void VertexAttribDivisor(uint index, uint divisor);
2133 *
2134 * is equivalent to (assuming no errors are generated):
2135 *
2136 * VertexAttribBinding(index, index);
2137 * VertexBindingDivisor(index, divisor);"
2138 */
2139 _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
2140 vertex_binding_divisor(ctx, vao, genericIndex, divisor);
2141 }
2142
2143
2144 /**
2145 * See GL_ARB_instanced_arrays.
2146 * Note that the instance divisor only applies to generic arrays, not
2147 * the legacy vertex arrays.
2148 */
2149 void GLAPIENTRY
2150 _mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
2151 {
2152 GET_CURRENT_CONTEXT(ctx);
2153
2154 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index);
2155 struct gl_vertex_array_object * const vao = ctx->Array.VAO;
2156
2157 if (!ctx->Extensions.ARB_instanced_arrays) {
2158 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
2159 return;
2160 }
2161
2162 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2163 _mesa_error(ctx, GL_INVALID_VALUE,
2164 "glVertexAttribDivisor(index = %u)", index);
2165 return;
2166 }
2167
2168 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
2169
2170 /* The ARB_vertex_attrib_binding spec says:
2171 *
2172 * "The command
2173 *
2174 * void VertexAttribDivisor(uint index, uint divisor);
2175 *
2176 * is equivalent to (assuming no errors are generated):
2177 *
2178 * VertexAttribBinding(index, index);
2179 * VertexBindingDivisor(index, divisor);"
2180 */
2181 _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
2182 vertex_binding_divisor(ctx, vao, genericIndex, divisor);
2183 }
2184
2185
2186 static ALWAYS_INLINE void
2187 vertex_array_vertex_buffer(struct gl_context *ctx,
2188 struct gl_vertex_array_object *vao,
2189 GLuint bindingIndex, GLuint buffer, GLintptr offset,
2190 GLsizei stride, bool no_error, const char *func)
2191 {
2192 struct gl_buffer_object *vbo;
2193 if (buffer ==
2194 vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj->Name) {
2195 vbo = vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj;
2196 } else if (buffer != 0) {
2197 vbo = _mesa_lookup_bufferobj(ctx, buffer);
2198
2199 if (!no_error && !vbo && _mesa_is_gles31(ctx)) {
2200 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", func);
2201 return;
2202 }
2203 /* From the GL_ARB_vertex_attrib_array spec:
2204 *
2205 * "[Core profile only:]
2206 * An INVALID_OPERATION error is generated if buffer is not zero or a
2207 * name returned from a previous call to GenBuffers, or if such a name
2208 * has since been deleted with DeleteBuffers.
2209 *
2210 * Otherwise, we fall back to the same compat profile behavior as other
2211 * object references (automatically gen it).
2212 */
2213 if (!_mesa_handle_bind_buffer_gen(ctx, buffer, &vbo, func))
2214 return;
2215 } else {
2216 /* The ARB_vertex_attrib_binding spec says:
2217 *
2218 * "If <buffer> is zero, any buffer object attached to this
2219 * bindpoint is detached."
2220 */
2221 vbo = ctx->Shared->NullBufferObj;
2222 }
2223
2224 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex),
2225 vbo, offset, stride);
2226 }
2227
2228
2229 /**
2230 * GL_ARB_vertex_attrib_binding
2231 */
2232 static void
2233 vertex_array_vertex_buffer_err(struct gl_context *ctx,
2234 struct gl_vertex_array_object *vao,
2235 GLuint bindingIndex, GLuint buffer,
2236 GLintptr offset, GLsizei stride,
2237 const char *func)
2238 {
2239 ASSERT_OUTSIDE_BEGIN_END(ctx);
2240
2241 /* The ARB_vertex_attrib_binding spec says:
2242 *
2243 * "An INVALID_VALUE error is generated if <bindingindex> is greater than
2244 * 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 /* The ARB_vertex_attrib_binding spec says:
2255 *
2256 * "The error INVALID_VALUE is generated if <stride> or <offset>
2257 * are negative."
2258 */
2259 if (offset < 0) {
2260 _mesa_error(ctx, GL_INVALID_VALUE,
2261 "%s(offset=%" PRId64 " < 0)",
2262 func, (int64_t) offset);
2263 return;
2264 }
2265
2266 if (stride < 0) {
2267 _mesa_error(ctx, GL_INVALID_VALUE,
2268 "%s(stride=%d < 0)", func, stride);
2269 return;
2270 }
2271
2272 if (((_mesa_is_desktop_gl(ctx) && ctx->Version >= 44) || _mesa_is_gles31(ctx)) &&
2273 stride > ctx->Const.MaxVertexAttribStride) {
2274 _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > "
2275 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride);
2276 return;
2277 }
2278
2279 vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset,
2280 stride, false, func);
2281 }
2282
2283
2284 void GLAPIENTRY
2285 _mesa_BindVertexBuffer_no_error(GLuint bindingIndex, GLuint buffer,
2286 GLintptr offset, GLsizei stride)
2287 {
2288 GET_CURRENT_CONTEXT(ctx);
2289 vertex_array_vertex_buffer(ctx, ctx->Array.VAO, bindingIndex,
2290 buffer, offset, stride, true,
2291 "glBindVertexBuffer");
2292 }
2293
2294
2295 void GLAPIENTRY
2296 _mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset,
2297 GLsizei stride)
2298 {
2299 GET_CURRENT_CONTEXT(ctx);
2300
2301 /* The ARB_vertex_attrib_binding spec says:
2302 *
2303 * "An INVALID_OPERATION error is generated if no vertex array object
2304 * is bound."
2305 */
2306 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2307 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2308 _mesa_error(ctx, GL_INVALID_OPERATION,
2309 "glBindVertexBuffer(No array object bound)");
2310 return;
2311 }
2312
2313 vertex_array_vertex_buffer_err(ctx, ctx->Array.VAO, bindingIndex,
2314 buffer, offset, stride,
2315 "glBindVertexBuffer");
2316 }
2317
2318
2319 void GLAPIENTRY
2320 _mesa_VertexArrayVertexBuffer_no_error(GLuint vaobj, GLuint bindingIndex,
2321 GLuint buffer, GLintptr offset,
2322 GLsizei stride)
2323 {
2324 GET_CURRENT_CONTEXT(ctx);
2325
2326 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2327 vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset,
2328 stride, true, "glVertexArrayVertexBuffer");
2329 }
2330
2331
2332 void GLAPIENTRY
2333 _mesa_VertexArrayVertexBuffer(GLuint vaobj, GLuint bindingIndex, GLuint buffer,
2334 GLintptr offset, GLsizei stride)
2335 {
2336 GET_CURRENT_CONTEXT(ctx);
2337 struct gl_vertex_array_object *vao;
2338
2339 /* The ARB_direct_state_access specification says:
2340 *
2341 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
2342 * if <vaobj> is not [compatibility profile: zero or] the name of an
2343 * existing vertex array object."
2344 */
2345 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayVertexBuffer");
2346 if (!vao)
2347 return;
2348
2349 vertex_array_vertex_buffer_err(ctx, vao, bindingIndex, buffer, offset,
2350 stride, "glVertexArrayVertexBuffer");
2351 }
2352
2353
2354 static ALWAYS_INLINE void
2355 vertex_array_vertex_buffers(struct gl_context *ctx,
2356 struct gl_vertex_array_object *vao,
2357 GLuint first, GLsizei count, const GLuint *buffers,
2358 const GLintptr *offsets, const GLsizei *strides,
2359 bool no_error, const char *func)
2360 {
2361 GLint i;
2362
2363 if (!buffers) {
2364 /**
2365 * The ARB_multi_bind spec says:
2366 *
2367 * "If <buffers> is NULL, each affected vertex buffer binding point
2368 * from <first> through <first>+<count>-1 will be reset to have no
2369 * bound buffer object. In this case, the offsets and strides
2370 * associated with the binding points are set to default values,
2371 * ignoring <offsets> and <strides>."
2372 */
2373 struct gl_buffer_object *vbo = ctx->Shared->NullBufferObj;
2374
2375 for (i = 0; i < count; i++)
2376 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
2377 vbo, 0, 16);
2378
2379 return;
2380 }
2381
2382 /* Note that the error semantics for multi-bind commands differ from
2383 * those of other GL commands.
2384 *
2385 * The Issues section in the ARB_multi_bind spec says:
2386 *
2387 * "(11) Typically, OpenGL specifies that if an error is generated by
2388 * a command, that command has no effect. This is somewhat
2389 * unfortunate for multi-bind commands, because it would require
2390 * a first pass to scan the entire list of bound objects for
2391 * errors and then a second pass to actually perform the
2392 * bindings. Should we have different error semantics?
2393 *
2394 * RESOLVED: Yes. In this specification, when the parameters for
2395 * one of the <count> binding points are invalid, that binding
2396 * point is not updated and an error will be generated. However,
2397 * other binding points in the same command will be updated if
2398 * their parameters are valid and no other error occurs."
2399 */
2400
2401 _mesa_HashLockMutex(ctx->Shared->BufferObjects);
2402
2403 for (i = 0; i < count; i++) {
2404 struct gl_buffer_object *vbo;
2405
2406 if (!no_error) {
2407 /* The ARB_multi_bind spec says:
2408 *
2409 * "An INVALID_VALUE error is generated if any value in
2410 * <offsets> or <strides> is negative (per binding)."
2411 */
2412 if (offsets[i] < 0) {
2413 _mesa_error(ctx, GL_INVALID_VALUE,
2414 "%s(offsets[%u]=%" PRId64 " < 0)",
2415 func, i, (int64_t) offsets[i]);
2416 continue;
2417 }
2418
2419 if (strides[i] < 0) {
2420 _mesa_error(ctx, GL_INVALID_VALUE,
2421 "%s(strides[%u]=%d < 0)",
2422 func, i, strides[i]);
2423 continue;
2424 }
2425
2426 if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 44 &&
2427 strides[i] > ctx->Const.MaxVertexAttribStride) {
2428 _mesa_error(ctx, GL_INVALID_VALUE,
2429 "%s(strides[%u]=%d > "
2430 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, i, strides[i]);
2431 continue;
2432 }
2433 }
2434
2435 if (buffers[i]) {
2436 struct gl_vertex_buffer_binding *binding =
2437 &vao->BufferBinding[VERT_ATTRIB_GENERIC(first + i)];
2438
2439 if (buffers[i] == binding->BufferObj->Name)
2440 vbo = binding->BufferObj;
2441 else
2442 vbo = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, func);
2443
2444 if (!vbo)
2445 continue;
2446 } else {
2447 vbo = ctx->Shared->NullBufferObj;
2448 }
2449
2450 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
2451 vbo, offsets[i], strides[i]);
2452 }
2453
2454 _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
2455 }
2456
2457
2458 static void
2459 vertex_array_vertex_buffers_err(struct gl_context *ctx,
2460 struct gl_vertex_array_object *vao,
2461 GLuint first, GLsizei count,
2462 const GLuint *buffers, const GLintptr *offsets,
2463 const GLsizei *strides, const char *func)
2464 {
2465 ASSERT_OUTSIDE_BEGIN_END(ctx);
2466
2467 /* The ARB_multi_bind spec says:
2468 *
2469 * "An INVALID_OPERATION error is generated if <first> + <count>
2470 * is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS."
2471 */
2472 if (first + count > ctx->Const.MaxVertexAttribBindings) {
2473 _mesa_error(ctx, GL_INVALID_OPERATION,
2474 "%s(first=%u + count=%d > the value of "
2475 "GL_MAX_VERTEX_ATTRIB_BINDINGS=%u)",
2476 func, first, count, ctx->Const.MaxVertexAttribBindings);
2477 return;
2478 }
2479
2480 vertex_array_vertex_buffers(ctx, vao, first, count, buffers, offsets,
2481 strides, false, func);
2482 }
2483
2484
2485 void GLAPIENTRY
2486 _mesa_BindVertexBuffers_no_error(GLuint first, GLsizei count,
2487 const GLuint *buffers, const GLintptr *offsets,
2488 const GLsizei *strides)
2489 {
2490 GET_CURRENT_CONTEXT(ctx);
2491
2492 vertex_array_vertex_buffers(ctx, ctx->Array.VAO, first, count,
2493 buffers, offsets, strides, true,
2494 "glBindVertexBuffers");
2495 }
2496
2497
2498 void GLAPIENTRY
2499 _mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers,
2500 const GLintptr *offsets, const GLsizei *strides)
2501 {
2502 GET_CURRENT_CONTEXT(ctx);
2503
2504 /* The ARB_vertex_attrib_binding spec says:
2505 *
2506 * "An INVALID_OPERATION error is generated if no
2507 * vertex array object is bound."
2508 */
2509 if (ctx->API == API_OPENGL_CORE &&
2510 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2511 _mesa_error(ctx, GL_INVALID_OPERATION,
2512 "glBindVertexBuffers(No array object bound)");
2513 return;
2514 }
2515
2516 vertex_array_vertex_buffers_err(ctx, ctx->Array.VAO, first, count,
2517 buffers, offsets, strides,
2518 "glBindVertexBuffers");
2519 }
2520
2521
2522 void GLAPIENTRY
2523 _mesa_VertexArrayVertexBuffers_no_error(GLuint vaobj, GLuint first,
2524 GLsizei count, const GLuint *buffers,
2525 const GLintptr *offsets,
2526 const GLsizei *strides)
2527 {
2528 GET_CURRENT_CONTEXT(ctx);
2529
2530 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2531 vertex_array_vertex_buffers(ctx, vao, first, count,
2532 buffers, offsets, strides, true,
2533 "glVertexArrayVertexBuffers");
2534 }
2535
2536
2537 void GLAPIENTRY
2538 _mesa_VertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count,
2539 const GLuint *buffers,
2540 const GLintptr *offsets, const GLsizei *strides)
2541 {
2542 GET_CURRENT_CONTEXT(ctx);
2543 struct gl_vertex_array_object *vao;
2544
2545 /* The ARB_direct_state_access specification says:
2546 *
2547 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
2548 * if <vaobj> is not [compatibility profile: zero or] the name of an
2549 * existing vertex array object."
2550 */
2551 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayVertexBuffers");
2552 if (!vao)
2553 return;
2554
2555 vertex_array_vertex_buffers_err(ctx, vao, first, count,
2556 buffers, offsets, strides,
2557 "glVertexArrayVertexBuffers");
2558 }
2559
2560
2561 static void
2562 vertex_attrib_format(GLuint attribIndex, GLint size, GLenum type,
2563 GLboolean normalized, GLboolean integer,
2564 GLboolean doubles, GLbitfield legalTypes,
2565 GLsizei sizeMax, GLuint relativeOffset,
2566 const char *func)
2567 {
2568 GET_CURRENT_CONTEXT(ctx);
2569 ASSERT_OUTSIDE_BEGIN_END(ctx);
2570
2571 GLenum format = get_array_format(ctx, sizeMax, &size);
2572
2573 if (!_mesa_is_no_error_enabled(ctx)) {
2574 /* The ARB_vertex_attrib_binding spec says:
2575 *
2576 * "An INVALID_OPERATION error is generated under any of the
2577 * following conditions:
2578 * - if no vertex array object is currently bound (see section
2579 * 2.10);
2580 * - ..."
2581 *
2582 * This error condition only applies to VertexAttribFormat and
2583 * VertexAttribIFormat in the extension spec, but we assume that this
2584 * is an oversight. In the OpenGL 4.3 (Core Profile) spec, it applies
2585 * to all three functions.
2586 */
2587 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2588 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2589 _mesa_error(ctx, GL_INVALID_OPERATION,
2590 "%s(No array object bound)", func);
2591 return;
2592 }
2593
2594 /* The ARB_vertex_attrib_binding spec says:
2595 *
2596 * "The error INVALID_VALUE is generated if index is greater than or
2597 * equal to the value of MAX_VERTEX_ATTRIBS."
2598 */
2599 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2600 _mesa_error(ctx, GL_INVALID_VALUE,
2601 "%s(attribindex=%u > "
2602 "GL_MAX_VERTEX_ATTRIBS)",
2603 func, attribIndex);
2604 return;
2605 }
2606
2607 if (!validate_array_format(ctx, func, ctx->Array.VAO,
2608 VERT_ATTRIB_GENERIC(attribIndex),
2609 legalTypes, 1, sizeMax, size, type,
2610 normalized, integer, doubles, relativeOffset,
2611 format)) {
2612 return;
2613 }
2614 }
2615
2616 _mesa_update_array_format(ctx, ctx->Array.VAO,
2617 VERT_ATTRIB_GENERIC(attribIndex), size, type,
2618 format, normalized, integer, doubles,
2619 relativeOffset);
2620 }
2621
2622
2623 void GLAPIENTRY
2624 _mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type,
2625 GLboolean normalized, GLuint relativeOffset)
2626 {
2627 vertex_attrib_format(attribIndex, size, type, normalized,
2628 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
2629 BGRA_OR_4, relativeOffset,
2630 "glVertexAttribFormat");
2631 }
2632
2633
2634 void GLAPIENTRY
2635 _mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type,
2636 GLuint relativeOffset)
2637 {
2638 vertex_attrib_format(attribIndex, size, type, GL_FALSE,
2639 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK, 4,
2640 relativeOffset, "glVertexAttribIFormat");
2641 }
2642
2643
2644 void GLAPIENTRY
2645 _mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type,
2646 GLuint relativeOffset)
2647 {
2648 vertex_attrib_format(attribIndex, size, type, GL_FALSE, GL_FALSE,
2649 GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK, 4,
2650 relativeOffset, "glVertexAttribLFormat");
2651 }
2652
2653
2654 static void
2655 vertex_array_attrib_format(GLuint vaobj, GLuint attribIndex, GLint size,
2656 GLenum type, GLboolean normalized,
2657 GLboolean integer, GLboolean doubles,
2658 GLbitfield legalTypes, GLsizei sizeMax,
2659 GLuint relativeOffset, const char *func)
2660 {
2661 GET_CURRENT_CONTEXT(ctx);
2662 struct gl_vertex_array_object *vao;
2663
2664 ASSERT_OUTSIDE_BEGIN_END(ctx);
2665
2666 GLenum format = get_array_format(ctx, sizeMax, &size);
2667
2668 if (_mesa_is_no_error_enabled(ctx)) {
2669 vao = _mesa_lookup_vao(ctx, vaobj);
2670 if (!vao)
2671 return;
2672 } else {
2673 /* The ARB_direct_state_access spec says:
2674 *
2675 * "An INVALID_OPERATION error is generated by
2676 * VertexArrayAttrib*Format if <vaobj> is not [compatibility profile:
2677 * zero or] the name of an existing vertex array object."
2678 */
2679 vao = _mesa_lookup_vao_err(ctx, false, vaobj, func);
2680 if (!vao)
2681 return;
2682
2683 /* The ARB_vertex_attrib_binding spec says:
2684 *
2685 * "The error INVALID_VALUE is generated if index is greater than or
2686 * equal to the value of MAX_VERTEX_ATTRIBS."
2687 */
2688 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2689 _mesa_error(ctx, GL_INVALID_VALUE,
2690 "%s(attribindex=%u > GL_MAX_VERTEX_ATTRIBS)",
2691 func, attribIndex);
2692 return;
2693 }
2694
2695 if (!validate_array_format(ctx, func, vao,
2696 VERT_ATTRIB_GENERIC(attribIndex),
2697 legalTypes, 1, sizeMax, size, type,
2698 normalized, integer, doubles, relativeOffset,
2699 format)) {
2700 return;
2701 }
2702 }
2703
2704 _mesa_update_array_format(ctx, vao, VERT_ATTRIB_GENERIC(attribIndex), size,
2705 type, format, normalized, integer, doubles,
2706 relativeOffset);
2707 }
2708
2709
2710 void GLAPIENTRY
2711 _mesa_VertexArrayAttribFormat(GLuint vaobj, GLuint attribIndex, GLint size,
2712 GLenum type, GLboolean normalized,
2713 GLuint relativeOffset)
2714 {
2715 vertex_array_attrib_format(vaobj, attribIndex, size, type, normalized,
2716 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
2717 BGRA_OR_4, relativeOffset,
2718 "glVertexArrayAttribFormat");
2719 }
2720
2721
2722 void GLAPIENTRY
2723 _mesa_VertexArrayAttribIFormat(GLuint vaobj, GLuint attribIndex,
2724 GLint size, GLenum type,
2725 GLuint relativeOffset)
2726 {
2727 vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE,
2728 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK,
2729 4, relativeOffset,
2730 "glVertexArrayAttribIFormat");
2731 }
2732
2733
2734 void GLAPIENTRY
2735 _mesa_VertexArrayAttribLFormat(GLuint vaobj, GLuint attribIndex,
2736 GLint size, GLenum type,
2737 GLuint relativeOffset)
2738 {
2739 vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE,
2740 GL_FALSE, GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK,
2741 4, relativeOffset,
2742 "glVertexArrayAttribLFormat");
2743 }
2744
2745
2746 static void
2747 vertex_array_attrib_binding(struct gl_context *ctx,
2748 struct gl_vertex_array_object *vao,
2749 GLuint attribIndex, GLuint bindingIndex,
2750 const char *func)
2751 {
2752 ASSERT_OUTSIDE_BEGIN_END(ctx);
2753
2754 /* The ARB_vertex_attrib_binding spec says:
2755 *
2756 * "<attribindex> must be less than the value of MAX_VERTEX_ATTRIBS and
2757 * <bindingindex> must be less than the value of
2758 * MAX_VERTEX_ATTRIB_BINDINGS, otherwise the error INVALID_VALUE
2759 * is generated."
2760 */
2761 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2762 _mesa_error(ctx, GL_INVALID_VALUE,
2763 "%s(attribindex=%u >= "
2764 "GL_MAX_VERTEX_ATTRIBS)",
2765 func, attribIndex);
2766 return;
2767 }
2768
2769 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2770 _mesa_error(ctx, GL_INVALID_VALUE,
2771 "%s(bindingindex=%u >= "
2772 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2773 func, bindingIndex);
2774 return;
2775 }
2776
2777 assert(VERT_ATTRIB_GENERIC(attribIndex) < ARRAY_SIZE(vao->VertexAttrib));
2778
2779 _mesa_vertex_attrib_binding(ctx, vao,
2780 VERT_ATTRIB_GENERIC(attribIndex),
2781 VERT_ATTRIB_GENERIC(bindingIndex));
2782 }
2783
2784
2785 void GLAPIENTRY
2786 _mesa_VertexAttribBinding_no_error(GLuint attribIndex, GLuint bindingIndex)
2787 {
2788 GET_CURRENT_CONTEXT(ctx);
2789 _mesa_vertex_attrib_binding(ctx, ctx->Array.VAO,
2790 VERT_ATTRIB_GENERIC(attribIndex),
2791 VERT_ATTRIB_GENERIC(bindingIndex));
2792 }
2793
2794
2795 void GLAPIENTRY
2796 _mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
2797 {
2798 GET_CURRENT_CONTEXT(ctx);
2799
2800 /* The ARB_vertex_attrib_binding spec says:
2801 *
2802 * "An INVALID_OPERATION error is generated if no vertex array object
2803 * is bound."
2804 */
2805 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2806 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2807 _mesa_error(ctx, GL_INVALID_OPERATION,
2808 "glVertexAttribBinding(No array object bound)");
2809 return;
2810 }
2811
2812 vertex_array_attrib_binding(ctx, ctx->Array.VAO,
2813 attribIndex, bindingIndex,
2814 "glVertexAttribBinding");
2815 }
2816
2817
2818 void GLAPIENTRY
2819 _mesa_VertexArrayAttribBinding_no_error(GLuint vaobj, GLuint attribIndex,
2820 GLuint bindingIndex)
2821 {
2822 GET_CURRENT_CONTEXT(ctx);
2823
2824 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2825 _mesa_vertex_attrib_binding(ctx, vao,
2826 VERT_ATTRIB_GENERIC(attribIndex),
2827 VERT_ATTRIB_GENERIC(bindingIndex));
2828 }
2829
2830
2831 void GLAPIENTRY
2832 _mesa_VertexArrayAttribBinding(GLuint vaobj, GLuint attribIndex, GLuint bindingIndex)
2833 {
2834 GET_CURRENT_CONTEXT(ctx);
2835 struct gl_vertex_array_object *vao;
2836
2837 /* The ARB_direct_state_access specification says:
2838 *
2839 * "An INVALID_OPERATION error is generated by VertexArrayAttribBinding
2840 * if <vaobj> is not [compatibility profile: zero or] the name of an
2841 * existing vertex array object."
2842 */
2843 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayAttribBinding");
2844 if (!vao)
2845 return;
2846
2847 vertex_array_attrib_binding(ctx, vao, attribIndex, bindingIndex,
2848 "glVertexArrayAttribBinding");
2849 }
2850
2851
2852 static void
2853 vertex_array_binding_divisor(struct gl_context *ctx,
2854 struct gl_vertex_array_object *vao,
2855 GLuint bindingIndex, GLuint divisor,
2856 const char *func)
2857 {
2858 ASSERT_OUTSIDE_BEGIN_END(ctx);
2859
2860 if (!ctx->Extensions.ARB_instanced_arrays) {
2861 _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", func);
2862 return;
2863 }
2864
2865 /* The ARB_vertex_attrib_binding spec says:
2866 *
2867 * "An INVALID_VALUE error is generated if <bindingindex> is greater
2868 * than or equal to the value of MAX_VERTEX_ATTRIB_BINDINGS."
2869 */
2870 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2871 _mesa_error(ctx, GL_INVALID_VALUE,
2872 "%s(bindingindex=%u > "
2873 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2874 func, bindingIndex);
2875 return;
2876 }
2877
2878 vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2879 }
2880
2881
2882 void GLAPIENTRY
2883 _mesa_VertexBindingDivisor_no_error(GLuint bindingIndex, GLuint divisor)
2884 {
2885 GET_CURRENT_CONTEXT(ctx);
2886 vertex_binding_divisor(ctx, ctx->Array.VAO,
2887 VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2888 }
2889
2890
2891 void GLAPIENTRY
2892 _mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
2893 {
2894 GET_CURRENT_CONTEXT(ctx);
2895
2896 /* The ARB_vertex_attrib_binding spec says:
2897 *
2898 * "An INVALID_OPERATION error is generated if no vertex array object
2899 * is bound."
2900 */
2901 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2902 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2903 _mesa_error(ctx, GL_INVALID_OPERATION,
2904 "glVertexBindingDivisor(No array object bound)");
2905 return;
2906 }
2907
2908 vertex_array_binding_divisor(ctx, ctx->Array.VAO,
2909 bindingIndex, divisor,
2910 "glVertexBindingDivisor");
2911 }
2912
2913
2914 void GLAPIENTRY
2915 _mesa_VertexArrayBindingDivisor_no_error(GLuint vaobj, GLuint bindingIndex,
2916 GLuint divisor)
2917 {
2918 GET_CURRENT_CONTEXT(ctx);
2919
2920 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2921 vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2922 }
2923
2924
2925 void GLAPIENTRY
2926 _mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex,
2927 GLuint divisor)
2928 {
2929 struct gl_vertex_array_object *vao;
2930 GET_CURRENT_CONTEXT(ctx);
2931
2932 /* The ARB_direct_state_access specification says:
2933 *
2934 * "An INVALID_OPERATION error is generated by VertexArrayBindingDivisor
2935 * if <vaobj> is not [compatibility profile: zero or] the name of an
2936 * existing vertex array object."
2937 */
2938 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayBindingDivisor");
2939 if (!vao)
2940 return;
2941
2942 vertex_array_binding_divisor(ctx, vao, bindingIndex, divisor,
2943 "glVertexArrayBindingDivisor");
2944 }
2945
2946
2947 void
2948 _mesa_copy_vertex_attrib_array(struct gl_context *ctx,
2949 struct gl_array_attributes *dst,
2950 const struct gl_array_attributes *src)
2951 {
2952 dst->Ptr = src->Ptr;
2953 dst->RelativeOffset = src->RelativeOffset;
2954 dst->Format = src->Format;
2955 dst->Stride = src->Stride;
2956 dst->BufferBindingIndex = src->BufferBindingIndex;
2957 dst->_EffBufferBindingIndex = src->_EffBufferBindingIndex;
2958 dst->_EffRelativeOffset = src->_EffRelativeOffset;
2959 }
2960
2961 void
2962 _mesa_copy_vertex_buffer_binding(struct gl_context *ctx,
2963 struct gl_vertex_buffer_binding *dst,
2964 const struct gl_vertex_buffer_binding *src)
2965 {
2966 dst->Offset = src->Offset;
2967 dst->Stride = src->Stride;
2968 dst->InstanceDivisor = src->InstanceDivisor;
2969 dst->_BoundArrays = src->_BoundArrays;
2970 dst->_EffBoundArrays = src->_EffBoundArrays;
2971 dst->_EffOffset = src->_EffOffset;
2972
2973 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
2974 }
2975
2976 /**
2977 * Print current vertex object/array info. For debug.
2978 */
2979 void
2980 _mesa_print_arrays(struct gl_context *ctx)
2981 {
2982 const struct gl_vertex_array_object *vao = ctx->Array.VAO;
2983
2984 fprintf(stderr, "Array Object %u\n", vao->Name);
2985
2986 GLbitfield mask = vao->Enabled;
2987 while (mask) {
2988 const gl_vert_attrib i = u_bit_scan(&mask);
2989 const struct gl_array_attributes *array = &vao->VertexAttrib[i];
2990
2991 const struct gl_vertex_buffer_binding *binding =
2992 &vao->BufferBinding[array->BufferBindingIndex];
2993 const struct gl_buffer_object *bo = binding->BufferObj;
2994
2995 fprintf(stderr, " %s: Ptr=%p, Type=%s, Size=%d, ElemSize=%u, "
2996 "Stride=%d, Buffer=%u(Size %lu)\n",
2997 gl_vert_attrib_name((gl_vert_attrib)i),
2998 array->Ptr, _mesa_enum_to_string(array->Format.Type),
2999 array->Format.Size,
3000 array->Format._ElementSize, binding->Stride, bo->Name,
3001 (unsigned long) bo->Size);
3002 }
3003 }
3004
3005
3006 /**
3007 * Initialize vertex array state for given context.
3008 */
3009 void
3010 _mesa_init_varray(struct gl_context *ctx)
3011 {
3012 ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0);
3013 _mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO);
3014 ctx->Array._EmptyVAO = _mesa_new_vao(ctx, ~0u);
3015 _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, ctx->Array._EmptyVAO);
3016 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
3017
3018 ctx->Array.Objects = _mesa_NewHashTable();
3019 }
3020
3021
3022 /**
3023 * Callback for deleting an array object. Called by _mesa_HashDeleteAll().
3024 */
3025 static void
3026 delete_arrayobj_cb(GLuint id, void *data, void *userData)
3027 {
3028 struct gl_vertex_array_object *vao = (struct gl_vertex_array_object *) data;
3029 struct gl_context *ctx = (struct gl_context *) userData;
3030 _mesa_delete_vao(ctx, vao);
3031 }
3032
3033
3034 /**
3035 * Free vertex array state for given context.
3036 */
3037 void
3038 _mesa_free_varray_data(struct gl_context *ctx)
3039 {
3040 _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx);
3041 _mesa_DeleteHashTable(ctx->Array.Objects);
3042 }