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