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