mesa: Flag _NEW_ARRAY only if we are changing ctx->Array.VAO.
[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_attrib(struct gl_context *ctx,
1075 struct gl_vertex_array_object *vao,
1076 gl_vert_attrib attrib)
1077 {
1078 assert(attrib < ARRAY_SIZE(vao->VertexAttrib));
1079 assert(!vao->SharedAndImmutable);
1080
1081 if (!vao->VertexAttrib[attrib].Enabled) {
1082 /* was disabled, now being enabled */
1083 vao->VertexAttrib[attrib].Enabled = GL_TRUE;
1084 const GLbitfield array_bit = VERT_BIT(attrib);
1085 vao->_Enabled |= array_bit;
1086 vao->NewArrays |= array_bit;
1087
1088 if (vao == ctx->Array.VAO)
1089 ctx->NewState |= _NEW_ARRAY;
1090
1091 /* Update the map mode if needed */
1092 if (array_bit & (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_attrib(struct gl_context *ctx,
1162 struct gl_vertex_array_object *vao,
1163 gl_vert_attrib attrib)
1164 {
1165 assert(attrib < ARRAY_SIZE(vao->VertexAttrib));
1166 assert(!vao->SharedAndImmutable);
1167
1168 if (vao->VertexAttrib[attrib].Enabled) {
1169 /* was enabled, now being disabled */
1170 vao->VertexAttrib[attrib].Enabled = GL_FALSE;
1171 const GLbitfield array_bit = VERT_BIT(attrib);
1172 vao->_Enabled &= ~array_bit;
1173 vao->NewArrays |= array_bit;
1174
1175 if (vao == ctx->Array.VAO)
1176 ctx->NewState |= _NEW_ARRAY;
1177
1178 /* Update the map mode if needed */
1179 if (array_bit & (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 array->Enabled;
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 /* GL_IBM_multimode_draw_arrays */
1909 void GLAPIENTRY
1910 _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
1911 const GLsizei * count,
1912 GLsizei primcount, GLint modestride )
1913 {
1914 GET_CURRENT_CONTEXT(ctx);
1915 GLint i;
1916
1917 FLUSH_VERTICES(ctx, 0);
1918
1919 for ( i = 0 ; i < primcount ; i++ ) {
1920 if ( count[i] > 0 ) {
1921 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1922 CALL_DrawArrays(ctx->CurrentServerDispatch, ( m, first[i], count[i] ));
1923 }
1924 }
1925 }
1926
1927
1928 /* GL_IBM_multimode_draw_arrays */
1929 void GLAPIENTRY
1930 _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
1931 GLenum type, const GLvoid * const * indices,
1932 GLsizei primcount, GLint modestride )
1933 {
1934 GET_CURRENT_CONTEXT(ctx);
1935 GLint i;
1936
1937 FLUSH_VERTICES(ctx, 0);
1938
1939 /* XXX not sure about ARB_vertex_buffer_object handling here */
1940
1941 for ( i = 0 ; i < primcount ; i++ ) {
1942 if ( count[i] > 0 ) {
1943 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1944 CALL_DrawElements(ctx->CurrentServerDispatch, ( m, count[i], type,
1945 indices[i] ));
1946 }
1947 }
1948 }
1949
1950
1951 static void
1952 primitive_restart_index(struct gl_context *ctx, GLuint index)
1953 {
1954 ctx->Array.RestartIndex = index;
1955 }
1956
1957
1958 /**
1959 * GL_NV_primitive_restart and GL 3.1
1960 */
1961 void GLAPIENTRY
1962 _mesa_PrimitiveRestartIndex_no_error(GLuint index)
1963 {
1964 GET_CURRENT_CONTEXT(ctx);
1965 primitive_restart_index(ctx, index);
1966 }
1967
1968
1969 void GLAPIENTRY
1970 _mesa_PrimitiveRestartIndex(GLuint index)
1971 {
1972 GET_CURRENT_CONTEXT(ctx);
1973
1974 if (!ctx->Extensions.NV_primitive_restart && ctx->Version < 31) {
1975 _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()");
1976 return;
1977 }
1978
1979 primitive_restart_index(ctx, index);
1980 }
1981
1982
1983 void GLAPIENTRY
1984 _mesa_VertexAttribDivisor_no_error(GLuint index, GLuint divisor)
1985 {
1986 GET_CURRENT_CONTEXT(ctx);
1987
1988 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index);
1989 struct gl_vertex_array_object * const vao = ctx->Array.VAO;
1990
1991 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
1992
1993 /* The ARB_vertex_attrib_binding spec says:
1994 *
1995 * "The command
1996 *
1997 * void VertexAttribDivisor(uint index, uint divisor);
1998 *
1999 * is equivalent to (assuming no errors are generated):
2000 *
2001 * VertexAttribBinding(index, index);
2002 * VertexBindingDivisor(index, divisor);"
2003 */
2004 _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
2005 vertex_binding_divisor(ctx, vao, genericIndex, divisor);
2006 }
2007
2008
2009 /**
2010 * See GL_ARB_instanced_arrays.
2011 * Note that the instance divisor only applies to generic arrays, not
2012 * the legacy vertex arrays.
2013 */
2014 void GLAPIENTRY
2015 _mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
2016 {
2017 GET_CURRENT_CONTEXT(ctx);
2018
2019 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index);
2020 struct gl_vertex_array_object * const vao = ctx->Array.VAO;
2021
2022 if (!ctx->Extensions.ARB_instanced_arrays) {
2023 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
2024 return;
2025 }
2026
2027 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2028 _mesa_error(ctx, GL_INVALID_VALUE,
2029 "glVertexAttribDivisor(index = %u)", index);
2030 return;
2031 }
2032
2033 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
2034
2035 /* The ARB_vertex_attrib_binding spec says:
2036 *
2037 * "The command
2038 *
2039 * void VertexAttribDivisor(uint index, uint divisor);
2040 *
2041 * is equivalent to (assuming no errors are generated):
2042 *
2043 * VertexAttribBinding(index, index);
2044 * VertexBindingDivisor(index, divisor);"
2045 */
2046 _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
2047 vertex_binding_divisor(ctx, vao, genericIndex, divisor);
2048 }
2049
2050
2051 static ALWAYS_INLINE void
2052 vertex_array_vertex_buffer(struct gl_context *ctx,
2053 struct gl_vertex_array_object *vao,
2054 GLuint bindingIndex, GLuint buffer, GLintptr offset,
2055 GLsizei stride, bool no_error, const char *func)
2056 {
2057 struct gl_buffer_object *vbo;
2058 if (buffer ==
2059 vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj->Name) {
2060 vbo = vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj;
2061 } else if (buffer != 0) {
2062 vbo = _mesa_lookup_bufferobj(ctx, buffer);
2063
2064 if (!no_error && !vbo && _mesa_is_gles31(ctx)) {
2065 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", func);
2066 return;
2067 }
2068 /* From the GL_ARB_vertex_attrib_array spec:
2069 *
2070 * "[Core profile only:]
2071 * An INVALID_OPERATION error is generated if buffer is not zero or a
2072 * name returned from a previous call to GenBuffers, or if such a name
2073 * has since been deleted with DeleteBuffers.
2074 *
2075 * Otherwise, we fall back to the same compat profile behavior as other
2076 * object references (automatically gen it).
2077 */
2078 if (!_mesa_handle_bind_buffer_gen(ctx, buffer, &vbo, func))
2079 return;
2080 } else {
2081 /* The ARB_vertex_attrib_binding spec says:
2082 *
2083 * "If <buffer> is zero, any buffer object attached to this
2084 * bindpoint is detached."
2085 */
2086 vbo = ctx->Shared->NullBufferObj;
2087 }
2088
2089 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex),
2090 vbo, offset, stride);
2091 }
2092
2093
2094 /**
2095 * GL_ARB_vertex_attrib_binding
2096 */
2097 static void
2098 vertex_array_vertex_buffer_err(struct gl_context *ctx,
2099 struct gl_vertex_array_object *vao,
2100 GLuint bindingIndex, GLuint buffer,
2101 GLintptr offset, GLsizei stride,
2102 const char *func)
2103 {
2104 ASSERT_OUTSIDE_BEGIN_END(ctx);
2105
2106 /* The ARB_vertex_attrib_binding spec says:
2107 *
2108 * "An INVALID_VALUE error is generated if <bindingindex> is greater than
2109 * the value of MAX_VERTEX_ATTRIB_BINDINGS."
2110 */
2111 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2112 _mesa_error(ctx, GL_INVALID_VALUE,
2113 "%s(bindingindex=%u > "
2114 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2115 func, bindingIndex);
2116 return;
2117 }
2118
2119 /* The ARB_vertex_attrib_binding spec says:
2120 *
2121 * "The error INVALID_VALUE is generated if <stride> or <offset>
2122 * are negative."
2123 */
2124 if (offset < 0) {
2125 _mesa_error(ctx, GL_INVALID_VALUE,
2126 "%s(offset=%" PRId64 " < 0)",
2127 func, (int64_t) offset);
2128 return;
2129 }
2130
2131 if (stride < 0) {
2132 _mesa_error(ctx, GL_INVALID_VALUE,
2133 "%s(stride=%d < 0)", func, stride);
2134 return;
2135 }
2136
2137 if (((_mesa_is_desktop_gl(ctx) && ctx->Version >= 44) || _mesa_is_gles31(ctx)) &&
2138 stride > ctx->Const.MaxVertexAttribStride) {
2139 _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > "
2140 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride);
2141 return;
2142 }
2143
2144 vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset,
2145 stride, false, func);
2146 }
2147
2148
2149 void GLAPIENTRY
2150 _mesa_BindVertexBuffer_no_error(GLuint bindingIndex, GLuint buffer,
2151 GLintptr offset, GLsizei stride)
2152 {
2153 GET_CURRENT_CONTEXT(ctx);
2154 vertex_array_vertex_buffer(ctx, ctx->Array.VAO, bindingIndex,
2155 buffer, offset, stride, true,
2156 "glBindVertexBuffer");
2157 }
2158
2159
2160 void GLAPIENTRY
2161 _mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset,
2162 GLsizei stride)
2163 {
2164 GET_CURRENT_CONTEXT(ctx);
2165
2166 /* The ARB_vertex_attrib_binding spec says:
2167 *
2168 * "An INVALID_OPERATION error is generated if no vertex array object
2169 * is bound."
2170 */
2171 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2172 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2173 _mesa_error(ctx, GL_INVALID_OPERATION,
2174 "glBindVertexBuffer(No array object bound)");
2175 return;
2176 }
2177
2178 vertex_array_vertex_buffer_err(ctx, ctx->Array.VAO, bindingIndex,
2179 buffer, offset, stride,
2180 "glBindVertexBuffer");
2181 }
2182
2183
2184 void GLAPIENTRY
2185 _mesa_VertexArrayVertexBuffer_no_error(GLuint vaobj, GLuint bindingIndex,
2186 GLuint buffer, GLintptr offset,
2187 GLsizei stride)
2188 {
2189 GET_CURRENT_CONTEXT(ctx);
2190
2191 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2192 vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset,
2193 stride, true, "glVertexArrayVertexBuffer");
2194 }
2195
2196
2197 void GLAPIENTRY
2198 _mesa_VertexArrayVertexBuffer(GLuint vaobj, GLuint bindingIndex, GLuint buffer,
2199 GLintptr offset, GLsizei stride)
2200 {
2201 GET_CURRENT_CONTEXT(ctx);
2202 struct gl_vertex_array_object *vao;
2203
2204 /* The ARB_direct_state_access specification says:
2205 *
2206 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
2207 * if <vaobj> is not [compatibility profile: zero or] the name of an
2208 * existing vertex array object."
2209 */
2210 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffer");
2211 if (!vao)
2212 return;
2213
2214 vertex_array_vertex_buffer_err(ctx, vao, bindingIndex, buffer, offset,
2215 stride, "glVertexArrayVertexBuffer");
2216 }
2217
2218
2219 static ALWAYS_INLINE void
2220 vertex_array_vertex_buffers(struct gl_context *ctx,
2221 struct gl_vertex_array_object *vao,
2222 GLuint first, GLsizei count, const GLuint *buffers,
2223 const GLintptr *offsets, const GLsizei *strides,
2224 bool no_error, const char *func)
2225 {
2226 GLint i;
2227
2228 if (!buffers) {
2229 /**
2230 * The ARB_multi_bind spec says:
2231 *
2232 * "If <buffers> is NULL, each affected vertex buffer binding point
2233 * from <first> through <first>+<count>-1 will be reset to have no
2234 * bound buffer object. In this case, the offsets and strides
2235 * associated with the binding points are set to default values,
2236 * ignoring <offsets> and <strides>."
2237 */
2238 struct gl_buffer_object *vbo = ctx->Shared->NullBufferObj;
2239
2240 for (i = 0; i < count; i++)
2241 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
2242 vbo, 0, 16);
2243
2244 return;
2245 }
2246
2247 /* Note that the error semantics for multi-bind commands differ from
2248 * those of other GL commands.
2249 *
2250 * The Issues section in the ARB_multi_bind spec says:
2251 *
2252 * "(11) Typically, OpenGL specifies that if an error is generated by
2253 * a command, that command has no effect. This is somewhat
2254 * unfortunate for multi-bind commands, because it would require
2255 * a first pass to scan the entire list of bound objects for
2256 * errors and then a second pass to actually perform the
2257 * bindings. Should we have different error semantics?
2258 *
2259 * RESOLVED: Yes. In this specification, when the parameters for
2260 * one of the <count> binding points are invalid, that binding
2261 * point is not updated and an error will be generated. However,
2262 * other binding points in the same command will be updated if
2263 * their parameters are valid and no other error occurs."
2264 */
2265
2266 _mesa_HashLockMutex(ctx->Shared->BufferObjects);
2267
2268 for (i = 0; i < count; i++) {
2269 struct gl_buffer_object *vbo;
2270
2271 if (!no_error) {
2272 /* The ARB_multi_bind spec says:
2273 *
2274 * "An INVALID_VALUE error is generated if any value in
2275 * <offsets> or <strides> is negative (per binding)."
2276 */
2277 if (offsets[i] < 0) {
2278 _mesa_error(ctx, GL_INVALID_VALUE,
2279 "%s(offsets[%u]=%" PRId64 " < 0)",
2280 func, i, (int64_t) offsets[i]);
2281 continue;
2282 }
2283
2284 if (strides[i] < 0) {
2285 _mesa_error(ctx, GL_INVALID_VALUE,
2286 "%s(strides[%u]=%d < 0)",
2287 func, i, strides[i]);
2288 continue;
2289 }
2290
2291 if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 44 &&
2292 strides[i] > ctx->Const.MaxVertexAttribStride) {
2293 _mesa_error(ctx, GL_INVALID_VALUE,
2294 "%s(strides[%u]=%d > "
2295 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, i, strides[i]);
2296 continue;
2297 }
2298 }
2299
2300 if (buffers[i]) {
2301 struct gl_vertex_buffer_binding *binding =
2302 &vao->BufferBinding[VERT_ATTRIB_GENERIC(first + i)];
2303
2304 if (buffers[i] == binding->BufferObj->Name)
2305 vbo = binding->BufferObj;
2306 else
2307 vbo = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, func);
2308
2309 if (!vbo)
2310 continue;
2311 } else {
2312 vbo = ctx->Shared->NullBufferObj;
2313 }
2314
2315 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
2316 vbo, offsets[i], strides[i]);
2317 }
2318
2319 _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
2320 }
2321
2322
2323 static void
2324 vertex_array_vertex_buffers_err(struct gl_context *ctx,
2325 struct gl_vertex_array_object *vao,
2326 GLuint first, GLsizei count,
2327 const GLuint *buffers, const GLintptr *offsets,
2328 const GLsizei *strides, const char *func)
2329 {
2330 ASSERT_OUTSIDE_BEGIN_END(ctx);
2331
2332 /* The ARB_multi_bind spec says:
2333 *
2334 * "An INVALID_OPERATION error is generated if <first> + <count>
2335 * is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS."
2336 */
2337 if (first + count > ctx->Const.MaxVertexAttribBindings) {
2338 _mesa_error(ctx, GL_INVALID_OPERATION,
2339 "%s(first=%u + count=%d > the value of "
2340 "GL_MAX_VERTEX_ATTRIB_BINDINGS=%u)",
2341 func, first, count, ctx->Const.MaxVertexAttribBindings);
2342 return;
2343 }
2344
2345 vertex_array_vertex_buffers(ctx, vao, first, count, buffers, offsets,
2346 strides, false, func);
2347 }
2348
2349
2350 void GLAPIENTRY
2351 _mesa_BindVertexBuffers_no_error(GLuint first, GLsizei count,
2352 const GLuint *buffers, const GLintptr *offsets,
2353 const GLsizei *strides)
2354 {
2355 GET_CURRENT_CONTEXT(ctx);
2356
2357 vertex_array_vertex_buffers(ctx, ctx->Array.VAO, first, count,
2358 buffers, offsets, strides, true,
2359 "glBindVertexBuffers");
2360 }
2361
2362
2363 void GLAPIENTRY
2364 _mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers,
2365 const GLintptr *offsets, const GLsizei *strides)
2366 {
2367 GET_CURRENT_CONTEXT(ctx);
2368
2369 /* The ARB_vertex_attrib_binding spec says:
2370 *
2371 * "An INVALID_OPERATION error is generated if no
2372 * vertex array object is bound."
2373 */
2374 if (ctx->API == API_OPENGL_CORE &&
2375 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2376 _mesa_error(ctx, GL_INVALID_OPERATION,
2377 "glBindVertexBuffers(No array object bound)");
2378 return;
2379 }
2380
2381 vertex_array_vertex_buffers_err(ctx, ctx->Array.VAO, first, count,
2382 buffers, offsets, strides,
2383 "glBindVertexBuffers");
2384 }
2385
2386
2387 void GLAPIENTRY
2388 _mesa_VertexArrayVertexBuffers_no_error(GLuint vaobj, GLuint first,
2389 GLsizei count, const GLuint *buffers,
2390 const GLintptr *offsets,
2391 const GLsizei *strides)
2392 {
2393 GET_CURRENT_CONTEXT(ctx);
2394
2395 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2396 vertex_array_vertex_buffers(ctx, vao, first, count,
2397 buffers, offsets, strides, true,
2398 "glVertexArrayVertexBuffers");
2399 }
2400
2401
2402 void GLAPIENTRY
2403 _mesa_VertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count,
2404 const GLuint *buffers,
2405 const GLintptr *offsets, const GLsizei *strides)
2406 {
2407 GET_CURRENT_CONTEXT(ctx);
2408 struct gl_vertex_array_object *vao;
2409
2410 /* The ARB_direct_state_access specification says:
2411 *
2412 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
2413 * if <vaobj> is not [compatibility profile: zero or] the name of an
2414 * existing vertex array object."
2415 */
2416 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffers");
2417 if (!vao)
2418 return;
2419
2420 vertex_array_vertex_buffers_err(ctx, vao, first, count,
2421 buffers, offsets, strides,
2422 "glVertexArrayVertexBuffers");
2423 }
2424
2425
2426 static void
2427 vertex_attrib_format(GLuint attribIndex, GLint size, GLenum type,
2428 GLboolean normalized, GLboolean integer,
2429 GLboolean doubles, GLbitfield legalTypes,
2430 GLsizei sizeMax, GLuint relativeOffset,
2431 const char *func)
2432 {
2433 GET_CURRENT_CONTEXT(ctx);
2434 ASSERT_OUTSIDE_BEGIN_END(ctx);
2435
2436 GLenum format = get_array_format(ctx, sizeMax, &size);
2437
2438 if (!_mesa_is_no_error_enabled(ctx)) {
2439 /* The ARB_vertex_attrib_binding spec says:
2440 *
2441 * "An INVALID_OPERATION error is generated under any of the
2442 * following conditions:
2443 * - if no vertex array object is currently bound (see section
2444 * 2.10);
2445 * - ..."
2446 *
2447 * This error condition only applies to VertexAttribFormat and
2448 * VertexAttribIFormat in the extension spec, but we assume that this
2449 * is an oversight. In the OpenGL 4.3 (Core Profile) spec, it applies
2450 * to all three functions.
2451 */
2452 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2453 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2454 _mesa_error(ctx, GL_INVALID_OPERATION,
2455 "%s(No array object bound)", func);
2456 return;
2457 }
2458
2459 /* The ARB_vertex_attrib_binding spec says:
2460 *
2461 * "The error INVALID_VALUE is generated if index is greater than or
2462 * equal to the value of MAX_VERTEX_ATTRIBS."
2463 */
2464 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2465 _mesa_error(ctx, GL_INVALID_VALUE,
2466 "%s(attribindex=%u > "
2467 "GL_MAX_VERTEX_ATTRIBS)",
2468 func, attribIndex);
2469 return;
2470 }
2471
2472 if (!validate_array_format(ctx, func, ctx->Array.VAO,
2473 VERT_ATTRIB_GENERIC(attribIndex),
2474 legalTypes, 1, sizeMax, size, type,
2475 normalized, integer, doubles, relativeOffset,
2476 format)) {
2477 return;
2478 }
2479 }
2480
2481 _mesa_update_array_format(ctx, ctx->Array.VAO,
2482 VERT_ATTRIB_GENERIC(attribIndex), size, type,
2483 format, normalized, integer, doubles,
2484 relativeOffset);
2485 }
2486
2487
2488 void GLAPIENTRY
2489 _mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type,
2490 GLboolean normalized, GLuint relativeOffset)
2491 {
2492 vertex_attrib_format(attribIndex, size, type, normalized,
2493 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
2494 BGRA_OR_4, relativeOffset,
2495 "glVertexAttribFormat");
2496 }
2497
2498
2499 void GLAPIENTRY
2500 _mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type,
2501 GLuint relativeOffset)
2502 {
2503 vertex_attrib_format(attribIndex, size, type, GL_FALSE,
2504 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK, 4,
2505 relativeOffset, "glVertexAttribIFormat");
2506 }
2507
2508
2509 void GLAPIENTRY
2510 _mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type,
2511 GLuint relativeOffset)
2512 {
2513 vertex_attrib_format(attribIndex, size, type, GL_FALSE, GL_FALSE,
2514 GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK, 4,
2515 relativeOffset, "glVertexAttribLFormat");
2516 }
2517
2518
2519 static void
2520 vertex_array_attrib_format(GLuint vaobj, GLuint attribIndex, GLint size,
2521 GLenum type, GLboolean normalized,
2522 GLboolean integer, GLboolean doubles,
2523 GLbitfield legalTypes, GLsizei sizeMax,
2524 GLuint relativeOffset, const char *func)
2525 {
2526 GET_CURRENT_CONTEXT(ctx);
2527 struct gl_vertex_array_object *vao;
2528
2529 ASSERT_OUTSIDE_BEGIN_END(ctx);
2530
2531 GLenum format = get_array_format(ctx, sizeMax, &size);
2532
2533 if (_mesa_is_no_error_enabled(ctx)) {
2534 vao = _mesa_lookup_vao(ctx, vaobj);
2535 if (!vao)
2536 return;
2537 } else {
2538 /* The ARB_direct_state_access spec says:
2539 *
2540 * "An INVALID_OPERATION error is generated by
2541 * VertexArrayAttrib*Format if <vaobj> is not [compatibility profile:
2542 * zero or] the name of an existing vertex array object."
2543 */
2544 vao = _mesa_lookup_vao_err(ctx, vaobj, func);
2545 if (!vao)
2546 return;
2547
2548 /* The ARB_vertex_attrib_binding spec says:
2549 *
2550 * "The error INVALID_VALUE is generated if index is greater than or
2551 * equal to the value of MAX_VERTEX_ATTRIBS."
2552 */
2553 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2554 _mesa_error(ctx, GL_INVALID_VALUE,
2555 "%s(attribindex=%u > GL_MAX_VERTEX_ATTRIBS)",
2556 func, attribIndex);
2557 return;
2558 }
2559
2560 if (!validate_array_format(ctx, func, vao,
2561 VERT_ATTRIB_GENERIC(attribIndex),
2562 legalTypes, 1, sizeMax, size, type,
2563 normalized, integer, doubles, relativeOffset,
2564 format)) {
2565 return;
2566 }
2567 }
2568
2569 _mesa_update_array_format(ctx, vao, VERT_ATTRIB_GENERIC(attribIndex), size,
2570 type, format, normalized, integer, doubles,
2571 relativeOffset);
2572 }
2573
2574
2575 void GLAPIENTRY
2576 _mesa_VertexArrayAttribFormat(GLuint vaobj, GLuint attribIndex, GLint size,
2577 GLenum type, GLboolean normalized,
2578 GLuint relativeOffset)
2579 {
2580 vertex_array_attrib_format(vaobj, attribIndex, size, type, normalized,
2581 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
2582 BGRA_OR_4, relativeOffset,
2583 "glVertexArrayAttribFormat");
2584 }
2585
2586
2587 void GLAPIENTRY
2588 _mesa_VertexArrayAttribIFormat(GLuint vaobj, GLuint attribIndex,
2589 GLint size, GLenum type,
2590 GLuint relativeOffset)
2591 {
2592 vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE,
2593 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK,
2594 4, relativeOffset,
2595 "glVertexArrayAttribIFormat");
2596 }
2597
2598
2599 void GLAPIENTRY
2600 _mesa_VertexArrayAttribLFormat(GLuint vaobj, GLuint attribIndex,
2601 GLint size, GLenum type,
2602 GLuint relativeOffset)
2603 {
2604 vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE,
2605 GL_FALSE, GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK,
2606 4, relativeOffset,
2607 "glVertexArrayAttribLFormat");
2608 }
2609
2610
2611 static void
2612 vertex_array_attrib_binding(struct gl_context *ctx,
2613 struct gl_vertex_array_object *vao,
2614 GLuint attribIndex, GLuint bindingIndex,
2615 const char *func)
2616 {
2617 ASSERT_OUTSIDE_BEGIN_END(ctx);
2618
2619 /* The ARB_vertex_attrib_binding spec says:
2620 *
2621 * "<attribindex> must be less than the value of MAX_VERTEX_ATTRIBS and
2622 * <bindingindex> must be less than the value of
2623 * MAX_VERTEX_ATTRIB_BINDINGS, otherwise the error INVALID_VALUE
2624 * is generated."
2625 */
2626 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2627 _mesa_error(ctx, GL_INVALID_VALUE,
2628 "%s(attribindex=%u >= "
2629 "GL_MAX_VERTEX_ATTRIBS)",
2630 func, attribIndex);
2631 return;
2632 }
2633
2634 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2635 _mesa_error(ctx, GL_INVALID_VALUE,
2636 "%s(bindingindex=%u >= "
2637 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2638 func, bindingIndex);
2639 return;
2640 }
2641
2642 assert(VERT_ATTRIB_GENERIC(attribIndex) < ARRAY_SIZE(vao->VertexAttrib));
2643
2644 _mesa_vertex_attrib_binding(ctx, vao,
2645 VERT_ATTRIB_GENERIC(attribIndex),
2646 VERT_ATTRIB_GENERIC(bindingIndex));
2647 }
2648
2649
2650 void GLAPIENTRY
2651 _mesa_VertexAttribBinding_no_error(GLuint attribIndex, GLuint bindingIndex)
2652 {
2653 GET_CURRENT_CONTEXT(ctx);
2654 _mesa_vertex_attrib_binding(ctx, ctx->Array.VAO,
2655 VERT_ATTRIB_GENERIC(attribIndex),
2656 VERT_ATTRIB_GENERIC(bindingIndex));
2657 }
2658
2659
2660 void GLAPIENTRY
2661 _mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
2662 {
2663 GET_CURRENT_CONTEXT(ctx);
2664
2665 /* The ARB_vertex_attrib_binding spec says:
2666 *
2667 * "An INVALID_OPERATION error is generated if no vertex array object
2668 * is bound."
2669 */
2670 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2671 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2672 _mesa_error(ctx, GL_INVALID_OPERATION,
2673 "glVertexAttribBinding(No array object bound)");
2674 return;
2675 }
2676
2677 vertex_array_attrib_binding(ctx, ctx->Array.VAO,
2678 attribIndex, bindingIndex,
2679 "glVertexAttribBinding");
2680 }
2681
2682
2683 void GLAPIENTRY
2684 _mesa_VertexArrayAttribBinding_no_error(GLuint vaobj, GLuint attribIndex,
2685 GLuint bindingIndex)
2686 {
2687 GET_CURRENT_CONTEXT(ctx);
2688
2689 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2690 _mesa_vertex_attrib_binding(ctx, vao,
2691 VERT_ATTRIB_GENERIC(attribIndex),
2692 VERT_ATTRIB_GENERIC(bindingIndex));
2693 }
2694
2695
2696 void GLAPIENTRY
2697 _mesa_VertexArrayAttribBinding(GLuint vaobj, GLuint attribIndex, GLuint bindingIndex)
2698 {
2699 GET_CURRENT_CONTEXT(ctx);
2700 struct gl_vertex_array_object *vao;
2701
2702 /* The ARB_direct_state_access specification says:
2703 *
2704 * "An INVALID_OPERATION error is generated by VertexArrayAttribBinding
2705 * if <vaobj> is not [compatibility profile: zero or] the name of an
2706 * existing vertex array object."
2707 */
2708 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayAttribBinding");
2709 if (!vao)
2710 return;
2711
2712 vertex_array_attrib_binding(ctx, vao, attribIndex, bindingIndex,
2713 "glVertexArrayAttribBinding");
2714 }
2715
2716
2717 static void
2718 vertex_array_binding_divisor(struct gl_context *ctx,
2719 struct gl_vertex_array_object *vao,
2720 GLuint bindingIndex, GLuint divisor,
2721 const char *func)
2722 {
2723 ASSERT_OUTSIDE_BEGIN_END(ctx);
2724
2725 if (!ctx->Extensions.ARB_instanced_arrays) {
2726 _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", func);
2727 return;
2728 }
2729
2730 /* The ARB_vertex_attrib_binding spec says:
2731 *
2732 * "An INVALID_VALUE error is generated if <bindingindex> is greater
2733 * than or equal to the value of MAX_VERTEX_ATTRIB_BINDINGS."
2734 */
2735 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2736 _mesa_error(ctx, GL_INVALID_VALUE,
2737 "%s(bindingindex=%u > "
2738 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2739 func, bindingIndex);
2740 return;
2741 }
2742
2743 vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2744 }
2745
2746
2747 void GLAPIENTRY
2748 _mesa_VertexBindingDivisor_no_error(GLuint bindingIndex, GLuint divisor)
2749 {
2750 GET_CURRENT_CONTEXT(ctx);
2751 vertex_binding_divisor(ctx, ctx->Array.VAO,
2752 VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2753 }
2754
2755
2756 void GLAPIENTRY
2757 _mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
2758 {
2759 GET_CURRENT_CONTEXT(ctx);
2760
2761 /* The ARB_vertex_attrib_binding spec says:
2762 *
2763 * "An INVALID_OPERATION error is generated if no vertex array object
2764 * is bound."
2765 */
2766 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2767 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2768 _mesa_error(ctx, GL_INVALID_OPERATION,
2769 "glVertexBindingDivisor(No array object bound)");
2770 return;
2771 }
2772
2773 vertex_array_binding_divisor(ctx, ctx->Array.VAO,
2774 bindingIndex, divisor,
2775 "glVertexBindingDivisor");
2776 }
2777
2778
2779 void GLAPIENTRY
2780 _mesa_VertexArrayBindingDivisor_no_error(GLuint vaobj, GLuint bindingIndex,
2781 GLuint divisor)
2782 {
2783 GET_CURRENT_CONTEXT(ctx);
2784
2785 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2786 vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2787 }
2788
2789
2790 void GLAPIENTRY
2791 _mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex,
2792 GLuint divisor)
2793 {
2794 struct gl_vertex_array_object *vao;
2795 GET_CURRENT_CONTEXT(ctx);
2796
2797 /* The ARB_direct_state_access specification says:
2798 *
2799 * "An INVALID_OPERATION error is generated by VertexArrayBindingDivisor
2800 * if <vaobj> is not [compatibility profile: zero or] the name of an
2801 * existing vertex array object."
2802 */
2803 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayBindingDivisor");
2804 if (!vao)
2805 return;
2806
2807 vertex_array_binding_divisor(ctx, vao, bindingIndex, divisor,
2808 "glVertexArrayBindingDivisor");
2809 }
2810
2811
2812 void
2813 _mesa_copy_vertex_attrib_array(struct gl_context *ctx,
2814 struct gl_array_attributes *dst,
2815 const struct gl_array_attributes *src)
2816 {
2817 dst->Size = src->Size;
2818 dst->Type = src->Type;
2819 dst->Format = src->Format;
2820 dst->BufferBindingIndex = src->BufferBindingIndex;
2821 dst->RelativeOffset = src->RelativeOffset;
2822 dst->Format = src->Format;
2823 dst->Integer = src->Integer;
2824 dst->Doubles = src->Doubles;
2825 dst->Normalized = src->Normalized;
2826 dst->Ptr = src->Ptr;
2827 dst->Enabled = src->Enabled;
2828 dst->_ElementSize = src->_ElementSize;
2829 dst->_EffBufferBindingIndex = src->_EffBufferBindingIndex;
2830 dst->_EffRelativeOffset = src->_EffRelativeOffset;
2831 }
2832
2833 void
2834 _mesa_copy_vertex_buffer_binding(struct gl_context *ctx,
2835 struct gl_vertex_buffer_binding *dst,
2836 const struct gl_vertex_buffer_binding *src)
2837 {
2838 dst->Offset = src->Offset;
2839 dst->Stride = src->Stride;
2840 dst->InstanceDivisor = src->InstanceDivisor;
2841 dst->_BoundArrays = src->_BoundArrays;
2842 dst->_EffBoundArrays = src->_EffBoundArrays;
2843 dst->_EffOffset = src->_EffOffset;
2844
2845 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
2846 }
2847
2848 /**
2849 * Print current vertex object/array info. For debug.
2850 */
2851 void
2852 _mesa_print_arrays(struct gl_context *ctx)
2853 {
2854 const struct gl_vertex_array_object *vao = ctx->Array.VAO;
2855
2856 fprintf(stderr, "Array Object %u\n", vao->Name);
2857
2858 gl_vert_attrib i;
2859 for (i = 0; i < VERT_ATTRIB_MAX; ++i) {
2860 const struct gl_array_attributes *array = &vao->VertexAttrib[i];
2861 if (!array->Enabled)
2862 continue;
2863
2864 const struct gl_vertex_buffer_binding *binding =
2865 &vao->BufferBinding[array->BufferBindingIndex];
2866 const struct gl_buffer_object *bo = binding->BufferObj;
2867
2868 fprintf(stderr, " %s: Ptr=%p, Type=%s, Size=%d, ElemSize=%u, "
2869 "Stride=%d, Buffer=%u(Size %lu)\n",
2870 gl_vert_attrib_name((gl_vert_attrib)i),
2871 array->Ptr, _mesa_enum_to_string(array->Type), array->Size,
2872 array->_ElementSize, binding->Stride, bo->Name,
2873 (unsigned long) bo->Size);
2874 }
2875 }
2876
2877
2878 /**
2879 * Initialize vertex array state for given context.
2880 */
2881 void
2882 _mesa_init_varray(struct gl_context *ctx)
2883 {
2884 ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0);
2885 _mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO);
2886 ctx->Array._EmptyVAO = _mesa_new_vao(ctx, ~0u);
2887 _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, ctx->Array._EmptyVAO);
2888 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
2889
2890 ctx->Array.Objects = _mesa_NewHashTable();
2891 }
2892
2893
2894 /**
2895 * Callback for deleting an array object. Called by _mesa_HashDeleteAll().
2896 */
2897 static void
2898 delete_arrayobj_cb(GLuint id, void *data, void *userData)
2899 {
2900 struct gl_vertex_array_object *vao = (struct gl_vertex_array_object *) data;
2901 struct gl_context *ctx = (struct gl_context *) userData;
2902 _mesa_delete_vao(ctx, vao);
2903 }
2904
2905
2906 /**
2907 * Free vertex array state for given context.
2908 */
2909 void
2910 _mesa_free_varray_data(struct gl_context *ctx)
2911 {
2912 _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx);
2913 _mesa_DeleteHashTable(ctx->Array.Objects);
2914 }