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