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