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