varray.c revision 01e04c3f
1/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5 * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27#include <stdio.h>
28#include <inttypes.h>  /* for PRId64 macro */
29
30#include "glheader.h"
31#include "imports.h"
32#include "bufferobj.h"
33#include "context.h"
34#include "enable.h"
35#include "enums.h"
36#include "hash.h"
37#include "image.h"
38#include "macros.h"
39#include "mtypes.h"
40#include "varray.h"
41#include "arrayobj.h"
42#include "main/dispatch.h"
43
44
45/** Used to do error checking for GL_EXT_vertex_array_bgra */
46#define BGRA_OR_4  5
47
48
49/** Used to indicate which GL datatypes are accepted by each of the
50 * glVertex/Color/Attrib/EtcPointer() functions.
51 */
52#define BOOL_BIT                          (1 << 0)
53#define BYTE_BIT                          (1 << 1)
54#define UNSIGNED_BYTE_BIT                 (1 << 2)
55#define SHORT_BIT                         (1 << 3)
56#define UNSIGNED_SHORT_BIT                (1 << 4)
57#define INT_BIT                           (1 << 5)
58#define UNSIGNED_INT_BIT                  (1 << 6)
59#define HALF_BIT                          (1 << 7)
60#define FLOAT_BIT                         (1 << 8)
61#define DOUBLE_BIT                        (1 << 9)
62#define FIXED_ES_BIT                      (1 << 10)
63#define FIXED_GL_BIT                      (1 << 11)
64#define UNSIGNED_INT_2_10_10_10_REV_BIT   (1 << 12)
65#define INT_2_10_10_10_REV_BIT            (1 << 13)
66#define UNSIGNED_INT_10F_11F_11F_REV_BIT  (1 << 14)
67#define ALL_TYPE_BITS                    ((1 << 15) - 1)
68
69#define ATTRIB_FORMAT_TYPES_MASK (BYTE_BIT | UNSIGNED_BYTE_BIT | \
70                                  SHORT_BIT | UNSIGNED_SHORT_BIT | \
71                                  INT_BIT | UNSIGNED_INT_BIT | \
72                                  HALF_BIT | FLOAT_BIT | DOUBLE_BIT | \
73                                  FIXED_GL_BIT | \
74                                  UNSIGNED_INT_2_10_10_10_REV_BIT | \
75                                  INT_2_10_10_10_REV_BIT | \
76                                  UNSIGNED_INT_10F_11F_11F_REV_BIT)
77
78#define ATTRIB_IFORMAT_TYPES_MASK (BYTE_BIT | UNSIGNED_BYTE_BIT | \
79                                   SHORT_BIT | UNSIGNED_SHORT_BIT | \
80                                   INT_BIT | UNSIGNED_INT_BIT)
81
82#define ATTRIB_LFORMAT_TYPES_MASK DOUBLE_BIT
83
84
85/** Convert GL datatype enum into a <type>_BIT value seen above */
86static GLbitfield
87type_to_bit(const struct gl_context *ctx, GLenum type)
88{
89   switch (type) {
90   case GL_BOOL:
91      return BOOL_BIT;
92   case GL_BYTE:
93      return BYTE_BIT;
94   case GL_UNSIGNED_BYTE:
95      return UNSIGNED_BYTE_BIT;
96   case GL_SHORT:
97      return SHORT_BIT;
98   case GL_UNSIGNED_SHORT:
99      return UNSIGNED_SHORT_BIT;
100   case GL_INT:
101      return INT_BIT;
102   case GL_UNSIGNED_INT:
103      return UNSIGNED_INT_BIT;
104   case GL_HALF_FLOAT:
105   case GL_HALF_FLOAT_OES:
106      if (ctx->Extensions.ARB_half_float_vertex)
107         return HALF_BIT;
108      else
109         return 0x0;
110   case GL_FLOAT:
111      return FLOAT_BIT;
112   case GL_DOUBLE:
113      return DOUBLE_BIT;
114   case GL_FIXED:
115      return _mesa_is_desktop_gl(ctx) ? FIXED_GL_BIT : FIXED_ES_BIT;
116   case GL_UNSIGNED_INT_2_10_10_10_REV:
117      return UNSIGNED_INT_2_10_10_10_REV_BIT;
118   case GL_INT_2_10_10_10_REV:
119      return INT_2_10_10_10_REV_BIT;
120   case GL_UNSIGNED_INT_10F_11F_11F_REV:
121      return UNSIGNED_INT_10F_11F_11F_REV_BIT;
122   default:
123      return 0;
124   }
125}
126
127
128/**
129 * Depending on the position and generic0 attributes enable flags select
130 * the one that is used for both attributes.
131 * The generic0 attribute takes precedence.
132 */
133static inline void
134update_attribute_map_mode(const struct gl_context *ctx,
135                          struct gl_vertex_array_object *vao)
136{
137   /*
138    * There is no need to change the mapping away from the
139    * identity mapping if we are not in compat mode.
140    */
141   if (ctx->API != API_OPENGL_COMPAT)
142      return;
143   /* The generic0 attribute superseeds the position attribute */
144   const GLbitfield enabled = vao->_Enabled;
145   if (enabled & VERT_BIT_GENERIC0)
146      vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_GENERIC0;
147   else if (enabled & VERT_BIT_POS)
148      vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_POSITION;
149   else
150      vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_IDENTITY;
151}
152
153
154/**
155 * Sets the BufferBindingIndex field for the vertex attribute given by
156 * attribIndex.
157 */
158void
159_mesa_vertex_attrib_binding(struct gl_context *ctx,
160                            struct gl_vertex_array_object *vao,
161                            gl_vert_attrib attribIndex,
162                            GLuint bindingIndex)
163{
164   struct gl_array_attributes *array = &vao->VertexAttrib[attribIndex];
165   assert(!vao->SharedAndImmutable);
166
167   if (array->BufferBindingIndex != bindingIndex) {
168      const GLbitfield array_bit = VERT_BIT(attribIndex);
169
170      if (_mesa_is_bufferobj(vao->BufferBinding[bindingIndex].BufferObj))
171         vao->VertexAttribBufferMask |= array_bit;
172      else
173         vao->VertexAttribBufferMask &= ~array_bit;
174
175      vao->BufferBinding[array->BufferBindingIndex]._BoundArrays &= ~array_bit;
176      vao->BufferBinding[bindingIndex]._BoundArrays |= array_bit;
177
178      array->BufferBindingIndex = bindingIndex;
179
180      vao->NewArrays |= vao->_Enabled & array_bit;
181      if (vao == ctx->Array.VAO)
182         ctx->NewState |= _NEW_ARRAY;
183   }
184}
185
186
187/**
188 * Binds a buffer object to the vertex buffer binding point given by index,
189 * and sets the Offset and Stride fields.
190 */
191void
192_mesa_bind_vertex_buffer(struct gl_context *ctx,
193                         struct gl_vertex_array_object *vao,
194                         GLuint index,
195                         struct gl_buffer_object *vbo,
196                         GLintptr offset, GLsizei stride)
197{
198   assert(index < ARRAY_SIZE(vao->BufferBinding));
199   assert(!vao->SharedAndImmutable);
200   struct gl_vertex_buffer_binding *binding = &vao->BufferBinding[index];
201
202   if (binding->BufferObj != vbo ||
203       binding->Offset != offset ||
204       binding->Stride != stride) {
205
206      _mesa_reference_buffer_object(ctx, &binding->BufferObj, vbo);
207
208      binding->Offset = offset;
209      binding->Stride = stride;
210
211      if (!_mesa_is_bufferobj(vbo))
212         vao->VertexAttribBufferMask &= ~binding->_BoundArrays;
213      else
214         vao->VertexAttribBufferMask |= binding->_BoundArrays;
215
216      vao->NewArrays |= vao->_Enabled & binding->_BoundArrays;
217      if (vao == ctx->Array.VAO)
218         ctx->NewState |= _NEW_ARRAY;
219   }
220}
221
222
223/**
224 * Sets the InstanceDivisor field in the vertex buffer binding point
225 * given by bindingIndex.
226 */
227static void
228vertex_binding_divisor(struct gl_context *ctx,
229                       struct gl_vertex_array_object *vao,
230                       GLuint bindingIndex,
231                       GLuint divisor)
232{
233   struct gl_vertex_buffer_binding *binding =
234      &vao->BufferBinding[bindingIndex];
235   assert(!vao->SharedAndImmutable);
236
237   if (binding->InstanceDivisor != divisor) {
238      binding->InstanceDivisor = divisor;
239      vao->NewArrays |= vao->_Enabled & binding->_BoundArrays;
240      if (vao == ctx->Array.VAO)
241         ctx->NewState |= _NEW_ARRAY;
242   }
243}
244
245
246/**
247 * Examine the API profile and extensions to determine which types are legal
248 * for vertex arrays.  This is called once from update_array_format().
249 */
250static GLbitfield
251get_legal_types_mask(const struct gl_context *ctx)
252{
253   GLbitfield legalTypesMask = ALL_TYPE_BITS;
254
255   if (_mesa_is_gles(ctx)) {
256      legalTypesMask &= ~(FIXED_GL_BIT |
257                          DOUBLE_BIT |
258                          UNSIGNED_INT_10F_11F_11F_REV_BIT);
259
260      /* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until
261       * 3.0.  The 2_10_10_10 types are added in OpenGL ES 3.0 or
262       * GL_OES_vertex_type_10_10_10_2.  GL_HALF_FLOAT data is not allowed
263       * until 3.0 or with the GL_OES_vertex_half float extension, which isn't
264       * quite as trivial as we'd like because it uses a different enum value
265       * for GL_HALF_FLOAT_OES.
266       */
267      if (ctx->Version < 30) {
268         legalTypesMask &= ~(UNSIGNED_INT_BIT |
269                             INT_BIT |
270                             UNSIGNED_INT_2_10_10_10_REV_BIT |
271                             INT_2_10_10_10_REV_BIT);
272
273         if (!_mesa_has_OES_vertex_half_float(ctx))
274            legalTypesMask &= ~HALF_BIT;
275      }
276   }
277   else {
278      legalTypesMask &= ~FIXED_ES_BIT;
279
280      if (!ctx->Extensions.ARB_ES2_compatibility)
281         legalTypesMask &= ~FIXED_GL_BIT;
282
283      if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev)
284         legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT |
285                             INT_2_10_10_10_REV_BIT);
286
287      if (!ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev)
288         legalTypesMask &= ~UNSIGNED_INT_10F_11F_11F_REV_BIT;
289   }
290
291   return legalTypesMask;
292}
293
294static GLenum
295get_array_format(const struct gl_context *ctx, GLint sizeMax, GLint *size)
296{
297   GLenum format = GL_RGBA;
298
299   /* Do size parameter checking.
300    * If sizeMax = BGRA_OR_4 it means that size = GL_BGRA is legal and
301    * must be handled specially.
302    */
303   if (ctx->Extensions.EXT_vertex_array_bgra && sizeMax == BGRA_OR_4 &&
304       *size == GL_BGRA) {
305      format = GL_BGRA;
306      *size = 4;
307   }
308
309   return format;
310}
311
312
313/**
314 * \param attrib         The index of the attribute array
315 * \param size           Components per element (1, 2, 3 or 4)
316 * \param type           Datatype of each component (GL_FLOAT, GL_INT, etc)
317 * \param format         Either GL_RGBA or GL_BGRA.
318 * \param normalized     Whether integer types are converted to floats in [-1, 1]
319 * \param integer        Integer-valued values (will not be normalized to [-1, 1])
320 * \param doubles        Double values not reduced to floats
321 * \param relativeOffset Offset of the first element relative to the binding
322 *                       offset.
323 */
324void
325_mesa_update_array_format(struct gl_context *ctx,
326                          struct gl_vertex_array_object *vao,
327                          gl_vert_attrib attrib, GLint size, GLenum type,
328                          GLenum format, GLboolean normalized,
329                          GLboolean integer, GLboolean doubles,
330                          GLuint relativeOffset)
331{
332   struct gl_array_attributes *const array = &vao->VertexAttrib[attrib];
333   GLint elementSize;
334
335   assert(!vao->SharedAndImmutable);
336   assert(size <= 4);
337
338   elementSize = _mesa_bytes_per_vertex_attrib(size, type);
339   assert(elementSize != -1);
340
341   array->Size = size;
342   array->Type = type;
343   array->Format = format;
344   array->Normalized = normalized;
345   array->Integer = integer;
346   array->Doubles = doubles;
347   array->RelativeOffset = relativeOffset;
348   array->_ElementSize = elementSize;
349
350   vao->NewArrays |= vao->_Enabled & VERT_BIT(attrib);
351   if (vao == ctx->Array.VAO)
352      ctx->NewState |= _NEW_ARRAY;
353}
354
355/**
356 * Does error checking of the format in an attrib array.
357 *
358 * Called by *Pointer() and VertexAttrib*Format().
359 *
360 * \param func         Name of calling function used for error reporting
361 * \param attrib       The index of the attribute array
362 * \param legalTypes   Bitmask of *_BIT above indicating legal datatypes
363 * \param sizeMin      Min allowable size value
364 * \param sizeMax      Max allowable size value (may also be BGRA_OR_4)
365 * \param size         Components per element (1, 2, 3 or 4)
366 * \param type         Datatype of each component (GL_FLOAT, GL_INT, etc)
367 * \param normalized   Whether integer types are converted to floats in [-1, 1]
368 * \param integer      Integer-valued values (will not be normalized to [-1, 1])
369 * \param doubles      Double values not reduced to floats
370 * \param relativeOffset Offset of the first element relative to the binding offset.
371 * \return bool True if validation is successful, False otherwise.
372 */
373static bool
374validate_array_format(struct gl_context *ctx, const char *func,
375                      struct gl_vertex_array_object *vao,
376                      GLuint attrib, GLbitfield legalTypesMask,
377                      GLint sizeMin, GLint sizeMax,
378                      GLint size, GLenum type, GLboolean normalized,
379                      GLboolean integer, GLboolean doubles,
380                      GLuint relativeOffset, GLenum format)
381{
382   GLbitfield typeBit;
383
384   /* at most, one of these bools can be true */
385   assert((int) normalized + (int) integer + (int) doubles <= 1);
386
387   if (ctx->Array.LegalTypesMask == 0 || ctx->Array.LegalTypesMaskAPI != ctx->API) {
388      /* Compute the LegalTypesMask only once, unless the context API has
389       * changed, in which case we want to compute it again.  We can't do this
390       * in _mesa_init_varrays() below because extensions are not yet enabled
391       * at that point.
392       */
393      ctx->Array.LegalTypesMask = get_legal_types_mask(ctx);
394      ctx->Array.LegalTypesMaskAPI = ctx->API;
395   }
396
397   legalTypesMask &= ctx->Array.LegalTypesMask;
398
399   if (_mesa_is_gles(ctx) && sizeMax == BGRA_OR_4) {
400      /* BGRA ordering is not supported in ES contexts.
401       */
402      sizeMax = 4;
403   }
404
405   typeBit = type_to_bit(ctx, type);
406   if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) {
407      _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)",
408                  func, _mesa_enum_to_string(type));
409      return false;
410   }
411
412   if (format == GL_BGRA) {
413      /* Page 298 of the PDF of the OpenGL 4.3 (Core Profile) spec says:
414       *
415       * "An INVALID_OPERATION error is generated under any of the following
416       *  conditions:
417       *    ...
418       *    • size is BGRA and type is not UNSIGNED_BYTE, INT_2_10_10_10_REV
419       *      or UNSIGNED_INT_2_10_10_10_REV;
420       *    ...
421       *    • size is BGRA and normalized is FALSE;"
422       */
423      bool bgra_error = false;
424
425      if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) {
426         if (type != GL_UNSIGNED_INT_2_10_10_10_REV &&
427             type != GL_INT_2_10_10_10_REV &&
428             type != GL_UNSIGNED_BYTE)
429            bgra_error = true;
430      } else if (type != GL_UNSIGNED_BYTE)
431         bgra_error = true;
432
433      if (bgra_error) {
434         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=GL_BGRA and type=%s)",
435                     func, _mesa_enum_to_string(type));
436         return false;
437      }
438
439      if (!normalized) {
440         _mesa_error(ctx, GL_INVALID_OPERATION,
441                     "%s(size=GL_BGRA and normalized=GL_FALSE)", func);
442         return false;
443      }
444   }
445   else if (size < sizeMin || size > sizeMax || size > 4) {
446      _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size);
447      return false;
448   }
449
450   if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev &&
451       (type == GL_UNSIGNED_INT_2_10_10_10_REV ||
452        type == GL_INT_2_10_10_10_REV) && size != 4) {
453      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size);
454      return false;
455   }
456
457   /* The ARB_vertex_attrib_binding_spec says:
458    *
459    *   An INVALID_VALUE error is generated if <relativeoffset> is larger than
460    *   the value of MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.
461    */
462   if (relativeOffset > ctx->Const.MaxVertexAttribRelativeOffset) {
463      _mesa_error(ctx, GL_INVALID_VALUE,
464                  "%s(relativeOffset=%d > "
465                  "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET)",
466                  func, relativeOffset);
467      return false;
468   }
469
470   if (ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev &&
471         type == GL_UNSIGNED_INT_10F_11F_11F_REV && size != 3) {
472      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size);
473      return false;
474   }
475
476   return true;
477}
478
479/**
480 * Do error checking for glVertex/Color/TexCoord/...Pointer functions.
481 *
482 * \param func  name of calling function used for error reporting
483 * \param attrib  the attribute array index to update
484 * \param legalTypes  bitmask of *_BIT above indicating legal datatypes
485 * \param sizeMin  min allowable size value
486 * \param sizeMax  max allowable size value (may also be BGRA_OR_4)
487 * \param size  components per element (1, 2, 3 or 4)
488 * \param type  datatype of each component (GL_FLOAT, GL_INT, etc)
489 * \param stride  stride between elements, in elements
490 * \param normalized  are integer types converted to floats in [-1, 1]?
491 * \param integer  integer-valued values (will not be normalized to [-1,1])
492 * \param doubles  Double values not reduced to floats
493 * \param ptr  the address (or offset inside VBO) of the array data
494 */
495static void
496validate_array(struct gl_context *ctx, const char *func,
497               GLuint attrib, GLbitfield legalTypesMask,
498               GLint sizeMin, GLint sizeMax,
499               GLint size, GLenum type, GLsizei stride,
500               GLboolean normalized, GLboolean integer, GLboolean doubles,
501               const GLvoid *ptr)
502{
503   struct gl_vertex_array_object *vao = ctx->Array.VAO;
504
505   /* Page 407 (page 423 of the PDF) of the OpenGL 3.0 spec says:
506    *
507    *     "Client vertex arrays - all vertex array attribute pointers must
508    *     refer to buffer objects (section 2.9.2). The default vertex array
509    *     object (the name zero) is also deprecated. Calling
510    *     VertexAttribPointer when no buffer object or no vertex array object
511    *     is bound will generate an INVALID_OPERATION error..."
512    *
513    * The check for VBOs is handled below.
514    */
515   if (ctx->API == API_OPENGL_CORE && (vao == ctx->Array.DefaultVAO)) {
516      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no array object bound)",
517                  func);
518      return;
519   }
520
521   if (stride < 0) {
522      _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride );
523      return;
524   }
525
526   if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 44 &&
527       stride > ctx->Const.MaxVertexAttribStride) {
528      _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > "
529                  "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride);
530      return;
531   }
532
533   /* Page 29 (page 44 of the PDF) of the OpenGL 3.3 spec says:
534    *
535    *     "An INVALID_OPERATION error is generated under any of the following
536    *     conditions:
537    *
538    *     ...
539    *
540    *     * any of the *Pointer commands specifying the location and
541    *       organization of vertex array data are called while zero is bound
542    *       to the ARRAY_BUFFER buffer object binding point (see section
543    *       2.9.6), and the pointer argument is not NULL."
544    */
545   if (ptr != NULL && vao != ctx->Array.DefaultVAO &&
546       !_mesa_is_bufferobj(ctx->Array.ArrayBufferObj)) {
547      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func);
548      return;
549   }
550}
551
552
553static bool
554validate_array_and_format(struct gl_context *ctx, const char *func,
555                          GLuint attrib, GLbitfield legalTypes,
556                          GLint sizeMin, GLint sizeMax,
557                          GLint size, GLenum type, GLsizei stride,
558                          GLboolean normalized, GLboolean integer,
559                          GLboolean doubles, GLenum format, const GLvoid *ptr,
560                          struct gl_vertex_array_object *vao)
561{
562   validate_array(ctx, func, attrib, legalTypes, sizeMin, sizeMax, size,
563                  type, stride, normalized, integer, doubles, ptr);
564
565   return validate_array_format(ctx, func, vao, attrib, legalTypes, sizeMin,
566                                sizeMax, size, type, normalized, integer,
567                                doubles, 0, format);
568}
569
570
571/**
572 * Update state for glVertex/Color/TexCoord/...Pointer functions.
573 *
574 * \param attrib  the attribute array index to update
575 * \param format  Either GL_RGBA or GL_BGRA.
576 * \param sizeMax  max allowable size value (may also be BGRA_OR_4)
577 * \param size  components per element (1, 2, 3 or 4)
578 * \param type  datatype of each component (GL_FLOAT, GL_INT, etc)
579 * \param stride  stride between elements, in elements
580 * \param normalized  are integer types converted to floats in [-1, 1]?
581 * \param integer  integer-valued values (will not be normalized to [-1,1])
582 * \param doubles  Double values not reduced to floats
583 * \param ptr  the address (or offset inside VBO) of the array data
584 */
585static void
586update_array(struct gl_context *ctx,
587             GLuint attrib, GLenum format,
588             GLint sizeMax,
589             GLint size, GLenum type, GLsizei stride,
590             GLboolean normalized, GLboolean integer, GLboolean doubles,
591             const GLvoid *ptr)
592{
593   struct gl_vertex_array_object *vao = ctx->Array.VAO;
594
595   _mesa_update_array_format(ctx, vao, attrib, size, type, format,
596                             normalized, integer, doubles, 0);
597
598   /* Reset the vertex attrib binding */
599   _mesa_vertex_attrib_binding(ctx, vao, attrib, attrib);
600
601   /* The Stride and Ptr fields are not set by update_array_format() */
602   struct gl_array_attributes *array = &vao->VertexAttrib[attrib];
603   array->Stride = stride;
604   /* For updating the pointer we would need to add the vao->NewArrays flag
605    * to the VAO. But but that is done already unconditionally in
606    * _mesa_update_array_format called above.
607    */
608   assert((vao->NewArrays | ~vao->_Enabled) & VERT_BIT(attrib));
609   array->Ptr = ptr;
610
611   /* Update the vertex buffer binding */
612   GLsizei effectiveStride = stride != 0 ? stride : array->_ElementSize;
613   _mesa_bind_vertex_buffer(ctx, vao, attrib,
614                            ctx->Array.ArrayBufferObj, (GLintptr) ptr,
615                            effectiveStride);
616}
617
618void GLAPIENTRY
619_mesa_VertexPointer_no_error(GLint size, GLenum type, GLsizei stride,
620                             const GLvoid *ptr)
621{
622   GET_CURRENT_CONTEXT(ctx);
623
624   update_array(ctx, VERT_ATTRIB_POS, GL_RGBA, 4, size, type, stride,
625                GL_FALSE, GL_FALSE, GL_FALSE, ptr);
626}
627
628
629void GLAPIENTRY
630_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
631{
632   GET_CURRENT_CONTEXT(ctx);
633
634   GLenum format = GL_RGBA;
635   GLbitfield legalTypes = (ctx->API == API_OPENGLES)
636      ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
637      : (SHORT_BIT | INT_BIT | FLOAT_BIT |
638         DOUBLE_BIT | HALF_BIT |
639         UNSIGNED_INT_2_10_10_10_REV_BIT |
640         INT_2_10_10_10_REV_BIT);
641
642   if (!validate_array_and_format(ctx, "glVertexPointer", VERT_ATTRIB_POS,
643                                  legalTypes, 2, 4, size, type, stride,
644                                  GL_FALSE, GL_FALSE, GL_FALSE, format,
645                                  ptr, ctx->Array.VAO))
646      return;
647
648   update_array(ctx, VERT_ATTRIB_POS, format, 4, size, type, stride,
649                GL_FALSE, GL_FALSE, GL_FALSE, ptr);
650}
651
652
653void GLAPIENTRY
654_mesa_NormalPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr )
655{
656   GET_CURRENT_CONTEXT(ctx);
657
658   update_array(ctx, VERT_ATTRIB_NORMAL, GL_RGBA, 3, 3, type, stride, GL_TRUE,
659                GL_FALSE, GL_FALSE, ptr);
660}
661
662
663void GLAPIENTRY
664_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
665{
666   GET_CURRENT_CONTEXT(ctx);
667
668   GLenum format = GL_RGBA;
669   const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
670      ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
671      : (BYTE_BIT | SHORT_BIT | INT_BIT |
672         HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
673         UNSIGNED_INT_2_10_10_10_REV_BIT |
674         INT_2_10_10_10_REV_BIT);
675
676   if (!validate_array_and_format(ctx, "glNormalPointer",
677                                  VERT_ATTRIB_NORMAL, legalTypes, 3, 3, 3,
678                                  type, stride, GL_TRUE, GL_FALSE,
679                                  GL_FALSE, format, ptr, ctx->Array.VAO))
680      return;
681
682   update_array(ctx, VERT_ATTRIB_NORMAL, format, 3, 3, type, stride, GL_TRUE,
683                GL_FALSE, GL_FALSE, ptr);
684}
685
686
687void GLAPIENTRY
688_mesa_ColorPointer_no_error(GLint size, GLenum type, GLsizei stride,
689                            const GLvoid *ptr)
690{
691   GET_CURRENT_CONTEXT(ctx);
692
693   GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
694   update_array(ctx, VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size,
695                type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
696}
697
698
699void GLAPIENTRY
700_mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
701{
702   GET_CURRENT_CONTEXT(ctx);
703   const GLint sizeMin = (ctx->API == API_OPENGLES) ? 4 : 3;
704
705   GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
706   const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
707      ? (UNSIGNED_BYTE_BIT | HALF_BIT | FLOAT_BIT | FIXED_ES_BIT)
708      : (BYTE_BIT | UNSIGNED_BYTE_BIT |
709         SHORT_BIT | UNSIGNED_SHORT_BIT |
710         INT_BIT | UNSIGNED_INT_BIT |
711         HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
712         UNSIGNED_INT_2_10_10_10_REV_BIT |
713         INT_2_10_10_10_REV_BIT);
714
715   if (!validate_array_and_format(ctx, "glColorPointer",
716                                  VERT_ATTRIB_COLOR0, legalTypes, sizeMin,
717                                  BGRA_OR_4, size, type, stride, GL_TRUE,
718                                  GL_FALSE, GL_FALSE, format, ptr,
719                                  ctx->Array.VAO))
720      return;
721
722   update_array(ctx, VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size,
723                type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
724}
725
726
727void GLAPIENTRY
728_mesa_FogCoordPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr)
729{
730   GET_CURRENT_CONTEXT(ctx);
731
732   update_array(ctx, VERT_ATTRIB_FOG, GL_RGBA, 1, 1, type, stride, GL_FALSE,
733                GL_FALSE, GL_FALSE, ptr);
734}
735
736
737void GLAPIENTRY
738_mesa_FogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
739{
740   GET_CURRENT_CONTEXT(ctx);
741
742   GLenum format = GL_RGBA;
743   const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT);
744
745   if (!validate_array_and_format(ctx, "glFogCoordPointer",
746                                  VERT_ATTRIB_FOG, legalTypes, 1, 1, 1,
747                                  type, stride, GL_FALSE, GL_FALSE,
748                                  GL_FALSE, format, ptr, ctx->Array.VAO))
749      return;
750
751   update_array(ctx, VERT_ATTRIB_FOG, format, 1, 1, type, stride, GL_FALSE,
752                GL_FALSE, GL_FALSE, ptr);
753}
754
755
756void GLAPIENTRY
757_mesa_IndexPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr)
758{
759   GET_CURRENT_CONTEXT(ctx);
760
761   update_array(ctx, VERT_ATTRIB_COLOR_INDEX, GL_RGBA, 1, 1, type, stride,
762                GL_FALSE, GL_FALSE, GL_FALSE, ptr);
763}
764
765
766void GLAPIENTRY
767_mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
768{
769   GET_CURRENT_CONTEXT(ctx);
770
771   GLenum format = GL_RGBA;
772   const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT |
773                                     FLOAT_BIT | DOUBLE_BIT);
774
775   if (!validate_array_and_format(ctx, "glIndexPointer",
776                                  VERT_ATTRIB_COLOR_INDEX,
777                                  legalTypes, 1, 1, 1, type, stride,
778                                  GL_FALSE, GL_FALSE, GL_FALSE, format,
779                                  ptr, ctx->Array.VAO))
780      return;
781
782   update_array(ctx, VERT_ATTRIB_COLOR_INDEX, format, 1, 1, type, stride,
783                GL_FALSE, GL_FALSE, GL_FALSE, ptr);
784}
785
786
787void GLAPIENTRY
788_mesa_SecondaryColorPointer_no_error(GLint size, GLenum type,
789                                     GLsizei stride, const GLvoid *ptr)
790{
791   GET_CURRENT_CONTEXT(ctx);
792
793   GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
794   update_array(ctx, VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type,
795                stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
796}
797
798
799void GLAPIENTRY
800_mesa_SecondaryColorPointer(GLint size, GLenum type,
801			       GLsizei stride, const GLvoid *ptr)
802{
803   GET_CURRENT_CONTEXT(ctx);
804
805   GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
806   const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
807                                  SHORT_BIT | UNSIGNED_SHORT_BIT |
808                                  INT_BIT | UNSIGNED_INT_BIT |
809                                  HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
810                                  UNSIGNED_INT_2_10_10_10_REV_BIT |
811                                  INT_2_10_10_10_REV_BIT);
812
813   if (!validate_array_and_format(ctx, "glSecondaryColorPointer",
814                                  VERT_ATTRIB_COLOR1, legalTypes, 3,
815                                  BGRA_OR_4, size, type, stride,
816                                  GL_TRUE, GL_FALSE, GL_FALSE, format, ptr,
817                                  ctx->Array.VAO))
818      return;
819
820   update_array(ctx, VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type,
821                stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
822}
823
824
825void GLAPIENTRY
826_mesa_TexCoordPointer_no_error(GLint size, GLenum type, GLsizei stride,
827                               const GLvoid *ptr)
828{
829   GET_CURRENT_CONTEXT(ctx);
830   const GLuint unit = ctx->Array.ActiveTexture;
831
832   update_array(ctx, VERT_ATTRIB_TEX(unit), GL_RGBA, 4, size, type,
833                stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr);
834}
835
836
837void GLAPIENTRY
838_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
839                      const GLvoid *ptr)
840{
841   GET_CURRENT_CONTEXT(ctx);
842   const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1;
843   const GLuint unit = ctx->Array.ActiveTexture;
844
845   GLenum format = GL_RGBA;
846   const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
847      ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
848      : (SHORT_BIT | INT_BIT |
849         HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
850         UNSIGNED_INT_2_10_10_10_REV_BIT |
851         INT_2_10_10_10_REV_BIT);
852
853   if (!validate_array_and_format(ctx, "glTexCoordPointer",
854                                  VERT_ATTRIB_TEX(unit), legalTypes,
855                                  sizeMin, 4, size, type, stride,
856                                  GL_FALSE, GL_FALSE, GL_FALSE, format, ptr,
857                                  ctx->Array.VAO))
858      return;
859
860   update_array(ctx, VERT_ATTRIB_TEX(unit), format, 4, size, type,
861                stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr);
862}
863
864
865void GLAPIENTRY
866_mesa_EdgeFlagPointer_no_error(GLsizei stride, const GLvoid *ptr)
867{
868   /* this is the same type that glEdgeFlag uses */
869   const GLboolean integer = GL_FALSE;
870   GET_CURRENT_CONTEXT(ctx);
871
872   update_array(ctx, VERT_ATTRIB_EDGEFLAG, GL_RGBA, 1, 1, GL_UNSIGNED_BYTE,
873                stride, GL_FALSE, integer, GL_FALSE, ptr);
874}
875
876
877void GLAPIENTRY
878_mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
879{
880   /* this is the same type that glEdgeFlag uses */
881   const GLboolean integer = GL_FALSE;
882   GET_CURRENT_CONTEXT(ctx);
883
884   GLenum format = GL_RGBA;
885   const GLbitfield legalTypes = UNSIGNED_BYTE_BIT;
886
887   if (!validate_array_and_format(ctx, "glEdgeFlagPointer",
888                                  VERT_ATTRIB_EDGEFLAG, legalTypes,
889                                  1, 1, 1, GL_UNSIGNED_BYTE, stride,
890                                  GL_FALSE, integer, GL_FALSE, format, ptr,
891                                  ctx->Array.VAO))
892      return;
893
894   update_array(ctx, VERT_ATTRIB_EDGEFLAG, format, 1, 1, GL_UNSIGNED_BYTE,
895                stride, GL_FALSE, integer, GL_FALSE, ptr);
896}
897
898
899void GLAPIENTRY
900_mesa_PointSizePointerOES_no_error(GLenum type, GLsizei stride,
901                                   const GLvoid *ptr)
902{
903   GET_CURRENT_CONTEXT(ctx);
904
905   update_array(ctx, VERT_ATTRIB_POINT_SIZE, GL_RGBA, 1, 1, type, stride,
906                GL_FALSE, GL_FALSE, GL_FALSE, ptr);
907}
908
909
910void GLAPIENTRY
911_mesa_PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *ptr)
912{
913   GET_CURRENT_CONTEXT(ctx);
914
915   GLenum format = GL_RGBA;
916   if (ctx->API != API_OPENGLES) {
917      _mesa_error(ctx, GL_INVALID_OPERATION,
918                  "glPointSizePointer(ES 1.x only)");
919      return;
920   }
921
922   const GLbitfield legalTypes = (FLOAT_BIT | FIXED_ES_BIT);
923
924   if (!validate_array_and_format(ctx, "glPointSizePointer",
925                                  VERT_ATTRIB_POINT_SIZE, legalTypes,
926                                  1, 1, 1, type, stride, GL_FALSE, GL_FALSE,
927                                  GL_FALSE, format, ptr, ctx->Array.VAO))
928      return;
929
930   update_array(ctx, VERT_ATTRIB_POINT_SIZE, format, 1, 1, type, stride,
931                GL_FALSE, GL_FALSE, GL_FALSE, ptr);
932}
933
934
935void GLAPIENTRY
936_mesa_VertexAttribPointer_no_error(GLuint index, GLint size, GLenum type,
937                                   GLboolean normalized,
938                                   GLsizei stride, const GLvoid *ptr)
939{
940   GET_CURRENT_CONTEXT(ctx);
941
942   GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
943   update_array(ctx, VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4,
944                size, type, stride, normalized, GL_FALSE, GL_FALSE, ptr);
945}
946
947
948/**
949 * Set a generic vertex attribute array.
950 * Note that these arrays DO NOT alias the conventional GL vertex arrays
951 * (position, normal, color, fog, texcoord, etc).
952 */
953void GLAPIENTRY
954_mesa_VertexAttribPointer(GLuint index, GLint size, GLenum type,
955                             GLboolean normalized,
956                             GLsizei stride, const GLvoid *ptr)
957{
958   GET_CURRENT_CONTEXT(ctx);
959
960   GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
961   if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
962      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(idx)");
963      return;
964   }
965
966   const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
967                                  SHORT_BIT | UNSIGNED_SHORT_BIT |
968                                  INT_BIT | UNSIGNED_INT_BIT |
969                                  HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
970                                  FIXED_ES_BIT | FIXED_GL_BIT |
971                                  UNSIGNED_INT_2_10_10_10_REV_BIT |
972                                  INT_2_10_10_10_REV_BIT |
973                                  UNSIGNED_INT_10F_11F_11F_REV_BIT);
974
975   if (!validate_array_and_format(ctx, "glVertexAttribPointer",
976                                  VERT_ATTRIB_GENERIC(index), legalTypes,
977                                  1, BGRA_OR_4, size, type, stride,
978                                  normalized, GL_FALSE, GL_FALSE, format,
979                                  ptr, ctx->Array.VAO))
980      return;
981
982   update_array(ctx, VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4,
983                size, type, stride, normalized, GL_FALSE, GL_FALSE, ptr);
984}
985
986
987void GLAPIENTRY
988_mesa_VertexAttribIPointer_no_error(GLuint index, GLint size, GLenum type,
989                                    GLsizei stride, const GLvoid *ptr)
990{
991   const GLboolean normalized = GL_FALSE;
992   const GLboolean integer = GL_TRUE;
993   GET_CURRENT_CONTEXT(ctx);
994
995   update_array(ctx, VERT_ATTRIB_GENERIC(index), GL_RGBA, 4,  size, type,
996                stride, normalized, integer, GL_FALSE, ptr);
997}
998
999
1000/**
1001 * GL_EXT_gpu_shader4 / GL 3.0.
1002 * Set an integer-valued vertex attribute array.
1003 * Note that these arrays DO NOT alias the conventional GL vertex arrays
1004 * (position, normal, color, fog, texcoord, etc).
1005 */
1006void GLAPIENTRY
1007_mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type,
1008                           GLsizei stride, const GLvoid *ptr)
1009{
1010   const GLboolean normalized = GL_FALSE;
1011   const GLboolean integer = GL_TRUE;
1012   GET_CURRENT_CONTEXT(ctx);
1013
1014   GLenum format = GL_RGBA;
1015   if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1016      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIPointer(index)");
1017      return;
1018   }
1019
1020   const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
1021                                  SHORT_BIT | UNSIGNED_SHORT_BIT |
1022                                  INT_BIT | UNSIGNED_INT_BIT);
1023
1024   if (!validate_array_and_format(ctx, "glVertexAttribIPointer",
1025                                  VERT_ATTRIB_GENERIC(index), legalTypes,
1026                                  1, 4, size, type, stride,
1027                                  normalized, integer, GL_FALSE, format,
1028                                  ptr, ctx->Array.VAO))
1029      return;
1030
1031   update_array(ctx, VERT_ATTRIB_GENERIC(index), format, 4,  size, type,
1032                stride, normalized, integer, GL_FALSE, ptr);
1033}
1034
1035
1036void GLAPIENTRY
1037_mesa_VertexAttribLPointer_no_error(GLuint index, GLint size, GLenum type,
1038                                    GLsizei stride, const GLvoid *ptr)
1039{
1040   GET_CURRENT_CONTEXT(ctx);
1041
1042   update_array(ctx, VERT_ATTRIB_GENERIC(index), GL_RGBA, 4, size, type,
1043                stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr);
1044}
1045
1046
1047void GLAPIENTRY
1048_mesa_VertexAttribLPointer(GLuint index, GLint size, GLenum type,
1049                           GLsizei stride, const GLvoid *ptr)
1050{
1051   GET_CURRENT_CONTEXT(ctx);
1052
1053   GLenum format = GL_RGBA;
1054   if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1055      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribLPointer(index)");
1056      return;
1057   }
1058
1059   const GLbitfield legalTypes = DOUBLE_BIT;
1060
1061   if (!validate_array_and_format(ctx, "glVertexAttribLPointer",
1062                                  VERT_ATTRIB_GENERIC(index), legalTypes,
1063                                  1, 4, size, type, stride,
1064                                  GL_FALSE, GL_FALSE, GL_TRUE, format,
1065                                  ptr, ctx->Array.VAO))
1066      return;
1067
1068   update_array(ctx, VERT_ATTRIB_GENERIC(index), format, 4, size, type,
1069                stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr);
1070}
1071
1072
1073void
1074_mesa_enable_vertex_array_attrib(struct gl_context *ctx,
1075                                 struct gl_vertex_array_object *vao,
1076                                 gl_vert_attrib attrib)
1077{
1078   assert(attrib < ARRAY_SIZE(vao->VertexAttrib));
1079   assert(!vao->SharedAndImmutable);
1080
1081   if (!vao->VertexAttrib[attrib].Enabled) {
1082      /* was disabled, now being enabled */
1083      vao->VertexAttrib[attrib].Enabled = GL_TRUE;
1084      const GLbitfield array_bit = VERT_BIT(attrib);
1085      vao->_Enabled |= array_bit;
1086      vao->NewArrays |= array_bit;
1087
1088      if (vao == ctx->Array.VAO)
1089         ctx->NewState |= _NEW_ARRAY;
1090
1091      /* Update the map mode if needed */
1092      if (array_bit & (VERT_BIT_POS|VERT_BIT_GENERIC0))
1093         update_attribute_map_mode(ctx, vao);
1094   }
1095}
1096
1097static void
1098enable_vertex_array_attrib(struct gl_context *ctx,
1099                           struct gl_vertex_array_object *vao,
1100                           GLuint index,
1101                           const char *func)
1102{
1103   if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1104      _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
1105      return;
1106   }
1107
1108   _mesa_enable_vertex_array_attrib(ctx, vao, VERT_ATTRIB_GENERIC(index));
1109}
1110
1111
1112void GLAPIENTRY
1113_mesa_EnableVertexAttribArray(GLuint index)
1114{
1115   GET_CURRENT_CONTEXT(ctx);
1116   enable_vertex_array_attrib(ctx, ctx->Array.VAO, index,
1117                              "glEnableVertexAttribArray");
1118}
1119
1120
1121void GLAPIENTRY
1122_mesa_EnableVertexAttribArray_no_error(GLuint index)
1123{
1124   GET_CURRENT_CONTEXT(ctx);
1125   _mesa_enable_vertex_array_attrib(ctx, ctx->Array.VAO,
1126                                    VERT_ATTRIB_GENERIC(index));
1127}
1128
1129
1130void GLAPIENTRY
1131_mesa_EnableVertexArrayAttrib(GLuint vaobj, GLuint index)
1132{
1133   GET_CURRENT_CONTEXT(ctx);
1134   struct gl_vertex_array_object *vao;
1135
1136   /* The ARB_direct_state_access specification says:
1137    *
1138    *   "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib
1139    *    and DisableVertexArrayAttrib if <vaobj> is not
1140    *    [compatibility profile: zero or] the name of an existing vertex
1141    *    array object."
1142    */
1143   vao = _mesa_lookup_vao_err(ctx, vaobj, "glEnableVertexArrayAttrib");
1144   if (!vao)
1145      return;
1146
1147   enable_vertex_array_attrib(ctx, vao, index, "glEnableVertexArrayAttrib");
1148}
1149
1150
1151void GLAPIENTRY
1152_mesa_EnableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index)
1153{
1154   GET_CURRENT_CONTEXT(ctx);
1155   struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
1156   _mesa_enable_vertex_array_attrib(ctx, vao, VERT_ATTRIB_GENERIC(index));
1157}
1158
1159
1160void
1161_mesa_disable_vertex_array_attrib(struct gl_context *ctx,
1162                                  struct gl_vertex_array_object *vao,
1163                                  gl_vert_attrib attrib)
1164{
1165   assert(attrib < ARRAY_SIZE(vao->VertexAttrib));
1166   assert(!vao->SharedAndImmutable);
1167
1168   if (vao->VertexAttrib[attrib].Enabled) {
1169      /* was enabled, now being disabled */
1170      vao->VertexAttrib[attrib].Enabled = GL_FALSE;
1171      const GLbitfield array_bit = VERT_BIT(attrib);
1172      vao->_Enabled &= ~array_bit;
1173      vao->NewArrays |= array_bit;
1174
1175      if (vao == ctx->Array.VAO)
1176         ctx->NewState |= _NEW_ARRAY;
1177
1178      /* Update the map mode if needed */
1179      if (array_bit & (VERT_BIT_POS|VERT_BIT_GENERIC0))
1180         update_attribute_map_mode(ctx, vao);
1181   }
1182}
1183
1184
1185void GLAPIENTRY
1186_mesa_DisableVertexAttribArray(GLuint index)
1187{
1188   GET_CURRENT_CONTEXT(ctx);
1189
1190   if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1191      _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexAttribArray(index)");
1192      return;
1193   }
1194
1195   const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1196   _mesa_disable_vertex_array_attrib(ctx, ctx->Array.VAO, attrib);
1197}
1198
1199
1200void GLAPIENTRY
1201_mesa_DisableVertexAttribArray_no_error(GLuint index)
1202{
1203   GET_CURRENT_CONTEXT(ctx);
1204   const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1205   _mesa_disable_vertex_array_attrib(ctx, ctx->Array.VAO, attrib);
1206}
1207
1208
1209void GLAPIENTRY
1210_mesa_DisableVertexArrayAttrib(GLuint vaobj, GLuint index)
1211{
1212   GET_CURRENT_CONTEXT(ctx);
1213   struct gl_vertex_array_object *vao;
1214
1215   /* The ARB_direct_state_access specification says:
1216    *
1217    *   "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib
1218    *    and DisableVertexArrayAttrib if <vaobj> is not
1219    *    [compatibility profile: zero or] the name of an existing vertex
1220    *    array object."
1221    */
1222   vao = _mesa_lookup_vao_err(ctx, vaobj, "glDisableVertexArrayAttrib");
1223   if (!vao)
1224      return;
1225
1226   if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1227      _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexArrayAttrib(index)");
1228      return;
1229   }
1230
1231   const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1232   _mesa_disable_vertex_array_attrib(ctx, vao, attrib);
1233}
1234
1235
1236void GLAPIENTRY
1237_mesa_DisableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index)
1238{
1239   GET_CURRENT_CONTEXT(ctx);
1240   struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
1241   const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1242   _mesa_disable_vertex_array_attrib(ctx, vao, attrib);
1243}
1244
1245
1246/**
1247 * Return info for a vertex attribute array (no alias with legacy
1248 * vertex attributes (pos, normal, color, etc)).  This function does
1249 * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query.
1250 */
1251static GLuint
1252get_vertex_array_attrib(struct gl_context *ctx,
1253                        const struct gl_vertex_array_object *vao,
1254                        GLuint index, GLenum pname,
1255                        const char *caller)
1256{
1257   const struct gl_array_attributes *array;
1258
1259   if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1260      _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index);
1261      return 0;
1262   }
1263
1264   assert(VERT_ATTRIB_GENERIC(index) < ARRAY_SIZE(vao->VertexAttrib));
1265
1266   array = &vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)];
1267
1268   switch (pname) {
1269   case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
1270      return array->Enabled;
1271   case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
1272      return (array->Format == GL_BGRA) ? GL_BGRA : array->Size;
1273   case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
1274      return array->Stride;
1275   case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
1276      return array->Type;
1277   case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
1278      return array->Normalized;
1279   case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
1280      return vao->BufferBinding[array->BufferBindingIndex].BufferObj->Name;
1281   case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
1282      if ((_mesa_is_desktop_gl(ctx)
1283           && (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))
1284          || _mesa_is_gles3(ctx)) {
1285         return array->Integer;
1286      }
1287      goto error;
1288   case GL_VERTEX_ATTRIB_ARRAY_LONG:
1289      if (_mesa_is_desktop_gl(ctx)) {
1290         return array->Doubles;
1291      }
1292      goto error;
1293   case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB:
1294      if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_instanced_arrays)
1295          || _mesa_is_gles3(ctx)) {
1296         return vao->BufferBinding[array->BufferBindingIndex].InstanceDivisor;
1297      }
1298      goto error;
1299   case GL_VERTEX_ATTRIB_BINDING:
1300      if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
1301         return array->BufferBindingIndex - VERT_ATTRIB_GENERIC0;
1302      }
1303      goto error;
1304   case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
1305      if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
1306         return array->RelativeOffset;
1307      }
1308      goto error;
1309   default:
1310      ; /* fall-through */
1311   }
1312
1313error:
1314   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname);
1315   return 0;
1316}
1317
1318
1319static const GLfloat *
1320get_current_attrib(struct gl_context *ctx, GLuint index, const char *function)
1321{
1322   if (index == 0) {
1323      if (_mesa_attr_zero_aliases_vertex(ctx)) {
1324	 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function);
1325	 return NULL;
1326      }
1327   }
1328   else if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1329      _mesa_error(ctx, GL_INVALID_VALUE,
1330		  "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function);
1331      return NULL;
1332   }
1333
1334   assert(VERT_ATTRIB_GENERIC(index) <
1335          ARRAY_SIZE(ctx->Array.VAO->VertexAttrib));
1336
1337   FLUSH_CURRENT(ctx, 0);
1338   return ctx->Current.Attrib[VERT_ATTRIB_GENERIC(index)];
1339}
1340
1341void GLAPIENTRY
1342_mesa_GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
1343{
1344   GET_CURRENT_CONTEXT(ctx);
1345
1346   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1347      const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv");
1348      if (v != NULL) {
1349         COPY_4V(params, v);
1350      }
1351   }
1352   else {
1353      params[0] = (GLfloat) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1354                                                    index, pname,
1355                                                    "glGetVertexAttribfv");
1356   }
1357}
1358
1359
1360void GLAPIENTRY
1361_mesa_GetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params)
1362{
1363   GET_CURRENT_CONTEXT(ctx);
1364
1365   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1366      const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv");
1367      if (v != NULL) {
1368         params[0] = (GLdouble) v[0];
1369         params[1] = (GLdouble) v[1];
1370         params[2] = (GLdouble) v[2];
1371         params[3] = (GLdouble) v[3];
1372      }
1373   }
1374   else {
1375      params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1376                                                     index, pname,
1377                                                     "glGetVertexAttribdv");
1378   }
1379}
1380
1381void GLAPIENTRY
1382_mesa_GetVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params)
1383{
1384   GET_CURRENT_CONTEXT(ctx);
1385
1386   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1387      const GLdouble *v =
1388         (const GLdouble *)get_current_attrib(ctx, index,
1389                                              "glGetVertexAttribLdv");
1390      if (v != NULL) {
1391         params[0] = v[0];
1392         params[1] = v[1];
1393         params[2] = v[2];
1394         params[3] = v[3];
1395      }
1396   }
1397   else {
1398      params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1399                                                     index, pname,
1400                                                     "glGetVertexAttribLdv");
1401   }
1402}
1403
1404void GLAPIENTRY
1405_mesa_GetVertexAttribiv(GLuint index, GLenum pname, GLint *params)
1406{
1407   GET_CURRENT_CONTEXT(ctx);
1408
1409   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1410      const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv");
1411      if (v != NULL) {
1412         /* XXX should floats in[0,1] be scaled to full int range? */
1413         params[0] = (GLint) v[0];
1414         params[1] = (GLint) v[1];
1415         params[2] = (GLint) v[2];
1416         params[3] = (GLint) v[3];
1417      }
1418   }
1419   else {
1420      params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1421                                                  index, pname,
1422                                                  "glGetVertexAttribiv");
1423   }
1424}
1425
1426void GLAPIENTRY
1427_mesa_GetVertexAttribLui64vARB(GLuint index, GLenum pname, GLuint64EXT *params)
1428{
1429   GET_CURRENT_CONTEXT(ctx);
1430
1431   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1432      const GLuint64 *v =
1433         (const GLuint64 *)get_current_attrib(ctx, index,
1434                                              "glGetVertexAttribLui64vARB");
1435      if (v != NULL) {
1436         params[0] = v[0];
1437         params[1] = v[1];
1438         params[2] = v[2];
1439         params[3] = v[3];
1440      }
1441   }
1442   else {
1443      params[0] = (GLuint64) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1444                                                     index, pname,
1445                                                     "glGetVertexAttribLui64vARB");
1446   }
1447}
1448
1449
1450/** GL 3.0 */
1451void GLAPIENTRY
1452_mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
1453{
1454   GET_CURRENT_CONTEXT(ctx);
1455
1456   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1457      const GLint *v = (const GLint *)
1458	 get_current_attrib(ctx, index, "glGetVertexAttribIiv");
1459      if (v != NULL) {
1460         COPY_4V(params, v);
1461      }
1462   }
1463   else {
1464      params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1465                                                  index, pname,
1466                                                  "glGetVertexAttribIiv");
1467   }
1468}
1469
1470
1471/** GL 3.0 */
1472void GLAPIENTRY
1473_mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
1474{
1475   GET_CURRENT_CONTEXT(ctx);
1476
1477   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1478      const GLuint *v = (const GLuint *)
1479	 get_current_attrib(ctx, index, "glGetVertexAttribIuiv");
1480      if (v != NULL) {
1481         COPY_4V(params, v);
1482      }
1483   }
1484   else {
1485      params[0] = get_vertex_array_attrib(ctx, ctx->Array.VAO,
1486                                          index, pname,
1487                                          "glGetVertexAttribIuiv");
1488   }
1489}
1490
1491
1492void GLAPIENTRY
1493_mesa_GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
1494{
1495   GET_CURRENT_CONTEXT(ctx);
1496
1497   if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1498      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
1499      return;
1500   }
1501
1502   if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
1503      _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
1504      return;
1505   }
1506
1507   assert(VERT_ATTRIB_GENERIC(index) <
1508          ARRAY_SIZE(ctx->Array.VAO->VertexAttrib));
1509
1510   *pointer = (GLvoid *)
1511      ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr;
1512}
1513
1514
1515/** ARB_direct_state_access */
1516void GLAPIENTRY
1517_mesa_GetVertexArrayIndexediv(GLuint vaobj, GLuint index,
1518                              GLenum pname, GLint *params)
1519{
1520   GET_CURRENT_CONTEXT(ctx);
1521   struct gl_vertex_array_object *vao;
1522
1523   /* The ARB_direct_state_access specification says:
1524    *
1525    *    "An INVALID_OPERATION error is generated if <vaobj> is not
1526    *     [compatibility profile: zero or] the name of an existing
1527    *     vertex array object."
1528    */
1529   vao = _mesa_lookup_vao_err(ctx, vaobj, "glGetVertexArrayIndexediv");
1530   if (!vao)
1531      return;
1532
1533   /* The ARB_direct_state_access specification says:
1534    *
1535    *    "For GetVertexArrayIndexediv, <pname> must be one of
1536    *     VERTEX_ATTRIB_ARRAY_ENABLED, VERTEX_ATTRIB_ARRAY_SIZE,
1537    *     VERTEX_ATTRIB_ARRAY_STRIDE, VERTEX_ATTRIB_ARRAY_TYPE,
1538    *     VERTEX_ATTRIB_ARRAY_NORMALIZED, VERTEX_ATTRIB_ARRAY_INTEGER,
1539    *     VERTEX_ATTRIB_ARRAY_LONG, VERTEX_ATTRIB_ARRAY_DIVISOR, or
1540    *     VERTEX_ATTRIB_RELATIVE_OFFSET."
1541    *
1542    * and:
1543    *
1544    *    "Add GetVertexArrayIndexediv in 'Get Command' for
1545    *     VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
1546    *     VERTEX_ATTRIB_BINDING,
1547    *     VERTEX_ATTRIB_RELATIVE_OFFSET,
1548    *     VERTEX_BINDING_OFFSET, and
1549    *     VERTEX_BINDING_STRIDE states"
1550    *
1551    * The only parameter name common to both lists is
1552    * VERTEX_ATTRIB_RELATIVE_OFFSET.  Also note that VERTEX_BINDING_BUFFER
1553    * and VERTEX_BINDING_DIVISOR are missing from both lists.  It seems
1554    * pretty clear however that the intent is that it should be possible
1555    * to query all vertex attrib and binding states that can be set with
1556    * a DSA function.
1557    */
1558   switch (pname) {
1559   case GL_VERTEX_BINDING_OFFSET:
1560      params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Offset;
1561      break;
1562   case GL_VERTEX_BINDING_STRIDE:
1563      params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Stride;
1564      break;
1565   case GL_VERTEX_BINDING_DIVISOR:
1566      params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].InstanceDivisor;
1567      break;
1568   case GL_VERTEX_BINDING_BUFFER:
1569      params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].BufferObj->Name;
1570      break;
1571   default:
1572      params[0] = get_vertex_array_attrib(ctx, vao, index, pname,
1573                                          "glGetVertexArrayIndexediv");
1574      break;
1575   }
1576}
1577
1578
1579void GLAPIENTRY
1580_mesa_GetVertexArrayIndexed64iv(GLuint vaobj, GLuint index,
1581                                GLenum pname, GLint64 *params)
1582{
1583   GET_CURRENT_CONTEXT(ctx);
1584   struct gl_vertex_array_object *vao;
1585
1586   /* The ARB_direct_state_access specification says:
1587    *
1588    *    "An INVALID_OPERATION error is generated if <vaobj> is not
1589    *     [compatibility profile: zero or] the name of an existing
1590    *     vertex array object."
1591    */
1592   vao = _mesa_lookup_vao_err(ctx, vaobj, "glGetVertexArrayIndexed64iv");
1593   if (!vao)
1594      return;
1595
1596   /* The ARB_direct_state_access specification says:
1597    *
1598    *    "For GetVertexArrayIndexed64iv, <pname> must be
1599    *     VERTEX_BINDING_OFFSET."
1600    *
1601    * and:
1602    *
1603    *    "An INVALID_ENUM error is generated if <pname> is not one of
1604    *     the valid values listed above for the corresponding command."
1605    */
1606   if (pname != GL_VERTEX_BINDING_OFFSET) {
1607      _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayIndexed64iv("
1608                  "pname != GL_VERTEX_BINDING_OFFSET)");
1609      return;
1610   }
1611
1612   /* The ARB_direct_state_access specification says:
1613    *
1614    *    "An INVALID_VALUE error is generated if <index> is greater than
1615    *     or equal to the value of MAX_VERTEX_ATTRIBS."
1616    *
1617    * Since the index refers to a buffer binding in this case, the intended
1618    * limit must be MAX_VERTEX_ATTRIB_BINDINGS.  Both limits are currently
1619    * required to be the same, so in practice this doesn't matter.
1620    */
1621   if (index >= ctx->Const.MaxVertexAttribBindings) {
1622      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexArrayIndexed64iv(index"
1623                  "%d >= the value of GL_MAX_VERTEX_ATTRIB_BINDINGS (%d))",
1624                  index, ctx->Const.MaxVertexAttribBindings);
1625      return;
1626   }
1627
1628   params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Offset;
1629}
1630
1631
1632void GLAPIENTRY
1633_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
1634                       GLsizei count, const GLvoid *ptr)
1635{
1636   (void) count;
1637   _mesa_VertexPointer(size, type, stride, ptr);
1638}
1639
1640
1641void GLAPIENTRY
1642_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
1643                       const GLvoid *ptr)
1644{
1645   (void) count;
1646   _mesa_NormalPointer(type, stride, ptr);
1647}
1648
1649
1650void GLAPIENTRY
1651_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
1652                      const GLvoid *ptr)
1653{
1654   (void) count;
1655   _mesa_ColorPointer(size, type, stride, ptr);
1656}
1657
1658
1659void GLAPIENTRY
1660_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
1661                      const GLvoid *ptr)
1662{
1663   (void) count;
1664   _mesa_IndexPointer(type, stride, ptr);
1665}
1666
1667
1668void GLAPIENTRY
1669_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
1670                         GLsizei count, const GLvoid *ptr)
1671{
1672   (void) count;
1673   _mesa_TexCoordPointer(size, type, stride, ptr);
1674}
1675
1676
1677void GLAPIENTRY
1678_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
1679{
1680   (void) count;
1681   _mesa_EdgeFlagPointer(stride, ptr);
1682}
1683
1684
1685void GLAPIENTRY
1686_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
1687{
1688   GET_CURRENT_CONTEXT(ctx);
1689   GLboolean tflag, cflag, nflag;  /* enable/disable flags */
1690   GLint tcomps, ccomps, vcomps;   /* components per texcoord, color, vertex */
1691   GLenum ctype = 0;               /* color type */
1692   GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
1693   const GLint toffset = 0;        /* always zero */
1694   GLint defstride;                /* default stride */
1695   GLint c, f;
1696
1697   f = sizeof(GLfloat);
1698   c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
1699
1700   if (stride < 0) {
1701      _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
1702      return;
1703   }
1704
1705   switch (format) {
1706      case GL_V2F:
1707         tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
1708         tcomps = 0;  ccomps = 0;  vcomps = 2;
1709         voffset = 0;
1710         defstride = 2*f;
1711         break;
1712      case GL_V3F:
1713         tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
1714         tcomps = 0;  ccomps = 0;  vcomps = 3;
1715         voffset = 0;
1716         defstride = 3*f;
1717         break;
1718      case GL_C4UB_V2F:
1719         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
1720         tcomps = 0;  ccomps = 4;  vcomps = 2;
1721         ctype = GL_UNSIGNED_BYTE;
1722         coffset = 0;
1723         voffset = c;
1724         defstride = c + 2*f;
1725         break;
1726      case GL_C4UB_V3F:
1727         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
1728         tcomps = 0;  ccomps = 4;  vcomps = 3;
1729         ctype = GL_UNSIGNED_BYTE;
1730         coffset = 0;
1731         voffset = c;
1732         defstride = c + 3*f;
1733         break;
1734      case GL_C3F_V3F:
1735         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
1736         tcomps = 0;  ccomps = 3;  vcomps = 3;
1737         ctype = GL_FLOAT;
1738         coffset = 0;
1739         voffset = 3*f;
1740         defstride = 6*f;
1741         break;
1742      case GL_N3F_V3F:
1743         tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_TRUE;
1744         tcomps = 0;  ccomps = 0;  vcomps = 3;
1745         noffset = 0;
1746         voffset = 3*f;
1747         defstride = 6*f;
1748         break;
1749      case GL_C4F_N3F_V3F:
1750         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_TRUE;
1751         tcomps = 0;  ccomps = 4;  vcomps = 3;
1752         ctype = GL_FLOAT;
1753         coffset = 0;
1754         noffset = 4*f;
1755         voffset = 7*f;
1756         defstride = 10*f;
1757         break;
1758      case GL_T2F_V3F:
1759         tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
1760         tcomps = 2;  ccomps = 0;  vcomps = 3;
1761         voffset = 2*f;
1762         defstride = 5*f;
1763         break;
1764      case GL_T4F_V4F:
1765         tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
1766         tcomps = 4;  ccomps = 0;  vcomps = 4;
1767         voffset = 4*f;
1768         defstride = 8*f;
1769         break;
1770      case GL_T2F_C4UB_V3F:
1771         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
1772         tcomps = 2;  ccomps = 4;  vcomps = 3;
1773         ctype = GL_UNSIGNED_BYTE;
1774         coffset = 2*f;
1775         voffset = c+2*f;
1776         defstride = c+5*f;
1777         break;
1778      case GL_T2F_C3F_V3F:
1779         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
1780         tcomps = 2;  ccomps = 3;  vcomps = 3;
1781         ctype = GL_FLOAT;
1782         coffset = 2*f;
1783         voffset = 5*f;
1784         defstride = 8*f;
1785         break;
1786      case GL_T2F_N3F_V3F:
1787         tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_TRUE;
1788         tcomps = 2;  ccomps = 0;  vcomps = 3;
1789         noffset = 2*f;
1790         voffset = 5*f;
1791         defstride = 8*f;
1792         break;
1793      case GL_T2F_C4F_N3F_V3F:
1794         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
1795         tcomps = 2;  ccomps = 4;  vcomps = 3;
1796         ctype = GL_FLOAT;
1797         coffset = 2*f;
1798         noffset = 6*f;
1799         voffset = 9*f;
1800         defstride = 12*f;
1801         break;
1802      case GL_T4F_C4F_N3F_V4F:
1803         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
1804         tcomps = 4;  ccomps = 4;  vcomps = 4;
1805         ctype = GL_FLOAT;
1806         coffset = 4*f;
1807         noffset = 8*f;
1808         voffset = 11*f;
1809         defstride = 15*f;
1810         break;
1811      default:
1812         _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
1813         return;
1814   }
1815
1816   if (stride==0) {
1817      stride = defstride;
1818   }
1819
1820   _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
1821   _mesa_DisableClientState( GL_INDEX_ARRAY );
1822   /* XXX also disable secondary color and generic arrays? */
1823
1824   /* Texcoords */
1825   if (tflag) {
1826      _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
1827      _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
1828                             (GLubyte *) pointer + toffset );
1829   }
1830   else {
1831      _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
1832   }
1833
1834   /* Color */
1835   if (cflag) {
1836      _mesa_EnableClientState( GL_COLOR_ARRAY );
1837      _mesa_ColorPointer( ccomps, ctype, stride,
1838			  (GLubyte *) pointer + coffset );
1839   }
1840   else {
1841      _mesa_DisableClientState( GL_COLOR_ARRAY );
1842   }
1843
1844
1845   /* Normals */
1846   if (nflag) {
1847      _mesa_EnableClientState( GL_NORMAL_ARRAY );
1848      _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset );
1849   }
1850   else {
1851      _mesa_DisableClientState( GL_NORMAL_ARRAY );
1852   }
1853
1854   /* Vertices */
1855   _mesa_EnableClientState( GL_VERTEX_ARRAY );
1856   _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
1857			(GLubyte *) pointer + voffset );
1858}
1859
1860
1861void GLAPIENTRY
1862_mesa_LockArraysEXT(GLint first, GLsizei count)
1863{
1864   GET_CURRENT_CONTEXT(ctx);
1865
1866   if (MESA_VERBOSE & VERBOSE_API)
1867      _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
1868
1869   if (first < 0) {
1870      _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" );
1871      return;
1872   }
1873   if (count <= 0) {
1874      _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" );
1875      return;
1876   }
1877   if (ctx->Array.LockCount != 0) {
1878      _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" );
1879      return;
1880   }
1881
1882   ctx->Array.LockFirst = first;
1883   ctx->Array.LockCount = count;
1884
1885   ctx->NewState |= _NEW_ARRAY;
1886}
1887
1888
1889void GLAPIENTRY
1890_mesa_UnlockArraysEXT( void )
1891{
1892   GET_CURRENT_CONTEXT(ctx);
1893
1894   if (MESA_VERBOSE & VERBOSE_API)
1895      _mesa_debug(ctx, "glUnlockArrays\n");
1896
1897   if (ctx->Array.LockCount == 0) {
1898      _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" );
1899      return;
1900   }
1901
1902   ctx->Array.LockFirst = 0;
1903   ctx->Array.LockCount = 0;
1904   ctx->NewState |= _NEW_ARRAY;
1905}
1906
1907
1908static void
1909primitive_restart_index(struct gl_context *ctx, GLuint index)
1910{
1911   ctx->Array.RestartIndex = index;
1912}
1913
1914
1915/**
1916 * GL_NV_primitive_restart and GL 3.1
1917 */
1918void GLAPIENTRY
1919_mesa_PrimitiveRestartIndex_no_error(GLuint index)
1920{
1921   GET_CURRENT_CONTEXT(ctx);
1922   primitive_restart_index(ctx, index);
1923}
1924
1925
1926void GLAPIENTRY
1927_mesa_PrimitiveRestartIndex(GLuint index)
1928{
1929   GET_CURRENT_CONTEXT(ctx);
1930
1931   if (!ctx->Extensions.NV_primitive_restart && ctx->Version < 31) {
1932      _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()");
1933      return;
1934   }
1935
1936   primitive_restart_index(ctx, index);
1937}
1938
1939
1940void GLAPIENTRY
1941_mesa_VertexAttribDivisor_no_error(GLuint index, GLuint divisor)
1942{
1943   GET_CURRENT_CONTEXT(ctx);
1944
1945   const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index);
1946   struct gl_vertex_array_object * const vao = ctx->Array.VAO;
1947
1948   assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
1949
1950   /* The ARB_vertex_attrib_binding spec says:
1951    *
1952    *    "The command
1953    *
1954    *       void VertexAttribDivisor(uint index, uint divisor);
1955    *
1956    *     is equivalent to (assuming no errors are generated):
1957    *
1958    *       VertexAttribBinding(index, index);
1959    *       VertexBindingDivisor(index, divisor);"
1960    */
1961   _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
1962   vertex_binding_divisor(ctx, vao, genericIndex, divisor);
1963}
1964
1965
1966/**
1967 * See GL_ARB_instanced_arrays.
1968 * Note that the instance divisor only applies to generic arrays, not
1969 * the legacy vertex arrays.
1970 */
1971void GLAPIENTRY
1972_mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
1973{
1974   GET_CURRENT_CONTEXT(ctx);
1975
1976   const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index);
1977   struct gl_vertex_array_object * const vao = ctx->Array.VAO;
1978
1979   if (!ctx->Extensions.ARB_instanced_arrays) {
1980      _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
1981      return;
1982   }
1983
1984   if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1985      _mesa_error(ctx, GL_INVALID_VALUE,
1986                  "glVertexAttribDivisor(index = %u)", index);
1987      return;
1988   }
1989
1990   assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
1991
1992   /* The ARB_vertex_attrib_binding spec says:
1993    *
1994    *    "The command
1995    *
1996    *       void VertexAttribDivisor(uint index, uint divisor);
1997    *
1998    *     is equivalent to (assuming no errors are generated):
1999    *
2000    *       VertexAttribBinding(index, index);
2001    *       VertexBindingDivisor(index, divisor);"
2002    */
2003   _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
2004   vertex_binding_divisor(ctx, vao, genericIndex, divisor);
2005}
2006
2007
2008static ALWAYS_INLINE void
2009vertex_array_vertex_buffer(struct gl_context *ctx,
2010                           struct gl_vertex_array_object *vao,
2011                           GLuint bindingIndex, GLuint buffer, GLintptr offset,
2012                           GLsizei stride, bool no_error, const char *func)
2013{
2014   struct gl_buffer_object *vbo;
2015   if (buffer ==
2016       vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj->Name) {
2017      vbo = vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj;
2018   } else if (buffer != 0) {
2019      vbo = _mesa_lookup_bufferobj(ctx, buffer);
2020
2021      if (!no_error && !vbo && _mesa_is_gles31(ctx)) {
2022         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", func);
2023         return;
2024      }
2025      /* From the GL_ARB_vertex_attrib_array spec:
2026       *
2027       *   "[Core profile only:]
2028       *    An INVALID_OPERATION error is generated if buffer is not zero or a
2029       *    name returned from a previous call to GenBuffers, or if such a name
2030       *    has since been deleted with DeleteBuffers.
2031       *
2032       * Otherwise, we fall back to the same compat profile behavior as other
2033       * object references (automatically gen it).
2034       */
2035      if (!_mesa_handle_bind_buffer_gen(ctx, buffer, &vbo, func))
2036         return;
2037   } else {
2038      /* The ARB_vertex_attrib_binding spec says:
2039       *
2040       *    "If <buffer> is zero, any buffer object attached to this
2041       *     bindpoint is detached."
2042       */
2043      vbo = ctx->Shared->NullBufferObj;
2044   }
2045
2046   _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex),
2047                            vbo, offset, stride);
2048}
2049
2050
2051/**
2052 * GL_ARB_vertex_attrib_binding
2053 */
2054static void
2055vertex_array_vertex_buffer_err(struct gl_context *ctx,
2056                               struct gl_vertex_array_object *vao,
2057                               GLuint bindingIndex, GLuint buffer,
2058                               GLintptr offset, GLsizei stride,
2059                               const char *func)
2060{
2061   ASSERT_OUTSIDE_BEGIN_END(ctx);
2062
2063   /* The ARB_vertex_attrib_binding spec says:
2064    *
2065    *    "An INVALID_VALUE error is generated if <bindingindex> is greater than
2066    *     the value of MAX_VERTEX_ATTRIB_BINDINGS."
2067    */
2068   if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2069      _mesa_error(ctx, GL_INVALID_VALUE,
2070                  "%s(bindingindex=%u > "
2071                  "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2072                  func, bindingIndex);
2073      return;
2074   }
2075
2076   /* The ARB_vertex_attrib_binding spec says:
2077    *
2078    *    "The error INVALID_VALUE is generated if <stride> or <offset>
2079    *     are negative."
2080    */
2081   if (offset < 0) {
2082      _mesa_error(ctx, GL_INVALID_VALUE,
2083                  "%s(offset=%" PRId64 " < 0)",
2084                  func, (int64_t) offset);
2085      return;
2086   }
2087
2088   if (stride < 0) {
2089      _mesa_error(ctx, GL_INVALID_VALUE,
2090                  "%s(stride=%d < 0)", func, stride);
2091      return;
2092   }
2093
2094   if (((_mesa_is_desktop_gl(ctx) && ctx->Version >= 44) || _mesa_is_gles31(ctx)) &&
2095       stride > ctx->Const.MaxVertexAttribStride) {
2096      _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > "
2097                  "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride);
2098      return;
2099   }
2100
2101   vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset,
2102                              stride, false, func);
2103}
2104
2105
2106void GLAPIENTRY
2107_mesa_BindVertexBuffer_no_error(GLuint bindingIndex, GLuint buffer,
2108                                GLintptr offset, GLsizei stride)
2109{
2110   GET_CURRENT_CONTEXT(ctx);
2111   vertex_array_vertex_buffer(ctx, ctx->Array.VAO, bindingIndex,
2112                              buffer, offset, stride, true,
2113                              "glBindVertexBuffer");
2114}
2115
2116
2117void GLAPIENTRY
2118_mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset,
2119                       GLsizei stride)
2120{
2121   GET_CURRENT_CONTEXT(ctx);
2122
2123   /* The ARB_vertex_attrib_binding spec says:
2124    *
2125    *    "An INVALID_OPERATION error is generated if no vertex array object
2126    *     is bound."
2127    */
2128   if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2129       ctx->Array.VAO == ctx->Array.DefaultVAO) {
2130      _mesa_error(ctx, GL_INVALID_OPERATION,
2131                  "glBindVertexBuffer(No array object bound)");
2132      return;
2133   }
2134
2135   vertex_array_vertex_buffer_err(ctx, ctx->Array.VAO, bindingIndex,
2136                                  buffer, offset, stride,
2137                                  "glBindVertexBuffer");
2138}
2139
2140
2141void GLAPIENTRY
2142_mesa_VertexArrayVertexBuffer_no_error(GLuint vaobj, GLuint bindingIndex,
2143                                       GLuint buffer, GLintptr offset,
2144                                       GLsizei stride)
2145{
2146   GET_CURRENT_CONTEXT(ctx);
2147
2148   struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2149   vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset,
2150                              stride, true, "glVertexArrayVertexBuffer");
2151}
2152
2153
2154void GLAPIENTRY
2155_mesa_VertexArrayVertexBuffer(GLuint vaobj, GLuint bindingIndex, GLuint buffer,
2156                              GLintptr offset, GLsizei stride)
2157{
2158   GET_CURRENT_CONTEXT(ctx);
2159   struct gl_vertex_array_object *vao;
2160
2161   /* The ARB_direct_state_access specification says:
2162    *
2163    *   "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
2164    *    if <vaobj> is not [compatibility profile: zero or] the name of an
2165    *    existing vertex array object."
2166    */
2167   vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffer");
2168   if (!vao)
2169      return;
2170
2171   vertex_array_vertex_buffer_err(ctx, vao, bindingIndex, buffer, offset,
2172                                  stride, "glVertexArrayVertexBuffer");
2173}
2174
2175
2176static ALWAYS_INLINE void
2177vertex_array_vertex_buffers(struct gl_context *ctx,
2178                            struct gl_vertex_array_object *vao,
2179                            GLuint first, GLsizei count, const GLuint *buffers,
2180                            const GLintptr *offsets, const GLsizei *strides,
2181                            bool no_error, const char *func)
2182{
2183   GLint i;
2184
2185   if (!buffers) {
2186      /**
2187       * The ARB_multi_bind spec says:
2188       *
2189       *    "If <buffers> is NULL, each affected vertex buffer binding point
2190       *     from <first> through <first>+<count>-1 will be reset to have no
2191       *     bound buffer object.  In this case, the offsets and strides
2192       *     associated with the binding points are set to default values,
2193       *     ignoring <offsets> and <strides>."
2194       */
2195      struct gl_buffer_object *vbo = ctx->Shared->NullBufferObj;
2196
2197      for (i = 0; i < count; i++)
2198         _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
2199                                  vbo, 0, 16);
2200
2201      return;
2202   }
2203
2204   /* Note that the error semantics for multi-bind commands differ from
2205    * those of other GL commands.
2206    *
2207    * The Issues section in the ARB_multi_bind spec says:
2208    *
2209    *    "(11) Typically, OpenGL specifies that if an error is generated by
2210    *          a command, that command has no effect.  This is somewhat
2211    *          unfortunate for multi-bind commands, because it would require
2212    *          a first pass to scan the entire list of bound objects for
2213    *          errors and then a second pass to actually perform the
2214    *          bindings.  Should we have different error semantics?
2215    *
2216    *       RESOLVED:  Yes.  In this specification, when the parameters for
2217    *       one of the <count> binding points are invalid, that binding
2218    *       point is not updated and an error will be generated.  However,
2219    *       other binding points in the same command will be updated if
2220    *       their parameters are valid and no other error occurs."
2221    */
2222
2223   _mesa_HashLockMutex(ctx->Shared->BufferObjects);
2224
2225   for (i = 0; i < count; i++) {
2226      struct gl_buffer_object *vbo;
2227
2228      if (!no_error) {
2229         /* The ARB_multi_bind spec says:
2230          *
2231          *    "An INVALID_VALUE error is generated if any value in
2232          *     <offsets> or <strides> is negative (per binding)."
2233          */
2234         if (offsets[i] < 0) {
2235            _mesa_error(ctx, GL_INVALID_VALUE,
2236                        "%s(offsets[%u]=%" PRId64 " < 0)",
2237                        func, i, (int64_t) offsets[i]);
2238            continue;
2239         }
2240
2241         if (strides[i] < 0) {
2242            _mesa_error(ctx, GL_INVALID_VALUE,
2243                        "%s(strides[%u]=%d < 0)",
2244                        func, i, strides[i]);
2245            continue;
2246         }
2247
2248         if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 44 &&
2249             strides[i] > ctx->Const.MaxVertexAttribStride) {
2250            _mesa_error(ctx, GL_INVALID_VALUE,
2251                        "%s(strides[%u]=%d > "
2252                        "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, i, strides[i]);
2253            continue;
2254         }
2255      }
2256
2257      if (buffers[i]) {
2258         struct gl_vertex_buffer_binding *binding =
2259            &vao->BufferBinding[VERT_ATTRIB_GENERIC(first + i)];
2260
2261         if (buffers[i] == binding->BufferObj->Name)
2262            vbo = binding->BufferObj;
2263         else
2264            vbo = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, func);
2265
2266         if (!vbo)
2267            continue;
2268      } else {
2269         vbo = ctx->Shared->NullBufferObj;
2270      }
2271
2272      _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
2273                               vbo, offsets[i], strides[i]);
2274   }
2275
2276   _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
2277}
2278
2279
2280static void
2281vertex_array_vertex_buffers_err(struct gl_context *ctx,
2282                                struct gl_vertex_array_object *vao,
2283                                GLuint first, GLsizei count,
2284                                const GLuint *buffers, const GLintptr *offsets,
2285                                const GLsizei *strides, const char *func)
2286{
2287   ASSERT_OUTSIDE_BEGIN_END(ctx);
2288
2289   /* The ARB_multi_bind spec says:
2290    *
2291    *    "An INVALID_OPERATION error is generated if <first> + <count>
2292    *     is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS."
2293    */
2294   if (first + count > ctx->Const.MaxVertexAttribBindings) {
2295      _mesa_error(ctx, GL_INVALID_OPERATION,
2296                  "%s(first=%u + count=%d > the value of "
2297                  "GL_MAX_VERTEX_ATTRIB_BINDINGS=%u)",
2298                  func, first, count, ctx->Const.MaxVertexAttribBindings);
2299      return;
2300   }
2301
2302   vertex_array_vertex_buffers(ctx, vao, first, count, buffers, offsets,
2303                               strides, false, func);
2304}
2305
2306
2307void GLAPIENTRY
2308_mesa_BindVertexBuffers_no_error(GLuint first, GLsizei count,
2309                                 const GLuint *buffers, const GLintptr *offsets,
2310                                 const GLsizei *strides)
2311{
2312   GET_CURRENT_CONTEXT(ctx);
2313
2314   vertex_array_vertex_buffers(ctx, ctx->Array.VAO, first, count,
2315                               buffers, offsets, strides, true,
2316                               "glBindVertexBuffers");
2317}
2318
2319
2320void GLAPIENTRY
2321_mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers,
2322                        const GLintptr *offsets, const GLsizei *strides)
2323{
2324   GET_CURRENT_CONTEXT(ctx);
2325
2326   /* The ARB_vertex_attrib_binding spec says:
2327    *
2328    *    "An INVALID_OPERATION error is generated if no
2329    *     vertex array object is bound."
2330    */
2331   if (ctx->API == API_OPENGL_CORE &&
2332       ctx->Array.VAO == ctx->Array.DefaultVAO) {
2333      _mesa_error(ctx, GL_INVALID_OPERATION,
2334                  "glBindVertexBuffers(No array object bound)");
2335      return;
2336   }
2337
2338   vertex_array_vertex_buffers_err(ctx, ctx->Array.VAO, first, count,
2339                                   buffers, offsets, strides,
2340                                   "glBindVertexBuffers");
2341}
2342
2343
2344void GLAPIENTRY
2345_mesa_VertexArrayVertexBuffers_no_error(GLuint vaobj, GLuint first,
2346                                        GLsizei count, const GLuint *buffers,
2347                                        const GLintptr *offsets,
2348                                        const GLsizei *strides)
2349{
2350   GET_CURRENT_CONTEXT(ctx);
2351
2352   struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2353   vertex_array_vertex_buffers(ctx, vao, first, count,
2354                               buffers, offsets, strides, true,
2355                               "glVertexArrayVertexBuffers");
2356}
2357
2358
2359void GLAPIENTRY
2360_mesa_VertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count,
2361                               const GLuint *buffers,
2362                               const GLintptr *offsets, const GLsizei *strides)
2363{
2364   GET_CURRENT_CONTEXT(ctx);
2365   struct gl_vertex_array_object *vao;
2366
2367   /* The ARB_direct_state_access specification says:
2368    *
2369    *   "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
2370    *    if <vaobj> is not [compatibility profile: zero or] the name of an
2371    *    existing vertex array object."
2372    */
2373   vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffers");
2374   if (!vao)
2375      return;
2376
2377   vertex_array_vertex_buffers_err(ctx, vao, first, count,
2378                                   buffers, offsets, strides,
2379                                   "glVertexArrayVertexBuffers");
2380}
2381
2382
2383static void
2384vertex_attrib_format(GLuint attribIndex, GLint size, GLenum type,
2385                     GLboolean normalized, GLboolean integer,
2386                     GLboolean doubles, GLbitfield legalTypes,
2387                     GLsizei sizeMax, GLuint relativeOffset,
2388                     const char *func)
2389{
2390   GET_CURRENT_CONTEXT(ctx);
2391   ASSERT_OUTSIDE_BEGIN_END(ctx);
2392
2393   GLenum format = get_array_format(ctx, sizeMax, &size);
2394
2395   if (!_mesa_is_no_error_enabled(ctx)) {
2396      /* The ARB_vertex_attrib_binding spec says:
2397       *
2398       *    "An INVALID_OPERATION error is generated under any of the
2399       *    following conditions:
2400       *     - if no vertex array object is currently bound (see section
2401       *       2.10);
2402       *     - ..."
2403       *
2404       * This error condition only applies to VertexAttribFormat and
2405       * VertexAttribIFormat in the extension spec, but we assume that this
2406       * is an oversight.  In the OpenGL 4.3 (Core Profile) spec, it applies
2407       * to all three functions.
2408       */
2409      if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2410          ctx->Array.VAO == ctx->Array.DefaultVAO) {
2411         _mesa_error(ctx, GL_INVALID_OPERATION,
2412                     "%s(No array object bound)", func);
2413         return;
2414      }
2415
2416      /* The ARB_vertex_attrib_binding spec says:
2417       *
2418       *   "The error INVALID_VALUE is generated if index is greater than or
2419       *   equal to the value of MAX_VERTEX_ATTRIBS."
2420       */
2421      if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2422         _mesa_error(ctx, GL_INVALID_VALUE,
2423                     "%s(attribindex=%u > "
2424                     "GL_MAX_VERTEX_ATTRIBS)",
2425                     func, attribIndex);
2426         return;
2427      }
2428
2429      if (!validate_array_format(ctx, func, ctx->Array.VAO,
2430                                 VERT_ATTRIB_GENERIC(attribIndex),
2431                                 legalTypes, 1, sizeMax, size, type,
2432                                 normalized, integer, doubles, relativeOffset,
2433                                 format)) {
2434         return;
2435      }
2436   }
2437
2438   _mesa_update_array_format(ctx, ctx->Array.VAO,
2439                             VERT_ATTRIB_GENERIC(attribIndex), size, type,
2440                             format, normalized, integer, doubles,
2441                             relativeOffset);
2442}
2443
2444
2445void GLAPIENTRY
2446_mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type,
2447                         GLboolean normalized, GLuint relativeOffset)
2448{
2449   vertex_attrib_format(attribIndex, size, type, normalized,
2450                        GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
2451                        BGRA_OR_4, relativeOffset,
2452                        "glVertexAttribFormat");
2453}
2454
2455
2456void GLAPIENTRY
2457_mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type,
2458                          GLuint relativeOffset)
2459{
2460   vertex_attrib_format(attribIndex, size, type, GL_FALSE,
2461                        GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK, 4,
2462                        relativeOffset, "glVertexAttribIFormat");
2463}
2464
2465
2466void GLAPIENTRY
2467_mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type,
2468                          GLuint relativeOffset)
2469{
2470   vertex_attrib_format(attribIndex, size, type, GL_FALSE, GL_FALSE,
2471                        GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK, 4,
2472                        relativeOffset, "glVertexAttribLFormat");
2473}
2474
2475
2476static void
2477vertex_array_attrib_format(GLuint vaobj, GLuint attribIndex, GLint size,
2478                           GLenum type, GLboolean normalized,
2479                           GLboolean integer, GLboolean doubles,
2480                           GLbitfield legalTypes, GLsizei sizeMax,
2481                           GLuint relativeOffset, const char *func)
2482{
2483   GET_CURRENT_CONTEXT(ctx);
2484   struct gl_vertex_array_object *vao;
2485
2486   ASSERT_OUTSIDE_BEGIN_END(ctx);
2487
2488   GLenum format = get_array_format(ctx, sizeMax, &size);
2489
2490   if (_mesa_is_no_error_enabled(ctx)) {
2491      vao = _mesa_lookup_vao(ctx, vaobj);
2492      if (!vao)
2493         return;
2494   } else {
2495      /* The ARB_direct_state_access spec says:
2496       *
2497       *   "An INVALID_OPERATION error is generated by
2498       *   VertexArrayAttrib*Format if <vaobj> is not [compatibility profile:
2499       *   zero or] the name of an existing vertex array object."
2500       */
2501      vao = _mesa_lookup_vao_err(ctx, vaobj, func);
2502      if (!vao)
2503         return;
2504
2505      /* The ARB_vertex_attrib_binding spec says:
2506       *
2507       *   "The error INVALID_VALUE is generated if index is greater than or
2508       *   equal to the value of MAX_VERTEX_ATTRIBS."
2509       */
2510      if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2511         _mesa_error(ctx, GL_INVALID_VALUE,
2512                     "%s(attribindex=%u > GL_MAX_VERTEX_ATTRIBS)",
2513                     func, attribIndex);
2514         return;
2515      }
2516
2517      if (!validate_array_format(ctx, func, vao,
2518                                 VERT_ATTRIB_GENERIC(attribIndex),
2519                                 legalTypes, 1, sizeMax, size, type,
2520                                 normalized, integer, doubles, relativeOffset,
2521                                 format)) {
2522         return;
2523      }
2524   }
2525
2526   _mesa_update_array_format(ctx, vao, VERT_ATTRIB_GENERIC(attribIndex), size,
2527                             type, format, normalized, integer, doubles,
2528                             relativeOffset);
2529}
2530
2531
2532void GLAPIENTRY
2533_mesa_VertexArrayAttribFormat(GLuint vaobj, GLuint attribIndex, GLint size,
2534                              GLenum type, GLboolean normalized,
2535                              GLuint relativeOffset)
2536{
2537   vertex_array_attrib_format(vaobj, attribIndex, size, type, normalized,
2538                              GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
2539                              BGRA_OR_4, relativeOffset,
2540                              "glVertexArrayAttribFormat");
2541}
2542
2543
2544void GLAPIENTRY
2545_mesa_VertexArrayAttribIFormat(GLuint vaobj, GLuint attribIndex,
2546                               GLint size, GLenum type,
2547                               GLuint relativeOffset)
2548{
2549   vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE,
2550                              GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK,
2551                              4, relativeOffset,
2552                              "glVertexArrayAttribIFormat");
2553}
2554
2555
2556void GLAPIENTRY
2557_mesa_VertexArrayAttribLFormat(GLuint vaobj, GLuint attribIndex,
2558                               GLint size, GLenum type,
2559                               GLuint relativeOffset)
2560{
2561   vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE,
2562                              GL_FALSE, GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK,
2563                              4, relativeOffset,
2564                              "glVertexArrayAttribLFormat");
2565}
2566
2567
2568static void
2569vertex_array_attrib_binding(struct gl_context *ctx,
2570                            struct gl_vertex_array_object *vao,
2571                            GLuint attribIndex, GLuint bindingIndex,
2572                            const char *func)
2573{
2574   ASSERT_OUTSIDE_BEGIN_END(ctx);
2575
2576   /* The ARB_vertex_attrib_binding spec says:
2577    *
2578    *    "<attribindex> must be less than the value of MAX_VERTEX_ATTRIBS and
2579    *     <bindingindex> must be less than the value of
2580    *     MAX_VERTEX_ATTRIB_BINDINGS, otherwise the error INVALID_VALUE
2581    *     is generated."
2582    */
2583   if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2584      _mesa_error(ctx, GL_INVALID_VALUE,
2585                  "%s(attribindex=%u >= "
2586                  "GL_MAX_VERTEX_ATTRIBS)",
2587                  func, attribIndex);
2588      return;
2589   }
2590
2591   if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2592      _mesa_error(ctx, GL_INVALID_VALUE,
2593                  "%s(bindingindex=%u >= "
2594                  "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2595                  func, bindingIndex);
2596      return;
2597   }
2598
2599   assert(VERT_ATTRIB_GENERIC(attribIndex) < ARRAY_SIZE(vao->VertexAttrib));
2600
2601   _mesa_vertex_attrib_binding(ctx, vao,
2602                               VERT_ATTRIB_GENERIC(attribIndex),
2603                               VERT_ATTRIB_GENERIC(bindingIndex));
2604}
2605
2606
2607void GLAPIENTRY
2608_mesa_VertexAttribBinding_no_error(GLuint attribIndex, GLuint bindingIndex)
2609{
2610   GET_CURRENT_CONTEXT(ctx);
2611   _mesa_vertex_attrib_binding(ctx, ctx->Array.VAO,
2612                               VERT_ATTRIB_GENERIC(attribIndex),
2613                               VERT_ATTRIB_GENERIC(bindingIndex));
2614}
2615
2616
2617void GLAPIENTRY
2618_mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
2619{
2620   GET_CURRENT_CONTEXT(ctx);
2621
2622   /* The ARB_vertex_attrib_binding spec says:
2623    *
2624    *    "An INVALID_OPERATION error is generated if no vertex array object
2625    *     is bound."
2626    */
2627   if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2628       ctx->Array.VAO == ctx->Array.DefaultVAO) {
2629      _mesa_error(ctx, GL_INVALID_OPERATION,
2630                  "glVertexAttribBinding(No array object bound)");
2631      return;
2632   }
2633
2634   vertex_array_attrib_binding(ctx, ctx->Array.VAO,
2635                               attribIndex, bindingIndex,
2636                               "glVertexAttribBinding");
2637}
2638
2639
2640void GLAPIENTRY
2641_mesa_VertexArrayAttribBinding_no_error(GLuint vaobj, GLuint attribIndex,
2642                                        GLuint bindingIndex)
2643{
2644   GET_CURRENT_CONTEXT(ctx);
2645
2646   struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2647   _mesa_vertex_attrib_binding(ctx, vao,
2648                               VERT_ATTRIB_GENERIC(attribIndex),
2649                               VERT_ATTRIB_GENERIC(bindingIndex));
2650}
2651
2652
2653void GLAPIENTRY
2654_mesa_VertexArrayAttribBinding(GLuint vaobj, GLuint attribIndex, GLuint bindingIndex)
2655{
2656   GET_CURRENT_CONTEXT(ctx);
2657   struct gl_vertex_array_object *vao;
2658
2659   /* The ARB_direct_state_access specification says:
2660    *
2661    *   "An INVALID_OPERATION error is generated by VertexArrayAttribBinding
2662    *    if <vaobj> is not [compatibility profile: zero or] the name of an
2663    *    existing vertex array object."
2664    */
2665   vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayAttribBinding");
2666   if (!vao)
2667      return;
2668
2669   vertex_array_attrib_binding(ctx, vao, attribIndex, bindingIndex,
2670                               "glVertexArrayAttribBinding");
2671}
2672
2673
2674static void
2675vertex_array_binding_divisor(struct gl_context *ctx,
2676                             struct gl_vertex_array_object *vao,
2677                             GLuint bindingIndex, GLuint divisor,
2678                             const char *func)
2679{
2680   ASSERT_OUTSIDE_BEGIN_END(ctx);
2681
2682   if (!ctx->Extensions.ARB_instanced_arrays) {
2683      _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", func);
2684      return;
2685   }
2686
2687   /* The ARB_vertex_attrib_binding spec says:
2688    *
2689    *    "An INVALID_VALUE error is generated if <bindingindex> is greater
2690    *     than or equal to the value of MAX_VERTEX_ATTRIB_BINDINGS."
2691    */
2692   if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2693      _mesa_error(ctx, GL_INVALID_VALUE,
2694                  "%s(bindingindex=%u > "
2695                  "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2696                  func, bindingIndex);
2697      return;
2698   }
2699
2700   vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2701}
2702
2703
2704void GLAPIENTRY
2705_mesa_VertexBindingDivisor_no_error(GLuint bindingIndex, GLuint divisor)
2706{
2707   GET_CURRENT_CONTEXT(ctx);
2708   vertex_binding_divisor(ctx, ctx->Array.VAO,
2709                          VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2710}
2711
2712
2713void GLAPIENTRY
2714_mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
2715{
2716   GET_CURRENT_CONTEXT(ctx);
2717
2718   /* The ARB_vertex_attrib_binding spec says:
2719    *
2720    *    "An INVALID_OPERATION error is generated if no vertex array object
2721    *     is bound."
2722    */
2723   if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2724       ctx->Array.VAO == ctx->Array.DefaultVAO) {
2725      _mesa_error(ctx, GL_INVALID_OPERATION,
2726                  "glVertexBindingDivisor(No array object bound)");
2727      return;
2728   }
2729
2730   vertex_array_binding_divisor(ctx, ctx->Array.VAO,
2731                                bindingIndex, divisor,
2732                                "glVertexBindingDivisor");
2733}
2734
2735
2736void GLAPIENTRY
2737_mesa_VertexArrayBindingDivisor_no_error(GLuint vaobj, GLuint bindingIndex,
2738                                         GLuint divisor)
2739{
2740   GET_CURRENT_CONTEXT(ctx);
2741
2742   struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2743   vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2744}
2745
2746
2747void GLAPIENTRY
2748_mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex,
2749                                GLuint divisor)
2750{
2751   struct gl_vertex_array_object *vao;
2752   GET_CURRENT_CONTEXT(ctx);
2753
2754   /* The ARB_direct_state_access specification says:
2755    *
2756    *   "An INVALID_OPERATION error is generated by VertexArrayBindingDivisor
2757    *    if <vaobj> is not [compatibility profile: zero or] the name of an
2758    *    existing vertex array object."
2759    */
2760   vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayBindingDivisor");
2761   if (!vao)
2762       return;
2763
2764   vertex_array_binding_divisor(ctx, vao, bindingIndex, divisor,
2765                                "glVertexArrayBindingDivisor");
2766}
2767
2768
2769void
2770_mesa_copy_vertex_attrib_array(struct gl_context *ctx,
2771                               struct gl_array_attributes *dst,
2772                               const struct gl_array_attributes *src)
2773{
2774   dst->Size           = src->Size;
2775   dst->Type           = src->Type;
2776   dst->Format         = src->Format;
2777   dst->BufferBindingIndex = src->BufferBindingIndex;
2778   dst->RelativeOffset = src->RelativeOffset;
2779   dst->Format         = src->Format;
2780   dst->Integer        = src->Integer;
2781   dst->Doubles        = src->Doubles;
2782   dst->Normalized     = src->Normalized;
2783   dst->Ptr            = src->Ptr;
2784   dst->Enabled        = src->Enabled;
2785   dst->_ElementSize   = src->_ElementSize;
2786   dst->_EffBufferBindingIndex = src->_EffBufferBindingIndex;
2787   dst->_EffRelativeOffset = src->_EffRelativeOffset;
2788}
2789
2790void
2791_mesa_copy_vertex_buffer_binding(struct gl_context *ctx,
2792                                 struct gl_vertex_buffer_binding *dst,
2793                                 const struct gl_vertex_buffer_binding *src)
2794{
2795   dst->Offset          = src->Offset;
2796   dst->Stride          = src->Stride;
2797   dst->InstanceDivisor = src->InstanceDivisor;
2798   dst->_BoundArrays    = src->_BoundArrays;
2799   dst->_EffBoundArrays = src->_EffBoundArrays;
2800   dst->_EffOffset      = src->_EffOffset;
2801
2802   _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
2803}
2804
2805/**
2806 * Print current vertex object/array info.  For debug.
2807 */
2808void
2809_mesa_print_arrays(struct gl_context *ctx)
2810{
2811   const struct gl_vertex_array_object *vao = ctx->Array.VAO;
2812
2813   fprintf(stderr, "Array Object %u\n", vao->Name);
2814
2815   gl_vert_attrib i;
2816   for (i = 0; i < VERT_ATTRIB_MAX; ++i) {
2817      const struct gl_array_attributes *array = &vao->VertexAttrib[i];
2818      if (!array->Enabled)
2819         continue;
2820
2821      const struct gl_vertex_buffer_binding *binding =
2822         &vao->BufferBinding[array->BufferBindingIndex];
2823      const struct gl_buffer_object *bo = binding->BufferObj;
2824
2825      fprintf(stderr, "  %s: Ptr=%p, Type=%s, Size=%d, ElemSize=%u, "
2826              "Stride=%d, Buffer=%u(Size %lu)\n",
2827              gl_vert_attrib_name((gl_vert_attrib)i),
2828              array->Ptr, _mesa_enum_to_string(array->Type), array->Size,
2829              array->_ElementSize, binding->Stride, bo->Name,
2830              (unsigned long) bo->Size);
2831   }
2832}
2833
2834
2835/**
2836 * Initialize vertex array state for given context.
2837 */
2838void
2839_mesa_init_varray(struct gl_context *ctx)
2840{
2841   ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0);
2842   _mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO);
2843   ctx->Array._EmptyVAO = _mesa_new_vao(ctx, ~0u);
2844   _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, ctx->Array._EmptyVAO);
2845   ctx->Array.ActiveTexture = 0;   /* GL_ARB_multitexture */
2846
2847   ctx->Array.Objects = _mesa_NewHashTable();
2848}
2849
2850
2851/**
2852 * Callback for deleting an array object.  Called by _mesa_HashDeleteAll().
2853 */
2854static void
2855delete_arrayobj_cb(GLuint id, void *data, void *userData)
2856{
2857   struct gl_vertex_array_object *vao = (struct gl_vertex_array_object *) data;
2858   struct gl_context *ctx = (struct gl_context *) userData;
2859   _mesa_delete_vao(ctx, vao);
2860}
2861
2862
2863/**
2864 * Free vertex array state for given context.
2865 */
2866void
2867_mesa_free_varray_data(struct gl_context *ctx)
2868{
2869   _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx);
2870   _mesa_DeleteHashTable(ctx->Array.Objects);
2871}
2872