mesa: import PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET handling
[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 "get.h"
44 #include "main/dispatch.h"
45
46
47 /** Used to do error checking for GL_EXT_vertex_array_bgra */
48 #define BGRA_OR_4 5
49
50
51 /** Used to indicate which GL datatypes are accepted by each of the
52 * glVertex/Color/Attrib/EtcPointer() functions.
53 */
54 #define BOOL_BIT (1 << 0)
55 #define BYTE_BIT (1 << 1)
56 #define UNSIGNED_BYTE_BIT (1 << 2)
57 #define SHORT_BIT (1 << 3)
58 #define UNSIGNED_SHORT_BIT (1 << 4)
59 #define INT_BIT (1 << 5)
60 #define UNSIGNED_INT_BIT (1 << 6)
61 #define HALF_BIT (1 << 7)
62 #define FLOAT_BIT (1 << 8)
63 #define DOUBLE_BIT (1 << 9)
64 #define FIXED_ES_BIT (1 << 10)
65 #define FIXED_GL_BIT (1 << 11)
66 #define UNSIGNED_INT_2_10_10_10_REV_BIT (1 << 12)
67 #define INT_2_10_10_10_REV_BIT (1 << 13)
68 #define UNSIGNED_INT_10F_11F_11F_REV_BIT (1 << 14)
69 #define ALL_TYPE_BITS ((1 << 15) - 1)
70
71 #define ATTRIB_FORMAT_TYPES_MASK (BYTE_BIT | UNSIGNED_BYTE_BIT | \
72 SHORT_BIT | UNSIGNED_SHORT_BIT | \
73 INT_BIT | UNSIGNED_INT_BIT | \
74 HALF_BIT | FLOAT_BIT | DOUBLE_BIT | \
75 FIXED_GL_BIT | \
76 UNSIGNED_INT_2_10_10_10_REV_BIT | \
77 INT_2_10_10_10_REV_BIT | \
78 UNSIGNED_INT_10F_11F_11F_REV_BIT)
79
80 #define ATTRIB_IFORMAT_TYPES_MASK (BYTE_BIT | UNSIGNED_BYTE_BIT | \
81 SHORT_BIT | UNSIGNED_SHORT_BIT | \
82 INT_BIT | UNSIGNED_INT_BIT)
83
84 #define ATTRIB_LFORMAT_TYPES_MASK DOUBLE_BIT
85
86
87 /** Convert GL datatype enum into a <type>_BIT value seen above */
88 static GLbitfield
89 type_to_bit(const struct gl_context *ctx, GLenum type)
90 {
91 switch (type) {
92 case GL_BOOL:
93 return BOOL_BIT;
94 case GL_BYTE:
95 return BYTE_BIT;
96 case GL_UNSIGNED_BYTE:
97 return UNSIGNED_BYTE_BIT;
98 case GL_SHORT:
99 return SHORT_BIT;
100 case GL_UNSIGNED_SHORT:
101 return UNSIGNED_SHORT_BIT;
102 case GL_INT:
103 return INT_BIT;
104 case GL_UNSIGNED_INT:
105 return UNSIGNED_INT_BIT;
106 case GL_HALF_FLOAT:
107 case GL_HALF_FLOAT_OES:
108 if (ctx->Extensions.ARB_half_float_vertex)
109 return HALF_BIT;
110 else
111 return 0x0;
112 case GL_FLOAT:
113 return FLOAT_BIT;
114 case GL_DOUBLE:
115 return DOUBLE_BIT;
116 case GL_FIXED:
117 return _mesa_is_desktop_gl(ctx) ? FIXED_GL_BIT : FIXED_ES_BIT;
118 case GL_UNSIGNED_INT_2_10_10_10_REV:
119 return UNSIGNED_INT_2_10_10_10_REV_BIT;
120 case GL_INT_2_10_10_10_REV:
121 return INT_2_10_10_10_REV_BIT;
122 case GL_UNSIGNED_INT_10F_11F_11F_REV:
123 return UNSIGNED_INT_10F_11F_11F_REV_BIT;
124 default:
125 return 0;
126 }
127 }
128
129
130 /**
131 * Depending on the position and generic0 attributes enable flags select
132 * the one that is used for both attributes.
133 * The generic0 attribute takes precedence.
134 */
135 static inline void
136 update_attribute_map_mode(const struct gl_context *ctx,
137 struct gl_vertex_array_object *vao)
138 {
139 /*
140 * There is no need to change the mapping away from the
141 * identity mapping if we are not in compat mode.
142 */
143 if (ctx->API != API_OPENGL_COMPAT)
144 return;
145 /* The generic0 attribute superseeds the position attribute */
146 const GLbitfield enabled = vao->Enabled;
147 if (enabled & VERT_BIT_GENERIC0)
148 vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_GENERIC0;
149 else if (enabled & VERT_BIT_POS)
150 vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_POSITION;
151 else
152 vao->_AttributeMapMode = ATTRIBUTE_MAP_MODE_IDENTITY;
153 }
154
155
156 /**
157 * Sets the BufferBindingIndex field for the vertex attribute given by
158 * attribIndex.
159 */
160 void
161 _mesa_vertex_attrib_binding(struct gl_context *ctx,
162 struct gl_vertex_array_object *vao,
163 gl_vert_attrib attribIndex,
164 GLuint bindingIndex)
165 {
166 struct gl_array_attributes *array = &vao->VertexAttrib[attribIndex];
167 assert(!vao->SharedAndImmutable);
168
169 if (array->BufferBindingIndex != bindingIndex) {
170 const GLbitfield array_bit = VERT_BIT(attribIndex);
171
172 if (_mesa_is_bufferobj(vao->BufferBinding[bindingIndex].BufferObj))
173 vao->VertexAttribBufferMask |= array_bit;
174 else
175 vao->VertexAttribBufferMask &= ~array_bit;
176
177 vao->BufferBinding[array->BufferBindingIndex]._BoundArrays &= ~array_bit;
178 vao->BufferBinding[bindingIndex]._BoundArrays |= array_bit;
179
180 array->BufferBindingIndex = bindingIndex;
181
182 vao->NewArrays |= vao->Enabled & array_bit;
183 }
184 }
185
186
187 /**
188 * Binds a buffer object to the vertex buffer binding point given by index,
189 * and sets the Offset and Stride fields.
190 */
191 void
192 _mesa_bind_vertex_buffer(struct gl_context *ctx,
193 struct gl_vertex_array_object *vao,
194 GLuint index,
195 struct gl_buffer_object *vbo,
196 GLintptr offset, GLsizei stride)
197 {
198 assert(index < ARRAY_SIZE(vao->BufferBinding));
199 assert(!vao->SharedAndImmutable);
200 struct gl_vertex_buffer_binding *binding = &vao->BufferBinding[index];
201
202 if (ctx->Const.VertexBufferOffsetIsInt32 && (int)offset < 0 &&
203 _mesa_is_bufferobj(vbo)) {
204 /* The offset will be interpreted as a signed int, so make sure
205 * the user supplied offset is not negative (driver limitation).
206 */
207 _mesa_warning(ctx, "Received negative int32 vertex buffer offset. "
208 "(driver limitation)\n");
209
210 /* We can't disable this binding, so use a non-negative offset value
211 * instead.
212 */
213 offset = 0;
214 }
215
216 if (binding->BufferObj != vbo ||
217 binding->Offset != offset ||
218 binding->Stride != stride) {
219
220 _mesa_reference_buffer_object(ctx, &binding->BufferObj, vbo);
221
222 binding->Offset = offset;
223 binding->Stride = stride;
224
225 if (!_mesa_is_bufferobj(vbo)) {
226 vao->VertexAttribBufferMask &= ~binding->_BoundArrays;
227 } else {
228 vao->VertexAttribBufferMask |= binding->_BoundArrays;
229 vbo->UsageHistory |= USAGE_ARRAY_BUFFER;
230 }
231
232 vao->NewArrays |= vao->Enabled & binding->_BoundArrays;
233 }
234 }
235
236
237 /**
238 * Sets the InstanceDivisor field in the vertex buffer binding point
239 * given by bindingIndex.
240 */
241 static void
242 vertex_binding_divisor(struct gl_context *ctx,
243 struct gl_vertex_array_object *vao,
244 GLuint bindingIndex,
245 GLuint divisor)
246 {
247 struct gl_vertex_buffer_binding *binding =
248 &vao->BufferBinding[bindingIndex];
249 assert(!vao->SharedAndImmutable);
250
251 if (binding->InstanceDivisor != divisor) {
252 binding->InstanceDivisor = divisor;
253 vao->NewArrays |= vao->Enabled & binding->_BoundArrays;
254 }
255 }
256
257
258 void
259 _mesa_set_vertex_format(struct gl_vertex_format *vertex_format,
260 GLubyte size, GLenum16 type, GLenum16 format,
261 GLboolean normalized, GLboolean integer,
262 GLboolean doubles)
263 {
264 assert(size <= 4);
265 vertex_format->Type = type;
266 vertex_format->Format = format;
267 vertex_format->Size = size;
268 vertex_format->Normalized = normalized;
269 vertex_format->Integer = integer;
270 vertex_format->Doubles = doubles;
271 vertex_format->_ElementSize = _mesa_bytes_per_vertex_attrib(size, type);
272 assert(vertex_format->_ElementSize <= 4*sizeof(double));
273 }
274
275
276 /**
277 * Examine the API profile and extensions to determine which types are legal
278 * for vertex arrays. This is called once from update_array_format().
279 */
280 static GLbitfield
281 get_legal_types_mask(const struct gl_context *ctx)
282 {
283 GLbitfield legalTypesMask = ALL_TYPE_BITS;
284
285 if (_mesa_is_gles(ctx)) {
286 legalTypesMask &= ~(FIXED_GL_BIT |
287 DOUBLE_BIT |
288 UNSIGNED_INT_10F_11F_11F_REV_BIT);
289
290 /* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until
291 * 3.0. The 2_10_10_10 types are added in OpenGL ES 3.0 or
292 * GL_OES_vertex_type_10_10_10_2. GL_HALF_FLOAT data is not allowed
293 * until 3.0 or with the GL_OES_vertex_half float extension, which isn't
294 * quite as trivial as we'd like because it uses a different enum value
295 * for GL_HALF_FLOAT_OES.
296 */
297 if (ctx->Version < 30) {
298 legalTypesMask &= ~(UNSIGNED_INT_BIT |
299 INT_BIT |
300 UNSIGNED_INT_2_10_10_10_REV_BIT |
301 INT_2_10_10_10_REV_BIT);
302
303 if (!_mesa_has_OES_vertex_half_float(ctx))
304 legalTypesMask &= ~HALF_BIT;
305 }
306 }
307 else {
308 legalTypesMask &= ~FIXED_ES_BIT;
309
310 if (!ctx->Extensions.ARB_ES2_compatibility)
311 legalTypesMask &= ~FIXED_GL_BIT;
312
313 if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev)
314 legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT |
315 INT_2_10_10_10_REV_BIT);
316
317 if (!ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev)
318 legalTypesMask &= ~UNSIGNED_INT_10F_11F_11F_REV_BIT;
319 }
320
321 return legalTypesMask;
322 }
323
324 static GLenum
325 get_array_format(const struct gl_context *ctx, GLint sizeMax, GLint *size)
326 {
327 GLenum format = GL_RGBA;
328
329 /* Do size parameter checking.
330 * If sizeMax = BGRA_OR_4 it means that size = GL_BGRA is legal and
331 * must be handled specially.
332 */
333 if (ctx->Extensions.EXT_vertex_array_bgra && sizeMax == BGRA_OR_4 &&
334 *size == GL_BGRA) {
335 format = GL_BGRA;
336 *size = 4;
337 }
338
339 return format;
340 }
341
342
343 /**
344 * \param attrib The index of the attribute array
345 * \param size Components per element (1, 2, 3 or 4)
346 * \param type Datatype of each component (GL_FLOAT, GL_INT, etc)
347 * \param format Either GL_RGBA or GL_BGRA.
348 * \param normalized Whether integer types are converted to floats in [-1, 1]
349 * \param integer Integer-valued values (will not be normalized to [-1, 1])
350 * \param doubles Double values not reduced to floats
351 * \param relativeOffset Offset of the first element relative to the binding
352 * offset.
353 */
354 void
355 _mesa_update_array_format(struct gl_context *ctx,
356 struct gl_vertex_array_object *vao,
357 gl_vert_attrib attrib, GLint size, GLenum type,
358 GLenum format, GLboolean normalized,
359 GLboolean integer, GLboolean doubles,
360 GLuint relativeOffset)
361 {
362 struct gl_array_attributes *const array = &vao->VertexAttrib[attrib];
363
364 assert(!vao->SharedAndImmutable);
365 assert(size <= 4);
366
367 array->RelativeOffset = relativeOffset;
368 _mesa_set_vertex_format(&array->Format, size, type, format,
369 normalized, integer, doubles);
370
371 vao->NewArrays |= vao->Enabled & VERT_BIT(attrib);
372 }
373
374 /**
375 * Does error checking of the format in an attrib array.
376 *
377 * Called by *Pointer() and VertexAttrib*Format().
378 *
379 * \param func Name of calling function used for error reporting
380 * \param attrib The index of the attribute array
381 * \param legalTypes Bitmask of *_BIT above indicating legal datatypes
382 * \param sizeMin Min allowable size value
383 * \param sizeMax Max allowable size value (may also be BGRA_OR_4)
384 * \param size Components per element (1, 2, 3 or 4)
385 * \param type Datatype of each component (GL_FLOAT, GL_INT, etc)
386 * \param normalized Whether integer types are converted to floats in [-1, 1]
387 * \param integer Integer-valued values (will not be normalized to [-1, 1])
388 * \param doubles Double values not reduced to floats
389 * \param relativeOffset Offset of the first element relative to the binding offset.
390 * \return bool True if validation is successful, False otherwise.
391 */
392 static bool
393 validate_array_format(struct gl_context *ctx, const char *func,
394 struct gl_vertex_array_object *vao,
395 GLuint attrib, GLbitfield legalTypesMask,
396 GLint sizeMin, GLint sizeMax,
397 GLint size, GLenum type, GLboolean normalized,
398 GLboolean integer, GLboolean doubles,
399 GLuint relativeOffset, GLenum format)
400 {
401 GLbitfield typeBit;
402
403 /* at most, one of these bools can be true */
404 assert((int) normalized + (int) integer + (int) doubles <= 1);
405
406 if (ctx->Array.LegalTypesMask == 0 || ctx->Array.LegalTypesMaskAPI != ctx->API) {
407 /* Compute the LegalTypesMask only once, unless the context API has
408 * changed, in which case we want to compute it again. We can't do this
409 * in _mesa_init_varrays() below because extensions are not yet enabled
410 * at that point.
411 */
412 ctx->Array.LegalTypesMask = get_legal_types_mask(ctx);
413 ctx->Array.LegalTypesMaskAPI = ctx->API;
414 }
415
416 legalTypesMask &= ctx->Array.LegalTypesMask;
417
418 if (_mesa_is_gles(ctx) && sizeMax == BGRA_OR_4) {
419 /* BGRA ordering is not supported in ES contexts.
420 */
421 sizeMax = 4;
422 }
423
424 typeBit = type_to_bit(ctx, type);
425 if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) {
426 _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)",
427 func, _mesa_enum_to_string(type));
428 return false;
429 }
430
431 if (format == GL_BGRA) {
432 /* Page 298 of the PDF of the OpenGL 4.3 (Core Profile) spec says:
433 *
434 * "An INVALID_OPERATION error is generated under any of the following
435 * conditions:
436 * ...
437 * • size is BGRA and type is not UNSIGNED_BYTE, INT_2_10_10_10_REV
438 * or UNSIGNED_INT_2_10_10_10_REV;
439 * ...
440 * • size is BGRA and normalized is FALSE;"
441 */
442 bool bgra_error = false;
443
444 if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) {
445 if (type != GL_UNSIGNED_INT_2_10_10_10_REV &&
446 type != GL_INT_2_10_10_10_REV &&
447 type != GL_UNSIGNED_BYTE)
448 bgra_error = true;
449 } else if (type != GL_UNSIGNED_BYTE)
450 bgra_error = true;
451
452 if (bgra_error) {
453 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=GL_BGRA and type=%s)",
454 func, _mesa_enum_to_string(type));
455 return false;
456 }
457
458 if (!normalized) {
459 _mesa_error(ctx, GL_INVALID_OPERATION,
460 "%s(size=GL_BGRA and normalized=GL_FALSE)", func);
461 return false;
462 }
463 }
464 else if (size < sizeMin || size > sizeMax || size > 4) {
465 _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size);
466 return false;
467 }
468
469 if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev &&
470 (type == GL_UNSIGNED_INT_2_10_10_10_REV ||
471 type == GL_INT_2_10_10_10_REV) && size != 4) {
472 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size);
473 return false;
474 }
475
476 /* The ARB_vertex_attrib_binding_spec says:
477 *
478 * An INVALID_VALUE error is generated if <relativeoffset> is larger than
479 * the value of MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.
480 */
481 if (relativeOffset > ctx->Const.MaxVertexAttribRelativeOffset) {
482 _mesa_error(ctx, GL_INVALID_VALUE,
483 "%s(relativeOffset=%d > "
484 "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET)",
485 func, relativeOffset);
486 return false;
487 }
488
489 if (ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev &&
490 type == GL_UNSIGNED_INT_10F_11F_11F_REV && size != 3) {
491 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size);
492 return false;
493 }
494
495 return true;
496 }
497
498 /**
499 * Do error checking for glVertex/Color/TexCoord/...Pointer functions.
500 *
501 * \param func name of calling function used for error reporting
502 * \param vao the vao to update
503 * \param obj the bound buffer object
504 * \param attrib the attribute array index to update
505 * \param legalTypes bitmask of *_BIT above indicating legal datatypes
506 * \param sizeMin min allowable size value
507 * \param sizeMax max allowable size value (may also be BGRA_OR_4)
508 * \param size components per element (1, 2, 3 or 4)
509 * \param type datatype of each component (GL_FLOAT, GL_INT, etc)
510 * \param stride stride between elements, in elements
511 * \param normalized are integer types converted to floats in [-1, 1]?
512 * \param integer integer-valued values (will not be normalized to [-1,1])
513 * \param doubles Double values not reduced to floats
514 * \param ptr the address (or offset inside VBO) of the array data
515 */
516 static void
517 validate_array(struct gl_context *ctx, const char *func,
518 struct gl_vertex_array_object *vao,
519 struct gl_buffer_object *obj,
520 GLuint attrib, GLbitfield legalTypesMask,
521 GLint sizeMin, GLint sizeMax,
522 GLint size, GLenum type, GLsizei stride,
523 GLboolean normalized, GLboolean integer, GLboolean doubles,
524 const GLvoid *ptr)
525 {
526 /* Page 407 (page 423 of the PDF) of the OpenGL 3.0 spec says:
527 *
528 * "Client vertex arrays - all vertex array attribute pointers must
529 * refer to buffer objects (section 2.9.2). The default vertex array
530 * object (the name zero) is also deprecated. Calling
531 * VertexAttribPointer when no buffer object or no vertex array object
532 * is bound will generate an INVALID_OPERATION error..."
533 *
534 * The check for VBOs is handled below.
535 */
536 if (ctx->API == API_OPENGL_CORE && (vao == ctx->Array.DefaultVAO)) {
537 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no array object bound)",
538 func);
539 return;
540 }
541
542 if (stride < 0) {
543 _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride );
544 return;
545 }
546
547 if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 44 &&
548 stride > ctx->Const.MaxVertexAttribStride) {
549 _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > "
550 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride);
551 return;
552 }
553
554 /* Page 29 (page 44 of the PDF) of the OpenGL 3.3 spec says:
555 *
556 * "An INVALID_OPERATION error is generated under any of the following
557 * conditions:
558 *
559 * ...
560 *
561 * * any of the *Pointer commands specifying the location and
562 * organization of vertex array data are called while zero is bound
563 * to the ARRAY_BUFFER buffer object binding point (see section
564 * 2.9.6), and the pointer argument is not NULL."
565 */
566 if (ptr != NULL && vao != ctx->Array.DefaultVAO &&
567 !_mesa_is_bufferobj(obj)) {
568 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func);
569 return;
570 }
571 }
572
573
574 static bool
575 validate_array_and_format(struct gl_context *ctx, const char *func,
576 struct gl_vertex_array_object *vao,
577 struct gl_buffer_object *obj,
578 GLuint attrib, GLbitfield legalTypes,
579 GLint sizeMin, GLint sizeMax,
580 GLint size, GLenum type, GLsizei stride,
581 GLboolean normalized, GLboolean integer,
582 GLboolean doubles, GLenum format, const GLvoid *ptr)
583 {
584 validate_array(ctx, func, vao, obj, attrib, legalTypes, sizeMin, sizeMax,
585 size, type, stride, normalized, integer, doubles, ptr);
586
587 return validate_array_format(ctx, func, vao, attrib, legalTypes, sizeMin,
588 sizeMax, size, type, normalized, integer,
589 doubles, 0, format);
590 }
591
592
593 /**
594 * Update state for glVertex/Color/TexCoord/...Pointer functions.
595 *
596 * \param vao the vao to update
597 * \param obj the bound buffer object
598 * \param attrib the attribute array index to update
599 * \param format Either GL_RGBA or GL_BGRA.
600 * \param sizeMax max allowable size value (may also be BGRA_OR_4)
601 * \param size components per element (1, 2, 3 or 4)
602 * \param type datatype of each component (GL_FLOAT, GL_INT, etc)
603 * \param stride stride between elements, in elements
604 * \param normalized are integer types converted to floats in [-1, 1]?
605 * \param integer integer-valued values (will not be normalized to [-1,1])
606 * \param doubles Double values not reduced to floats
607 * \param ptr the address (or offset inside VBO) of the array data
608 */
609 static void
610 update_array(struct gl_context *ctx,
611 struct gl_vertex_array_object *vao,
612 struct gl_buffer_object *obj,
613 GLuint attrib, GLenum format,
614 GLint sizeMax,
615 GLint size, GLenum type, GLsizei stride,
616 GLboolean normalized, GLboolean integer, GLboolean doubles,
617 const GLvoid *ptr)
618 {
619 _mesa_update_array_format(ctx, vao, attrib, size, type, format,
620 normalized, integer, doubles, 0);
621
622 /* Reset the vertex attrib binding */
623 _mesa_vertex_attrib_binding(ctx, vao, attrib, attrib);
624
625 /* The Stride and Ptr fields are not set by update_array_format() */
626 struct gl_array_attributes *array = &vao->VertexAttrib[attrib];
627 array->Stride = stride;
628 /* For updating the pointer we would need to add the vao->NewArrays flag
629 * to the VAO. But but that is done already unconditionally in
630 * _mesa_update_array_format called above.
631 */
632 assert((vao->NewArrays | ~vao->Enabled) & VERT_BIT(attrib));
633 array->Ptr = ptr;
634
635 /* Update the vertex buffer binding */
636 GLsizei effectiveStride = stride != 0 ?
637 stride : array->Format._ElementSize;
638 _mesa_bind_vertex_buffer(ctx, vao, attrib,
639 obj, (GLintptr) ptr,
640 effectiveStride);
641 }
642
643
644 /* Helper function for all EXT_direct_state_access glVertexArray* functions */
645 static bool
646 _lookup_vao_and_vbo_dsa(struct gl_context *ctx,
647 GLuint vaobj, GLuint buffer,
648 GLintptr offset,
649 struct gl_vertex_array_object** vao,
650 struct gl_buffer_object** vbo,
651 const char* caller)
652 {
653 *vao = _mesa_lookup_vao_err(ctx, vaobj, true, caller);
654 if (!(*vao))
655 return false;
656
657 if (buffer != 0) {
658 *vbo = _mesa_lookup_bufferobj(ctx, buffer);
659 if (!_mesa_handle_bind_buffer_gen(ctx, buffer, vbo, caller))
660 return false;
661
662 if (offset < 0) {
663 _mesa_error(ctx, GL_INVALID_VALUE,
664 "%s(negative offset with non-0 buffer)", caller);
665 return false;
666 }
667 } else {
668 *vbo = ctx->Shared->NullBufferObj;
669 }
670
671 return true;
672 }
673
674
675 void GLAPIENTRY
676 _mesa_VertexPointer_no_error(GLint size, GLenum type, GLsizei stride,
677 const GLvoid *ptr)
678 {
679 GET_CURRENT_CONTEXT(ctx);
680
681 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
682 VERT_ATTRIB_POS, GL_RGBA, 4, size, type, stride,
683 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
684 }
685
686
687 void GLAPIENTRY
688 _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
689 {
690 GET_CURRENT_CONTEXT(ctx);
691
692 GLenum format = GL_RGBA;
693 GLbitfield legalTypes = (ctx->API == API_OPENGLES)
694 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
695 : (SHORT_BIT | INT_BIT | FLOAT_BIT |
696 DOUBLE_BIT | HALF_BIT |
697 UNSIGNED_INT_2_10_10_10_REV_BIT |
698 INT_2_10_10_10_REV_BIT);
699
700 if (!validate_array_and_format(ctx, "glVertexPointer",
701 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
702 VERT_ATTRIB_POS, legalTypes, 2, 4, size,
703 type, stride, GL_FALSE, GL_FALSE, GL_FALSE,
704 format, ptr))
705 return;
706
707 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
708 VERT_ATTRIB_POS, format, 4, size, type, stride,
709 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
710 }
711
712
713 void GLAPIENTRY
714 _mesa_VertexArrayVertexOffsetEXT(GLuint vaobj, GLuint buffer, GLint size,
715 GLenum type, GLsizei stride, GLintptr offset)
716 {
717 GET_CURRENT_CONTEXT(ctx);
718
719 GLenum format = GL_RGBA;
720 GLbitfield legalTypes = (ctx->API == API_OPENGLES)
721 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
722 : (SHORT_BIT | INT_BIT | FLOAT_BIT |
723 DOUBLE_BIT | HALF_BIT |
724 UNSIGNED_INT_2_10_10_10_REV_BIT |
725 INT_2_10_10_10_REV_BIT);
726
727 struct gl_vertex_array_object* vao;
728 struct gl_buffer_object* vbo;
729
730 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
731 &vao, &vbo,
732 "glVertexArrayVertexOffsetEXT"))
733 return;
734
735 if (!validate_array_and_format(ctx, "glVertexArrayVertexOffsetEXT",
736 vao, vbo,
737 VERT_ATTRIB_POS, legalTypes, 2, 4, size,
738 type, stride, GL_FALSE, GL_FALSE, GL_FALSE,
739 format, (void*) offset))
740 return;
741
742 update_array(ctx, vao, vbo,
743 VERT_ATTRIB_POS, format, 4, size, type, stride,
744 GL_FALSE, GL_FALSE, GL_FALSE, (void*) offset);
745 }
746
747
748 void GLAPIENTRY
749 _mesa_NormalPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr )
750 {
751 GET_CURRENT_CONTEXT(ctx);
752
753 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
754 VERT_ATTRIB_NORMAL, GL_RGBA, 3, 3, type, stride, GL_TRUE,
755 GL_FALSE, GL_FALSE, ptr);
756 }
757
758
759 void GLAPIENTRY
760 _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
761 {
762 GET_CURRENT_CONTEXT(ctx);
763
764 GLenum format = GL_RGBA;
765 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
766 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
767 : (BYTE_BIT | SHORT_BIT | INT_BIT |
768 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
769 UNSIGNED_INT_2_10_10_10_REV_BIT |
770 INT_2_10_10_10_REV_BIT);
771
772 if (!validate_array_and_format(ctx, "glNormalPointer",
773 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
774 VERT_ATTRIB_NORMAL, legalTypes, 3, 3, 3,
775 type, stride, GL_TRUE, GL_FALSE,
776 GL_FALSE, format, ptr))
777 return;
778
779 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
780 VERT_ATTRIB_NORMAL, format, 3, 3, type, stride, GL_TRUE,
781 GL_FALSE, GL_FALSE, ptr);
782 }
783
784
785 void GLAPIENTRY
786 _mesa_VertexArrayNormalOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type,
787 GLsizei stride, GLintptr offset)
788 {
789 GET_CURRENT_CONTEXT(ctx);
790
791 GLenum format = GL_RGBA;
792 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
793 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
794 : (BYTE_BIT | SHORT_BIT | INT_BIT |
795 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
796 UNSIGNED_INT_2_10_10_10_REV_BIT |
797 INT_2_10_10_10_REV_BIT);
798
799 struct gl_vertex_array_object* vao;
800 struct gl_buffer_object* vbo;
801
802 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
803 &vao, &vbo,
804 "glNormalPointer"))
805 return;
806
807 if (!validate_array_and_format(ctx, "glNormalPointer",
808 vao, vbo,
809 VERT_ATTRIB_NORMAL, legalTypes, 3, 3, 3,
810 type, stride, GL_TRUE, GL_FALSE,
811 GL_FALSE, format, (void*) offset))
812 return;
813
814 update_array(ctx, vao, vbo,
815 VERT_ATTRIB_NORMAL, format, 3, 3, type, stride, GL_TRUE,
816 GL_FALSE, GL_FALSE, (void*) offset);
817 }
818
819
820 void GLAPIENTRY
821 _mesa_ColorPointer_no_error(GLint size, GLenum type, GLsizei stride,
822 const GLvoid *ptr)
823 {
824 GET_CURRENT_CONTEXT(ctx);
825
826 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
827 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
828 VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size,
829 type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
830 }
831
832
833 void GLAPIENTRY
834 _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
835 {
836 GET_CURRENT_CONTEXT(ctx);
837 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 4 : 3;
838
839 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
840 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
841 ? (UNSIGNED_BYTE_BIT | HALF_BIT | FLOAT_BIT | FIXED_ES_BIT)
842 : (BYTE_BIT | UNSIGNED_BYTE_BIT |
843 SHORT_BIT | UNSIGNED_SHORT_BIT |
844 INT_BIT | UNSIGNED_INT_BIT |
845 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
846 UNSIGNED_INT_2_10_10_10_REV_BIT |
847 INT_2_10_10_10_REV_BIT);
848
849 if (!validate_array_and_format(ctx, "glColorPointer",
850 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
851 VERT_ATTRIB_COLOR0, legalTypes, sizeMin,
852 BGRA_OR_4, size, type, stride, GL_TRUE,
853 GL_FALSE, GL_FALSE, format, ptr))
854 return;
855
856 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
857 VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size,
858 type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
859 }
860
861
862 void GLAPIENTRY
863 _mesa_VertexArrayColorOffsetEXT(GLuint vaobj, GLuint buffer, GLint size,
864 GLenum type, GLsizei stride, GLintptr offset)
865 {
866 GET_CURRENT_CONTEXT(ctx);
867 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 4 : 3;
868
869 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
870 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
871 ? (UNSIGNED_BYTE_BIT | HALF_BIT | FLOAT_BIT | FIXED_ES_BIT)
872 : (BYTE_BIT | UNSIGNED_BYTE_BIT |
873 SHORT_BIT | UNSIGNED_SHORT_BIT |
874 INT_BIT | UNSIGNED_INT_BIT |
875 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
876 UNSIGNED_INT_2_10_10_10_REV_BIT |
877 INT_2_10_10_10_REV_BIT);
878
879 struct gl_vertex_array_object* vao;
880 struct gl_buffer_object* vbo;
881
882 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
883 &vao, &vbo,
884 "glVertexArrayColorOffsetEXT"))
885 return;
886
887 if (!validate_array_and_format(ctx, "glVertexArrayColorOffsetEXT",
888 vao, vbo,
889 VERT_ATTRIB_COLOR0, legalTypes, sizeMin,
890 BGRA_OR_4, size, type, stride, GL_TRUE,
891 GL_FALSE, GL_FALSE, format, (void*) offset))
892 return;
893
894 update_array(ctx, vao, vbo,
895 VERT_ATTRIB_COLOR0, format, BGRA_OR_4, size,
896 type, stride, GL_TRUE, GL_FALSE, GL_FALSE, (void*) offset);
897 }
898
899
900 void GLAPIENTRY
901 _mesa_FogCoordPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr)
902 {
903 GET_CURRENT_CONTEXT(ctx);
904
905 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
906 VERT_ATTRIB_FOG, GL_RGBA, 1, 1, type, stride, GL_FALSE,
907 GL_FALSE, GL_FALSE, ptr);
908 }
909
910
911 void GLAPIENTRY
912 _mesa_FogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
913 {
914 GET_CURRENT_CONTEXT(ctx);
915
916 GLenum format = GL_RGBA;
917 const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT);
918
919 if (!validate_array_and_format(ctx, "glFogCoordPointer",
920 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
921 VERT_ATTRIB_FOG, legalTypes, 1, 1, 1,
922 type, stride, GL_FALSE, GL_FALSE,
923 GL_FALSE, format, ptr))
924 return;
925
926 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
927 VERT_ATTRIB_FOG, format, 1, 1, type, stride, GL_FALSE,
928 GL_FALSE, GL_FALSE, ptr);
929 }
930
931
932 void GLAPIENTRY
933 _mesa_VertexArrayFogCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type,
934 GLsizei stride, GLintptr offset)
935 {
936 GET_CURRENT_CONTEXT(ctx);
937
938 GLenum format = GL_RGBA;
939 const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT);
940
941 struct gl_vertex_array_object* vao;
942 struct gl_buffer_object* vbo;
943
944 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
945 &vao, &vbo,
946 "glVertexArrayFogCoordOffsetEXT"))
947 return;
948
949 if (!validate_array_and_format(ctx, "glVertexArrayFogCoordOffsetEXT",
950 vao, vbo,
951 VERT_ATTRIB_FOG, legalTypes, 1, 1, 1,
952 type, stride, GL_FALSE, GL_FALSE,
953 GL_FALSE, format, (void*) offset))
954 return;
955
956 update_array(ctx, vao, vbo,
957 VERT_ATTRIB_FOG, format, 1, 1, type, stride, GL_FALSE,
958 GL_FALSE, GL_FALSE, (void*) offset);
959 }
960
961
962 void GLAPIENTRY
963 _mesa_IndexPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr)
964 {
965 GET_CURRENT_CONTEXT(ctx);
966
967 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
968 VERT_ATTRIB_COLOR_INDEX, GL_RGBA, 1, 1, type, stride,
969 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
970 }
971
972
973 void GLAPIENTRY
974 _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
975 {
976 GET_CURRENT_CONTEXT(ctx);
977
978 GLenum format = GL_RGBA;
979 const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT |
980 FLOAT_BIT | DOUBLE_BIT);
981
982 if (!validate_array_and_format(ctx, "glIndexPointer",
983 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
984 VERT_ATTRIB_COLOR_INDEX,
985 legalTypes, 1, 1, 1, type, stride,
986 GL_FALSE, GL_FALSE, GL_FALSE, format, ptr))
987 return;
988
989 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
990 VERT_ATTRIB_COLOR_INDEX, format, 1, 1, type, stride,
991 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
992 }
993
994
995 void GLAPIENTRY
996 _mesa_VertexArrayIndexOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type,
997 GLsizei stride, GLintptr offset)
998 {
999 GET_CURRENT_CONTEXT(ctx);
1000
1001 GLenum format = GL_RGBA;
1002 const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT |
1003 FLOAT_BIT | DOUBLE_BIT);
1004
1005 struct gl_vertex_array_object* vao;
1006 struct gl_buffer_object* vbo;
1007
1008 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
1009 &vao, &vbo,
1010 "glVertexArrayIndexOffsetEXT"))
1011 return;
1012
1013 if (!validate_array_and_format(ctx, "glVertexArrayIndexOffsetEXT",
1014 vao, vbo,
1015 VERT_ATTRIB_COLOR_INDEX,
1016 legalTypes, 1, 1, 1, type, stride,
1017 GL_FALSE, GL_FALSE, GL_FALSE, format, (void*) offset))
1018 return;
1019
1020 update_array(ctx, vao, vbo,
1021 VERT_ATTRIB_COLOR_INDEX, format, 1, 1, type, stride,
1022 GL_FALSE, GL_FALSE, GL_FALSE, (void*) offset);
1023 }
1024
1025
1026 void GLAPIENTRY
1027 _mesa_SecondaryColorPointer_no_error(GLint size, GLenum type,
1028 GLsizei stride, const GLvoid *ptr)
1029 {
1030 GET_CURRENT_CONTEXT(ctx);
1031
1032 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
1033 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1034 VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type,
1035 stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
1036 }
1037
1038
1039 void GLAPIENTRY
1040 _mesa_SecondaryColorPointer(GLint size, GLenum type,
1041 GLsizei stride, const GLvoid *ptr)
1042 {
1043 GET_CURRENT_CONTEXT(ctx);
1044
1045 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
1046 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
1047 SHORT_BIT | UNSIGNED_SHORT_BIT |
1048 INT_BIT | UNSIGNED_INT_BIT |
1049 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
1050 UNSIGNED_INT_2_10_10_10_REV_BIT |
1051 INT_2_10_10_10_REV_BIT);
1052
1053 if (!validate_array_and_format(ctx, "glSecondaryColorPointer",
1054 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1055 VERT_ATTRIB_COLOR1, legalTypes, 3,
1056 BGRA_OR_4, size, type, stride,
1057 GL_TRUE, GL_FALSE, GL_FALSE, format, ptr))
1058 return;
1059
1060 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1061 VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type,
1062 stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr);
1063 }
1064
1065
1066 void GLAPIENTRY
1067 _mesa_VertexArraySecondaryColorOffsetEXT(GLuint vaobj, GLuint buffer, GLint size,
1068 GLenum type, GLsizei stride, GLintptr offset)
1069 {
1070 GET_CURRENT_CONTEXT(ctx);
1071
1072 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
1073 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
1074 SHORT_BIT | UNSIGNED_SHORT_BIT |
1075 INT_BIT | UNSIGNED_INT_BIT |
1076 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
1077 UNSIGNED_INT_2_10_10_10_REV_BIT |
1078 INT_2_10_10_10_REV_BIT);
1079
1080 struct gl_vertex_array_object* vao;
1081 struct gl_buffer_object* vbo;
1082
1083 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
1084 &vao, &vbo,
1085 "glVertexArraySecondaryColorOffsetEXT"))
1086 return;
1087
1088 if (!validate_array_and_format(ctx, "glVertexArraySecondaryColorOffsetEXT",
1089 vao, vbo,
1090 VERT_ATTRIB_COLOR1, legalTypes, 3,
1091 BGRA_OR_4, size, type, stride,
1092 GL_TRUE, GL_FALSE, GL_FALSE, format, (void*) offset))
1093 return;
1094
1095 update_array(ctx, vao, vbo,
1096 VERT_ATTRIB_COLOR1, format, BGRA_OR_4, size, type,
1097 stride, GL_TRUE, GL_FALSE, GL_FALSE, (void*) offset);
1098 }
1099
1100
1101 void GLAPIENTRY
1102 _mesa_TexCoordPointer_no_error(GLint size, GLenum type, GLsizei stride,
1103 const GLvoid *ptr)
1104 {
1105 GET_CURRENT_CONTEXT(ctx);
1106 const GLuint unit = ctx->Array.ActiveTexture;
1107
1108 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1109 VERT_ATTRIB_TEX(unit), GL_RGBA, 4, size, type,
1110 stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr);
1111 }
1112
1113
1114 void GLAPIENTRY
1115 _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
1116 const GLvoid *ptr)
1117 {
1118 GET_CURRENT_CONTEXT(ctx);
1119 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1;
1120 const GLuint unit = ctx->Array.ActiveTexture;
1121
1122 GLenum format = GL_RGBA;
1123 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
1124 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
1125 : (SHORT_BIT | INT_BIT |
1126 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
1127 UNSIGNED_INT_2_10_10_10_REV_BIT |
1128 INT_2_10_10_10_REV_BIT);
1129
1130 if (!validate_array_and_format(ctx, "glTexCoordPointer",
1131 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1132 VERT_ATTRIB_TEX(unit), legalTypes,
1133 sizeMin, 4, size, type, stride,
1134 GL_FALSE, GL_FALSE, GL_FALSE, format, ptr))
1135 return;
1136
1137 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1138 VERT_ATTRIB_TEX(unit), format, 4, size, type,
1139 stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr);
1140 }
1141
1142
1143 void GLAPIENTRY
1144 _mesa_VertexArrayTexCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLint size,
1145 GLenum type, GLsizei stride, GLintptr offset)
1146 {
1147 GET_CURRENT_CONTEXT(ctx);
1148 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1;
1149 const GLuint unit = ctx->Array.ActiveTexture;
1150
1151 GLenum format = GL_RGBA;
1152 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
1153 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
1154 : (SHORT_BIT | INT_BIT |
1155 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
1156 UNSIGNED_INT_2_10_10_10_REV_BIT |
1157 INT_2_10_10_10_REV_BIT);
1158
1159 struct gl_vertex_array_object* vao;
1160 struct gl_buffer_object* vbo;
1161
1162 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
1163 &vao, &vbo,
1164 "glVertexArrayTexCoordOffsetEXT"))
1165 return;
1166
1167 if (!validate_array_and_format(ctx, "glVertexArrayTexCoordOffsetEXT",
1168 vao, vbo,
1169 VERT_ATTRIB_TEX(unit), legalTypes,
1170 sizeMin, 4, size, type, stride,
1171 GL_FALSE, GL_FALSE, GL_FALSE, format, (void*) offset))
1172 return;
1173
1174 update_array(ctx, vao, vbo,
1175 VERT_ATTRIB_TEX(unit), format, 4, size, type,
1176 stride, GL_FALSE, GL_FALSE, GL_FALSE, (void*) offset);
1177 }
1178
1179
1180 void GLAPIENTRY
1181 _mesa_VertexArrayMultiTexCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLenum texunit,
1182 GLint size, GLenum type, GLsizei stride,
1183 GLintptr offset)
1184 {
1185 GET_CURRENT_CONTEXT(ctx);
1186 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1;
1187 const GLuint unit = texunit - GL_TEXTURE0;
1188
1189 GLenum format = GL_RGBA;
1190 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
1191 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
1192 : (SHORT_BIT | INT_BIT |
1193 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
1194 UNSIGNED_INT_2_10_10_10_REV_BIT |
1195 INT_2_10_10_10_REV_BIT);
1196
1197 struct gl_vertex_array_object* vao;
1198 struct gl_buffer_object* vbo;
1199
1200 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
1201 &vao, &vbo,
1202 "glVertexArrayMultiTexCoordOffsetEXT"))
1203 return;
1204
1205 if (unit >= ctx->Const.MaxCombinedTextureImageUnits) {
1206 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexArrayMultiTexCoordOffsetEXT(texunit=%d)",
1207 texunit);
1208 return;
1209 }
1210
1211 if (!validate_array_and_format(ctx, "glVertexArrayMultiTexCoordOffsetEXT",
1212 vao, vbo,
1213 VERT_ATTRIB_TEX(unit), legalTypes,
1214 sizeMin, 4, size, type, stride,
1215 GL_FALSE, GL_FALSE, GL_FALSE, format, (void*) offset))
1216 return;
1217
1218 update_array(ctx, vao, vbo,
1219 VERT_ATTRIB_TEX(unit), format, 4, size, type,
1220 stride, GL_FALSE, GL_FALSE, GL_FALSE, (void*) offset);
1221 }
1222
1223
1224 void GLAPIENTRY
1225 _mesa_EdgeFlagPointer_no_error(GLsizei stride, const GLvoid *ptr)
1226 {
1227 /* this is the same type that glEdgeFlag uses */
1228 const GLboolean integer = GL_FALSE;
1229 GET_CURRENT_CONTEXT(ctx);
1230
1231 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1232 VERT_ATTRIB_EDGEFLAG, GL_RGBA, 1, 1, GL_UNSIGNED_BYTE,
1233 stride, GL_FALSE, integer, GL_FALSE, ptr);
1234 }
1235
1236
1237 void GLAPIENTRY
1238 _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
1239 {
1240 /* this is the same type that glEdgeFlag uses */
1241 const GLboolean integer = GL_FALSE;
1242 GET_CURRENT_CONTEXT(ctx);
1243
1244 GLenum format = GL_RGBA;
1245 const GLbitfield legalTypes = UNSIGNED_BYTE_BIT;
1246
1247 if (!validate_array_and_format(ctx, "glEdgeFlagPointer",
1248 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1249 VERT_ATTRIB_EDGEFLAG, legalTypes,
1250 1, 1, 1, GL_UNSIGNED_BYTE, stride,
1251 GL_FALSE, integer, GL_FALSE, format, ptr))
1252 return;
1253
1254 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1255 VERT_ATTRIB_EDGEFLAG, format, 1, 1, GL_UNSIGNED_BYTE,
1256 stride, GL_FALSE, integer, GL_FALSE, ptr);
1257 }
1258
1259
1260 void GLAPIENTRY
1261 _mesa_VertexArrayEdgeFlagOffsetEXT(GLuint vaobj, GLuint buffer, GLsizei stride,
1262 GLintptr offset)
1263 {
1264 /* this is the same type that glEdgeFlag uses */
1265 const GLboolean integer = GL_FALSE;
1266 GET_CURRENT_CONTEXT(ctx);
1267
1268 GLenum format = GL_RGBA;
1269 const GLbitfield legalTypes = UNSIGNED_BYTE_BIT;
1270
1271 struct gl_vertex_array_object* vao;
1272 struct gl_buffer_object* vbo;
1273
1274 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
1275 &vao, &vbo,
1276 "glVertexArrayEdgeFlagOffsetEXT"))
1277 return;
1278
1279 if (!validate_array_and_format(ctx, "glVertexArrayEdgeFlagOffsetEXT",
1280 vao, vbo,
1281 VERT_ATTRIB_EDGEFLAG, legalTypes,
1282 1, 1, 1, GL_UNSIGNED_BYTE, stride,
1283 GL_FALSE, integer, GL_FALSE, format, (void*) offset))
1284 return;
1285
1286 update_array(ctx, vao, vbo,
1287 VERT_ATTRIB_EDGEFLAG, format, 1, 1, GL_UNSIGNED_BYTE,
1288 stride, GL_FALSE, integer, GL_FALSE, (void*) offset);
1289 }
1290
1291
1292 void GLAPIENTRY
1293 _mesa_PointSizePointerOES_no_error(GLenum type, GLsizei stride,
1294 const GLvoid *ptr)
1295 {
1296 GET_CURRENT_CONTEXT(ctx);
1297
1298 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1299 VERT_ATTRIB_POINT_SIZE, GL_RGBA, 1, 1, type, stride,
1300 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
1301 }
1302
1303
1304 void GLAPIENTRY
1305 _mesa_PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *ptr)
1306 {
1307 GET_CURRENT_CONTEXT(ctx);
1308
1309 GLenum format = GL_RGBA;
1310 if (ctx->API != API_OPENGLES) {
1311 _mesa_error(ctx, GL_INVALID_OPERATION,
1312 "glPointSizePointer(ES 1.x only)");
1313 return;
1314 }
1315
1316 const GLbitfield legalTypes = (FLOAT_BIT | FIXED_ES_BIT);
1317
1318 if (!validate_array_and_format(ctx, "glPointSizePointer",
1319 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1320 VERT_ATTRIB_POINT_SIZE, legalTypes,
1321 1, 1, 1, type, stride, GL_FALSE, GL_FALSE,
1322 GL_FALSE, format, ptr))
1323 return;
1324
1325 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1326 VERT_ATTRIB_POINT_SIZE, format, 1, 1, type, stride,
1327 GL_FALSE, GL_FALSE, GL_FALSE, ptr);
1328 }
1329
1330
1331 void GLAPIENTRY
1332 _mesa_VertexAttribPointer_no_error(GLuint index, GLint size, GLenum type,
1333 GLboolean normalized,
1334 GLsizei stride, const GLvoid *ptr)
1335 {
1336 GET_CURRENT_CONTEXT(ctx);
1337
1338 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
1339 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1340 VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4,
1341 size, type, stride, normalized, GL_FALSE, GL_FALSE, ptr);
1342 }
1343
1344
1345 /**
1346 * Set a generic vertex attribute array.
1347 * Note that these arrays DO NOT alias the conventional GL vertex arrays
1348 * (position, normal, color, fog, texcoord, etc).
1349 */
1350 void GLAPIENTRY
1351 _mesa_VertexAttribPointer(GLuint index, GLint size, GLenum type,
1352 GLboolean normalized,
1353 GLsizei stride, const GLvoid *ptr)
1354 {
1355 GET_CURRENT_CONTEXT(ctx);
1356
1357 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
1358 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1359 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(idx)");
1360 return;
1361 }
1362
1363 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
1364 SHORT_BIT | UNSIGNED_SHORT_BIT |
1365 INT_BIT | UNSIGNED_INT_BIT |
1366 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
1367 FIXED_ES_BIT | FIXED_GL_BIT |
1368 UNSIGNED_INT_2_10_10_10_REV_BIT |
1369 INT_2_10_10_10_REV_BIT |
1370 UNSIGNED_INT_10F_11F_11F_REV_BIT);
1371
1372 if (!validate_array_and_format(ctx, "glVertexAttribPointer",
1373 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1374 VERT_ATTRIB_GENERIC(index), legalTypes,
1375 1, BGRA_OR_4, size, type, stride,
1376 normalized, GL_FALSE, GL_FALSE, format, ptr))
1377 return;
1378
1379 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1380 VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4,
1381 size, type, stride, normalized, GL_FALSE, GL_FALSE, ptr);
1382 }
1383
1384
1385 void GLAPIENTRY
1386 _mesa_VertexArrayVertexAttribOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size,
1387 GLenum type, GLboolean normalized,
1388 GLsizei stride, GLintptr offset)
1389 {
1390 GET_CURRENT_CONTEXT(ctx);
1391 GLenum format = get_array_format(ctx, BGRA_OR_4, &size);
1392 struct gl_vertex_array_object* vao;
1393 struct gl_buffer_object* vbo;
1394
1395 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
1396 &vao, &vbo,
1397 "glVertexArrayVertexAttribOffsetEXT"))
1398 return;
1399
1400 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1401 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexArrayVertexAttribOffsetEXT(idx)");
1402 return;
1403 }
1404
1405 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
1406 SHORT_BIT | UNSIGNED_SHORT_BIT |
1407 INT_BIT | UNSIGNED_INT_BIT |
1408 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
1409 FIXED_ES_BIT | FIXED_GL_BIT |
1410 UNSIGNED_INT_2_10_10_10_REV_BIT |
1411 INT_2_10_10_10_REV_BIT |
1412 UNSIGNED_INT_10F_11F_11F_REV_BIT);
1413
1414 if (!validate_array_and_format(ctx, "glVertexArrayVertexAttribOffsetEXT",
1415 vao, vbo,
1416 VERT_ATTRIB_GENERIC(index), legalTypes,
1417 1, BGRA_OR_4, size, type, stride,
1418 normalized, GL_FALSE, GL_FALSE, format, (void*) offset))
1419 return;
1420
1421 update_array(ctx, vao, vbo,
1422 VERT_ATTRIB_GENERIC(index), format, BGRA_OR_4,
1423 size, type, stride, normalized, GL_FALSE, GL_FALSE, (void*) offset);
1424 }
1425
1426
1427 void GLAPIENTRY
1428 _mesa_VertexArrayVertexAttribLOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size,
1429 GLenum type, GLsizei stride, GLintptr offset)
1430 {
1431 GET_CURRENT_CONTEXT(ctx);
1432 GLenum format = GL_RGBA;
1433 struct gl_vertex_array_object* vao;
1434 struct gl_buffer_object* vbo;
1435
1436 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
1437 &vao, &vbo,
1438 "glVertexArrayVertexAttribLOffsetEXT"))
1439 return;
1440
1441 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1442 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexArrayVertexAttribLOffsetEXT(idx)");
1443 return;
1444 }
1445
1446 const GLbitfield legalTypes = DOUBLE_BIT;
1447
1448 if (!validate_array_and_format(ctx, "glVertexArrayVertexAttribLOffsetEXT",
1449 vao, vbo,
1450 VERT_ATTRIB_GENERIC(index), legalTypes,
1451 1, 4, size, type, stride,
1452 GL_FALSE, GL_FALSE, GL_TRUE, format, (void*) offset))
1453 return;
1454
1455 update_array(ctx, vao, vbo,
1456 VERT_ATTRIB_GENERIC(index), format, 4,
1457 size, type, stride, GL_FALSE, GL_FALSE, GL_TRUE, (void*) offset);
1458 }
1459
1460
1461 void GLAPIENTRY
1462 _mesa_VertexAttribIPointer_no_error(GLuint index, GLint size, GLenum type,
1463 GLsizei stride, const GLvoid *ptr)
1464 {
1465 const GLboolean normalized = GL_FALSE;
1466 const GLboolean integer = GL_TRUE;
1467 GET_CURRENT_CONTEXT(ctx);
1468
1469 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1470 VERT_ATTRIB_GENERIC(index), GL_RGBA, 4, size, type,
1471 stride, normalized, integer, GL_FALSE, ptr);
1472 }
1473
1474
1475 /**
1476 * GL_EXT_gpu_shader4 / GL 3.0.
1477 * Set an integer-valued vertex attribute array.
1478 * Note that these arrays DO NOT alias the conventional GL vertex arrays
1479 * (position, normal, color, fog, texcoord, etc).
1480 */
1481 void GLAPIENTRY
1482 _mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type,
1483 GLsizei stride, const GLvoid *ptr)
1484 {
1485 const GLboolean normalized = GL_FALSE;
1486 const GLboolean integer = GL_TRUE;
1487 GET_CURRENT_CONTEXT(ctx);
1488
1489 GLenum format = GL_RGBA;
1490 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1491 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIPointer(index)");
1492 return;
1493 }
1494
1495 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
1496 SHORT_BIT | UNSIGNED_SHORT_BIT |
1497 INT_BIT | UNSIGNED_INT_BIT);
1498
1499 if (!validate_array_and_format(ctx, "glVertexAttribIPointer",
1500 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1501 VERT_ATTRIB_GENERIC(index), legalTypes,
1502 1, 4, size, type, stride,
1503 normalized, integer, GL_FALSE, format, ptr))
1504 return;
1505
1506 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1507 VERT_ATTRIB_GENERIC(index), format, 4, size, type,
1508 stride, normalized, integer, GL_FALSE, ptr);
1509 }
1510
1511
1512 void GLAPIENTRY
1513 _mesa_VertexAttribLPointer_no_error(GLuint index, GLint size, GLenum type,
1514 GLsizei stride, const GLvoid *ptr)
1515 {
1516 GET_CURRENT_CONTEXT(ctx);
1517
1518 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1519 VERT_ATTRIB_GENERIC(index), GL_RGBA, 4, size, type,
1520 stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr);
1521 }
1522
1523
1524 void GLAPIENTRY
1525 _mesa_VertexArrayVertexAttribIOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size,
1526 GLenum type, GLsizei stride, GLintptr offset)
1527 {
1528 const GLboolean normalized = GL_FALSE;
1529 const GLboolean integer = GL_TRUE;
1530 GET_CURRENT_CONTEXT(ctx);
1531 GLenum format = GL_RGBA;
1532
1533 struct gl_vertex_array_object* vao;
1534 struct gl_buffer_object* vbo;
1535
1536 if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset,
1537 &vao, &vbo,
1538 "glVertexArrayVertexAttribIOffsetEXT"))
1539 return;
1540
1541 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1542 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexArrayVertexAttribIOffsetEXT(index)");
1543 return;
1544 }
1545
1546 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
1547 SHORT_BIT | UNSIGNED_SHORT_BIT |
1548 INT_BIT | UNSIGNED_INT_BIT);
1549
1550 if (!validate_array_and_format(ctx, "glVertexArrayVertexAttribIOffsetEXT",
1551 vao, vbo,
1552 VERT_ATTRIB_GENERIC(index), legalTypes,
1553 1, 4, size, type, stride,
1554 normalized, integer, GL_FALSE, format, (void*) offset))
1555 return;
1556
1557 update_array(ctx, vao, vbo,
1558 VERT_ATTRIB_GENERIC(index), format, 4, size, type,
1559 stride, normalized, integer, GL_FALSE, (void*) offset);
1560 }
1561
1562
1563 void GLAPIENTRY
1564 _mesa_VertexAttribLPointer(GLuint index, GLint size, GLenum type,
1565 GLsizei stride, const GLvoid *ptr)
1566 {
1567 GET_CURRENT_CONTEXT(ctx);
1568
1569 GLenum format = GL_RGBA;
1570 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1571 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribLPointer(index)");
1572 return;
1573 }
1574
1575 const GLbitfield legalTypes = DOUBLE_BIT;
1576
1577 if (!validate_array_and_format(ctx, "glVertexAttribLPointer",
1578 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1579 VERT_ATTRIB_GENERIC(index), legalTypes,
1580 1, 4, size, type, stride,
1581 GL_FALSE, GL_FALSE, GL_TRUE, format, ptr))
1582 return;
1583
1584 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
1585 VERT_ATTRIB_GENERIC(index), format, 4, size, type,
1586 stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr);
1587 }
1588
1589
1590 void
1591 _mesa_enable_vertex_array_attribs(struct gl_context *ctx,
1592 struct gl_vertex_array_object *vao,
1593 GLbitfield attrib_bits)
1594 {
1595 assert((attrib_bits & ~VERT_BIT_ALL) == 0);
1596 assert(!vao->SharedAndImmutable);
1597
1598 /* Only work on bits that are disabled */
1599 attrib_bits &= ~vao->Enabled;
1600 if (attrib_bits) {
1601 /* was disabled, now being enabled */
1602 vao->Enabled |= attrib_bits;
1603 vao->NewArrays |= attrib_bits;
1604
1605 /* Update the map mode if needed */
1606 if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0))
1607 update_attribute_map_mode(ctx, vao);
1608 }
1609 }
1610
1611 static void
1612 enable_vertex_array_attrib(struct gl_context *ctx,
1613 struct gl_vertex_array_object *vao,
1614 GLuint index,
1615 const char *func)
1616 {
1617 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1618 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index)", func);
1619 return;
1620 }
1621
1622 _mesa_enable_vertex_array_attrib(ctx, vao, VERT_ATTRIB_GENERIC(index));
1623 }
1624
1625
1626 void GLAPIENTRY
1627 _mesa_EnableVertexAttribArray(GLuint index)
1628 {
1629 GET_CURRENT_CONTEXT(ctx);
1630 enable_vertex_array_attrib(ctx, ctx->Array.VAO, index,
1631 "glEnableVertexAttribArray");
1632 }
1633
1634
1635 void GLAPIENTRY
1636 _mesa_EnableVertexAttribArray_no_error(GLuint index)
1637 {
1638 GET_CURRENT_CONTEXT(ctx);
1639 _mesa_enable_vertex_array_attrib(ctx, ctx->Array.VAO,
1640 VERT_ATTRIB_GENERIC(index));
1641 }
1642
1643
1644 void GLAPIENTRY
1645 _mesa_EnableVertexArrayAttrib(GLuint vaobj, GLuint index)
1646 {
1647 GET_CURRENT_CONTEXT(ctx);
1648 struct gl_vertex_array_object *vao;
1649
1650 /* The ARB_direct_state_access specification says:
1651 *
1652 * "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib
1653 * and DisableVertexArrayAttrib if <vaobj> is not
1654 * [compatibility profile: zero or] the name of an existing vertex
1655 * array object."
1656 */
1657 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glEnableVertexArrayAttrib");
1658 if (!vao)
1659 return;
1660
1661 enable_vertex_array_attrib(ctx, vao, index, "glEnableVertexArrayAttrib");
1662 }
1663
1664 void GLAPIENTRY
1665 _mesa_EnableVertexArrayAttribEXT(GLuint vaobj, GLuint index)
1666 {
1667 GET_CURRENT_CONTEXT(ctx);
1668 struct gl_vertex_array_object* vao = _mesa_lookup_vao_err(ctx, vaobj,
1669 true,
1670 "glEnableVertexArrayAttribEXT");
1671 if (!vao)
1672 return;
1673
1674 enable_vertex_array_attrib(ctx, vao, index, "glEnableVertexArrayAttribEXT");
1675 }
1676
1677
1678 void GLAPIENTRY
1679 _mesa_EnableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index)
1680 {
1681 GET_CURRENT_CONTEXT(ctx);
1682 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
1683 _mesa_enable_vertex_array_attrib(ctx, vao, VERT_ATTRIB_GENERIC(index));
1684 }
1685
1686
1687 void
1688 _mesa_disable_vertex_array_attribs(struct gl_context *ctx,
1689 struct gl_vertex_array_object *vao,
1690 GLbitfield attrib_bits)
1691 {
1692 assert((attrib_bits & ~VERT_BIT_ALL) == 0);
1693 assert(!vao->SharedAndImmutable);
1694
1695 /* Only work on bits that are enabled */
1696 attrib_bits &= vao->Enabled;
1697 if (attrib_bits) {
1698 /* was enabled, now being disabled */
1699 vao->Enabled &= ~attrib_bits;
1700 vao->NewArrays |= attrib_bits;
1701
1702 /* Update the map mode if needed */
1703 if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0))
1704 update_attribute_map_mode(ctx, vao);
1705 }
1706 }
1707
1708
1709 void GLAPIENTRY
1710 _mesa_DisableVertexAttribArray(GLuint index)
1711 {
1712 GET_CURRENT_CONTEXT(ctx);
1713
1714 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1715 _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexAttribArray(index)");
1716 return;
1717 }
1718
1719 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1720 _mesa_disable_vertex_array_attrib(ctx, ctx->Array.VAO, attrib);
1721 }
1722
1723
1724 void GLAPIENTRY
1725 _mesa_DisableVertexAttribArray_no_error(GLuint index)
1726 {
1727 GET_CURRENT_CONTEXT(ctx);
1728 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1729 _mesa_disable_vertex_array_attrib(ctx, ctx->Array.VAO, attrib);
1730 }
1731
1732
1733 void GLAPIENTRY
1734 _mesa_DisableVertexArrayAttrib(GLuint vaobj, GLuint index)
1735 {
1736 GET_CURRENT_CONTEXT(ctx);
1737 struct gl_vertex_array_object *vao;
1738
1739 /* The ARB_direct_state_access specification says:
1740 *
1741 * "An INVALID_OPERATION error is generated by EnableVertexArrayAttrib
1742 * and DisableVertexArrayAttrib if <vaobj> is not
1743 * [compatibility profile: zero or] the name of an existing vertex
1744 * array object."
1745 */
1746 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glDisableVertexArrayAttrib");
1747 if (!vao)
1748 return;
1749
1750 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1751 _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexArrayAttrib(index)");
1752 return;
1753 }
1754
1755 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1756 _mesa_disable_vertex_array_attrib(ctx, vao, attrib);
1757 }
1758
1759 void GLAPIENTRY
1760 _mesa_DisableVertexArrayAttribEXT(GLuint vaobj, GLuint index)
1761 {
1762 GET_CURRENT_CONTEXT(ctx);
1763 struct gl_vertex_array_object* vao = _mesa_lookup_vao_err(ctx, vaobj,
1764 true,
1765 "glEnableVertexArrayAttribEXT");
1766 if (!vao)
1767 return;
1768
1769 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1770 _mesa_error(ctx, GL_INVALID_VALUE, "glDisableVertexArrayAttrib(index)");
1771 return;
1772 }
1773
1774 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1775 _mesa_disable_vertex_array_attrib(ctx, vao, attrib);
1776 }
1777
1778
1779 void GLAPIENTRY
1780 _mesa_DisableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index)
1781 {
1782 GET_CURRENT_CONTEXT(ctx);
1783 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
1784 const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC(index);
1785 _mesa_disable_vertex_array_attrib(ctx, vao, attrib);
1786 }
1787
1788
1789 /**
1790 * Return info for a vertex attribute array (no alias with legacy
1791 * vertex attributes (pos, normal, color, etc)). This function does
1792 * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query.
1793 */
1794 static GLuint
1795 get_vertex_array_attrib(struct gl_context *ctx,
1796 const struct gl_vertex_array_object *vao,
1797 GLuint index, GLenum pname,
1798 const char *caller)
1799 {
1800 const struct gl_array_attributes *array;
1801
1802 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1803 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index);
1804 return 0;
1805 }
1806
1807 assert(VERT_ATTRIB_GENERIC(index) < ARRAY_SIZE(vao->VertexAttrib));
1808
1809 array = &vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)];
1810
1811 switch (pname) {
1812 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
1813 return !!(vao->Enabled & VERT_BIT_GENERIC(index));
1814 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
1815 return (array->Format.Format == GL_BGRA) ? GL_BGRA : array->Format.Size;
1816 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
1817 return array->Stride;
1818 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
1819 return array->Format.Type;
1820 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
1821 return array->Format.Normalized;
1822 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
1823 return vao->BufferBinding[array->BufferBindingIndex].BufferObj->Name;
1824 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
1825 if ((_mesa_is_desktop_gl(ctx)
1826 && (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))
1827 || _mesa_is_gles3(ctx)) {
1828 return array->Format.Integer;
1829 }
1830 goto error;
1831 case GL_VERTEX_ATTRIB_ARRAY_LONG:
1832 if (_mesa_is_desktop_gl(ctx)) {
1833 return array->Format.Doubles;
1834 }
1835 goto error;
1836 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB:
1837 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_instanced_arrays)
1838 || _mesa_is_gles3(ctx)) {
1839 return vao->BufferBinding[array->BufferBindingIndex].InstanceDivisor;
1840 }
1841 goto error;
1842 case GL_VERTEX_ATTRIB_BINDING:
1843 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
1844 return array->BufferBindingIndex - VERT_ATTRIB_GENERIC0;
1845 }
1846 goto error;
1847 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
1848 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
1849 return array->RelativeOffset;
1850 }
1851 goto error;
1852 default:
1853 ; /* fall-through */
1854 }
1855
1856 error:
1857 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname);
1858 return 0;
1859 }
1860
1861
1862 static const GLfloat *
1863 get_current_attrib(struct gl_context *ctx, GLuint index, const char *function)
1864 {
1865 if (index == 0) {
1866 if (_mesa_attr_zero_aliases_vertex(ctx)) {
1867 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function);
1868 return NULL;
1869 }
1870 }
1871 else if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1872 _mesa_error(ctx, GL_INVALID_VALUE,
1873 "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function);
1874 return NULL;
1875 }
1876
1877 assert(VERT_ATTRIB_GENERIC(index) <
1878 ARRAY_SIZE(ctx->Array.VAO->VertexAttrib));
1879
1880 FLUSH_CURRENT(ctx, 0);
1881 return ctx->Current.Attrib[VERT_ATTRIB_GENERIC(index)];
1882 }
1883
1884 void GLAPIENTRY
1885 _mesa_GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
1886 {
1887 GET_CURRENT_CONTEXT(ctx);
1888
1889 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1890 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv");
1891 if (v != NULL) {
1892 COPY_4V(params, v);
1893 }
1894 }
1895 else {
1896 params[0] = (GLfloat) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1897 index, pname,
1898 "glGetVertexAttribfv");
1899 }
1900 }
1901
1902
1903 void GLAPIENTRY
1904 _mesa_GetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params)
1905 {
1906 GET_CURRENT_CONTEXT(ctx);
1907
1908 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1909 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv");
1910 if (v != NULL) {
1911 params[0] = (GLdouble) v[0];
1912 params[1] = (GLdouble) v[1];
1913 params[2] = (GLdouble) v[2];
1914 params[3] = (GLdouble) v[3];
1915 }
1916 }
1917 else {
1918 params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1919 index, pname,
1920 "glGetVertexAttribdv");
1921 }
1922 }
1923
1924 void GLAPIENTRY
1925 _mesa_GetVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params)
1926 {
1927 GET_CURRENT_CONTEXT(ctx);
1928
1929 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1930 const GLdouble *v =
1931 (const GLdouble *)get_current_attrib(ctx, index,
1932 "glGetVertexAttribLdv");
1933 if (v != NULL) {
1934 params[0] = v[0];
1935 params[1] = v[1];
1936 params[2] = v[2];
1937 params[3] = v[3];
1938 }
1939 }
1940 else {
1941 params[0] = (GLdouble) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1942 index, pname,
1943 "glGetVertexAttribLdv");
1944 }
1945 }
1946
1947 void GLAPIENTRY
1948 _mesa_GetVertexAttribiv(GLuint index, GLenum pname, GLint *params)
1949 {
1950 GET_CURRENT_CONTEXT(ctx);
1951
1952 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1953 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv");
1954 if (v != NULL) {
1955 /* XXX should floats in[0,1] be scaled to full int range? */
1956 params[0] = (GLint) v[0];
1957 params[1] = (GLint) v[1];
1958 params[2] = (GLint) v[2];
1959 params[3] = (GLint) v[3];
1960 }
1961 }
1962 else {
1963 params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1964 index, pname,
1965 "glGetVertexAttribiv");
1966 }
1967 }
1968
1969 void GLAPIENTRY
1970 _mesa_GetVertexAttribLui64vARB(GLuint index, GLenum pname, GLuint64EXT *params)
1971 {
1972 GET_CURRENT_CONTEXT(ctx);
1973
1974 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1975 const GLuint64 *v =
1976 (const GLuint64 *)get_current_attrib(ctx, index,
1977 "glGetVertexAttribLui64vARB");
1978 if (v != NULL) {
1979 params[0] = v[0];
1980 params[1] = v[1];
1981 params[2] = v[2];
1982 params[3] = v[3];
1983 }
1984 }
1985 else {
1986 params[0] = (GLuint64) get_vertex_array_attrib(ctx, ctx->Array.VAO,
1987 index, pname,
1988 "glGetVertexAttribLui64vARB");
1989 }
1990 }
1991
1992
1993 /** GL 3.0 */
1994 void GLAPIENTRY
1995 _mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
1996 {
1997 GET_CURRENT_CONTEXT(ctx);
1998
1999 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
2000 const GLint *v = (const GLint *)
2001 get_current_attrib(ctx, index, "glGetVertexAttribIiv");
2002 if (v != NULL) {
2003 COPY_4V(params, v);
2004 }
2005 }
2006 else {
2007 params[0] = (GLint) get_vertex_array_attrib(ctx, ctx->Array.VAO,
2008 index, pname,
2009 "glGetVertexAttribIiv");
2010 }
2011 }
2012
2013
2014 /** GL 3.0 */
2015 void GLAPIENTRY
2016 _mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
2017 {
2018 GET_CURRENT_CONTEXT(ctx);
2019
2020 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
2021 const GLuint *v = (const GLuint *)
2022 get_current_attrib(ctx, index, "glGetVertexAttribIuiv");
2023 if (v != NULL) {
2024 COPY_4V(params, v);
2025 }
2026 }
2027 else {
2028 params[0] = get_vertex_array_attrib(ctx, ctx->Array.VAO,
2029 index, pname,
2030 "glGetVertexAttribIuiv");
2031 }
2032 }
2033
2034
2035 void GLAPIENTRY
2036 _mesa_GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
2037 {
2038 GET_CURRENT_CONTEXT(ctx);
2039
2040 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2041 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
2042 return;
2043 }
2044
2045 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
2046 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
2047 return;
2048 }
2049
2050 assert(VERT_ATTRIB_GENERIC(index) <
2051 ARRAY_SIZE(ctx->Array.VAO->VertexAttrib));
2052
2053 *pointer = (GLvoid *)
2054 ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr;
2055 }
2056
2057
2058 /** ARB_direct_state_access */
2059 void GLAPIENTRY
2060 _mesa_GetVertexArrayIndexediv(GLuint vaobj, GLuint index,
2061 GLenum pname, GLint *params)
2062 {
2063 GET_CURRENT_CONTEXT(ctx);
2064 struct gl_vertex_array_object *vao;
2065
2066 /* The ARB_direct_state_access specification says:
2067 *
2068 * "An INVALID_OPERATION error is generated if <vaobj> is not
2069 * [compatibility profile: zero or] the name of an existing
2070 * vertex array object."
2071 */
2072 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glGetVertexArrayIndexediv");
2073 if (!vao)
2074 return;
2075
2076 /* The ARB_direct_state_access specification says:
2077 *
2078 * "For GetVertexArrayIndexediv, <pname> must be one of
2079 * VERTEX_ATTRIB_ARRAY_ENABLED, VERTEX_ATTRIB_ARRAY_SIZE,
2080 * VERTEX_ATTRIB_ARRAY_STRIDE, VERTEX_ATTRIB_ARRAY_TYPE,
2081 * VERTEX_ATTRIB_ARRAY_NORMALIZED, VERTEX_ATTRIB_ARRAY_INTEGER,
2082 * VERTEX_ATTRIB_ARRAY_LONG, VERTEX_ATTRIB_ARRAY_DIVISOR, or
2083 * VERTEX_ATTRIB_RELATIVE_OFFSET."
2084 *
2085 * and:
2086 *
2087 * "Add GetVertexArrayIndexediv in 'Get Command' for
2088 * VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
2089 * VERTEX_ATTRIB_BINDING,
2090 * VERTEX_ATTRIB_RELATIVE_OFFSET,
2091 * VERTEX_BINDING_OFFSET, and
2092 * VERTEX_BINDING_STRIDE states"
2093 *
2094 * The only parameter name common to both lists is
2095 * VERTEX_ATTRIB_RELATIVE_OFFSET. Also note that VERTEX_BINDING_BUFFER
2096 * and VERTEX_BINDING_DIVISOR are missing from both lists. It seems
2097 * pretty clear however that the intent is that it should be possible
2098 * to query all vertex attrib and binding states that can be set with
2099 * a DSA function.
2100 */
2101 switch (pname) {
2102 case GL_VERTEX_BINDING_OFFSET:
2103 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Offset;
2104 break;
2105 case GL_VERTEX_BINDING_STRIDE:
2106 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Stride;
2107 break;
2108 case GL_VERTEX_BINDING_DIVISOR:
2109 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].InstanceDivisor;
2110 break;
2111 case GL_VERTEX_BINDING_BUFFER:
2112 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].BufferObj->Name;
2113 break;
2114 default:
2115 params[0] = get_vertex_array_attrib(ctx, vao, index, pname,
2116 "glGetVertexArrayIndexediv");
2117 break;
2118 }
2119 }
2120
2121
2122 void GLAPIENTRY
2123 _mesa_GetVertexArrayIndexed64iv(GLuint vaobj, GLuint index,
2124 GLenum pname, GLint64 *params)
2125 {
2126 GET_CURRENT_CONTEXT(ctx);
2127 struct gl_vertex_array_object *vao;
2128
2129 /* The ARB_direct_state_access specification says:
2130 *
2131 * "An INVALID_OPERATION error is generated if <vaobj> is not
2132 * [compatibility profile: zero or] the name of an existing
2133 * vertex array object."
2134 */
2135 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glGetVertexArrayIndexed64iv");
2136 if (!vao)
2137 return;
2138
2139 /* The ARB_direct_state_access specification says:
2140 *
2141 * "For GetVertexArrayIndexed64iv, <pname> must be
2142 * VERTEX_BINDING_OFFSET."
2143 *
2144 * and:
2145 *
2146 * "An INVALID_ENUM error is generated if <pname> is not one of
2147 * the valid values listed above for the corresponding command."
2148 */
2149 if (pname != GL_VERTEX_BINDING_OFFSET) {
2150 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayIndexed64iv("
2151 "pname != GL_VERTEX_BINDING_OFFSET)");
2152 return;
2153 }
2154
2155 /* The ARB_direct_state_access specification says:
2156 *
2157 * "An INVALID_VALUE error is generated if <index> is greater than
2158 * or equal to the value of MAX_VERTEX_ATTRIBS."
2159 *
2160 * Since the index refers to a buffer binding in this case, the intended
2161 * limit must be MAX_VERTEX_ATTRIB_BINDINGS. Both limits are currently
2162 * required to be the same, so in practice this doesn't matter.
2163 */
2164 if (index >= ctx->Const.MaxVertexAttribBindings) {
2165 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexArrayIndexed64iv(index"
2166 "%d >= the value of GL_MAX_VERTEX_ATTRIB_BINDINGS (%d))",
2167 index, ctx->Const.MaxVertexAttribBindings);
2168 return;
2169 }
2170
2171 params[0] = vao->BufferBinding[VERT_ATTRIB_GENERIC(index)].Offset;
2172 }
2173
2174
2175 void GLAPIENTRY
2176 _mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
2177 GLsizei count, const GLvoid *ptr)
2178 {
2179 (void) count;
2180 _mesa_VertexPointer(size, type, stride, ptr);
2181 }
2182
2183
2184 void GLAPIENTRY
2185 _mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
2186 const GLvoid *ptr)
2187 {
2188 (void) count;
2189 _mesa_NormalPointer(type, stride, ptr);
2190 }
2191
2192
2193 void GLAPIENTRY
2194 _mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
2195 const GLvoid *ptr)
2196 {
2197 (void) count;
2198 _mesa_ColorPointer(size, type, stride, ptr);
2199 }
2200
2201
2202 void GLAPIENTRY
2203 _mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
2204 const GLvoid *ptr)
2205 {
2206 (void) count;
2207 _mesa_IndexPointer(type, stride, ptr);
2208 }
2209
2210
2211 void GLAPIENTRY
2212 _mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
2213 GLsizei count, const GLvoid *ptr)
2214 {
2215 (void) count;
2216 _mesa_TexCoordPointer(size, type, stride, ptr);
2217 }
2218
2219
2220 void GLAPIENTRY
2221 _mesa_MultiTexCoordPointerEXT(GLenum texunit, GLint size, GLenum type,
2222 GLsizei stride, const GLvoid *ptr)
2223 {
2224 GET_CURRENT_CONTEXT(ctx);
2225 const GLint sizeMin = 1;
2226 const GLuint unit = texunit - GL_TEXTURE0;
2227
2228 GLenum format = GL_RGBA;
2229 const GLbitfield legalTypes = (SHORT_BIT | INT_BIT |
2230 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
2231 UNSIGNED_INT_2_10_10_10_REV_BIT |
2232 INT_2_10_10_10_REV_BIT);
2233
2234 if (!validate_array_and_format(ctx, "glMultiTexCoordPointerEXT",
2235 ctx->Array.VAO, ctx->Array.ArrayBufferObj,
2236 VERT_ATTRIB_TEX(unit), legalTypes,
2237 sizeMin, 4, size, type, stride,
2238 GL_FALSE, GL_FALSE, GL_FALSE, format, ptr))
2239 return;
2240
2241 update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj,
2242 VERT_ATTRIB_TEX(unit), format, 4, size, type,
2243 stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr);
2244 }
2245
2246
2247 void GLAPIENTRY
2248 _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
2249 {
2250 (void) count;
2251 _mesa_EdgeFlagPointer(stride, ptr);
2252 }
2253
2254
2255 void GLAPIENTRY
2256 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
2257 {
2258 GET_CURRENT_CONTEXT(ctx);
2259 GLboolean tflag, cflag, nflag; /* enable/disable flags */
2260 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
2261 GLenum ctype = 0; /* color type */
2262 GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
2263 const GLint toffset = 0; /* always zero */
2264 GLint defstride; /* default stride */
2265 GLint c, f;
2266
2267 f = sizeof(GLfloat);
2268 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
2269
2270 if (stride < 0) {
2271 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
2272 return;
2273 }
2274
2275 switch (format) {
2276 case GL_V2F:
2277 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
2278 tcomps = 0; ccomps = 0; vcomps = 2;
2279 voffset = 0;
2280 defstride = 2*f;
2281 break;
2282 case GL_V3F:
2283 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
2284 tcomps = 0; ccomps = 0; vcomps = 3;
2285 voffset = 0;
2286 defstride = 3*f;
2287 break;
2288 case GL_C4UB_V2F:
2289 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
2290 tcomps = 0; ccomps = 4; vcomps = 2;
2291 ctype = GL_UNSIGNED_BYTE;
2292 coffset = 0;
2293 voffset = c;
2294 defstride = c + 2*f;
2295 break;
2296 case GL_C4UB_V3F:
2297 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
2298 tcomps = 0; ccomps = 4; vcomps = 3;
2299 ctype = GL_UNSIGNED_BYTE;
2300 coffset = 0;
2301 voffset = c;
2302 defstride = c + 3*f;
2303 break;
2304 case GL_C3F_V3F:
2305 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
2306 tcomps = 0; ccomps = 3; vcomps = 3;
2307 ctype = GL_FLOAT;
2308 coffset = 0;
2309 voffset = 3*f;
2310 defstride = 6*f;
2311 break;
2312 case GL_N3F_V3F:
2313 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
2314 tcomps = 0; ccomps = 0; vcomps = 3;
2315 noffset = 0;
2316 voffset = 3*f;
2317 defstride = 6*f;
2318 break;
2319 case GL_C4F_N3F_V3F:
2320 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
2321 tcomps = 0; ccomps = 4; vcomps = 3;
2322 ctype = GL_FLOAT;
2323 coffset = 0;
2324 noffset = 4*f;
2325 voffset = 7*f;
2326 defstride = 10*f;
2327 break;
2328 case GL_T2F_V3F:
2329 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
2330 tcomps = 2; ccomps = 0; vcomps = 3;
2331 voffset = 2*f;
2332 defstride = 5*f;
2333 break;
2334 case GL_T4F_V4F:
2335 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
2336 tcomps = 4; ccomps = 0; vcomps = 4;
2337 voffset = 4*f;
2338 defstride = 8*f;
2339 break;
2340 case GL_T2F_C4UB_V3F:
2341 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
2342 tcomps = 2; ccomps = 4; vcomps = 3;
2343 ctype = GL_UNSIGNED_BYTE;
2344 coffset = 2*f;
2345 voffset = c+2*f;
2346 defstride = c+5*f;
2347 break;
2348 case GL_T2F_C3F_V3F:
2349 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
2350 tcomps = 2; ccomps = 3; vcomps = 3;
2351 ctype = GL_FLOAT;
2352 coffset = 2*f;
2353 voffset = 5*f;
2354 defstride = 8*f;
2355 break;
2356 case GL_T2F_N3F_V3F:
2357 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
2358 tcomps = 2; ccomps = 0; vcomps = 3;
2359 noffset = 2*f;
2360 voffset = 5*f;
2361 defstride = 8*f;
2362 break;
2363 case GL_T2F_C4F_N3F_V3F:
2364 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
2365 tcomps = 2; ccomps = 4; vcomps = 3;
2366 ctype = GL_FLOAT;
2367 coffset = 2*f;
2368 noffset = 6*f;
2369 voffset = 9*f;
2370 defstride = 12*f;
2371 break;
2372 case GL_T4F_C4F_N3F_V4F:
2373 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
2374 tcomps = 4; ccomps = 4; vcomps = 4;
2375 ctype = GL_FLOAT;
2376 coffset = 4*f;
2377 noffset = 8*f;
2378 voffset = 11*f;
2379 defstride = 15*f;
2380 break;
2381 default:
2382 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
2383 return;
2384 }
2385
2386 if (stride==0) {
2387 stride = defstride;
2388 }
2389
2390 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
2391 _mesa_DisableClientState( GL_INDEX_ARRAY );
2392 /* XXX also disable secondary color and generic arrays? */
2393
2394 /* Texcoords */
2395 if (tflag) {
2396 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
2397 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
2398 (GLubyte *) pointer + toffset );
2399 }
2400 else {
2401 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
2402 }
2403
2404 /* Color */
2405 if (cflag) {
2406 _mesa_EnableClientState( GL_COLOR_ARRAY );
2407 _mesa_ColorPointer( ccomps, ctype, stride,
2408 (GLubyte *) pointer + coffset );
2409 }
2410 else {
2411 _mesa_DisableClientState( GL_COLOR_ARRAY );
2412 }
2413
2414
2415 /* Normals */
2416 if (nflag) {
2417 _mesa_EnableClientState( GL_NORMAL_ARRAY );
2418 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset );
2419 }
2420 else {
2421 _mesa_DisableClientState( GL_NORMAL_ARRAY );
2422 }
2423
2424 /* Vertices */
2425 _mesa_EnableClientState( GL_VERTEX_ARRAY );
2426 _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
2427 (GLubyte *) pointer + voffset );
2428 }
2429
2430
2431 void GLAPIENTRY
2432 _mesa_LockArraysEXT(GLint first, GLsizei count)
2433 {
2434 GET_CURRENT_CONTEXT(ctx);
2435
2436 if (MESA_VERBOSE & VERBOSE_API)
2437 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
2438
2439 if (first < 0) {
2440 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" );
2441 return;
2442 }
2443 if (count <= 0) {
2444 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" );
2445 return;
2446 }
2447 if (ctx->Array.LockCount != 0) {
2448 _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" );
2449 return;
2450 }
2451
2452 ctx->Array.LockFirst = first;
2453 ctx->Array.LockCount = count;
2454 }
2455
2456
2457 void GLAPIENTRY
2458 _mesa_UnlockArraysEXT( void )
2459 {
2460 GET_CURRENT_CONTEXT(ctx);
2461
2462 if (MESA_VERBOSE & VERBOSE_API)
2463 _mesa_debug(ctx, "glUnlockArrays\n");
2464
2465 if (ctx->Array.LockCount == 0) {
2466 _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" );
2467 return;
2468 }
2469
2470 ctx->Array.LockFirst = 0;
2471 ctx->Array.LockCount = 0;
2472 }
2473
2474
2475 static void
2476 primitive_restart_index(struct gl_context *ctx, GLuint index)
2477 {
2478 ctx->Array.RestartIndex = index;
2479 }
2480
2481
2482 /**
2483 * GL_NV_primitive_restart and GL 3.1
2484 */
2485 void GLAPIENTRY
2486 _mesa_PrimitiveRestartIndex_no_error(GLuint index)
2487 {
2488 GET_CURRENT_CONTEXT(ctx);
2489 primitive_restart_index(ctx, index);
2490 }
2491
2492
2493 void GLAPIENTRY
2494 _mesa_PrimitiveRestartIndex(GLuint index)
2495 {
2496 GET_CURRENT_CONTEXT(ctx);
2497
2498 if (!ctx->Extensions.NV_primitive_restart && ctx->Version < 31) {
2499 _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()");
2500 return;
2501 }
2502
2503 primitive_restart_index(ctx, index);
2504 }
2505
2506
2507 void GLAPIENTRY
2508 _mesa_VertexAttribDivisor_no_error(GLuint index, GLuint divisor)
2509 {
2510 GET_CURRENT_CONTEXT(ctx);
2511
2512 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index);
2513 struct gl_vertex_array_object * const vao = ctx->Array.VAO;
2514
2515 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
2516
2517 /* The ARB_vertex_attrib_binding spec says:
2518 *
2519 * "The command
2520 *
2521 * void VertexAttribDivisor(uint index, uint divisor);
2522 *
2523 * is equivalent to (assuming no errors are generated):
2524 *
2525 * VertexAttribBinding(index, index);
2526 * VertexBindingDivisor(index, divisor);"
2527 */
2528 _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
2529 vertex_binding_divisor(ctx, vao, genericIndex, divisor);
2530 }
2531
2532
2533 /**
2534 * See GL_ARB_instanced_arrays.
2535 * Note that the instance divisor only applies to generic arrays, not
2536 * the legacy vertex arrays.
2537 */
2538 void GLAPIENTRY
2539 _mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
2540 {
2541 GET_CURRENT_CONTEXT(ctx);
2542
2543 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index);
2544 struct gl_vertex_array_object * const vao = ctx->Array.VAO;
2545
2546 if (!ctx->Extensions.ARB_instanced_arrays) {
2547 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
2548 return;
2549 }
2550
2551 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2552 _mesa_error(ctx, GL_INVALID_VALUE,
2553 "glVertexAttribDivisor(index = %u)", index);
2554 return;
2555 }
2556
2557 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
2558
2559 /* The ARB_vertex_attrib_binding spec says:
2560 *
2561 * "The command
2562 *
2563 * void VertexAttribDivisor(uint index, uint divisor);
2564 *
2565 * is equivalent to (assuming no errors are generated):
2566 *
2567 * VertexAttribBinding(index, index);
2568 * VertexBindingDivisor(index, divisor);"
2569 */
2570 _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
2571 vertex_binding_divisor(ctx, vao, genericIndex, divisor);
2572 }
2573
2574
2575 void GLAPIENTRY
2576 _mesa_VertexArrayVertexAttribDivisorEXT(GLuint vaobj, GLuint index, GLuint divisor)
2577 {
2578 GET_CURRENT_CONTEXT(ctx);
2579
2580 const gl_vert_attrib genericIndex = VERT_ATTRIB_GENERIC(index);
2581 struct gl_vertex_array_object * vao;
2582 /* The ARB_instanced_arrays spec says:
2583 *
2584 * "The vertex array object named by vaobj must
2585 * be generated by GenVertexArrays (and not since deleted);
2586 * otherwise an INVALID_OPERATION error is generated."
2587 */
2588 vao = _mesa_lookup_vao_err(ctx, vaobj,
2589 false,
2590 "glVertexArrayVertexAttribDivisorEXT");
2591 if (!vao)
2592 return;
2593
2594 if (!ctx->Extensions.ARB_instanced_arrays) {
2595 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexArrayVertexAttribDivisorEXT()");
2596 return;
2597 }
2598
2599 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
2600 _mesa_error(ctx, GL_INVALID_VALUE,
2601 "glVertexArrayVertexAttribDivisorEXT(index = %u)", index);
2602 return;
2603 }
2604
2605 assert(genericIndex < ARRAY_SIZE(vao->VertexAttrib));
2606
2607 /* The ARB_vertex_attrib_binding spec says:
2608 *
2609 * "The command
2610 *
2611 * void VertexAttribDivisor(uint index, uint divisor);
2612 *
2613 * is equivalent to (assuming no errors are generated):
2614 *
2615 * VertexAttribBinding(index, index);
2616 * VertexBindingDivisor(index, divisor);"
2617 */
2618 _mesa_vertex_attrib_binding(ctx, vao, genericIndex, genericIndex);
2619 vertex_binding_divisor(ctx, vao, genericIndex, divisor);
2620 }
2621
2622
2623
2624 static ALWAYS_INLINE void
2625 vertex_array_vertex_buffer(struct gl_context *ctx,
2626 struct gl_vertex_array_object *vao,
2627 GLuint bindingIndex, GLuint buffer, GLintptr offset,
2628 GLsizei stride, bool no_error, const char *func)
2629 {
2630 struct gl_buffer_object *vbo;
2631 if (buffer ==
2632 vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj->Name) {
2633 vbo = vao->BufferBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj;
2634 } else if (buffer != 0) {
2635 vbo = _mesa_lookup_bufferobj(ctx, buffer);
2636
2637 if (!no_error && !vbo && _mesa_is_gles31(ctx)) {
2638 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", func);
2639 return;
2640 }
2641 /* From the GL_ARB_vertex_attrib_array spec:
2642 *
2643 * "[Core profile only:]
2644 * An INVALID_OPERATION error is generated if buffer is not zero or a
2645 * name returned from a previous call to GenBuffers, or if such a name
2646 * has since been deleted with DeleteBuffers.
2647 *
2648 * Otherwise, we fall back to the same compat profile behavior as other
2649 * object references (automatically gen it).
2650 */
2651 if (!_mesa_handle_bind_buffer_gen(ctx, buffer, &vbo, func))
2652 return;
2653 } else {
2654 /* The ARB_vertex_attrib_binding spec says:
2655 *
2656 * "If <buffer> is zero, any buffer object attached to this
2657 * bindpoint is detached."
2658 */
2659 vbo = ctx->Shared->NullBufferObj;
2660 }
2661
2662 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex),
2663 vbo, offset, stride);
2664 }
2665
2666
2667 /**
2668 * GL_ARB_vertex_attrib_binding
2669 */
2670 static void
2671 vertex_array_vertex_buffer_err(struct gl_context *ctx,
2672 struct gl_vertex_array_object *vao,
2673 GLuint bindingIndex, GLuint buffer,
2674 GLintptr offset, GLsizei stride,
2675 const char *func)
2676 {
2677 ASSERT_OUTSIDE_BEGIN_END(ctx);
2678
2679 /* The ARB_vertex_attrib_binding spec says:
2680 *
2681 * "An INVALID_VALUE error is generated if <bindingindex> is greater than
2682 * the value of MAX_VERTEX_ATTRIB_BINDINGS."
2683 */
2684 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
2685 _mesa_error(ctx, GL_INVALID_VALUE,
2686 "%s(bindingindex=%u > "
2687 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
2688 func, bindingIndex);
2689 return;
2690 }
2691
2692 /* The ARB_vertex_attrib_binding spec says:
2693 *
2694 * "The error INVALID_VALUE is generated if <stride> or <offset>
2695 * are negative."
2696 */
2697 if (offset < 0) {
2698 _mesa_error(ctx, GL_INVALID_VALUE,
2699 "%s(offset=%" PRId64 " < 0)",
2700 func, (int64_t) offset);
2701 return;
2702 }
2703
2704 if (stride < 0) {
2705 _mesa_error(ctx, GL_INVALID_VALUE,
2706 "%s(stride=%d < 0)", func, stride);
2707 return;
2708 }
2709
2710 if (((_mesa_is_desktop_gl(ctx) && ctx->Version >= 44) || _mesa_is_gles31(ctx)) &&
2711 stride > ctx->Const.MaxVertexAttribStride) {
2712 _mesa_error(ctx, GL_INVALID_VALUE, "%s(stride=%d > "
2713 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, stride);
2714 return;
2715 }
2716
2717 vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset,
2718 stride, false, func);
2719 }
2720
2721
2722 void GLAPIENTRY
2723 _mesa_BindVertexBuffer_no_error(GLuint bindingIndex, GLuint buffer,
2724 GLintptr offset, GLsizei stride)
2725 {
2726 GET_CURRENT_CONTEXT(ctx);
2727 vertex_array_vertex_buffer(ctx, ctx->Array.VAO, bindingIndex,
2728 buffer, offset, stride, true,
2729 "glBindVertexBuffer");
2730 }
2731
2732
2733 void GLAPIENTRY
2734 _mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset,
2735 GLsizei stride)
2736 {
2737 GET_CURRENT_CONTEXT(ctx);
2738
2739 /* The ARB_vertex_attrib_binding spec says:
2740 *
2741 * "An INVALID_OPERATION error is generated if no vertex array object
2742 * is bound."
2743 */
2744 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
2745 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2746 _mesa_error(ctx, GL_INVALID_OPERATION,
2747 "glBindVertexBuffer(No array object bound)");
2748 return;
2749 }
2750
2751 vertex_array_vertex_buffer_err(ctx, ctx->Array.VAO, bindingIndex,
2752 buffer, offset, stride,
2753 "glBindVertexBuffer");
2754 }
2755
2756
2757 void GLAPIENTRY
2758 _mesa_VertexArrayVertexBuffer_no_error(GLuint vaobj, GLuint bindingIndex,
2759 GLuint buffer, GLintptr offset,
2760 GLsizei stride)
2761 {
2762 GET_CURRENT_CONTEXT(ctx);
2763
2764 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2765 vertex_array_vertex_buffer(ctx, vao, bindingIndex, buffer, offset,
2766 stride, true, "glVertexArrayVertexBuffer");
2767 }
2768
2769
2770 void GLAPIENTRY
2771 _mesa_VertexArrayVertexBuffer(GLuint vaobj, GLuint bindingIndex, GLuint buffer,
2772 GLintptr offset, GLsizei stride)
2773 {
2774 GET_CURRENT_CONTEXT(ctx);
2775 struct gl_vertex_array_object *vao;
2776
2777 /* The ARB_direct_state_access specification says:
2778 *
2779 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
2780 * if <vaobj> is not [compatibility profile: zero or] the name of an
2781 * existing vertex array object."
2782 */
2783 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayVertexBuffer");
2784 if (!vao)
2785 return;
2786
2787 vertex_array_vertex_buffer_err(ctx, vao, bindingIndex, buffer, offset,
2788 stride, "glVertexArrayVertexBuffer");
2789 }
2790
2791
2792 void GLAPIENTRY
2793 _mesa_VertexArrayBindVertexBufferEXT(GLuint vaobj, GLuint bindingIndex, GLuint buffer,
2794 GLintptr offset, GLsizei stride)
2795 {
2796 GET_CURRENT_CONTEXT(ctx);
2797 struct gl_vertex_array_object *vao;
2798 vao = _mesa_lookup_vao_err(ctx, vaobj, true, "glVertexArrayBindVertexBufferEXT");
2799 if (!vao)
2800 return;
2801
2802 vertex_array_vertex_buffer_err(ctx, vao, bindingIndex, buffer, offset,
2803 stride, "glVertexArrayBindVertexBufferEXT");
2804 }
2805
2806
2807 static ALWAYS_INLINE void
2808 vertex_array_vertex_buffers(struct gl_context *ctx,
2809 struct gl_vertex_array_object *vao,
2810 GLuint first, GLsizei count, const GLuint *buffers,
2811 const GLintptr *offsets, const GLsizei *strides,
2812 bool no_error, const char *func)
2813 {
2814 GLint i;
2815
2816 if (!buffers) {
2817 /**
2818 * The ARB_multi_bind spec says:
2819 *
2820 * "If <buffers> is NULL, each affected vertex buffer binding point
2821 * from <first> through <first>+<count>-1 will be reset to have no
2822 * bound buffer object. In this case, the offsets and strides
2823 * associated with the binding points are set to default values,
2824 * ignoring <offsets> and <strides>."
2825 */
2826 struct gl_buffer_object *vbo = ctx->Shared->NullBufferObj;
2827
2828 for (i = 0; i < count; i++)
2829 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
2830 vbo, 0, 16);
2831
2832 return;
2833 }
2834
2835 /* Note that the error semantics for multi-bind commands differ from
2836 * those of other GL commands.
2837 *
2838 * The Issues section in the ARB_multi_bind spec says:
2839 *
2840 * "(11) Typically, OpenGL specifies that if an error is generated by
2841 * a command, that command has no effect. This is somewhat
2842 * unfortunate for multi-bind commands, because it would require
2843 * a first pass to scan the entire list of bound objects for
2844 * errors and then a second pass to actually perform the
2845 * bindings. Should we have different error semantics?
2846 *
2847 * RESOLVED: Yes. In this specification, when the parameters for
2848 * one of the <count> binding points are invalid, that binding
2849 * point is not updated and an error will be generated. However,
2850 * other binding points in the same command will be updated if
2851 * their parameters are valid and no other error occurs."
2852 */
2853
2854 _mesa_HashLockMutex(ctx->Shared->BufferObjects);
2855
2856 for (i = 0; i < count; i++) {
2857 struct gl_buffer_object *vbo;
2858
2859 if (!no_error) {
2860 /* The ARB_multi_bind spec says:
2861 *
2862 * "An INVALID_VALUE error is generated if any value in
2863 * <offsets> or <strides> is negative (per binding)."
2864 */
2865 if (offsets[i] < 0) {
2866 _mesa_error(ctx, GL_INVALID_VALUE,
2867 "%s(offsets[%u]=%" PRId64 " < 0)",
2868 func, i, (int64_t) offsets[i]);
2869 continue;
2870 }
2871
2872 if (strides[i] < 0) {
2873 _mesa_error(ctx, GL_INVALID_VALUE,
2874 "%s(strides[%u]=%d < 0)",
2875 func, i, strides[i]);
2876 continue;
2877 }
2878
2879 if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 44 &&
2880 strides[i] > ctx->Const.MaxVertexAttribStride) {
2881 _mesa_error(ctx, GL_INVALID_VALUE,
2882 "%s(strides[%u]=%d > "
2883 "GL_MAX_VERTEX_ATTRIB_STRIDE)", func, i, strides[i]);
2884 continue;
2885 }
2886 }
2887
2888 if (buffers[i]) {
2889 struct gl_vertex_buffer_binding *binding =
2890 &vao->BufferBinding[VERT_ATTRIB_GENERIC(first + i)];
2891
2892 if (buffers[i] == binding->BufferObj->Name)
2893 vbo = binding->BufferObj;
2894 else
2895 vbo = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, func);
2896
2897 if (!vbo)
2898 continue;
2899 } else {
2900 vbo = ctx->Shared->NullBufferObj;
2901 }
2902
2903 _mesa_bind_vertex_buffer(ctx, vao, VERT_ATTRIB_GENERIC(first + i),
2904 vbo, offsets[i], strides[i]);
2905 }
2906
2907 _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
2908 }
2909
2910
2911 static void
2912 vertex_array_vertex_buffers_err(struct gl_context *ctx,
2913 struct gl_vertex_array_object *vao,
2914 GLuint first, GLsizei count,
2915 const GLuint *buffers, const GLintptr *offsets,
2916 const GLsizei *strides, const char *func)
2917 {
2918 ASSERT_OUTSIDE_BEGIN_END(ctx);
2919
2920 /* The ARB_multi_bind spec says:
2921 *
2922 * "An INVALID_OPERATION error is generated if <first> + <count>
2923 * is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS."
2924 */
2925 if (first + count > ctx->Const.MaxVertexAttribBindings) {
2926 _mesa_error(ctx, GL_INVALID_OPERATION,
2927 "%s(first=%u + count=%d > the value of "
2928 "GL_MAX_VERTEX_ATTRIB_BINDINGS=%u)",
2929 func, first, count, ctx->Const.MaxVertexAttribBindings);
2930 return;
2931 }
2932
2933 vertex_array_vertex_buffers(ctx, vao, first, count, buffers, offsets,
2934 strides, false, func);
2935 }
2936
2937
2938 void GLAPIENTRY
2939 _mesa_BindVertexBuffers_no_error(GLuint first, GLsizei count,
2940 const GLuint *buffers, const GLintptr *offsets,
2941 const GLsizei *strides)
2942 {
2943 GET_CURRENT_CONTEXT(ctx);
2944
2945 vertex_array_vertex_buffers(ctx, ctx->Array.VAO, first, count,
2946 buffers, offsets, strides, true,
2947 "glBindVertexBuffers");
2948 }
2949
2950
2951 void GLAPIENTRY
2952 _mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers,
2953 const GLintptr *offsets, const GLsizei *strides)
2954 {
2955 GET_CURRENT_CONTEXT(ctx);
2956
2957 /* The ARB_vertex_attrib_binding spec says:
2958 *
2959 * "An INVALID_OPERATION error is generated if no
2960 * vertex array object is bound."
2961 */
2962 if (ctx->API == API_OPENGL_CORE &&
2963 ctx->Array.VAO == ctx->Array.DefaultVAO) {
2964 _mesa_error(ctx, GL_INVALID_OPERATION,
2965 "glBindVertexBuffers(No array object bound)");
2966 return;
2967 }
2968
2969 vertex_array_vertex_buffers_err(ctx, ctx->Array.VAO, first, count,
2970 buffers, offsets, strides,
2971 "glBindVertexBuffers");
2972 }
2973
2974
2975 void GLAPIENTRY
2976 _mesa_VertexArrayVertexBuffers_no_error(GLuint vaobj, GLuint first,
2977 GLsizei count, const GLuint *buffers,
2978 const GLintptr *offsets,
2979 const GLsizei *strides)
2980 {
2981 GET_CURRENT_CONTEXT(ctx);
2982
2983 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
2984 vertex_array_vertex_buffers(ctx, vao, first, count,
2985 buffers, offsets, strides, true,
2986 "glVertexArrayVertexBuffers");
2987 }
2988
2989
2990 void GLAPIENTRY
2991 _mesa_VertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count,
2992 const GLuint *buffers,
2993 const GLintptr *offsets, const GLsizei *strides)
2994 {
2995 GET_CURRENT_CONTEXT(ctx);
2996 struct gl_vertex_array_object *vao;
2997
2998 /* The ARB_direct_state_access specification says:
2999 *
3000 * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer
3001 * if <vaobj> is not [compatibility profile: zero or] the name of an
3002 * existing vertex array object."
3003 */
3004 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayVertexBuffers");
3005 if (!vao)
3006 return;
3007
3008 vertex_array_vertex_buffers_err(ctx, vao, first, count,
3009 buffers, offsets, strides,
3010 "glVertexArrayVertexBuffers");
3011 }
3012
3013
3014 static void
3015 vertex_attrib_format(GLuint attribIndex, GLint size, GLenum type,
3016 GLboolean normalized, GLboolean integer,
3017 GLboolean doubles, GLbitfield legalTypes,
3018 GLsizei sizeMax, GLuint relativeOffset,
3019 const char *func)
3020 {
3021 GET_CURRENT_CONTEXT(ctx);
3022 ASSERT_OUTSIDE_BEGIN_END(ctx);
3023
3024 GLenum format = get_array_format(ctx, sizeMax, &size);
3025
3026 if (!_mesa_is_no_error_enabled(ctx)) {
3027 /* The ARB_vertex_attrib_binding spec says:
3028 *
3029 * "An INVALID_OPERATION error is generated under any of the
3030 * following conditions:
3031 * - if no vertex array object is currently bound (see section
3032 * 2.10);
3033 * - ..."
3034 *
3035 * This error condition only applies to VertexAttribFormat and
3036 * VertexAttribIFormat in the extension spec, but we assume that this
3037 * is an oversight. In the OpenGL 4.3 (Core Profile) spec, it applies
3038 * to all three functions.
3039 */
3040 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
3041 ctx->Array.VAO == ctx->Array.DefaultVAO) {
3042 _mesa_error(ctx, GL_INVALID_OPERATION,
3043 "%s(No array object bound)", func);
3044 return;
3045 }
3046
3047 /* The ARB_vertex_attrib_binding spec says:
3048 *
3049 * "The error INVALID_VALUE is generated if index is greater than or
3050 * equal to the value of MAX_VERTEX_ATTRIBS."
3051 */
3052 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
3053 _mesa_error(ctx, GL_INVALID_VALUE,
3054 "%s(attribindex=%u > "
3055 "GL_MAX_VERTEX_ATTRIBS)",
3056 func, attribIndex);
3057 return;
3058 }
3059
3060 if (!validate_array_format(ctx, func, ctx->Array.VAO,
3061 VERT_ATTRIB_GENERIC(attribIndex),
3062 legalTypes, 1, sizeMax, size, type,
3063 normalized, integer, doubles, relativeOffset,
3064 format)) {
3065 return;
3066 }
3067 }
3068
3069 _mesa_update_array_format(ctx, ctx->Array.VAO,
3070 VERT_ATTRIB_GENERIC(attribIndex), size, type,
3071 format, normalized, integer, doubles,
3072 relativeOffset);
3073 }
3074
3075
3076 void GLAPIENTRY
3077 _mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type,
3078 GLboolean normalized, GLuint relativeOffset)
3079 {
3080 vertex_attrib_format(attribIndex, size, type, normalized,
3081 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
3082 BGRA_OR_4, relativeOffset,
3083 "glVertexAttribFormat");
3084 }
3085
3086
3087 void GLAPIENTRY
3088 _mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type,
3089 GLuint relativeOffset)
3090 {
3091 vertex_attrib_format(attribIndex, size, type, GL_FALSE,
3092 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK, 4,
3093 relativeOffset, "glVertexAttribIFormat");
3094 }
3095
3096
3097 void GLAPIENTRY
3098 _mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type,
3099 GLuint relativeOffset)
3100 {
3101 vertex_attrib_format(attribIndex, size, type, GL_FALSE, GL_FALSE,
3102 GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK, 4,
3103 relativeOffset, "glVertexAttribLFormat");
3104 }
3105
3106
3107 static void
3108 vertex_array_attrib_format(GLuint vaobj, bool isExtDsa, GLuint attribIndex,
3109 GLint size, GLenum type, GLboolean normalized,
3110 GLboolean integer, GLboolean doubles,
3111 GLbitfield legalTypes, GLsizei sizeMax,
3112 GLuint relativeOffset, const char *func)
3113 {
3114 GET_CURRENT_CONTEXT(ctx);
3115 struct gl_vertex_array_object *vao;
3116
3117 ASSERT_OUTSIDE_BEGIN_END(ctx);
3118
3119 GLenum format = get_array_format(ctx, sizeMax, &size);
3120
3121 if (_mesa_is_no_error_enabled(ctx)) {
3122 vao = _mesa_lookup_vao(ctx, vaobj);
3123 if (!vao)
3124 return;
3125 } else {
3126 vao = _mesa_lookup_vao_err(ctx, vaobj, isExtDsa, func);
3127 if (!vao)
3128 return;
3129
3130 /* The ARB_vertex_attrib_binding spec says:
3131 *
3132 * "The error INVALID_VALUE is generated if index is greater than or
3133 * equal to the value of MAX_VERTEX_ATTRIBS."
3134 */
3135 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
3136 _mesa_error(ctx, GL_INVALID_VALUE,
3137 "%s(attribindex=%u > GL_MAX_VERTEX_ATTRIBS)",
3138 func, attribIndex);
3139 return;
3140 }
3141
3142 if (!validate_array_format(ctx, func, vao,
3143 VERT_ATTRIB_GENERIC(attribIndex),
3144 legalTypes, 1, sizeMax, size, type,
3145 normalized, integer, doubles, relativeOffset,
3146 format)) {
3147 return;
3148 }
3149 }
3150
3151 _mesa_update_array_format(ctx, vao, VERT_ATTRIB_GENERIC(attribIndex), size,
3152 type, format, normalized, integer, doubles,
3153 relativeOffset);
3154 }
3155
3156
3157 void GLAPIENTRY
3158 _mesa_VertexArrayAttribFormat(GLuint vaobj, GLuint attribIndex, GLint size,
3159 GLenum type, GLboolean normalized,
3160 GLuint relativeOffset)
3161 {
3162 vertex_array_attrib_format(vaobj, false, attribIndex, size, type, normalized,
3163 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
3164 BGRA_OR_4, relativeOffset,
3165 "glVertexArrayAttribFormat");
3166 }
3167
3168
3169 void GLAPIENTRY
3170 _mesa_VertexArrayVertexAttribFormatEXT(GLuint vaobj, GLuint attribIndex, GLint size,
3171 GLenum type, GLboolean normalized,
3172 GLuint relativeOffset)
3173 {
3174 vertex_array_attrib_format(vaobj, true, attribIndex, size, type, normalized,
3175 GL_FALSE, GL_FALSE, ATTRIB_FORMAT_TYPES_MASK,
3176 BGRA_OR_4, relativeOffset,
3177 "glVertexArrayVertexAttribFormatEXT");
3178 }
3179
3180
3181 void GLAPIENTRY
3182 _mesa_VertexArrayAttribIFormat(GLuint vaobj, GLuint attribIndex,
3183 GLint size, GLenum type,
3184 GLuint relativeOffset)
3185 {
3186 vertex_array_attrib_format(vaobj, false, attribIndex, size, type, GL_FALSE,
3187 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK,
3188 4, relativeOffset,
3189 "glVertexArrayAttribIFormat");
3190 }
3191
3192
3193 void GLAPIENTRY
3194 _mesa_VertexArrayVertexAttribIFormatEXT(GLuint vaobj, GLuint attribIndex,
3195 GLint size, GLenum type,
3196 GLuint relativeOffset)
3197 {
3198 vertex_array_attrib_format(vaobj, true, attribIndex, size, type, GL_FALSE,
3199 GL_TRUE, GL_FALSE, ATTRIB_IFORMAT_TYPES_MASK,
3200 4, relativeOffset,
3201 "glVertexArrayVertexAttribIFormatEXT");
3202 }
3203
3204
3205 void GLAPIENTRY
3206 _mesa_VertexArrayAttribLFormat(GLuint vaobj, GLuint attribIndex,
3207 GLint size, GLenum type,
3208 GLuint relativeOffset)
3209 {
3210 vertex_array_attrib_format(vaobj, false, attribIndex, size, type, GL_FALSE,
3211 GL_FALSE, GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK,
3212 4, relativeOffset,
3213 "glVertexArrayAttribLFormat");
3214 }
3215
3216
3217 void GLAPIENTRY
3218 _mesa_VertexArrayVertexAttribLFormatEXT(GLuint vaobj, GLuint attribIndex,
3219 GLint size, GLenum type,
3220 GLuint relativeOffset)
3221 {
3222 vertex_array_attrib_format(vaobj, true, attribIndex, size, type, GL_FALSE,
3223 GL_FALSE, GL_TRUE, ATTRIB_LFORMAT_TYPES_MASK,
3224 4, relativeOffset,
3225 "glVertexArrayVertexAttribLFormatEXT");
3226 }
3227
3228
3229 static void
3230 vertex_array_attrib_binding(struct gl_context *ctx,
3231 struct gl_vertex_array_object *vao,
3232 GLuint attribIndex, GLuint bindingIndex,
3233 const char *func)
3234 {
3235 ASSERT_OUTSIDE_BEGIN_END(ctx);
3236
3237 /* The ARB_vertex_attrib_binding spec says:
3238 *
3239 * "<attribindex> must be less than the value of MAX_VERTEX_ATTRIBS and
3240 * <bindingindex> must be less than the value of
3241 * MAX_VERTEX_ATTRIB_BINDINGS, otherwise the error INVALID_VALUE
3242 * is generated."
3243 */
3244 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
3245 _mesa_error(ctx, GL_INVALID_VALUE,
3246 "%s(attribindex=%u >= "
3247 "GL_MAX_VERTEX_ATTRIBS)",
3248 func, attribIndex);
3249 return;
3250 }
3251
3252 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
3253 _mesa_error(ctx, GL_INVALID_VALUE,
3254 "%s(bindingindex=%u >= "
3255 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
3256 func, bindingIndex);
3257 return;
3258 }
3259
3260 assert(VERT_ATTRIB_GENERIC(attribIndex) < ARRAY_SIZE(vao->VertexAttrib));
3261
3262 _mesa_vertex_attrib_binding(ctx, vao,
3263 VERT_ATTRIB_GENERIC(attribIndex),
3264 VERT_ATTRIB_GENERIC(bindingIndex));
3265 }
3266
3267
3268 void GLAPIENTRY
3269 _mesa_VertexAttribBinding_no_error(GLuint attribIndex, GLuint bindingIndex)
3270 {
3271 GET_CURRENT_CONTEXT(ctx);
3272 _mesa_vertex_attrib_binding(ctx, ctx->Array.VAO,
3273 VERT_ATTRIB_GENERIC(attribIndex),
3274 VERT_ATTRIB_GENERIC(bindingIndex));
3275 }
3276
3277
3278 void GLAPIENTRY
3279 _mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3280 {
3281 GET_CURRENT_CONTEXT(ctx);
3282
3283 /* The ARB_vertex_attrib_binding spec says:
3284 *
3285 * "An INVALID_OPERATION error is generated if no vertex array object
3286 * is bound."
3287 */
3288 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
3289 ctx->Array.VAO == ctx->Array.DefaultVAO) {
3290 _mesa_error(ctx, GL_INVALID_OPERATION,
3291 "glVertexAttribBinding(No array object bound)");
3292 return;
3293 }
3294
3295 vertex_array_attrib_binding(ctx, ctx->Array.VAO,
3296 attribIndex, bindingIndex,
3297 "glVertexAttribBinding");
3298 }
3299
3300
3301 void GLAPIENTRY
3302 _mesa_VertexArrayAttribBinding_no_error(GLuint vaobj, GLuint attribIndex,
3303 GLuint bindingIndex)
3304 {
3305 GET_CURRENT_CONTEXT(ctx);
3306
3307 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
3308 _mesa_vertex_attrib_binding(ctx, vao,
3309 VERT_ATTRIB_GENERIC(attribIndex),
3310 VERT_ATTRIB_GENERIC(bindingIndex));
3311 }
3312
3313
3314 void GLAPIENTRY
3315 _mesa_VertexArrayAttribBinding(GLuint vaobj, GLuint attribIndex, GLuint bindingIndex)
3316 {
3317 GET_CURRENT_CONTEXT(ctx);
3318 struct gl_vertex_array_object *vao;
3319
3320 /* The ARB_direct_state_access specification says:
3321 *
3322 * "An INVALID_OPERATION error is generated by VertexArrayAttribBinding
3323 * if <vaobj> is not [compatibility profile: zero or] the name of an
3324 * existing vertex array object."
3325 */
3326 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayAttribBinding");
3327 if (!vao)
3328 return;
3329
3330 vertex_array_attrib_binding(ctx, vao, attribIndex, bindingIndex,
3331 "glVertexArrayAttribBinding");
3332 }
3333
3334
3335 void GLAPIENTRY
3336 _mesa_VertexArrayVertexAttribBindingEXT(GLuint vaobj, GLuint attribIndex, GLuint bindingIndex)
3337 {
3338 GET_CURRENT_CONTEXT(ctx);
3339 struct gl_vertex_array_object *vao;
3340 vao = _mesa_lookup_vao_err(ctx, vaobj, true, "glVertexArrayVertexAttribBindingEXT");
3341 if (!vao)
3342 return;
3343
3344 vertex_array_attrib_binding(ctx, vao, attribIndex, bindingIndex,
3345 "glVertexArrayVertexAttribBindingEXT");
3346 }
3347
3348
3349 static void
3350 vertex_array_binding_divisor(struct gl_context *ctx,
3351 struct gl_vertex_array_object *vao,
3352 GLuint bindingIndex, GLuint divisor,
3353 const char *func)
3354 {
3355 ASSERT_OUTSIDE_BEGIN_END(ctx);
3356
3357 if (!ctx->Extensions.ARB_instanced_arrays) {
3358 _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", func);
3359 return;
3360 }
3361
3362 /* The ARB_vertex_attrib_binding spec says:
3363 *
3364 * "An INVALID_VALUE error is generated if <bindingindex> is greater
3365 * than or equal to the value of MAX_VERTEX_ATTRIB_BINDINGS."
3366 */
3367 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
3368 _mesa_error(ctx, GL_INVALID_VALUE,
3369 "%s(bindingindex=%u > "
3370 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
3371 func, bindingIndex);
3372 return;
3373 }
3374
3375 vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
3376 }
3377
3378
3379 void GLAPIENTRY
3380 _mesa_VertexBindingDivisor_no_error(GLuint bindingIndex, GLuint divisor)
3381 {
3382 GET_CURRENT_CONTEXT(ctx);
3383 vertex_binding_divisor(ctx, ctx->Array.VAO,
3384 VERT_ATTRIB_GENERIC(bindingIndex), divisor);
3385 }
3386
3387
3388 void GLAPIENTRY
3389 _mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3390 {
3391 GET_CURRENT_CONTEXT(ctx);
3392
3393 /* The ARB_vertex_attrib_binding spec says:
3394 *
3395 * "An INVALID_OPERATION error is generated if no vertex array object
3396 * is bound."
3397 */
3398 if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) &&
3399 ctx->Array.VAO == ctx->Array.DefaultVAO) {
3400 _mesa_error(ctx, GL_INVALID_OPERATION,
3401 "glVertexBindingDivisor(No array object bound)");
3402 return;
3403 }
3404
3405 vertex_array_binding_divisor(ctx, ctx->Array.VAO,
3406 bindingIndex, divisor,
3407 "glVertexBindingDivisor");
3408 }
3409
3410
3411 void GLAPIENTRY
3412 _mesa_VertexArrayBindingDivisor_no_error(GLuint vaobj, GLuint bindingIndex,
3413 GLuint divisor)
3414 {
3415 GET_CURRENT_CONTEXT(ctx);
3416
3417 struct gl_vertex_array_object *vao = _mesa_lookup_vao(ctx, vaobj);
3418 vertex_binding_divisor(ctx, vao, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
3419 }
3420
3421
3422 void GLAPIENTRY
3423 _mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex,
3424 GLuint divisor)
3425 {
3426 struct gl_vertex_array_object *vao;
3427 GET_CURRENT_CONTEXT(ctx);
3428
3429 /* The ARB_direct_state_access specification says:
3430 *
3431 * "An INVALID_OPERATION error is generated by VertexArrayBindingDivisor
3432 * if <vaobj> is not [compatibility profile: zero or] the name of an
3433 * existing vertex array object."
3434 */
3435 vao = _mesa_lookup_vao_err(ctx, vaobj, false, "glVertexArrayBindingDivisor");
3436 if (!vao)
3437 return;
3438
3439 vertex_array_binding_divisor(ctx, vao, bindingIndex, divisor,
3440 "glVertexArrayBindingDivisor");
3441 }
3442
3443
3444 void GLAPIENTRY
3445 _mesa_VertexArrayVertexBindingDivisorEXT(GLuint vaobj, GLuint bindingIndex,
3446 GLuint divisor)
3447 {
3448 struct gl_vertex_array_object *vao;
3449 GET_CURRENT_CONTEXT(ctx);
3450
3451 /* The ARB_direct_state_access specification says:
3452 *
3453 * "An INVALID_OPERATION error is generated by VertexArrayBindingDivisor
3454 * if <vaobj> is not [compatibility profile: zero or] the name of an
3455 * existing vertex array object."
3456 */
3457 vao = _mesa_lookup_vao_err(ctx, vaobj, true, "glVertexArrayVertexBindingDivisorEXT");
3458 if (!vao)
3459 return;
3460
3461 vertex_array_binding_divisor(ctx, vao, bindingIndex, divisor,
3462 "glVertexArrayVertexBindingDivisorEXT");
3463 }
3464
3465
3466 void
3467 _mesa_copy_vertex_attrib_array(struct gl_context *ctx,
3468 struct gl_array_attributes *dst,
3469 const struct gl_array_attributes *src)
3470 {
3471 dst->Ptr = src->Ptr;
3472 dst->RelativeOffset = src->RelativeOffset;
3473 dst->Format = src->Format;
3474 dst->Stride = src->Stride;
3475 dst->BufferBindingIndex = src->BufferBindingIndex;
3476 dst->_EffBufferBindingIndex = src->_EffBufferBindingIndex;
3477 dst->_EffRelativeOffset = src->_EffRelativeOffset;
3478 }
3479
3480 void
3481 _mesa_copy_vertex_buffer_binding(struct gl_context *ctx,
3482 struct gl_vertex_buffer_binding *dst,
3483 const struct gl_vertex_buffer_binding *src)
3484 {
3485 dst->Offset = src->Offset;
3486 dst->Stride = src->Stride;
3487 dst->InstanceDivisor = src->InstanceDivisor;
3488 dst->_BoundArrays = src->_BoundArrays;
3489 dst->_EffBoundArrays = src->_EffBoundArrays;
3490 dst->_EffOffset = src->_EffOffset;
3491
3492 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
3493 }
3494
3495 /**
3496 * Print current vertex object/array info. For debug.
3497 */
3498 void
3499 _mesa_print_arrays(struct gl_context *ctx)
3500 {
3501 const struct gl_vertex_array_object *vao = ctx->Array.VAO;
3502
3503 fprintf(stderr, "Array Object %u\n", vao->Name);
3504
3505 GLbitfield mask = vao->Enabled;
3506 while (mask) {
3507 const gl_vert_attrib i = u_bit_scan(&mask);
3508 const struct gl_array_attributes *array = &vao->VertexAttrib[i];
3509
3510 const struct gl_vertex_buffer_binding *binding =
3511 &vao->BufferBinding[array->BufferBindingIndex];
3512 const struct gl_buffer_object *bo = binding->BufferObj;
3513
3514 fprintf(stderr, " %s: Ptr=%p, Type=%s, Size=%d, ElemSize=%u, "
3515 "Stride=%d, Buffer=%u(Size %lu)\n",
3516 gl_vert_attrib_name((gl_vert_attrib)i),
3517 array->Ptr, _mesa_enum_to_string(array->Format.Type),
3518 array->Format.Size,
3519 array->Format._ElementSize, binding->Stride, bo->Name,
3520 (unsigned long) bo->Size);
3521 }
3522 }
3523
3524
3525 /**
3526 * Initialize vertex array state for given context.
3527 */
3528 void
3529 _mesa_init_varray(struct gl_context *ctx)
3530 {
3531 ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0);
3532 _mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO);
3533 ctx->Array._EmptyVAO = _mesa_new_vao(ctx, ~0u);
3534 _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, ctx->Array._EmptyVAO);
3535 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
3536
3537 ctx->Array.Objects = _mesa_NewHashTable();
3538 }
3539
3540
3541 /**
3542 * Callback for deleting an array object. Called by _mesa_HashDeleteAll().
3543 */
3544 static void
3545 delete_arrayobj_cb(GLuint id, void *data, void *userData)
3546 {
3547 struct gl_vertex_array_object *vao = (struct gl_vertex_array_object *) data;
3548 struct gl_context *ctx = (struct gl_context *) userData;
3549 _mesa_delete_vao(ctx, vao);
3550 }
3551
3552
3553 /**
3554 * Free vertex array state for given context.
3555 */
3556 void
3557 _mesa_free_varray_data(struct gl_context *ctx)
3558 {
3559 _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx);
3560 _mesa_DeleteHashTable(ctx->Array.Objects);
3561 }
3562
3563 void GLAPIENTRY
3564 _mesa_GetVertexArrayIntegervEXT(GLuint vaobj, GLenum pname, GLint *param)
3565 {
3566 GET_CURRENT_CONTEXT(ctx);
3567 struct gl_vertex_array_object* vao;
3568 void* ptr;
3569
3570 vao = _mesa_lookup_vao_err(ctx, vaobj, true,
3571 "glGetVertexArrayIntegervEXT");
3572 if (!vao)
3573 return;
3574
3575 /* The EXT_direct_state_access spec says:
3576 *
3577 * "For GetVertexArrayIntegervEXT, pname must be one of the "Get value" tokens
3578 * in tables 6.6, 6.7, 6.8, and 6.9 that use GetIntegerv, IsEnabled, or
3579 * GetPointerv for their "Get command" (so excluding the VERTEX_ATTRIB_*
3580 * tokens)."
3581 */
3582 switch (pname) {
3583 /* Tokens using GetIntegerv */
3584 case GL_CLIENT_ACTIVE_TEXTURE:
3585 *param = GL_TEXTURE0_ARB + ctx->Array.ActiveTexture;
3586 break;
3587 case GL_VERTEX_ARRAY_SIZE:
3588 *param = vao->VertexAttrib[VERT_ATTRIB_POS].Format.Size;
3589 break;
3590 case GL_VERTEX_ARRAY_TYPE:
3591 *param = vao->VertexAttrib[VERT_ATTRIB_POS].Format.Type;
3592 break;
3593 case GL_VERTEX_ARRAY_STRIDE:
3594 *param = vao->VertexAttrib[VERT_ATTRIB_POS].Stride;
3595 break;
3596 case GL_VERTEX_ARRAY_BUFFER_BINDING:
3597 *param = vao->BufferBinding[VERT_ATTRIB_POS].BufferObj->Name;
3598 break;
3599 case GL_COLOR_ARRAY_SIZE:
3600 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR0].Format.Size;
3601 break;
3602 case GL_COLOR_ARRAY_TYPE:
3603 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR0].Format.Type;
3604 break;
3605 case GL_COLOR_ARRAY_STRIDE:
3606 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR0].Stride;
3607 break;
3608 case GL_COLOR_ARRAY_BUFFER_BINDING:
3609 *param = vao->BufferBinding[VERT_ATTRIB_COLOR0].BufferObj->Name;
3610 break;
3611 case GL_EDGE_FLAG_ARRAY_STRIDE:
3612 *param = vao->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Stride;
3613 break;
3614 case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING:
3615 *param = vao->BufferBinding[VERT_ATTRIB_EDGEFLAG].BufferObj->Name;
3616 break;
3617 case GL_INDEX_ARRAY_TYPE:
3618 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Format.Type;
3619 break;
3620 case GL_INDEX_ARRAY_STRIDE:
3621 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Stride;
3622 break;
3623 case GL_INDEX_ARRAY_BUFFER_BINDING:
3624 *param = vao->BufferBinding[VERT_ATTRIB_COLOR_INDEX].BufferObj->Name;
3625 break;
3626 case GL_NORMAL_ARRAY_TYPE:
3627 *param = vao->VertexAttrib[VERT_ATTRIB_NORMAL].Format.Type;
3628 break;
3629 case GL_NORMAL_ARRAY_STRIDE:
3630 *param = vao->VertexAttrib[VERT_ATTRIB_NORMAL].Stride;
3631 break;
3632 case GL_NORMAL_ARRAY_BUFFER_BINDING:
3633 *param = vao->BufferBinding[VERT_ATTRIB_NORMAL].BufferObj->Name;
3634 break;
3635 case GL_TEXTURE_COORD_ARRAY_SIZE:
3636 *param = vao->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].Format.Size;
3637 break;
3638 case GL_TEXTURE_COORD_ARRAY_TYPE:
3639 *param = vao->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].Format.Type;
3640 break;
3641 case GL_TEXTURE_COORD_ARRAY_STRIDE:
3642 *param = vao->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].Stride;
3643 break;
3644 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
3645 *param = vao->BufferBinding[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].BufferObj->Name;
3646 break;
3647 case GL_FOG_COORD_ARRAY_TYPE:
3648 *param = vao->VertexAttrib[VERT_ATTRIB_FOG].Format.Type;
3649 break;
3650 case GL_FOG_COORD_ARRAY_STRIDE:
3651 *param = vao->VertexAttrib[VERT_ATTRIB_FOG].Stride;
3652 break;
3653 case GL_FOG_COORD_ARRAY_BUFFER_BINDING:
3654 *param = vao->BufferBinding[VERT_ATTRIB_FOG].BufferObj->Name;
3655 break;
3656 case GL_SECONDARY_COLOR_ARRAY_SIZE:
3657 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR1].Format.Size;
3658 break;
3659 case GL_SECONDARY_COLOR_ARRAY_TYPE:
3660 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR1].Format.Type;
3661 break;
3662 case GL_SECONDARY_COLOR_ARRAY_STRIDE:
3663 *param = vao->VertexAttrib[VERT_ATTRIB_COLOR1].Stride;
3664 break;
3665 case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING:
3666 *param = vao->BufferBinding[VERT_ATTRIB_COLOR1].BufferObj->Name;
3667 break;
3668
3669 /* Tokens using IsEnabled */
3670 case GL_VERTEX_ARRAY:
3671 *param = !!(vao->Enabled & VERT_BIT_POS);
3672 break;
3673 case GL_COLOR_ARRAY:
3674 *param = !!(vao->Enabled & VERT_BIT_COLOR0);
3675 break;
3676 case GL_EDGE_FLAG_ARRAY:
3677 *param = !!(vao->Enabled & VERT_BIT_EDGEFLAG);
3678 break;
3679 case GL_INDEX_ARRAY:
3680 *param = !!(vao->Enabled & VERT_BIT_COLOR_INDEX);
3681 break;
3682 case GL_NORMAL_ARRAY:
3683 *param = !!(vao->Enabled & VERT_BIT_NORMAL);
3684 break;
3685 case GL_TEXTURE_COORD_ARRAY:
3686 *param = !!(vao->Enabled & VERT_BIT_TEX(ctx->Array.ActiveTexture));
3687 break;
3688 case GL_FOG_COORD_ARRAY:
3689 *param = !!(vao->Enabled & VERT_BIT_FOG);
3690 break;
3691 case GL_SECONDARY_COLOR_ARRAY:
3692 *param = !!(vao->Enabled & VERT_BIT_COLOR1);
3693 break;
3694
3695 /* Tokens using GetPointerv */
3696 case GL_VERTEX_ARRAY_POINTER:
3697 case GL_COLOR_ARRAY_POINTER:
3698 case GL_EDGE_FLAG_ARRAY_POINTER:
3699 case GL_INDEX_ARRAY_POINTER:
3700 case GL_NORMAL_ARRAY_POINTER:
3701 case GL_TEXTURE_COORD_ARRAY_POINTER:
3702 case GL_FOG_COORD_ARRAY_POINTER:
3703 case GL_SECONDARY_COLOR_ARRAY_POINTER:
3704 _get_vao_pointerv(pname, vao, &ptr, "glGetVertexArrayIntegervEXT");
3705 *param = (int) ((intptr_t) ptr & 0xFFFFFFFF);
3706 break;
3707
3708 default:
3709 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayIntegervEXT(pname)");
3710 }
3711 }
3712
3713 void GLAPIENTRY
3714 _mesa_GetVertexArrayPointervEXT(GLuint vaobj, GLenum pname, GLvoid** param)
3715 {
3716 GET_CURRENT_CONTEXT(ctx);
3717 struct gl_vertex_array_object* vao;
3718
3719 vao = _mesa_lookup_vao_err(ctx, vaobj, true,
3720 "glGetVertexArrayPointervEXT");
3721 if (!vao)
3722 return;
3723
3724 /* The EXT_direct_state_access spec says:
3725 *
3726 * "For GetVertexArrayPointervEXT, pname must be a *_ARRAY_POINTER token from
3727 * tables 6.6, 6.7, and 6.8 excluding VERTEX_ATTRIB_ARRAY_POINT."
3728 */
3729 switch (pname) {
3730 case GL_VERTEX_ARRAY_POINTER:
3731 case GL_COLOR_ARRAY_POINTER:
3732 case GL_EDGE_FLAG_ARRAY_POINTER:
3733 case GL_INDEX_ARRAY_POINTER:
3734 case GL_NORMAL_ARRAY_POINTER:
3735 case GL_TEXTURE_COORD_ARRAY_POINTER:
3736 case GL_FOG_COORD_ARRAY_POINTER:
3737 case GL_SECONDARY_COLOR_ARRAY_POINTER:
3738 break;
3739
3740 default:
3741 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayPointervEXT(pname)");
3742 return;
3743 }
3744
3745 /* pname has been validated, we can now use the helper function */
3746 _get_vao_pointerv(pname, vao, param, "glGetVertexArrayPointervEXT");
3747 }
3748
3749 void GLAPIENTRY
3750 _mesa_GetVertexArrayIntegeri_vEXT(GLuint vaobj, GLuint index, GLenum pname, GLint *param)
3751 {
3752 GET_CURRENT_CONTEXT(ctx);
3753 struct gl_vertex_array_object* vao;
3754
3755 vao = _mesa_lookup_vao_err(ctx, vaobj, true,
3756 "glGetVertexArrayIntegeri_vEXT");
3757 if (!vao)
3758 return;
3759
3760
3761 /* The EXT_direct_state_access spec says:
3762 *
3763 * "For GetVertexArrayIntegeri_vEXT, pname must be one of the
3764 * "Get value" tokens in tables 6.8 and 6.9 that use GetVertexAttribiv
3765 * or GetVertexAttribPointerv (so allowing only the VERTEX_ATTRIB_*
3766 * tokens) or a token of the form TEXTURE_COORD_ARRAY (the enable) or
3767 * TEXTURE_COORD_ARRAY_*; index identifies the vertex attribute
3768 * array to query or texture coordinate set index respectively."
3769 */
3770
3771 switch (pname) {
3772 case GL_TEXTURE_COORD_ARRAY:
3773 *param = !!(vao->Enabled & VERT_BIT_TEX(index));
3774 break;
3775 case GL_TEXTURE_COORD_ARRAY_SIZE:
3776 *param = vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Format.Size;
3777 break;
3778 case GL_TEXTURE_COORD_ARRAY_TYPE:
3779 *param = vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Format.Type;
3780 break;
3781 case GL_TEXTURE_COORD_ARRAY_STRIDE:
3782 *param = vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Stride;
3783 break;
3784 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
3785 *param = vao->BufferBinding[VERT_ATTRIB_TEX(index)].BufferObj->Name;
3786 break;
3787 default:
3788 *param = get_vertex_array_attrib(ctx, vao, index, pname, "glGetVertexArrayIntegeri_vEXT");
3789 }
3790 }
3791
3792 void GLAPIENTRY
3793 _mesa_GetVertexArrayPointeri_vEXT(GLuint vaobj, GLuint index, GLenum pname, GLvoid** param)
3794 {
3795 GET_CURRENT_CONTEXT(ctx);
3796 struct gl_vertex_array_object* vao;
3797
3798 vao = _mesa_lookup_vao_err(ctx, vaobj, true,
3799 "glGetVertexArrayPointeri_vEXT");
3800 if (!vao)
3801 return;
3802
3803 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
3804 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexArrayPointeri_vEXT(index)");
3805 return;
3806 }
3807
3808 /* The EXT_direct_state_access spec says:
3809 *
3810 * "For GetVertexArrayPointeri_vEXT, pname must be VERTEX_ATTRIB_ARRAY_POINTER
3811 * or TEXTURE_COORD_ARRAY_POINTER with the index parameter indicating the vertex
3812 * attribute or texture coordindate set index."
3813 */
3814 switch(pname) {
3815 case GL_VERTEX_ATTRIB_ARRAY_POINTER:
3816 *param = (GLvoid *) vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr;
3817 break;
3818 case GL_TEXTURE_COORD_ARRAY_POINTER:
3819 *param = (GLvoid *) vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Ptr;
3820 break;
3821 default:
3822 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexArrayPointeri_vEXT(pname)");
3823 }
3824 }