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