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