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