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