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