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