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