mesa: add EXT_dsa glMultiTexParameter* functions
[mesa.git] / src / mesa / main / varray.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27 #include <stdio.h>
28 #include <inttypes.h> /* for PRId64 macro */
29
30 #include "glheader.h"
31 #include "imports.h"
32 #include "bufferobj.h"
33 #include "context.h"
34 #include "enable.h"
35 #include "enums.h"
36 #include "glformats.h"
37 #include "hash.h"
38 #include "image.h"
39 #include "macros.h"
40 #include "mtypes.h"
41 #include "varray.h"
42 #include "arrayobj.h"
43 #include "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_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
1678 {
1679 (void) count;
1680 _mesa_EdgeFlagPointer(stride, ptr);
1681 }
1682
1683
1684 void GLAPIENTRY
1685 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
1686 {
1687 GET_CURRENT_CONTEXT(ctx);
1688 GLboolean tflag, cflag, nflag; /* enable/disable flags */
1689 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
1690 GLenum ctype = 0; /* color type */
1691 GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
1692 const GLint toffset = 0; /* always zero */
1693 GLint defstride; /* default stride */
1694 GLint c, f;
1695
1696 f = sizeof(GLfloat);
1697 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
1698
1699 if (stride < 0) {
1700 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
1701 return;
1702 }
1703
1704 switch (format) {
1705 case GL_V2F:
1706 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1707 tcomps = 0; ccomps = 0; vcomps = 2;
1708 voffset = 0;
1709 defstride = 2*f;
1710 break;
1711 case GL_V3F:
1712 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1713 tcomps = 0; ccomps = 0; vcomps = 3;
1714 voffset = 0;
1715 defstride = 3*f;
1716 break;
1717 case GL_C4UB_V2F:
1718 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1719 tcomps = 0; ccomps = 4; vcomps = 2;
1720 ctype = GL_UNSIGNED_BYTE;
1721 coffset = 0;
1722 voffset = c;
1723 defstride = c + 2*f;
1724 break;
1725 case GL_C4UB_V3F:
1726 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1727 tcomps = 0; ccomps = 4; vcomps = 3;
1728 ctype = GL_UNSIGNED_BYTE;
1729 coffset = 0;
1730 voffset = c;
1731 defstride = c + 3*f;
1732 break;
1733 case GL_C3F_V3F:
1734 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1735 tcomps = 0; ccomps = 3; vcomps = 3;
1736 ctype = GL_FLOAT;
1737 coffset = 0;
1738 voffset = 3*f;
1739 defstride = 6*f;
1740 break;
1741 case GL_N3F_V3F:
1742 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
1743 tcomps = 0; ccomps = 0; vcomps = 3;
1744 noffset = 0;
1745 voffset = 3*f;
1746 defstride = 6*f;
1747 break;
1748 case GL_C4F_N3F_V3F:
1749 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
1750 tcomps = 0; ccomps = 4; vcomps = 3;
1751 ctype = GL_FLOAT;
1752 coffset = 0;
1753 noffset = 4*f;
1754 voffset = 7*f;
1755 defstride = 10*f;
1756 break;
1757 case GL_T2F_V3F:
1758 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1759 tcomps = 2; ccomps = 0; vcomps = 3;
1760 voffset = 2*f;
1761 defstride = 5*f;
1762 break;
1763 case GL_T4F_V4F:
1764 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1765 tcomps = 4; ccomps = 0; vcomps = 4;
1766 voffset = 4*f;
1767 defstride = 8*f;
1768 break;
1769 case GL_T2F_C4UB_V3F:
1770 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1771 tcomps = 2; ccomps = 4; vcomps = 3;
1772 ctype = GL_UNSIGNED_BYTE;
1773 coffset = 2*f;
1774 voffset = c+2*f;
1775 defstride = c+5*f;
1776 break;
1777 case GL_T2F_C3F_V3F:
1778 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1779 tcomps = 2; ccomps = 3; vcomps = 3;
1780 ctype = GL_FLOAT;
1781 coffset = 2*f;
1782 voffset = 5*f;
1783 defstride = 8*f;
1784 break;
1785 case GL_T2F_N3F_V3F:
1786 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
1787 tcomps = 2; ccomps = 0; vcomps = 3;
1788 noffset = 2*f;
1789 voffset = 5*f;
1790 defstride = 8*f;
1791 break;
1792 case GL_T2F_C4F_N3F_V3F:
1793 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1794 tcomps = 2; ccomps = 4; vcomps = 3;
1795 ctype = GL_FLOAT;
1796 coffset = 2*f;
1797 noffset = 6*f;
1798 voffset = 9*f;
1799 defstride = 12*f;
1800 break;
1801 case GL_T4F_C4F_N3F_V4F:
1802 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1803 tcomps = 4; ccomps = 4; vcomps = 4;
1804 ctype = GL_FLOAT;
1805 coffset = 4*f;
1806 noffset = 8*f;
1807 voffset = 11*f;
1808 defstride = 15*f;
1809 break;
1810 default:
1811 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
1812 return;
1813 }
1814
1815 if (stride==0) {
1816 stride = defstride;
1817 }
1818
1819 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
1820 _mesa_DisableClientState( GL_INDEX_ARRAY );
1821 /* XXX also disable secondary color and generic arrays? */
1822
1823 /* Texcoords */
1824 if (tflag) {
1825 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
1826 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
1827 (GLubyte *) pointer + toffset );
1828 }
1829 else {
1830 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
1831 }
1832
1833 /* Color */
1834 if (cflag) {
1835 _mesa_EnableClientState( GL_COLOR_ARRAY );
1836 _mesa_ColorPointer( ccomps, ctype, stride,
1837 (GLubyte *) pointer + coffset );
1838 }
1839 else {
1840 _mesa_DisableClientState( GL_COLOR_ARRAY );
1841 }
1842
1843
1844 /* Normals */
1845 if (nflag) {
1846 _mesa_EnableClientState( GL_NORMAL_ARRAY );
1847 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset );
1848 }
1849 else {
1850 _mesa_DisableClientState( GL_NORMAL_ARRAY );
1851 }
1852
1853 /* Vertices */
1854 _mesa_EnableClientState( GL_VERTEX_ARRAY );
1855 _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
1856 (GLubyte *) pointer + voffset );
1857 }
1858
1859
1860 void GLAPIENTRY
1861 _mesa_LockArraysEXT(GLint first, GLsizei count)
1862 {
1863 GET_CURRENT_CONTEXT(ctx);
1864
1865 if (MESA_VERBOSE & VERBOSE_API)
1866 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
1867
1868 if (first < 0) {
1869 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" );
1870 return;
1871 }
1872 if (count <= 0) {
1873 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" );
1874 return;
1875 }
1876 if (ctx->Array.LockCount != 0) {
1877 _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" );
1878 return;
1879 }
1880
1881 ctx->Array.LockFirst = first;
1882 ctx->Array.LockCount = count;
1883 }
1884
1885
1886 void GLAPIENTRY
1887 _mesa_UnlockArraysEXT( void )
1888 {
1889 GET_CURRENT_CONTEXT(ctx);
1890
1891 if (MESA_VERBOSE & VERBOSE_API)
1892 _mesa_debug(ctx, "glUnlockArrays\n");
1893
1894 if (ctx->Array.LockCount == 0) {
1895 _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" );
1896 return;
1897 }
1898
1899 ctx->Array.LockFirst = 0;
1900 ctx->Array.LockCount = 0;
1901 }
1902
1903
1904 static void
1905 primitive_restart_index(struct gl_context *ctx, GLuint index)
1906 {
1907 ctx->Array.RestartIndex = index;
1908 }
1909
1910
1911 /**
1912 * GL_NV_primitive_restart and GL 3.1
1913 */
1914 void GLAPIENTRY
1915 _mesa_PrimitiveRestartIndex_no_error(GLuint index)
1916 {
1917 GET_CURRENT_CONTEXT(ctx);
1918 primitive_restart_index(ctx, index);
1919 }
1920
1921
1922 void GLAPIENTRY
1923 _mesa_PrimitiveRestartIndex(GLuint index)
1924 {
1925 GET_CURRENT_CONTEXT(ctx);
1926
1927 if (!ctx->Extensions.NV_primitive_restart && ctx->Version < 31) {
1928 _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()");
1929 return;
1930 }
1931
1932 primitive_restart_index(ctx, index);
1933 }
1934
1935
1936 void GLAPIENTRY
1937 _mesa_VertexAttribDivisor_no_error(GLuint index, GLuint divisor)
1938 {
1939 GET_CURRENT_CONTEXT(ctx);
1940
1941 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index);
1942 struct gl_vertex_array_object * const vao = ctx->Array.VAO;
1943
1944 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
1945
1946 /* The ARB_vertex_attrib_binding spec says:
1947 *
1948 * "The command
1949 *
1950 * void VertexAttribDivisor(uint index, uint divisor);
1951 *
1952 * is equivalent to (assuming no errors are generated):
1953 *
1954 * VertexAttribBinding(index, index);
1955 * VertexBindingDivisor(index, divisor);"
1956 */
1957 _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
1958 vertex_binding_divisor(ctx, vao, genericIndex, divisor);
1959 }
1960
1961
1962 /**
1963 * See GL_ARB_instanced_arrays.
1964 * Note that the instance divisor only applies to generic arrays, not
1965 * the legacy vertex arrays.
1966 */
1967 void GLAPIENTRY
1968 _mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
1969 {
1970 GET_CURRENT_CONTEXT(ctx);
1971
1972 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index);
1973 struct gl_vertex_array_object * const vao = ctx->Array.VAO;
1974
1975 if (!ctx->Extensions.ARB_instanced_arrays) {
1976 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
1977 return;
1978 }
1979
1980 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1981 _mesa_error(ctx, GL_INVALID_VALUE,
1982 "glVertexAttribDivisor(index = %u)", index);
1983 return;
1984 }
1985
1986 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
1987
1988 /* The ARB_vertex_attrib_binding spec says:
1989 *
1990 * "The command
1991 *
1992 * void VertexAttribDivisor(uint index, uint divisor);
1993 *
1994 * is equivalent to (assuming no errors are generated):
1995 *
1996 * VertexAttribBinding(index, index);
1997 * VertexBindingDivisor(index, divisor);"
1998 */
1999 _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
2000 vertex_binding_divisor(ctx, vao, genericIndex, divisor);
2001 }
2002
2003
2004 static ALWAYS_INLINE void
2005 vertex_array_vertex_buffer(struct gl_context *ctx,
2006 struct gl_vertex_array_object *vao,
2007 GLuint bindingIndex, GLuint buffer, GLintptr offset,
2008 GLsizei stride, bool no_error, const char *func)
2009 {
2010 struct gl_buffer_object *vbo;
2011 if (buffer ==
2012 vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj->Name) {
2013 vbo = vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj;
2014 } else if (buffer != 0) {
2015 vbo = _mesa_lookup_bufferobj(ctx, buffer);
2016
2017 if (!no_error && !vbo && _mesa_is_gles31(ctx)) {
2018 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", func);
2019 return;
2020 }
2021 /* From the GL_ARB_vertex_attrib_array spec:
2022 *
2023 * "[Core profile only:]
2024 * An INVALID_OPERATION error is generated if buffer is not zero or a
2025 * name returned from a previous call to GenBuffers, or if such a name
2026 * has since been deleted with DeleteBuffers.
2027 *
2028 * Otherwise, we fall back to the same compat profile behavior as other
2029 * object references (automatically gen it).
2030 */
2031 if (!_mesa_handle_bind_buffer_gen(ctx, buffer, &vbo, func))
2032 return;
2033 } else {
2034 /* The ARB_vertex_attrib_binding spec says:
2035 *
2036 * "If <buffer> is zero, any buffer object attached to this
2037 * bindpoint is detached."
2038 */
2039 vbo = ctx->Shared->NullBufferObj;
2040 }
2041
2042 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex),
2043 vbo, offset, stride);
2044 }
2045
2046
2047 /**
2048 * GL_ARB_vertex_attrib_binding
2049 */
2050 static void
2051 vertex_array_vertex_buffer_err(struct gl_context *ctx,
2052 struct gl_vertex_array_object *vao,
2053 GLuint bindingIndex, GLuint buffer,
2054 GLintptr offset, GLsizei stride,
2055 const char *func)
2056 {
2057 ASSERT_OUTSIDE_BEGIN_END(ctx);
2058
2059 /* The ARB_vertex_attrib_binding spec says:
2060 *
2061 * "An INVALID_VALUE error is generated if <bindingindex> is greater than
2062 * the value of MAX_VERTEX_ATTRIB_BINDINGS."
2063 */
2064 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2065 _mesa_error(ctx, GL_INVALID_VALUE,
2066 "%s(bindingindex=%u > "
2067 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2068 func, bindingIndex);
2069 return;
2070 }
2071
2072 /* The ARB_vertex_attrib_binding spec says:
2073 *
2074 * "The error INVALID_VALUE is generated if <stride> or <offset>
2075 * are negative."
2076 */
2077 if (offset < 0) {
2078 _mesa_error(ctx, GL_INVALID_VALUE,
2079 "%s(offset=%" PRId64 " < 0)",
2080 func, (int64_t) offset);
2081 return;
2082 }
2083
2084 if (stride < 0) {
2085 _mesa_error(ctx, GL_INVALID_VALUE,
2086 "%s(stride=%d < 0)", func, stride);
2087 return;
2088 }
2089
2090 if (((_mesa_is_desktop_gl(ctx) && ctx->Version >= 44) || _mesa_is_gles31(ctx)) &&
2091 stride > ctx->Const.MaxVertexAttribStride) {
2092 _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > "
2093 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride);
2094 return;
2095 }
2096
2097 vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset,
2098 stride, false, func);
2099 }
2100
2101
2102 void GLAPIENTRY
2103 _mesa_BindVertexBuffer_no_error(GLuint bindingIndex, GLuint buffer,
2104 GLintptr offset, GLsizei stride)
2105 {
2106 GET_CURRENT_CONTEXT(ctx);
2107 vertex_array_vertex_buffer(ctx, ctx->Array.VAO, bindingIndex,
2108 buffer, offset, stride, true,
2109 "glBindVertexBuffer");
2110 }
2111
2112
2113 void GLAPIENTRY
2114 _mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset,
2115 GLsizei stride)
2116 {
2117 GET_CURRENT_CONTEXT(ctx);
2118
2119 /* The ARB_vertex_attrib_binding spec says:
2120 *
2121 * "An INVALID_OPERATION error is generated if no vertex array object
2122 * is bound."
2123 */
2124 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2125 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2126 _mesa_error(ctx, GL_INVALID_OPERATION,
2127 "glBindVertexBuffer(No array object bound)");
2128 return;
2129 }
2130
2131 vertex_array_vertex_buffer_err(ctx, ctx->Array.VAO, bindingIndex,
2132 buffer, offset, stride,
2133 "glBindVertexBuffer");
2134 }
2135
2136
2137 void GLAPIENTRY
2138 _mesa_VertexArrayVertexBuffer_no_error(GLuint vaobj, GLuint bindingIndex,
2139 GLuint buffer, GLintptr offset,
2140 GLsizei stride)
2141 {
2142 GET_CURRENT_CONTEXT(ctx);
2143
2144 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2145 vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset,
2146 stride, true, "glVertexArrayVertexBuffer");
2147 }
2148
2149
2150 void GLAPIENTRY
2151 _mesa_VertexArrayVertexBuffer(GLuint vaobj, GLuint bindingIndex, GLuint buffer,
2152 GLintptr offset, GLsizei stride)
2153 {
2154 GET_CURRENT_CONTEXT(ctx);
2155 struct gl_vertex_array_object *vao;
2156
2157 /* The ARB_direct_state_access specification says:
2158 *
2159 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
2160 * if <vaobj> is not [compatibility profile: zero or] the name of an
2161 * existing vertex array object."
2162 */
2163 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffer");
2164 if (!vao)
2165 return;
2166
2167 vertex_array_vertex_buffer_err(ctx, vao, bindingIndex, buffer, offset,
2168 stride, "glVertexArrayVertexBuffer");
2169 }
2170
2171
2172 static ALWAYS_INLINE void
2173 vertex_array_vertex_buffers(struct gl_context *ctx,
2174 struct gl_vertex_array_object *vao,
2175 GLuint first, GLsizei count, const GLuint *buffers,
2176 const GLintptr *offsets, const GLsizei *strides,
2177 bool no_error, const char *func)
2178 {
2179 GLint i;
2180
2181 if (!buffers) {
2182 /**
2183 * The ARB_multi_bind spec says:
2184 *
2185 * "If <buffers> is NULL, each affected vertex buffer binding point
2186 * from <first> through <first>+<count>-1 will be reset to have no
2187 * bound buffer object. In this case, the offsets and strides
2188 * associated with the binding points are set to default values,
2189 * ignoring <offsets> and <strides>."
2190 */
2191 struct gl_buffer_object *vbo = ctx->Shared->NullBufferObj;
2192
2193 for (i = 0; i < count; i++)
2194 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
2195 vbo, 0, 16);
2196
2197 return;
2198 }
2199
2200 /* Note that the error semantics for multi-bind commands differ from
2201 * those of other GL commands.
2202 *
2203 * The Issues section in the ARB_multi_bind spec says:
2204 *
2205 * "(11) Typically, OpenGL specifies that if an error is generated by
2206 * a command, that command has no effect. This is somewhat
2207 * unfortunate for multi-bind commands, because it would require
2208 * a first pass to scan the entire list of bound objects for
2209 * errors and then a second pass to actually perform the
2210 * bindings. Should we have different error semantics?
2211 *
2212 * RESOLVED: Yes. In this specification, when the parameters for
2213 * one of the <count> binding points are invalid, that binding
2214 * point is not updated and an error will be generated. However,
2215 * other binding points in the same command will be updated if
2216 * their parameters are valid and no other error occurs."
2217 */
2218
2219 _mesa_HashLockMutex(ctx->Shared->BufferObjects);
2220
2221 for (i = 0; i < count; i++) {
2222 struct gl_buffer_object *vbo;
2223
2224 if (!no_error) {
2225 /* The ARB_multi_bind spec says:
2226 *
2227 * "An INVALID_VALUE error is generated if any value in
2228 * <offsets> or <strides> is negative (per binding)."
2229 */
2230 if (offsets[i] < 0) {
2231 _mesa_error(ctx, GL_INVALID_VALUE,
2232 "%s(offsets[%u]=%" PRId64 " < 0)",
2233 func, i, (int64_t) offsets[i]);
2234 continue;
2235 }
2236
2237 if (strides[i] < 0) {
2238 _mesa_error(ctx, GL_INVALID_VALUE,
2239 "%s(strides[%u]=%d < 0)",
2240 func, i, strides[i]);
2241 continue;
2242 }
2243
2244 if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 44 &&
2245 strides[i] > ctx->Const.MaxVertexAttribStride) {
2246 _mesa_error(ctx, GL_INVALID_VALUE,
2247 "%s(strides[%u]=%d > "
2248 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, i, strides[i]);
2249 continue;
2250 }
2251 }
2252
2253 if (buffers[i]) {
2254 struct gl_vertex_buffer_binding *binding =
2255 &vao->BufferBinding[VERT_ATTRIB_GENERIC(first + i)];
2256
2257 if (buffers[i] == binding->BufferObj->Name)
2258 vbo = binding->BufferObj;
2259 else
2260 vbo = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, func);
2261
2262 if (!vbo)
2263 continue;
2264 } else {
2265 vbo = ctx->Shared->NullBufferObj;
2266 }
2267
2268 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
2269 vbo, offsets[i], strides[i]);
2270 }
2271
2272 _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
2273 }
2274
2275
2276 static void
2277 vertex_array_vertex_buffers_err(struct gl_context *ctx,
2278 struct gl_vertex_array_object *vao,
2279 GLuint first, GLsizei count,
2280 const GLuint *buffers, const GLintptr *offsets,
2281 const GLsizei *strides, const char *func)
2282 {
2283 ASSERT_OUTSIDE_BEGIN_END(ctx);
2284
2285 /* The ARB_multi_bind spec says:
2286 *
2287 * "An INVALID_OPERATION error is generated if <first> + <count>
2288 * is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS."
2289 */
2290 if (first + count > ctx->Const.MaxVertexAttribBindings) {
2291 _mesa_error(ctx, GL_INVALID_OPERATION,
2292 "%s(first=%u + count=%d > the value of "
2293 "GL_MAX_VERTEX_ATTRIB_BINDINGS=%u)",
2294 func, first, count, ctx->Const.MaxVertexAttribBindings);
2295 return;
2296 }
2297
2298 vertex_array_vertex_buffers(ctx, vao, first, count, buffers, offsets,
2299 strides, false, func);
2300 }
2301
2302
2303 void GLAPIENTRY
2304 _mesa_BindVertexBuffers_no_error(GLuint first, GLsizei count,
2305 const GLuint *buffers, const GLintptr *offsets,
2306 const GLsizei *strides)
2307 {
2308 GET_CURRENT_CONTEXT(ctx);
2309
2310 vertex_array_vertex_buffers(ctx, ctx->Array.VAO, first, count,
2311 buffers, offsets, strides, true,
2312 "glBindVertexBuffers");
2313 }
2314
2315
2316 void GLAPIENTRY
2317 _mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers,
2318 const GLintptr *offsets, const GLsizei *strides)
2319 {
2320 GET_CURRENT_CONTEXT(ctx);
2321
2322 /* The ARB_vertex_attrib_binding spec says:
2323 *
2324 * "An INVALID_OPERATION error is generated if no
2325 * vertex array object is bound."
2326 */
2327 if (ctx->API == API_OPENGL_CORE &&
2328 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2329 _mesa_error(ctx, GL_INVALID_OPERATION,
2330 "glBindVertexBuffers(No array object bound)");
2331 return;
2332 }
2333
2334 vertex_array_vertex_buffers_err(ctx, ctx->Array.VAO, first, count,
2335 buffers, offsets, strides,
2336 "glBindVertexBuffers");
2337 }
2338
2339
2340 void GLAPIENTRY
2341 _mesa_VertexArrayVertexBuffers_no_error(GLuint vaobj, GLuint first,
2342 GLsizei count, const GLuint *buffers,
2343 const GLintptr *offsets,
2344 const GLsizei *strides)
2345 {
2346 GET_CURRENT_CONTEXT(ctx);
2347
2348 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2349 vertex_array_vertex_buffers(ctx, vao, first, count,
2350 buffers, offsets, strides, true,
2351 "glVertexArrayVertexBuffers");
2352 }
2353
2354
2355 void GLAPIENTRY
2356 _mesa_VertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count,
2357 const GLuint *buffers,
2358 const GLintptr *offsets, const GLsizei *strides)
2359 {
2360 GET_CURRENT_CONTEXT(ctx);
2361 struct gl_vertex_array_object *vao;
2362
2363 /* The ARB_direct_state_access specification says:
2364 *
2365 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
2366 * if <vaobj> is not [compatibility profile: zero or] the name of an
2367 * existing vertex array object."
2368 */
2369 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayVertexBuffers");
2370 if (!vao)
2371 return;
2372
2373 vertex_array_vertex_buffers_err(ctx, vao, first, count,
2374 buffers, offsets, strides,
2375 "glVertexArrayVertexBuffers");
2376 }
2377
2378
2379 static void
2380 vertex_attrib_format(GLuint attribIndex, GLint size, GLenum type,
2381 GLboolean normalized, GLboolean integer,
2382 GLboolean doubles, GLbitfield legalTypes,
2383 GLsizei sizeMax, GLuint relativeOffset,
2384 const char *func)
2385 {
2386 GET_CURRENT_CONTEXT(ctx);
2387 ASSERT_OUTSIDE_BEGIN_END(ctx);
2388
2389 GLenum format = get_array_format(ctx, sizeMax, &size);
2390
2391 if (!_mesa_is_no_error_enabled(ctx)) {
2392 /* The ARB_vertex_attrib_binding spec says:
2393 *
2394 * "An INVALID_OPERATION error is generated under any of the
2395 * following conditions:
2396 * - if no vertex array object is currently bound (see section
2397 * 2.10);
2398 * - ..."
2399 *
2400 * This error condition only applies to VertexAttribFormat and
2401 * VertexAttribIFormat in the extension spec, but we assume that this
2402 * is an oversight. In the OpenGL 4.3 (Core Profile) spec, it applies
2403 * to all three functions.
2404 */
2405 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2406 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2407 _mesa_error(ctx, GL_INVALID_OPERATION,
2408 "%s(No array object bound)", func);
2409 return;
2410 }
2411
2412 /* The ARB_vertex_attrib_binding spec says:
2413 *
2414 * "The error INVALID_VALUE is generated if index is greater than or
2415 * equal to the value of MAX_VERTEX_ATTRIBS."
2416 */
2417 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2418 _mesa_error(ctx, GL_INVALID_VALUE,
2419 "%s(attribindex=%u > "
2420 "GL_MAX_VERTEX_ATTRIBS)",
2421 func, attribIndex);
2422 return;
2423 }
2424
2425 if (!validate_array_format(ctx, func, ctx->Array.VAO,
2426 VERT_ATTRIB_GENERIC(attribIndex),
2427 legalTypes, 1, sizeMax, size, type,
2428 normalized, integer, doubles, relativeOffset,
2429 format)) {
2430 return;
2431 }
2432 }
2433
2434 _mesa_update_array_format(ctx, ctx->Array.VAO,
2435 VERT_ATTRIB_GENERIC(attribIndex), size, type,
2436 format, normalized, integer, doubles,
2437 relativeOffset);
2438 }
2439
2440
2441 void GLAPIENTRY
2442 _mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type,
2443 GLboolean normalized, GLuint relativeOffset)
2444 {
2445 vertex_attrib_format(attribIndex, size, type, normalized,
2446 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
2447 BGRA_OR_4, relativeOffset,
2448 "glVertexAttribFormat");
2449 }
2450
2451
2452 void GLAPIENTRY
2453 _mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type,
2454 GLuint relativeOffset)
2455 {
2456 vertex_attrib_format(attribIndex, size, type, GL_FALSE,
2457 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK, 4,
2458 relativeOffset, "glVertexAttribIFormat");
2459 }
2460
2461
2462 void GLAPIENTRY
2463 _mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type,
2464 GLuint relativeOffset)
2465 {
2466 vertex_attrib_format(attribIndex, size, type, GL_FALSE, GL_FALSE,
2467 GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK, 4,
2468 relativeOffset, "glVertexAttribLFormat");
2469 }
2470
2471
2472 static void
2473 vertex_array_attrib_format(GLuint vaobj, GLuint attribIndex, GLint size,
2474 GLenum type, GLboolean normalized,
2475 GLboolean integer, GLboolean doubles,
2476 GLbitfield legalTypes, GLsizei sizeMax,
2477 GLuint relativeOffset, const char *func)
2478 {
2479 GET_CURRENT_CONTEXT(ctx);
2480 struct gl_vertex_array_object *vao;
2481
2482 ASSERT_OUTSIDE_BEGIN_END(ctx);
2483
2484 GLenum format = get_array_format(ctx, sizeMax, &size);
2485
2486 if (_mesa_is_no_error_enabled(ctx)) {
2487 vao = _mesa_lookup_vao(ctx, vaobj);
2488 if (!vao)
2489 return;
2490 } else {
2491 /* The ARB_direct_state_access spec says:
2492 *
2493 * "An INVALID_OPERATION error is generated by
2494 * VertexArrayAttrib*Format if <vaobj> is not [compatibility profile:
2495 * zero or] the name of an existing vertex array object."
2496 */
2497 vao = _mesa_lookup_vao_err(ctx, vaobj, func);
2498 if (!vao)
2499 return;
2500
2501 /* The ARB_vertex_attrib_binding spec says:
2502 *
2503 * "The error INVALID_VALUE is generated if index is greater than or
2504 * equal to the value of MAX_VERTEX_ATTRIBS."
2505 */
2506 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2507 _mesa_error(ctx, GL_INVALID_VALUE,
2508 "%s(attribindex=%u > GL_MAX_VERTEX_ATTRIBS)",
2509 func, attribIndex);
2510 return;
2511 }
2512
2513 if (!validate_array_format(ctx, func, vao,
2514 VERT_ATTRIB_GENERIC(attribIndex),
2515 legalTypes, 1, sizeMax, size, type,
2516 normalized, integer, doubles, relativeOffset,
2517 format)) {
2518 return;
2519 }
2520 }
2521
2522 _mesa_update_array_format(ctx, vao, VERT_ATTRIB_GENERIC(attribIndex), size,
2523 type, format, normalized, integer, doubles,
2524 relativeOffset);
2525 }
2526
2527
2528 void GLAPIENTRY
2529 _mesa_VertexArrayAttribFormat(GLuint vaobj, GLuint attribIndex, GLint size,
2530 GLenum type, GLboolean normalized,
2531 GLuint relativeOffset)
2532 {
2533 vertex_array_attrib_format(vaobj, attribIndex, size, type, normalized,
2534 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
2535 BGRA_OR_4, relativeOffset,
2536 "glVertexArrayAttribFormat");
2537 }
2538
2539
2540 void GLAPIENTRY
2541 _mesa_VertexArrayAttribIFormat(GLuint vaobj, GLuint attribIndex,
2542 GLint size, GLenum type,
2543 GLuint relativeOffset)
2544 {
2545 vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE,
2546 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK,
2547 4, relativeOffset,
2548 "glVertexArrayAttribIFormat");
2549 }
2550
2551
2552 void GLAPIENTRY
2553 _mesa_VertexArrayAttribLFormat(GLuint vaobj, GLuint attribIndex,
2554 GLint size, GLenum type,
2555 GLuint relativeOffset)
2556 {
2557 vertex_array_attrib_format(vaobj, attribIndex, size, type, GL_FALSE,
2558 GL_FALSE, GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK,
2559 4, relativeOffset,
2560 "glVertexArrayAttribLFormat");
2561 }
2562
2563
2564 static void
2565 vertex_array_attrib_binding(struct gl_context *ctx,
2566 struct gl_vertex_array_object *vao,
2567 GLuint attribIndex, GLuint bindingIndex,
2568 const char *func)
2569 {
2570 ASSERT_OUTSIDE_BEGIN_END(ctx);
2571
2572 /* The ARB_vertex_attrib_binding spec says:
2573 *
2574 * "<attribindex> must be less than the value of MAX_VERTEX_ATTRIBS and
2575 * <bindingindex> must be less than the value of
2576 * MAX_VERTEX_ATTRIB_BINDINGS, otherwise the error INVALID_VALUE
2577 * is generated."
2578 */
2579 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2580 _mesa_error(ctx, GL_INVALID_VALUE,
2581 "%s(attribindex=%u >= "
2582 "GL_MAX_VERTEX_ATTRIBS)",
2583 func, attribIndex);
2584 return;
2585 }
2586
2587 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2588 _mesa_error(ctx, GL_INVALID_VALUE,
2589 "%s(bindingindex=%u >= "
2590 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2591 func, bindingIndex);
2592 return;
2593 }
2594
2595 assert(VERT_ATTRIB_GENERIC(attribIndex) < ARRAY_SIZE(vao->VertexAttrib));
2596
2597 _mesa_vertex_attrib_binding(ctx, vao,
2598 VERT_ATTRIB_GENERIC(attribIndex),
2599 VERT_ATTRIB_GENERIC(bindingIndex));
2600 }
2601
2602
2603 void GLAPIENTRY
2604 _mesa_VertexAttribBinding_no_error(GLuint attribIndex, GLuint bindingIndex)
2605 {
2606 GET_CURRENT_CONTEXT(ctx);
2607 _mesa_vertex_attrib_binding(ctx, ctx->Array.VAO,
2608 VERT_ATTRIB_GENERIC(attribIndex),
2609 VERT_ATTRIB_GENERIC(bindingIndex));
2610 }
2611
2612
2613 void GLAPIENTRY
2614 _mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
2615 {
2616 GET_CURRENT_CONTEXT(ctx);
2617
2618 /* The ARB_vertex_attrib_binding spec says:
2619 *
2620 * "An INVALID_OPERATION error is generated if no vertex array object
2621 * is bound."
2622 */
2623 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2624 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2625 _mesa_error(ctx, GL_INVALID_OPERATION,
2626 "glVertexAttribBinding(No array object bound)");
2627 return;
2628 }
2629
2630 vertex_array_attrib_binding(ctx, ctx->Array.VAO,
2631 attribIndex, bindingIndex,
2632 "glVertexAttribBinding");
2633 }
2634
2635
2636 void GLAPIENTRY
2637 _mesa_VertexArrayAttribBinding_no_error(GLuint vaobj, GLuint attribIndex,
2638 GLuint bindingIndex)
2639 {
2640 GET_CURRENT_CONTEXT(ctx);
2641
2642 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2643 _mesa_vertex_attrib_binding(ctx, vao,
2644 VERT_ATTRIB_GENERIC(attribIndex),
2645 VERT_ATTRIB_GENERIC(bindingIndex));
2646 }
2647
2648
2649 void GLAPIENTRY
2650 _mesa_VertexArrayAttribBinding(GLuint vaobj, GLuint attribIndex, GLuint bindingIndex)
2651 {
2652 GET_CURRENT_CONTEXT(ctx);
2653 struct gl_vertex_array_object *vao;
2654
2655 /* The ARB_direct_state_access specification says:
2656 *
2657 * "An INVALID_OPERATION error is generated by VertexArrayAttribBinding
2658 * if <vaobj> is not [compatibility profile: zero or] the name of an
2659 * existing vertex array object."
2660 */
2661 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayAttribBinding");
2662 if (!vao)
2663 return;
2664
2665 vertex_array_attrib_binding(ctx, vao, attribIndex, bindingIndex,
2666 "glVertexArrayAttribBinding");
2667 }
2668
2669
2670 static void
2671 vertex_array_binding_divisor(struct gl_context *ctx,
2672 struct gl_vertex_array_object *vao,
2673 GLuint bindingIndex, GLuint divisor,
2674 const char *func)
2675 {
2676 ASSERT_OUTSIDE_BEGIN_END(ctx);
2677
2678 if (!ctx->Extensions.ARB_instanced_arrays) {
2679 _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", func);
2680 return;
2681 }
2682
2683 /* The ARB_vertex_attrib_binding spec says:
2684 *
2685 * "An INVALID_VALUE error is generated if <bindingindex> is greater
2686 * than or equal to the value of MAX_VERTEX_ATTRIB_BINDINGS."
2687 */
2688 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2689 _mesa_error(ctx, GL_INVALID_VALUE,
2690 "%s(bindingindex=%u > "
2691 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2692 func, bindingIndex);
2693 return;
2694 }
2695
2696 vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2697 }
2698
2699
2700 void GLAPIENTRY
2701 _mesa_VertexBindingDivisor_no_error(GLuint bindingIndex, GLuint divisor)
2702 {
2703 GET_CURRENT_CONTEXT(ctx);
2704 vertex_binding_divisor(ctx, ctx->Array.VAO,
2705 VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2706 }
2707
2708
2709 void GLAPIENTRY
2710 _mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
2711 {
2712 GET_CURRENT_CONTEXT(ctx);
2713
2714 /* The ARB_vertex_attrib_binding spec says:
2715 *
2716 * "An INVALID_OPERATION error is generated if no vertex array object
2717 * is bound."
2718 */
2719 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2720 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2721 _mesa_error(ctx, GL_INVALID_OPERATION,
2722 "glVertexBindingDivisor(No array object bound)");
2723 return;
2724 }
2725
2726 vertex_array_binding_divisor(ctx, ctx->Array.VAO,
2727 bindingIndex, divisor,
2728 "glVertexBindingDivisor");
2729 }
2730
2731
2732 void GLAPIENTRY
2733 _mesa_VertexArrayBindingDivisor_no_error(GLuint vaobj, GLuint bindingIndex,
2734 GLuint divisor)
2735 {
2736 GET_CURRENT_CONTEXT(ctx);
2737
2738 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2739 vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
2740 }
2741
2742
2743 void GLAPIENTRY
2744 _mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex,
2745 GLuint divisor)
2746 {
2747 struct gl_vertex_array_object *vao;
2748 GET_CURRENT_CONTEXT(ctx);
2749
2750 /* The ARB_direct_state_access specification says:
2751 *
2752 * "An INVALID_OPERATION error is generated by VertexArrayBindingDivisor
2753 * if <vaobj> is not [compatibility profile: zero or] the name of an
2754 * existing vertex array object."
2755 */
2756 vao = _mesa_lookup_vao_err(ctx, vaobj, "glVertexArrayBindingDivisor");
2757 if (!vao)
2758 return;
2759
2760 vertex_array_binding_divisor(ctx, vao, bindingIndex, divisor,
2761 "glVertexArrayBindingDivisor");
2762 }
2763
2764
2765 void
2766 _mesa_copy_vertex_attrib_array(struct gl_context *ctx,
2767 struct gl_array_attributes *dst,
2768 const struct gl_array_attributes *src)
2769 {
2770 dst->Ptr = src->Ptr;
2771 dst->RelativeOffset = src->RelativeOffset;
2772 dst->Format = src->Format;
2773 dst->Stride = src->Stride;
2774 dst->BufferBindingIndex = src->BufferBindingIndex;
2775 dst->_EffBufferBindingIndex = src->_EffBufferBindingIndex;
2776 dst->_EffRelativeOffset = src->_EffRelativeOffset;
2777 }
2778
2779 void
2780 _mesa_copy_vertex_buffer_binding(struct gl_context *ctx,
2781 struct gl_vertex_buffer_binding *dst,
2782 const struct gl_vertex_buffer_binding *src)
2783 {
2784 dst->Offset = src->Offset;
2785 dst->Stride = src->Stride;
2786 dst->InstanceDivisor = src->InstanceDivisor;
2787 dst->_BoundArrays = src->_BoundArrays;
2788 dst->_EffBoundArrays = src->_EffBoundArrays;
2789 dst->_EffOffset = src->_EffOffset;
2790
2791 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
2792 }
2793
2794 /**
2795 * Print current vertex object/array info. For debug.
2796 */
2797 void
2798 _mesa_print_arrays(struct gl_context *ctx)
2799 {
2800 const struct gl_vertex_array_object *vao = ctx->Array.VAO;
2801
2802 fprintf(stderr, "Array Object %u\n", vao->Name);
2803
2804 GLbitfield mask = vao->Enabled;
2805 while (mask) {
2806 const gl_vert_attrib i = u_bit_scan(&mask);
2807 const struct gl_array_attributes *array = &vao->VertexAttrib[i];
2808
2809 const struct gl_vertex_buffer_binding *binding =
2810 &vao->BufferBinding[array->BufferBindingIndex];
2811 const struct gl_buffer_object *bo = binding->BufferObj;
2812
2813 fprintf(stderr, " %s: Ptr=%p, Type=%s, Size=%d, ElemSize=%u, "
2814 "Stride=%d, Buffer=%u(Size %lu)\n",
2815 gl_vert_attrib_name((gl_vert_attrib)i),
2816 array->Ptr, _mesa_enum_to_string(array->Format.Type),
2817 array->Format.Size,
2818 array->Format._ElementSize, binding->Stride, bo->Name,
2819 (unsigned long) bo->Size);
2820 }
2821 }
2822
2823
2824 /**
2825 * Initialize vertex array state for given context.
2826 */
2827 void
2828 _mesa_init_varray(struct gl_context *ctx)
2829 {
2830 ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0);
2831 _mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO);
2832 ctx->Array._EmptyVAO = _mesa_new_vao(ctx, ~0u);
2833 _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, ctx->Array._EmptyVAO);
2834 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
2835
2836 ctx->Array.Objects = _mesa_NewHashTable();
2837 }
2838
2839
2840 /**
2841 * Callback for deleting an array object. Called by _mesa_HashDeleteAll().
2842 */
2843 static void
2844 delete_arrayobj_cb(GLuint id, void *data, void *userData)
2845 {
2846 struct gl_vertex_array_object *vao = (struct gl_vertex_array_object *) data;
2847 struct gl_context *ctx = (struct gl_context *) userData;
2848 _mesa_delete_vao(ctx, vao);
2849 }
2850
2851
2852 /**
2853 * Free vertex array state for given context.
2854 */
2855 void
2856 _mesa_free_varray_data(struct gl_context *ctx)
2857 {
2858 _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx);
2859 _mesa_DeleteHashTable(ctx->Array.Objects);
2860 }