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