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