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