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