mesa: make vertex array type error checking a little more efficient
[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 "glheader.h"
28 #include "imports.h"
29 #include "bufferobj.h"
30 #include "context.h"
31 #include "enable.h"
32 #include "enums.h"
33 #include "hash.h"
34 #include "image.h"
35 #include "macros.h"
36 #include "mtypes.h"
37 #include "varray.h"
38 #include "arrayobj.h"
39 #include "main/dispatch.h"
40
41
42 /** Used to do error checking for GL_EXT_vertex_array_bgra */
43 #define BGRA_OR_4 5
44
45
46 /** Used to indicate which GL datatypes are accepted by each of the
47 * glVertex/Color/Attrib/EtcPointer() functions.
48 */
49 #define BOOL_BIT 0x1
50 #define BYTE_BIT 0x2
51 #define UNSIGNED_BYTE_BIT 0x4
52 #define SHORT_BIT 0x8
53 #define UNSIGNED_SHORT_BIT 0x10
54 #define INT_BIT 0x20
55 #define UNSIGNED_INT_BIT 0x40
56 #define HALF_BIT 0x80
57 #define FLOAT_BIT 0x100
58 #define DOUBLE_BIT 0x200
59 #define FIXED_ES_BIT 0x400
60 #define FIXED_GL_BIT 0x800
61 #define UNSIGNED_INT_2_10_10_10_REV_BIT 0x1000
62 #define INT_2_10_10_10_REV_BIT 0x2000
63 #define UNSIGNED_INT_10F_11F_11F_REV_BIT 0x4000
64
65
66 /** Convert GL datatype enum into a <type>_BIT value seen above */
67 static GLbitfield
68 type_to_bit(const struct gl_context *ctx, GLenum type)
69 {
70 switch (type) {
71 case GL_BOOL:
72 return BOOL_BIT;
73 case GL_BYTE:
74 return BYTE_BIT;
75 case GL_UNSIGNED_BYTE:
76 return UNSIGNED_BYTE_BIT;
77 case GL_SHORT:
78 return SHORT_BIT;
79 case GL_UNSIGNED_SHORT:
80 return UNSIGNED_SHORT_BIT;
81 case GL_INT:
82 return INT_BIT;
83 case GL_UNSIGNED_INT:
84 return UNSIGNED_INT_BIT;
85 case GL_HALF_FLOAT:
86 if (ctx->Extensions.ARB_half_float_vertex)
87 return HALF_BIT;
88 else
89 return 0x0;
90 case GL_FLOAT:
91 return FLOAT_BIT;
92 case GL_DOUBLE:
93 return DOUBLE_BIT;
94 case GL_FIXED:
95 return _mesa_is_desktop_gl(ctx) ? FIXED_GL_BIT : FIXED_ES_BIT;
96 case GL_UNSIGNED_INT_2_10_10_10_REV:
97 return UNSIGNED_INT_2_10_10_10_REV_BIT;
98 case GL_INT_2_10_10_10_REV:
99 return INT_2_10_10_10_REV_BIT;
100 case GL_UNSIGNED_INT_10F_11F_11F_REV:
101 return UNSIGNED_INT_10F_11F_11F_REV_BIT;
102 default:
103 return 0;
104 }
105 }
106
107
108 /**
109 * Sets the VertexBinding field in the vertex attribute given by attribIndex.
110 */
111 static void
112 vertex_attrib_binding(struct gl_context *ctx, GLuint attribIndex,
113 GLuint bindingIndex)
114 {
115 struct gl_vertex_array_object *vao = ctx->Array.VAO;
116 struct gl_vertex_attrib_array *array = &vao->VertexAttrib[attribIndex];
117
118 if (array->VertexBinding != bindingIndex) {
119 const GLbitfield64 array_bit = VERT_BIT(attribIndex);
120
121 FLUSH_VERTICES(ctx, _NEW_ARRAY);
122
123 vao->VertexBinding[array->VertexBinding]._BoundArrays &= ~array_bit;
124 vao->VertexBinding[bindingIndex]._BoundArrays |= array_bit;
125
126 array->VertexBinding = bindingIndex;
127
128 vao->NewArrays |= array_bit;
129 }
130 }
131
132
133 /**
134 * Binds a buffer object to the vertex buffer binding point given by index,
135 * and sets the Offset and Stride fields.
136 */
137 static void
138 bind_vertex_buffer(struct gl_context *ctx, GLuint index,
139 struct gl_buffer_object *vbo,
140 GLintptr offset, GLsizei stride)
141 {
142 struct gl_vertex_array_object *vao = ctx->Array.VAO;
143 struct gl_vertex_buffer_binding *binding = &vao->VertexBinding[index];
144
145 if (binding->BufferObj != vbo ||
146 binding->Offset != offset ||
147 binding->Stride != stride) {
148
149 FLUSH_VERTICES(ctx, _NEW_ARRAY);
150
151 _mesa_reference_buffer_object(ctx, &binding->BufferObj, vbo);
152
153 binding->Offset = offset;
154 binding->Stride = stride;
155
156 vao->NewArrays |= binding->_BoundArrays;
157 }
158 }
159
160
161 /**
162 * Sets the InstanceDivisor field in the vertex buffer binding point
163 * given by bindingIndex.
164 */
165 static void
166 vertex_binding_divisor(struct gl_context *ctx, GLuint bindingIndex,
167 GLuint divisor)
168 {
169 struct gl_vertex_array_object *vao = ctx->Array.VAO;
170 struct gl_vertex_buffer_binding *binding =
171 &vao->VertexBinding[bindingIndex];
172
173 if (binding->InstanceDivisor != divisor) {
174 FLUSH_VERTICES(ctx, _NEW_ARRAY);
175 binding->InstanceDivisor = divisor;
176 vao->NewArrays |= binding->_BoundArrays;
177 }
178 }
179
180
181 /**
182 * Examine the API profile and extensions to determine which types are legal
183 * for vertex arrays. This is called once from update_array_format().
184 */
185 static GLbitfield
186 get_legal_types_mask(const struct gl_context *ctx)
187 {
188 GLbitfield legalTypesMask = ~0u; /* all */
189
190 if (_mesa_is_gles(ctx)) {
191 legalTypesMask &= ~(FIXED_GL_BIT |
192 DOUBLE_BIT |
193 UNSIGNED_INT_10F_11F_11F_REV_BIT);
194
195 /* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until
196 * 3.0. The 2_10_10_10 types are added in OpenGL ES 3.0 or
197 * GL_OES_vertex_type_10_10_10_2. GL_HALF_FLOAT data is not allowed
198 * until 3.0 or with the GL_OES_vertex_half float extension, which isn't
199 * quite as trivial as we'd like because it uses a different enum value
200 * for GL_HALF_FLOAT_OES.
201 */
202 if (ctx->Version < 30) {
203 legalTypesMask &= ~(UNSIGNED_INT_BIT |
204 INT_BIT |
205 UNSIGNED_INT_2_10_10_10_REV_BIT |
206 INT_2_10_10_10_REV_BIT |
207 HALF_BIT);
208 }
209 }
210 else {
211 legalTypesMask &= ~FIXED_ES_BIT;
212
213 if (!ctx->Extensions.ARB_ES2_compatibility)
214 legalTypesMask &= ~FIXED_GL_BIT;
215
216 if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev)
217 legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT |
218 INT_2_10_10_10_REV_BIT);
219
220 if (!ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev)
221 legalTypesMask &= ~UNSIGNED_INT_10F_11F_11F_REV_BIT;
222 }
223
224 return legalTypesMask;
225 }
226
227
228 /**
229 * Does error checking and updates the format in an attrib array.
230 *
231 * Called by update_array() and VertexAttrib*Format().
232 *
233 * \param func Name of calling function used for error reporting
234 * \param attrib The index of the attribute array
235 * \param legalTypes Bitmask of *_BIT above indicating legal datatypes
236 * \param sizeMin Min allowable size value
237 * \param sizeMax Max allowable size value (may also be BGRA_OR_4)
238 * \param size Components per element (1, 2, 3 or 4)
239 * \param type Datatype of each component (GL_FLOAT, GL_INT, etc)
240 * \param normalized Whether integer types are converted to floats in [-1, 1]
241 * \param integer Integer-valued values (will not be normalized to [-1, 1])
242 * \param relativeOffset Offset of the first element relative to the binding offset.
243 */
244 static bool
245 update_array_format(struct gl_context *ctx,
246 const char *func,
247 GLuint attrib, GLbitfield legalTypesMask,
248 GLint sizeMin, GLint sizeMax,
249 GLint size, GLenum type,
250 GLboolean normalized, GLboolean integer,
251 GLuint relativeOffset)
252 {
253 struct gl_vertex_attrib_array *array;
254 GLbitfield typeBit;
255 GLuint elementSize;
256 GLenum format = GL_RGBA;
257
258 if (ctx->Array.LegalTypesMask == 0) {
259 /* One-time initialization. We can't do this in _mesa_init_varrays()
260 * below because extensions are not yet enabled at that point.
261 */
262 ctx->Array.LegalTypesMask = get_legal_types_mask(ctx);
263 }
264
265 legalTypesMask &= ctx->Array.LegalTypesMask;
266
267 if (_mesa_is_gles(ctx) && sizeMax == BGRA_OR_4) {
268 /* BGRA ordering is not supported in ES contexts.
269 */
270 sizeMax = 4;
271 }
272
273 typeBit = type_to_bit(ctx, type);
274 if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) {
275 _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)",
276 func, _mesa_lookup_enum_by_nr(type));
277 return false;
278 }
279
280 /* Do size parameter checking.
281 * If sizeMax = BGRA_OR_4 it means that size = GL_BGRA is legal and
282 * must be handled specially.
283 */
284 if (ctx->Extensions.EXT_vertex_array_bgra &&
285 sizeMax == BGRA_OR_4 &&
286 size == GL_BGRA) {
287 /* Page 298 of the PDF of the OpenGL 4.3 (Core Profile) spec says:
288 *
289 * "An INVALID_OPERATION error is generated under any of the following
290 * conditions:
291 * ...
292 * • size is BGRA and type is not UNSIGNED_BYTE, INT_2_10_10_10_REV
293 * or UNSIGNED_INT_2_10_10_10_REV;
294 * ...
295 * • size is BGRA and normalized is FALSE;"
296 */
297 bool bgra_error = false;
298
299 if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) {
300 if (type != GL_UNSIGNED_INT_2_10_10_10_REV &&
301 type != GL_INT_2_10_10_10_REV &&
302 type != GL_UNSIGNED_BYTE)
303 bgra_error = true;
304 } else if (type != GL_UNSIGNED_BYTE)
305 bgra_error = true;
306
307 if (bgra_error) {
308 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=GL_BGRA and type=%s)",
309 func, _mesa_lookup_enum_by_nr(type));
310 return false;
311 }
312
313 if (!normalized) {
314 _mesa_error(ctx, GL_INVALID_OPERATION,
315 "%s(size=GL_BGRA and normalized=GL_FALSE)", func);
316 return false;
317 }
318
319 format = GL_BGRA;
320 size = 4;
321 }
322 else if (size < sizeMin || size > sizeMax || size > 4) {
323 _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size);
324 return false;
325 }
326
327 if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev &&
328 (type == GL_UNSIGNED_INT_2_10_10_10_REV ||
329 type == GL_INT_2_10_10_10_REV) && size != 4) {
330 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size);
331 return false;
332 }
333
334 /* The ARB_vertex_attrib_binding_spec says:
335 *
336 * An INVALID_VALUE error is generated if <relativeoffset> is larger than
337 * the value of MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.
338 */
339 if (relativeOffset > ctx->Const.MaxVertexAttribRelativeOffset) {
340 _mesa_error(ctx, GL_INVALID_VALUE,
341 "%s(relativeOffset=%d > "
342 "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET)",
343 func, relativeOffset);
344 return false;
345 }
346
347 if (ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev &&
348 type == GL_UNSIGNED_INT_10F_11F_11F_REV && size != 3) {
349 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size);
350 return false;
351 }
352
353 ASSERT(size <= 4);
354
355 elementSize = _mesa_bytes_per_vertex_attrib(size, type);
356 assert(elementSize != -1);
357
358 array = &ctx->Array.VAO->VertexAttrib[attrib];
359 array->Size = size;
360 array->Type = type;
361 array->Format = format;
362 array->Normalized = normalized;
363 array->Integer = integer;
364 array->RelativeOffset = relativeOffset;
365 array->_ElementSize = elementSize;
366
367 ctx->Array.VAO->NewArrays |= VERT_BIT(attrib);
368 ctx->NewState |= _NEW_ARRAY;
369
370 return true;
371 }
372
373
374 /**
375 * Do error checking and update state for glVertex/Color/TexCoord/...Pointer
376 * functions.
377 *
378 * \param func name of calling function used for error reporting
379 * \param attrib the attribute array index to update
380 * \param legalTypes bitmask of *_BIT above indicating legal datatypes
381 * \param sizeMin min allowable size value
382 * \param sizeMax max allowable size value (may also be BGRA_OR_4)
383 * \param size components per element (1, 2, 3 or 4)
384 * \param type datatype of each component (GL_FLOAT, GL_INT, etc)
385 * \param stride stride between elements, in elements
386 * \param normalized are integer types converted to floats in [-1, 1]?
387 * \param integer integer-valued values (will not be normalized to [-1,1])
388 * \param ptr the address (or offset inside VBO) of the array data
389 */
390 static void
391 update_array(struct gl_context *ctx,
392 const char *func,
393 GLuint attrib, GLbitfield legalTypesMask,
394 GLint sizeMin, GLint sizeMax,
395 GLint size, GLenum type, GLsizei stride,
396 GLboolean normalized, GLboolean integer,
397 const GLvoid *ptr)
398 {
399 struct gl_vertex_attrib_array *array;
400 GLsizei effectiveStride;
401
402 /* Page 407 (page 423 of the PDF) of the OpenGL 3.0 spec says:
403 *
404 * "Client vertex arrays - all vertex array attribute pointers must
405 * refer to buffer objects (section 2.9.2). The default vertex array
406 * object (the name zero) is also deprecated. Calling
407 * VertexAttribPointer when no buffer object or no vertex array object
408 * is bound will generate an INVALID_OPERATION error..."
409 *
410 * The check for VBOs is handled below.
411 */
412 if (ctx->API == API_OPENGL_CORE
413 && (ctx->Array.VAO == ctx->Array.DefaultVAO)) {
414 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no array object bound)",
415 func);
416 return;
417 }
418
419 if (stride < 0) {
420 _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride );
421 return;
422 }
423
424 /* Page 29 (page 44 of the PDF) of the OpenGL 3.3 spec says:
425 *
426 * "An INVALID_OPERATION error is generated under any of the following
427 * conditions:
428 *
429 * ...
430 *
431 * * any of the *Pointer commands specifying the location and
432 * organization of vertex array data are called while zero is bound
433 * to the ARRAY_BUFFER buffer object binding point (see section
434 * 2.9.6), and the pointer argument is not NULL."
435 */
436 if (ptr != NULL && ctx->Array.VAO->ARBsemantics &&
437 !_mesa_is_bufferobj(ctx->Array.ArrayBufferObj)) {
438 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func);
439 return;
440 }
441
442 if (!update_array_format(ctx, func, attrib, legalTypesMask, sizeMin,
443 sizeMax, size, type, normalized, integer, 0)) {
444 return;
445 }
446
447 /* Reset the vertex attrib binding */
448 vertex_attrib_binding(ctx, attrib, attrib);
449
450 /* The Stride and Ptr fields are not set by update_array_format() */
451 array = &ctx->Array.VAO->VertexAttrib[attrib];
452 array->Stride = stride;
453 array->Ptr = (const GLvoid *) ptr;
454
455 /* Update the vertex buffer binding */
456 effectiveStride = stride != 0 ? stride : array->_ElementSize;
457 bind_vertex_buffer(ctx, attrib, ctx->Array.ArrayBufferObj,
458 (GLintptr) ptr, effectiveStride);
459 }
460
461
462 void GLAPIENTRY
463 _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
464 {
465 GET_CURRENT_CONTEXT(ctx);
466 GLbitfield legalTypes = (ctx->API == API_OPENGLES)
467 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
468 : (SHORT_BIT | INT_BIT | FLOAT_BIT |
469 DOUBLE_BIT | HALF_BIT |
470 UNSIGNED_INT_2_10_10_10_REV_BIT |
471 INT_2_10_10_10_REV_BIT);
472
473 FLUSH_VERTICES(ctx, 0);
474
475 update_array(ctx, "glVertexPointer", VERT_ATTRIB_POS,
476 legalTypes, 2, 4,
477 size, type, stride, GL_FALSE, GL_FALSE, ptr);
478 }
479
480
481 void GLAPIENTRY
482 _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
483 {
484 GET_CURRENT_CONTEXT(ctx);
485 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
486 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
487 : (BYTE_BIT | SHORT_BIT | INT_BIT |
488 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
489 UNSIGNED_INT_2_10_10_10_REV_BIT |
490 INT_2_10_10_10_REV_BIT);
491
492 FLUSH_VERTICES(ctx, 0);
493
494 update_array(ctx, "glNormalPointer", VERT_ATTRIB_NORMAL,
495 legalTypes, 3, 3,
496 3, type, stride, GL_TRUE, GL_FALSE, ptr);
497 }
498
499
500 void GLAPIENTRY
501 _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
502 {
503 GET_CURRENT_CONTEXT(ctx);
504 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
505 ? (UNSIGNED_BYTE_BIT | HALF_BIT | FLOAT_BIT | FIXED_ES_BIT)
506 : (BYTE_BIT | UNSIGNED_BYTE_BIT |
507 SHORT_BIT | UNSIGNED_SHORT_BIT |
508 INT_BIT | UNSIGNED_INT_BIT |
509 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
510 UNSIGNED_INT_2_10_10_10_REV_BIT |
511 INT_2_10_10_10_REV_BIT);
512 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 4 : 3;
513
514 FLUSH_VERTICES(ctx, 0);
515
516 update_array(ctx, "glColorPointer", VERT_ATTRIB_COLOR0,
517 legalTypes, sizeMin, BGRA_OR_4,
518 size, type, stride, GL_TRUE, GL_FALSE, ptr);
519 }
520
521
522 void GLAPIENTRY
523 _mesa_FogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
524 {
525 const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT);
526 GET_CURRENT_CONTEXT(ctx);
527
528 FLUSH_VERTICES(ctx, 0);
529
530 update_array(ctx, "glFogCoordPointer", VERT_ATTRIB_FOG,
531 legalTypes, 1, 1,
532 1, type, stride, GL_FALSE, GL_FALSE, ptr);
533 }
534
535
536 void GLAPIENTRY
537 _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
538 {
539 const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT |
540 FLOAT_BIT | DOUBLE_BIT);
541 GET_CURRENT_CONTEXT(ctx);
542
543 FLUSH_VERTICES(ctx, 0);
544
545 update_array(ctx, "glIndexPointer", VERT_ATTRIB_COLOR_INDEX,
546 legalTypes, 1, 1,
547 1, type, stride, GL_FALSE, GL_FALSE, ptr);
548 }
549
550
551 void GLAPIENTRY
552 _mesa_SecondaryColorPointer(GLint size, GLenum type,
553 GLsizei stride, const GLvoid *ptr)
554 {
555 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
556 SHORT_BIT | UNSIGNED_SHORT_BIT |
557 INT_BIT | UNSIGNED_INT_BIT |
558 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
559 UNSIGNED_INT_2_10_10_10_REV_BIT |
560 INT_2_10_10_10_REV_BIT);
561 GET_CURRENT_CONTEXT(ctx);
562
563 FLUSH_VERTICES(ctx, 0);
564
565 update_array(ctx, "glSecondaryColorPointer", VERT_ATTRIB_COLOR1,
566 legalTypes, 3, BGRA_OR_4,
567 size, type, stride, GL_TRUE, GL_FALSE, ptr);
568 }
569
570
571 void GLAPIENTRY
572 _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
573 const GLvoid *ptr)
574 {
575 GET_CURRENT_CONTEXT(ctx);
576 GLbitfield legalTypes = (ctx->API == API_OPENGLES)
577 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
578 : (SHORT_BIT | INT_BIT |
579 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
580 UNSIGNED_INT_2_10_10_10_REV_BIT |
581 INT_2_10_10_10_REV_BIT);
582 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1;
583 const GLuint unit = ctx->Array.ActiveTexture;
584
585 FLUSH_VERTICES(ctx, 0);
586
587 update_array(ctx, "glTexCoordPointer", VERT_ATTRIB_TEX(unit),
588 legalTypes, sizeMin, 4,
589 size, type, stride, GL_FALSE, GL_FALSE,
590 ptr);
591 }
592
593
594 void GLAPIENTRY
595 _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
596 {
597 const GLbitfield legalTypes = UNSIGNED_BYTE_BIT;
598 /* this is the same type that glEdgeFlag uses */
599 const GLboolean integer = GL_FALSE;
600 GET_CURRENT_CONTEXT(ctx);
601
602 FLUSH_VERTICES(ctx, 0);
603
604 update_array(ctx, "glEdgeFlagPointer", VERT_ATTRIB_EDGEFLAG,
605 legalTypes, 1, 1,
606 1, GL_UNSIGNED_BYTE, stride, GL_FALSE, integer, ptr);
607 }
608
609
610 void GLAPIENTRY
611 _mesa_PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *ptr)
612 {
613 const GLbitfield legalTypes = (FLOAT_BIT | FIXED_ES_BIT);
614 GET_CURRENT_CONTEXT(ctx);
615
616 FLUSH_VERTICES(ctx, 0);
617
618 if (ctx->API != API_OPENGLES) {
619 _mesa_error(ctx, GL_INVALID_OPERATION,
620 "glPointSizePointer(ES 1.x only)");
621 return;
622 }
623
624 update_array(ctx, "glPointSizePointer", VERT_ATTRIB_POINT_SIZE,
625 legalTypes, 1, 1,
626 1, type, stride, GL_FALSE, GL_FALSE, ptr);
627 }
628
629
630 /**
631 * Set a generic vertex attribute array.
632 * Note that these arrays DO NOT alias the conventional GL vertex arrays
633 * (position, normal, color, fog, texcoord, etc).
634 */
635 void GLAPIENTRY
636 _mesa_VertexAttribPointer(GLuint index, GLint size, GLenum type,
637 GLboolean normalized,
638 GLsizei stride, const GLvoid *ptr)
639 {
640 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
641 SHORT_BIT | UNSIGNED_SHORT_BIT |
642 INT_BIT | UNSIGNED_INT_BIT |
643 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
644 FIXED_ES_BIT | FIXED_GL_BIT |
645 UNSIGNED_INT_2_10_10_10_REV_BIT |
646 INT_2_10_10_10_REV_BIT |
647 UNSIGNED_INT_10F_11F_11F_REV_BIT);
648 GET_CURRENT_CONTEXT(ctx);
649
650 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
651 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)");
652 return;
653 }
654
655 update_array(ctx, "glVertexAttribPointer", VERT_ATTRIB_GENERIC(index),
656 legalTypes, 1, BGRA_OR_4,
657 size, type, stride, normalized, GL_FALSE, ptr);
658 }
659
660
661 /**
662 * GL_EXT_gpu_shader4 / GL 3.0.
663 * Set an integer-valued vertex attribute array.
664 * Note that these arrays DO NOT alias the conventional GL vertex arrays
665 * (position, normal, color, fog, texcoord, etc).
666 */
667 void GLAPIENTRY
668 _mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type,
669 GLsizei stride, const GLvoid *ptr)
670 {
671 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
672 SHORT_BIT | UNSIGNED_SHORT_BIT |
673 INT_BIT | UNSIGNED_INT_BIT);
674 const GLboolean normalized = GL_FALSE;
675 const GLboolean integer = GL_TRUE;
676 GET_CURRENT_CONTEXT(ctx);
677
678 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
679 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIPointer(index)");
680 return;
681 }
682
683 update_array(ctx, "glVertexAttribIPointer", VERT_ATTRIB_GENERIC(index),
684 legalTypes, 1, 4,
685 size, type, stride, normalized, integer, ptr);
686 }
687
688
689
690 void GLAPIENTRY
691 _mesa_EnableVertexAttribArray(GLuint index)
692 {
693 struct gl_vertex_array_object *vao;
694 GET_CURRENT_CONTEXT(ctx);
695
696 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
697 _mesa_error(ctx, GL_INVALID_VALUE,
698 "glEnableVertexAttribArrayARB(index)");
699 return;
700 }
701
702 vao = ctx->Array.VAO;
703
704 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(vao->_VertexAttrib));
705
706 if (!vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled) {
707 /* was disabled, now being enabled */
708 FLUSH_VERTICES(ctx, _NEW_ARRAY);
709 vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_TRUE;
710 vao->_Enabled |= VERT_BIT_GENERIC(index);
711 vao->NewArrays |= VERT_BIT_GENERIC(index);
712 }
713 }
714
715
716 void GLAPIENTRY
717 _mesa_DisableVertexAttribArray(GLuint index)
718 {
719 struct gl_vertex_array_object *vao;
720 GET_CURRENT_CONTEXT(ctx);
721
722 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
723 _mesa_error(ctx, GL_INVALID_VALUE,
724 "glDisableVertexAttribArrayARB(index)");
725 return;
726 }
727
728 vao = ctx->Array.VAO;
729
730 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(vao->_VertexAttrib));
731
732 if (vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled) {
733 /* was enabled, now being disabled */
734 FLUSH_VERTICES(ctx, _NEW_ARRAY);
735 vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_FALSE;
736 vao->_Enabled &= ~VERT_BIT_GENERIC(index);
737 vao->NewArrays |= VERT_BIT_GENERIC(index);
738 }
739 }
740
741
742 /**
743 * Return info for a vertex attribute array (no alias with legacy
744 * vertex attributes (pos, normal, color, etc)). This function does
745 * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query.
746 */
747 static GLuint
748 get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname,
749 const char *caller)
750 {
751 const struct gl_vertex_array_object *vao = ctx->Array.VAO;
752 const struct gl_vertex_attrib_array *array;
753
754 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
755 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index);
756 return 0;
757 }
758
759 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(vao->VertexAttrib));
760
761 array = &vao->VertexAttrib[VERT_ATTRIB_GENERIC(index)];
762
763 switch (pname) {
764 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
765 return array->Enabled;
766 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
767 return (array->Format == GL_BGRA) ? GL_BGRA : array->Size;
768 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
769 return array->Stride;
770 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
771 return array->Type;
772 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
773 return array->Normalized;
774 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
775 return vao->VertexBinding[array->VertexBinding].BufferObj->Name;
776 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
777 if ((_mesa_is_desktop_gl(ctx)
778 && (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))
779 || _mesa_is_gles3(ctx)) {
780 return array->Integer;
781 }
782 goto error;
783 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB:
784 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_instanced_arrays)
785 || _mesa_is_gles3(ctx)) {
786 return vao->VertexBinding[array->VertexBinding].InstanceDivisor;
787 }
788 goto error;
789 case GL_VERTEX_ATTRIB_BINDING:
790 if (_mesa_is_desktop_gl(ctx)) {
791 return array->VertexBinding - VERT_ATTRIB_GENERIC0;
792 }
793 goto error;
794 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
795 if (_mesa_is_desktop_gl(ctx)) {
796 return array->RelativeOffset;
797 }
798 goto error;
799 default:
800 ; /* fall-through */
801 }
802
803 error:
804 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname);
805 return 0;
806 }
807
808
809 static const GLfloat *
810 get_current_attrib(struct gl_context *ctx, GLuint index, const char *function)
811 {
812 if (index == 0) {
813 if (_mesa_attr_zero_aliases_vertex(ctx)) {
814 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function);
815 return NULL;
816 }
817 }
818 else if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
819 _mesa_error(ctx, GL_INVALID_VALUE,
820 "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function);
821 return NULL;
822 }
823
824 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.VAO->_VertexAttrib));
825
826 FLUSH_CURRENT(ctx, 0);
827 return ctx->Current.Attrib[VERT_ATTRIB_GENERIC(index)];
828 }
829
830 void GLAPIENTRY
831 _mesa_GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
832 {
833 GET_CURRENT_CONTEXT(ctx);
834
835 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
836 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv");
837 if (v != NULL) {
838 COPY_4V(params, v);
839 }
840 }
841 else {
842 params[0] = (GLfloat) get_vertex_array_attrib(ctx, index, pname,
843 "glGetVertexAttribfv");
844 }
845 }
846
847
848 void GLAPIENTRY
849 _mesa_GetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params)
850 {
851 GET_CURRENT_CONTEXT(ctx);
852
853 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
854 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv");
855 if (v != NULL) {
856 params[0] = (GLdouble) v[0];
857 params[1] = (GLdouble) v[1];
858 params[2] = (GLdouble) v[2];
859 params[3] = (GLdouble) v[3];
860 }
861 }
862 else {
863 params[0] = (GLdouble) get_vertex_array_attrib(ctx, index, pname,
864 "glGetVertexAttribdv");
865 }
866 }
867
868
869 void GLAPIENTRY
870 _mesa_GetVertexAttribiv(GLuint index, GLenum pname, GLint *params)
871 {
872 GET_CURRENT_CONTEXT(ctx);
873
874 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
875 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv");
876 if (v != NULL) {
877 /* XXX should floats in[0,1] be scaled to full int range? */
878 params[0] = (GLint) v[0];
879 params[1] = (GLint) v[1];
880 params[2] = (GLint) v[2];
881 params[3] = (GLint) v[3];
882 }
883 }
884 else {
885 params[0] = (GLint) get_vertex_array_attrib(ctx, index, pname,
886 "glGetVertexAttribiv");
887 }
888 }
889
890
891 /** GL 3.0 */
892 void GLAPIENTRY
893 _mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
894 {
895 GET_CURRENT_CONTEXT(ctx);
896
897 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
898 const GLint *v = (const GLint *)
899 get_current_attrib(ctx, index, "glGetVertexAttribIiv");
900 if (v != NULL) {
901 COPY_4V(params, v);
902 }
903 }
904 else {
905 params[0] = (GLint) get_vertex_array_attrib(ctx, index, pname,
906 "glGetVertexAttribIiv");
907 }
908 }
909
910
911 /** GL 3.0 */
912 void GLAPIENTRY
913 _mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
914 {
915 GET_CURRENT_CONTEXT(ctx);
916
917 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
918 const GLuint *v = (const GLuint *)
919 get_current_attrib(ctx, index, "glGetVertexAttribIuiv");
920 if (v != NULL) {
921 COPY_4V(params, v);
922 }
923 }
924 else {
925 params[0] = get_vertex_array_attrib(ctx, index, pname,
926 "glGetVertexAttribIuiv");
927 }
928 }
929
930
931 void GLAPIENTRY
932 _mesa_GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
933 {
934 GET_CURRENT_CONTEXT(ctx);
935
936 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
937 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
938 return;
939 }
940
941 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
942 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
943 return;
944 }
945
946 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.VAO->_VertexAttrib));
947
948 *pointer = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr;
949 }
950
951
952 void GLAPIENTRY
953 _mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
954 GLsizei count, const GLvoid *ptr)
955 {
956 (void) count;
957 _mesa_VertexPointer(size, type, stride, ptr);
958 }
959
960
961 void GLAPIENTRY
962 _mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
963 const GLvoid *ptr)
964 {
965 (void) count;
966 _mesa_NormalPointer(type, stride, ptr);
967 }
968
969
970 void GLAPIENTRY
971 _mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
972 const GLvoid *ptr)
973 {
974 (void) count;
975 _mesa_ColorPointer(size, type, stride, ptr);
976 }
977
978
979 void GLAPIENTRY
980 _mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
981 const GLvoid *ptr)
982 {
983 (void) count;
984 _mesa_IndexPointer(type, stride, ptr);
985 }
986
987
988 void GLAPIENTRY
989 _mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
990 GLsizei count, const GLvoid *ptr)
991 {
992 (void) count;
993 _mesa_TexCoordPointer(size, type, stride, ptr);
994 }
995
996
997 void GLAPIENTRY
998 _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
999 {
1000 (void) count;
1001 _mesa_EdgeFlagPointer(stride, ptr);
1002 }
1003
1004
1005 void GLAPIENTRY
1006 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
1007 {
1008 GET_CURRENT_CONTEXT(ctx);
1009 GLboolean tflag, cflag, nflag; /* enable/disable flags */
1010 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
1011 GLenum ctype = 0; /* color type */
1012 GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
1013 const GLint toffset = 0; /* always zero */
1014 GLint defstride; /* default stride */
1015 GLint c, f;
1016
1017 FLUSH_VERTICES(ctx, 0);
1018
1019 f = sizeof(GLfloat);
1020 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
1021
1022 if (stride < 0) {
1023 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
1024 return;
1025 }
1026
1027 switch (format) {
1028 case GL_V2F:
1029 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1030 tcomps = 0; ccomps = 0; vcomps = 2;
1031 voffset = 0;
1032 defstride = 2*f;
1033 break;
1034 case GL_V3F:
1035 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1036 tcomps = 0; ccomps = 0; vcomps = 3;
1037 voffset = 0;
1038 defstride = 3*f;
1039 break;
1040 case GL_C4UB_V2F:
1041 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1042 tcomps = 0; ccomps = 4; vcomps = 2;
1043 ctype = GL_UNSIGNED_BYTE;
1044 coffset = 0;
1045 voffset = c;
1046 defstride = c + 2*f;
1047 break;
1048 case GL_C4UB_V3F:
1049 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1050 tcomps = 0; ccomps = 4; vcomps = 3;
1051 ctype = GL_UNSIGNED_BYTE;
1052 coffset = 0;
1053 voffset = c;
1054 defstride = c + 3*f;
1055 break;
1056 case GL_C3F_V3F:
1057 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1058 tcomps = 0; ccomps = 3; vcomps = 3;
1059 ctype = GL_FLOAT;
1060 coffset = 0;
1061 voffset = 3*f;
1062 defstride = 6*f;
1063 break;
1064 case GL_N3F_V3F:
1065 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
1066 tcomps = 0; ccomps = 0; vcomps = 3;
1067 noffset = 0;
1068 voffset = 3*f;
1069 defstride = 6*f;
1070 break;
1071 case GL_C4F_N3F_V3F:
1072 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
1073 tcomps = 0; ccomps = 4; vcomps = 3;
1074 ctype = GL_FLOAT;
1075 coffset = 0;
1076 noffset = 4*f;
1077 voffset = 7*f;
1078 defstride = 10*f;
1079 break;
1080 case GL_T2F_V3F:
1081 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1082 tcomps = 2; ccomps = 0; vcomps = 3;
1083 voffset = 2*f;
1084 defstride = 5*f;
1085 break;
1086 case GL_T4F_V4F:
1087 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1088 tcomps = 4; ccomps = 0; vcomps = 4;
1089 voffset = 4*f;
1090 defstride = 8*f;
1091 break;
1092 case GL_T2F_C4UB_V3F:
1093 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1094 tcomps = 2; ccomps = 4; vcomps = 3;
1095 ctype = GL_UNSIGNED_BYTE;
1096 coffset = 2*f;
1097 voffset = c+2*f;
1098 defstride = c+5*f;
1099 break;
1100 case GL_T2F_C3F_V3F:
1101 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1102 tcomps = 2; ccomps = 3; vcomps = 3;
1103 ctype = GL_FLOAT;
1104 coffset = 2*f;
1105 voffset = 5*f;
1106 defstride = 8*f;
1107 break;
1108 case GL_T2F_N3F_V3F:
1109 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
1110 tcomps = 2; ccomps = 0; vcomps = 3;
1111 noffset = 2*f;
1112 voffset = 5*f;
1113 defstride = 8*f;
1114 break;
1115 case GL_T2F_C4F_N3F_V3F:
1116 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1117 tcomps = 2; ccomps = 4; vcomps = 3;
1118 ctype = GL_FLOAT;
1119 coffset = 2*f;
1120 noffset = 6*f;
1121 voffset = 9*f;
1122 defstride = 12*f;
1123 break;
1124 case GL_T4F_C4F_N3F_V4F:
1125 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1126 tcomps = 4; ccomps = 4; vcomps = 4;
1127 ctype = GL_FLOAT;
1128 coffset = 4*f;
1129 noffset = 8*f;
1130 voffset = 11*f;
1131 defstride = 15*f;
1132 break;
1133 default:
1134 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
1135 return;
1136 }
1137
1138 if (stride==0) {
1139 stride = defstride;
1140 }
1141
1142 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
1143 _mesa_DisableClientState( GL_INDEX_ARRAY );
1144 /* XXX also disable secondary color and generic arrays? */
1145
1146 /* Texcoords */
1147 if (tflag) {
1148 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
1149 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
1150 (GLubyte *) pointer + toffset );
1151 }
1152 else {
1153 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
1154 }
1155
1156 /* Color */
1157 if (cflag) {
1158 _mesa_EnableClientState( GL_COLOR_ARRAY );
1159 _mesa_ColorPointer( ccomps, ctype, stride,
1160 (GLubyte *) pointer + coffset );
1161 }
1162 else {
1163 _mesa_DisableClientState( GL_COLOR_ARRAY );
1164 }
1165
1166
1167 /* Normals */
1168 if (nflag) {
1169 _mesa_EnableClientState( GL_NORMAL_ARRAY );
1170 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset );
1171 }
1172 else {
1173 _mesa_DisableClientState( GL_NORMAL_ARRAY );
1174 }
1175
1176 /* Vertices */
1177 _mesa_EnableClientState( GL_VERTEX_ARRAY );
1178 _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
1179 (GLubyte *) pointer + voffset );
1180 }
1181
1182
1183 void GLAPIENTRY
1184 _mesa_LockArraysEXT(GLint first, GLsizei count)
1185 {
1186 GET_CURRENT_CONTEXT(ctx);
1187
1188 FLUSH_VERTICES(ctx, 0);
1189
1190 if (MESA_VERBOSE & VERBOSE_API)
1191 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
1192
1193 if (first < 0) {
1194 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" );
1195 return;
1196 }
1197 if (count <= 0) {
1198 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" );
1199 return;
1200 }
1201 if (ctx->Array.LockCount != 0) {
1202 _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" );
1203 return;
1204 }
1205
1206 ctx->Array.LockFirst = first;
1207 ctx->Array.LockCount = count;
1208
1209 ctx->NewState |= _NEW_ARRAY;
1210 }
1211
1212
1213 void GLAPIENTRY
1214 _mesa_UnlockArraysEXT( void )
1215 {
1216 GET_CURRENT_CONTEXT(ctx);
1217
1218 FLUSH_VERTICES(ctx, 0);
1219
1220 if (MESA_VERBOSE & VERBOSE_API)
1221 _mesa_debug(ctx, "glUnlockArrays\n");
1222
1223 if (ctx->Array.LockCount == 0) {
1224 _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" );
1225 return;
1226 }
1227
1228 ctx->Array.LockFirst = 0;
1229 ctx->Array.LockCount = 0;
1230 ctx->NewState |= _NEW_ARRAY;
1231 }
1232
1233
1234 /* GL_EXT_multi_draw_arrays */
1235 void GLAPIENTRY
1236 _mesa_MultiDrawArrays( GLenum mode, const GLint *first,
1237 const GLsizei *count, GLsizei primcount )
1238 {
1239 GET_CURRENT_CONTEXT(ctx);
1240 GLint i;
1241
1242 FLUSH_VERTICES(ctx, 0);
1243
1244 for (i = 0; i < primcount; i++) {
1245 if (count[i] > 0) {
1246 CALL_DrawArrays(ctx->CurrentDispatch, (mode, first[i], count[i]));
1247 }
1248 }
1249 }
1250
1251
1252 /* GL_IBM_multimode_draw_arrays */
1253 void GLAPIENTRY
1254 _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
1255 const GLsizei * count,
1256 GLsizei primcount, GLint modestride )
1257 {
1258 GET_CURRENT_CONTEXT(ctx);
1259 GLint i;
1260
1261 FLUSH_VERTICES(ctx, 0);
1262
1263 for ( i = 0 ; i < primcount ; i++ ) {
1264 if ( count[i] > 0 ) {
1265 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1266 CALL_DrawArrays(ctx->CurrentDispatch, ( m, first[i], count[i] ));
1267 }
1268 }
1269 }
1270
1271
1272 /* GL_IBM_multimode_draw_arrays */
1273 void GLAPIENTRY
1274 _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
1275 GLenum type, const GLvoid * const * indices,
1276 GLsizei primcount, GLint modestride )
1277 {
1278 GET_CURRENT_CONTEXT(ctx);
1279 GLint i;
1280
1281 FLUSH_VERTICES(ctx, 0);
1282
1283 /* XXX not sure about ARB_vertex_buffer_object handling here */
1284
1285 for ( i = 0 ; i < primcount ; i++ ) {
1286 if ( count[i] > 0 ) {
1287 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1288 CALL_DrawElements(ctx->CurrentDispatch, ( m, count[i], type,
1289 indices[i] ));
1290 }
1291 }
1292 }
1293
1294
1295 /**
1296 * GL_NV_primitive_restart and GL 3.1
1297 */
1298 void GLAPIENTRY
1299 _mesa_PrimitiveRestartIndex(GLuint index)
1300 {
1301 GET_CURRENT_CONTEXT(ctx);
1302
1303 if (!ctx->Extensions.NV_primitive_restart && ctx->Version < 31) {
1304 _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()");
1305 return;
1306 }
1307
1308 if (ctx->Array.RestartIndex != index) {
1309 FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
1310 ctx->Array.RestartIndex = index;
1311 }
1312 }
1313
1314
1315 /**
1316 * See GL_ARB_instanced_arrays.
1317 * Note that the instance divisor only applies to generic arrays, not
1318 * the legacy vertex arrays.
1319 */
1320 void GLAPIENTRY
1321 _mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
1322 {
1323 GET_CURRENT_CONTEXT(ctx);
1324
1325 const GLuint genericIndex = VERT_ATTRIB_GENERIC(index);
1326
1327 if (!ctx->Extensions.ARB_instanced_arrays) {
1328 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
1329 return;
1330 }
1331
1332 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1333 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribDivisor(index = %u)",
1334 index);
1335 return;
1336 }
1337
1338 ASSERT(genericIndex < Elements(ctx->Array.VAO->VertexAttrib));
1339
1340 /* The ARB_vertex_attrib_binding spec says:
1341 *
1342 * "The command
1343 *
1344 * void VertexAttribDivisor(uint index, uint divisor);
1345 *
1346 * is equivalent to (assuming no errors are generated):
1347 *
1348 * VertexAttribBinding(index, index);
1349 * VertexBindingDivisor(index, divisor);"
1350 */
1351 vertex_attrib_binding(ctx, genericIndex, genericIndex);
1352 vertex_binding_divisor(ctx, genericIndex, divisor);
1353 }
1354
1355
1356 unsigned
1357 _mesa_primitive_restart_index(const struct gl_context *ctx, GLenum ib_type)
1358 {
1359 /* From the OpenGL 4.3 core specification, page 302:
1360 * "If both PRIMITIVE_RESTART and PRIMITIVE_RESTART_FIXED_INDEX are
1361 * enabled, the index value determined by PRIMITIVE_RESTART_FIXED_INDEX
1362 * is used."
1363 */
1364 if (ctx->Array.PrimitiveRestartFixedIndex) {
1365 switch (ib_type) {
1366 case GL_UNSIGNED_BYTE:
1367 return 0xff;
1368 case GL_UNSIGNED_SHORT:
1369 return 0xffff;
1370 case GL_UNSIGNED_INT:
1371 return 0xffffffff;
1372 default:
1373 assert(!"_mesa_primitive_restart_index: Invalid index buffer type.");
1374 }
1375 }
1376
1377 return ctx->Array.RestartIndex;
1378 }
1379
1380
1381 /**
1382 * GL_ARB_vertex_attrib_binding
1383 */
1384 void GLAPIENTRY
1385 _mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset,
1386 GLsizei stride)
1387 {
1388 GET_CURRENT_CONTEXT(ctx);
1389 const struct gl_vertex_array_object *vao = ctx->Array.VAO;
1390 struct gl_buffer_object *vbo;
1391
1392 ASSERT_OUTSIDE_BEGIN_END(ctx);
1393
1394 /* The ARB_vertex_attrib_binding spec says:
1395 *
1396 * "An INVALID_OPERATION error is generated if no vertex array object
1397 * is bound."
1398 */
1399 if (ctx->API == API_OPENGL_CORE &&
1400 ctx->Array.VAO == ctx->Array.DefaultVAO) {
1401 _mesa_error(ctx, GL_INVALID_OPERATION,
1402 "glBindVertexBuffer(No array object bound)");
1403 return;
1404 }
1405
1406 /* The ARB_vertex_attrib_binding spec says:
1407 *
1408 * "An INVALID_VALUE error is generated if <bindingindex> is greater than
1409 * the value of MAX_VERTEX_ATTRIB_BINDINGS."
1410 */
1411 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
1412 _mesa_error(ctx, GL_INVALID_VALUE,
1413 "glBindVertexBuffer(bindingindex=%u > "
1414 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
1415 bindingIndex);
1416 return;
1417 }
1418
1419 /* The ARB_vertex_attrib_binding spec says:
1420 *
1421 * "The error INVALID_VALUE is generated if <stride> or <offset>
1422 * are negative."
1423 */
1424 if (offset < 0) {
1425 _mesa_error(ctx, GL_INVALID_VALUE,
1426 "glBindVertexBuffer(offset=%lld < 0)", (long long)offset);
1427 return;
1428 }
1429
1430 if (stride < 0) {
1431 _mesa_error(ctx, GL_INVALID_VALUE,
1432 "glBindVertexBuffer(stride=%d < 0)", stride);
1433 return;
1434 }
1435
1436 if (buffer == vao->VertexBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj->Name) {
1437 vbo = vao->VertexBinding[VERT_ATTRIB_GENERIC(bindingIndex)].BufferObj;
1438 } else if (buffer != 0) {
1439 vbo = _mesa_lookup_bufferobj(ctx, buffer);
1440
1441 /* From the GL_ARB_vertex_attrib_array spec:
1442 *
1443 * "[Core profile only:]
1444 * An INVALID_OPERATION error is generated if buffer is not zero or a
1445 * name returned from a previous call to GenBuffers, or if such a name
1446 * has since been deleted with DeleteBuffers.
1447 *
1448 * Otherwise, we fall back to the same compat profile behavior as other
1449 * object references (automatically gen it).
1450 */
1451 if (!_mesa_handle_bind_buffer_gen(ctx, GL_ARRAY_BUFFER, buffer,
1452 &vbo, "glBindVertexBuffer"))
1453 return;
1454 } else {
1455 /* The ARB_vertex_attrib_binding spec says:
1456 *
1457 * "If <buffer> is zero, any buffer object attached to this
1458 * bindpoint is detached."
1459 */
1460 vbo = ctx->Shared->NullBufferObj;
1461 }
1462
1463 bind_vertex_buffer(ctx, VERT_ATTRIB_GENERIC(bindingIndex),
1464 vbo, offset, stride);
1465 }
1466
1467
1468 void GLAPIENTRY
1469 _mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers,
1470 const GLintptr *offsets, const GLsizei *strides)
1471 {
1472 GET_CURRENT_CONTEXT(ctx);
1473 struct gl_vertex_array_object * const vao = ctx->Array.VAO;
1474 GLuint i;
1475
1476 ASSERT_OUTSIDE_BEGIN_END(ctx);
1477
1478 /* The ARB_vertex_attrib_binding spec says:
1479 *
1480 * "An INVALID_OPERATION error is generated if no
1481 * vertex array object is bound."
1482 */
1483 if (ctx->API == API_OPENGL_CORE &&
1484 ctx->Array.VAO == ctx->Array.DefaultVAO) {
1485 _mesa_error(ctx, GL_INVALID_OPERATION,
1486 "glBindVertexBuffers(No array object bound)");
1487 return;
1488 }
1489
1490 /* The ARB_multi_bind spec says:
1491 *
1492 * "An INVALID_OPERATION error is generated if <first> + <count>
1493 * is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS."
1494 */
1495 if (first + count > ctx->Const.MaxVertexAttribBindings) {
1496 _mesa_error(ctx, GL_INVALID_OPERATION,
1497 "glBindVertexBuffers(first=%u + count=%d > the value of "
1498 "GL_MAX_VERTEX_ATTRIB_BINDINGS=%u)",
1499 first, count, ctx->Const.MaxVertexAttribBindings);
1500 return;
1501 }
1502
1503 if (!buffers) {
1504 /**
1505 * The ARB_multi_bind spec says:
1506 *
1507 * "If <buffers> is NULL, each affected vertex buffer binding point
1508 * from <first> through <first>+<count>-1 will be reset to have no
1509 * bound buffer object. In this case, the offsets and strides
1510 * associated with the binding points are set to default values,
1511 * ignoring <offsets> and <strides>."
1512 */
1513 struct gl_buffer_object *vbo = ctx->Shared->NullBufferObj;
1514
1515 for (i = 0; i < count; i++)
1516 bind_vertex_buffer(ctx, VERT_ATTRIB_GENERIC(first + i), vbo, 0, 16);
1517
1518 return;
1519 }
1520
1521 /* Note that the error semantics for multi-bind commands differ from
1522 * those of other GL commands.
1523 *
1524 * The Issues section in the ARB_multi_bind spec says:
1525 *
1526 * "(11) Typically, OpenGL specifies that if an error is generated by
1527 * a command, that command has no effect. This is somewhat
1528 * unfortunate for multi-bind commands, because it would require
1529 * a first pass to scan the entire list of bound objects for
1530 * errors and then a second pass to actually perform the
1531 * bindings. Should we have different error semantics?
1532 *
1533 * RESOLVED: Yes. In this specification, when the parameters for
1534 * one of the <count> binding points are invalid, that binding
1535 * point is not updated and an error will be generated. However,
1536 * other binding points in the same command will be updated if
1537 * their parameters are valid and no other error occurs."
1538 */
1539
1540 _mesa_begin_bufferobj_lookups(ctx);
1541
1542 for (i = 0; i < count; i++) {
1543 struct gl_buffer_object *vbo;
1544
1545 /* The ARB_multi_bind spec says:
1546 *
1547 * "An INVALID_VALUE error is generated if any value in
1548 * <offsets> or <strides> is negative (per binding)."
1549 */
1550 if (offsets[i] < 0) {
1551 _mesa_error(ctx, GL_INVALID_VALUE,
1552 "glBindVertexBuffer(offsets[%u]=%lldd < 0)",
1553 i, (long long int) offsets[i]);
1554 continue;
1555 }
1556
1557 if (strides[i] < 0) {
1558 _mesa_error(ctx, GL_INVALID_VALUE,
1559 "glBindVertexBuffer(strides[%u]=%lld < 0)",
1560 i, (long long int) strides[i]);
1561 continue;
1562 }
1563
1564 if (buffers[i]) {
1565 struct gl_vertex_buffer_binding *binding =
1566 &vao->VertexBinding[VERT_ATTRIB_GENERIC(first + i)];
1567
1568 if (buffers[i] == binding->BufferObj->Name)
1569 vbo = binding->BufferObj;
1570 else
1571 vbo = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i,
1572 "glBindVertexBuffers");
1573
1574 if (!vbo)
1575 continue;
1576 } else {
1577 vbo = ctx->Shared->NullBufferObj;
1578 }
1579
1580 bind_vertex_buffer(ctx, VERT_ATTRIB_GENERIC(first + i), vbo,
1581 offsets[i], strides[i]);
1582 }
1583
1584 _mesa_end_bufferobj_lookups(ctx);
1585 }
1586
1587
1588 void GLAPIENTRY
1589 _mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type,
1590 GLboolean normalized, GLuint relativeOffset)
1591 {
1592 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
1593 SHORT_BIT | UNSIGNED_SHORT_BIT |
1594 INT_BIT | UNSIGNED_INT_BIT |
1595 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
1596 FIXED_GL_BIT |
1597 UNSIGNED_INT_2_10_10_10_REV_BIT |
1598 INT_2_10_10_10_REV_BIT |
1599 UNSIGNED_INT_10F_11F_11F_REV_BIT);
1600
1601 GET_CURRENT_CONTEXT(ctx);
1602 ASSERT_OUTSIDE_BEGIN_END(ctx);
1603
1604 /* The ARB_vertex_attrib_binding spec says:
1605 *
1606 * "An INVALID_OPERATION error is generated under any of the following
1607 * conditions:
1608 * - if no vertex array object is currently bound (see section 2.10);
1609 * - ..."
1610 */
1611 if (ctx->API == API_OPENGL_CORE &&
1612 ctx->Array.VAO == ctx->Array.DefaultVAO) {
1613 _mesa_error(ctx, GL_INVALID_OPERATION,
1614 "glVertexAttribFormat(No array object bound)");
1615 return;
1616 }
1617
1618 /* The ARB_vertex_attrib_binding spec says:
1619 *
1620 * "The error INVALID_VALUE is generated if index is greater than or equal
1621 * to the value of MAX_VERTEX_ATTRIBS."
1622 */
1623 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1624 _mesa_error(ctx, GL_INVALID_VALUE,
1625 "glVertexAttribFormat(attribindex=%u > "
1626 "GL_MAX_VERTEX_ATTRIBS)",
1627 attribIndex);
1628 return;
1629 }
1630
1631 FLUSH_VERTICES(ctx, 0);
1632
1633 update_array_format(ctx, "glVertexAttribFormat",
1634 VERT_ATTRIB_GENERIC(attribIndex),
1635 legalTypes, 1, BGRA_OR_4, size, type, normalized,
1636 GL_FALSE, relativeOffset);
1637 }
1638
1639
1640 void GLAPIENTRY
1641 _mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type,
1642 GLuint relativeOffset)
1643 {
1644 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
1645 SHORT_BIT | UNSIGNED_SHORT_BIT |
1646 INT_BIT | UNSIGNED_INT_BIT);
1647
1648 GET_CURRENT_CONTEXT(ctx);
1649 ASSERT_OUTSIDE_BEGIN_END(ctx);
1650
1651 /* The ARB_vertex_attrib_binding spec says:
1652 *
1653 * "An INVALID_OPERATION error is generated under any of the following
1654 * conditions:
1655 * - if no vertex array object is currently bound (see section 2.10);
1656 * - ..."
1657 */
1658 if (ctx->API == API_OPENGL_CORE &&
1659 ctx->Array.VAO == ctx->Array.DefaultVAO) {
1660 _mesa_error(ctx, GL_INVALID_OPERATION,
1661 "glVertexAttribIFormat(No array object bound)");
1662 return;
1663 }
1664
1665 /* The ARB_vertex_attrib_binding spec says:
1666 *
1667 * "The error INVALID_VALUE is generated if index is greater than
1668 * or equal to the value of MAX_VERTEX_ATTRIBS."
1669 */
1670 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1671 _mesa_error(ctx, GL_INVALID_VALUE,
1672 "glVertexAttribIFormat(attribindex=%u > "
1673 "GL_MAX_VERTEX_ATTRIBS)",
1674 attribIndex);
1675 return;
1676 }
1677
1678 FLUSH_VERTICES(ctx, 0);
1679
1680 update_array_format(ctx, "glVertexAttribIFormat",
1681 VERT_ATTRIB_GENERIC(attribIndex),
1682 legalTypes, 1, 4, size, type, GL_FALSE, GL_TRUE,
1683 relativeOffset);
1684 }
1685
1686
1687 void GLAPIENTRY
1688 _mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type,
1689 GLuint relativeOffset)
1690 {
1691 const GLbitfield legalTypes = DOUBLE_BIT;
1692
1693 GET_CURRENT_CONTEXT(ctx);
1694 ASSERT_OUTSIDE_BEGIN_END(ctx);
1695
1696 /* Page 298 of the PDF of the OpenGL 4.3 (Core Profile) spec says:
1697 *
1698 * "An INVALID_OPERATION error is generated under any of the following
1699 * conditions:
1700 * • if no vertex array object is currently bound (see section 10.4);
1701 * • ..."
1702 *
1703 * This language is missing from the extension spec, but we assume
1704 * that this is an oversight.
1705 */
1706 if (ctx->API == API_OPENGL_CORE &&
1707 ctx->Array.VAO == ctx->Array.DefaultVAO) {
1708 _mesa_error(ctx, GL_INVALID_OPERATION,
1709 "glVertexAttribLFormat(No array object bound)");
1710 return;
1711 }
1712
1713 /* The ARB_vertex_attrib_binding spec says:
1714 *
1715 * "The error INVALID_VALUE is generated if <attribindex> is greater than
1716 * or equal to the value of MAX_VERTEX_ATTRIBS."
1717 */
1718 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1719 _mesa_error(ctx, GL_INVALID_VALUE,
1720 "glVertexAttribLFormat(attribindex=%u > "
1721 "GL_MAX_VERTEX_ATTRIBS)",
1722 attribIndex);
1723 return;
1724 }
1725
1726 FLUSH_VERTICES(ctx, 0);
1727
1728 update_array_format(ctx, "glVertexAttribLFormat",
1729 VERT_ATTRIB_GENERIC(attribIndex),
1730 legalTypes, 1, 4, size, type, GL_FALSE, GL_FALSE,
1731 relativeOffset);
1732 }
1733
1734
1735 void GLAPIENTRY
1736 _mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
1737 {
1738 GET_CURRENT_CONTEXT(ctx);
1739 ASSERT_OUTSIDE_BEGIN_END(ctx);
1740
1741 /* The ARB_vertex_attrib_binding spec says:
1742 *
1743 * "An INVALID_OPERATION error is generated if no vertex array object
1744 * is bound."
1745 */
1746 if (ctx->API == API_OPENGL_CORE &&
1747 ctx->Array.VAO == ctx->Array.DefaultVAO) {
1748 _mesa_error(ctx, GL_INVALID_OPERATION,
1749 "glVertexAttribBinding(No array object bound)");
1750 return;
1751 }
1752
1753 /* The ARB_vertex_attrib_binding spec says:
1754 *
1755 * "<attribindex> must be less than the value of MAX_VERTEX_ATTRIBS and
1756 * <bindingindex> must be less than the value of
1757 * MAX_VERTEX_ATTRIB_BINDINGS, otherwise the error INVALID_VALUE
1758 * is generated."
1759 */
1760 if (attribIndex >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
1761 _mesa_error(ctx, GL_INVALID_VALUE,
1762 "glVertexAttribBinding(attribindex=%u >= "
1763 "GL_MAX_VERTEX_ATTRIBS)",
1764 attribIndex);
1765 return;
1766 }
1767
1768 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
1769 _mesa_error(ctx, GL_INVALID_VALUE,
1770 "glVertexAttribBinding(bindingindex=%u >= "
1771 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
1772 bindingIndex);
1773 return;
1774 }
1775
1776 ASSERT(VERT_ATTRIB_GENERIC(attribIndex) <
1777 Elements(ctx->Array.VAO->VertexAttrib));
1778
1779 vertex_attrib_binding(ctx, VERT_ATTRIB_GENERIC(attribIndex),
1780 VERT_ATTRIB_GENERIC(bindingIndex));
1781 }
1782
1783
1784 void GLAPIENTRY
1785 _mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
1786 {
1787 GET_CURRENT_CONTEXT(ctx);
1788 ASSERT_OUTSIDE_BEGIN_END(ctx);
1789
1790 if (!ctx->Extensions.ARB_instanced_arrays) {
1791 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexBindingDivisor()");
1792 return;
1793 }
1794
1795 /* The ARB_vertex_attrib_binding spec says:
1796 *
1797 * "An INVALID_OPERATION error is generated if no vertex array object
1798 * is bound."
1799 */
1800 if (ctx->API == API_OPENGL_CORE &&
1801 ctx->Array.VAO == ctx->Array.DefaultVAO) {
1802 _mesa_error(ctx, GL_INVALID_OPERATION,
1803 "glVertexBindingDivisor(No array object bound)");
1804 return;
1805 }
1806
1807 /* The ARB_vertex_attrib_binding spec says:
1808 *
1809 * "An INVALID_VALUE error is generated if <bindingindex> is greater
1810 * than or equal to the value of MAX_VERTEX_ATTRIB_BINDINGS."
1811 */
1812 if (bindingIndex >= ctx->Const.MaxVertexAttribBindings) {
1813 _mesa_error(ctx, GL_INVALID_VALUE,
1814 "glVertexBindingDivisor(bindingindex=%u > "
1815 "GL_MAX_VERTEX_ATTRIB_BINDINGS)",
1816 bindingIndex);
1817 return;
1818 }
1819
1820 vertex_binding_divisor(ctx, VERT_ATTRIB_GENERIC(bindingIndex), divisor);
1821 }
1822
1823
1824 /**
1825 * Copy one client vertex array to another.
1826 */
1827 void
1828 _mesa_copy_client_array(struct gl_context *ctx,
1829 struct gl_client_array *dst,
1830 struct gl_client_array *src)
1831 {
1832 dst->Size = src->Size;
1833 dst->Type = src->Type;
1834 dst->Format = src->Format;
1835 dst->Stride = src->Stride;
1836 dst->StrideB = src->StrideB;
1837 dst->Ptr = src->Ptr;
1838 dst->Enabled = src->Enabled;
1839 dst->Normalized = src->Normalized;
1840 dst->Integer = src->Integer;
1841 dst->InstanceDivisor = src->InstanceDivisor;
1842 dst->_ElementSize = src->_ElementSize;
1843 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
1844 dst->_MaxElement = src->_MaxElement;
1845 }
1846
1847 void
1848 _mesa_copy_vertex_attrib_array(struct gl_context *ctx,
1849 struct gl_vertex_attrib_array *dst,
1850 const struct gl_vertex_attrib_array *src)
1851 {
1852 dst->Size = src->Size;
1853 dst->Type = src->Type;
1854 dst->Format = src->Format;
1855 dst->VertexBinding = src->VertexBinding;
1856 dst->RelativeOffset = src->RelativeOffset;
1857 dst->Format = src->Format;
1858 dst->Integer = src->Integer;
1859 dst->Normalized = src->Normalized;
1860 dst->Ptr = src->Ptr;
1861 dst->Enabled = src->Enabled;
1862 dst->_ElementSize = src->_ElementSize;
1863 }
1864
1865 void
1866 _mesa_copy_vertex_buffer_binding(struct gl_context *ctx,
1867 struct gl_vertex_buffer_binding *dst,
1868 const struct gl_vertex_buffer_binding *src)
1869 {
1870 dst->Offset = src->Offset;
1871 dst->Stride = src->Stride;
1872 dst->InstanceDivisor = src->InstanceDivisor;
1873 dst->_BoundArrays = src->_BoundArrays;
1874
1875 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
1876 }
1877
1878 /**
1879 * Print vertex array's fields.
1880 */
1881 static void
1882 print_array(const char *name, GLint index, const struct gl_client_array *array)
1883 {
1884 if (index >= 0)
1885 printf(" %s[%d]: ", name, index);
1886 else
1887 printf(" %s: ", name);
1888 printf("Ptr=%p, Type=0x%x, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %lu), MaxElem=%u\n",
1889 array->Ptr, array->Type, array->Size,
1890 array->_ElementSize, array->StrideB,
1891 array->BufferObj->Name, (unsigned long) array->BufferObj->Size,
1892 array->_MaxElement);
1893 }
1894
1895
1896 /**
1897 * Print current vertex object/array info. For debug.
1898 */
1899 void
1900 _mesa_print_arrays(struct gl_context *ctx)
1901 {
1902 struct gl_vertex_array_object *vao = ctx->Array.VAO;
1903 GLuint i;
1904
1905 _mesa_update_vao_max_element(ctx, vao);
1906
1907 printf("Array Object %u\n", vao->Name);
1908 if (vao->_VertexAttrib[VERT_ATTRIB_POS].Enabled)
1909 print_array("Vertex", -1, &vao->_VertexAttrib[VERT_ATTRIB_POS]);
1910 if (vao->_VertexAttrib[VERT_ATTRIB_NORMAL].Enabled)
1911 print_array("Normal", -1, &vao->_VertexAttrib[VERT_ATTRIB_NORMAL]);
1912 if (vao->_VertexAttrib[VERT_ATTRIB_COLOR0].Enabled)
1913 print_array("Color", -1, &vao->_VertexAttrib[VERT_ATTRIB_COLOR0]);
1914 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
1915 if (vao->_VertexAttrib[VERT_ATTRIB_TEX(i)].Enabled)
1916 print_array("TexCoord", i, &vao->_VertexAttrib[VERT_ATTRIB_TEX(i)]);
1917 for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++)
1918 if (vao->_VertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
1919 print_array("Attrib", i, &vao->_VertexAttrib[VERT_ATTRIB_GENERIC(i)]);
1920 printf(" _MaxElement = %u\n", vao->_MaxElement);
1921 }
1922
1923
1924 /**
1925 * Initialize vertex array state for given context.
1926 */
1927 void
1928 _mesa_init_varray(struct gl_context *ctx)
1929 {
1930 ctx->Array.DefaultVAO = ctx->Driver.NewArrayObject(ctx, 0);
1931 _mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO);
1932 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
1933
1934 ctx->Array.Objects = _mesa_NewHashTable();
1935 }
1936
1937
1938 /**
1939 * Callback for deleting an array object. Called by _mesa_HashDeleteAll().
1940 */
1941 static void
1942 delete_arrayobj_cb(GLuint id, void *data, void *userData)
1943 {
1944 struct gl_vertex_array_object *vao = (struct gl_vertex_array_object *) data;
1945 struct gl_context *ctx = (struct gl_context *) userData;
1946 _mesa_delete_vao(ctx, vao);
1947 }
1948
1949
1950 /**
1951 * Free vertex array state for given context.
1952 */
1953 void
1954 _mesa_free_varray_data(struct gl_context *ctx)
1955 {
1956 _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx);
1957 _mesa_DeleteHashTable(ctx->Array.Objects);
1958 }