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