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