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