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