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