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