glapi: Add infrastructure for ARB_vertex_attrib_binding
[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
64
65 /** Convert GL datatype enum into a <type>_BIT value seen above */
66 static GLbitfield
67 type_to_bit(const struct gl_context *ctx, GLenum type)
68 {
69 switch (type) {
70 case GL_BOOL:
71 return BOOL_BIT;
72 case GL_BYTE:
73 return BYTE_BIT;
74 case GL_UNSIGNED_BYTE:
75 return UNSIGNED_BYTE_BIT;
76 case GL_SHORT:
77 return SHORT_BIT;
78 case GL_UNSIGNED_SHORT:
79 return UNSIGNED_SHORT_BIT;
80 case GL_INT:
81 return INT_BIT;
82 case GL_UNSIGNED_INT:
83 return UNSIGNED_INT_BIT;
84 case GL_HALF_FLOAT:
85 if (ctx->Extensions.ARB_half_float_vertex)
86 return HALF_BIT;
87 else
88 return 0x0;
89 case GL_FLOAT:
90 return FLOAT_BIT;
91 case GL_DOUBLE:
92 return DOUBLE_BIT;
93 case GL_FIXED:
94 return _mesa_is_desktop_gl(ctx) ? FIXED_GL_BIT : FIXED_ES_BIT;
95 case GL_UNSIGNED_INT_2_10_10_10_REV:
96 return UNSIGNED_INT_2_10_10_10_REV_BIT;
97 case GL_INT_2_10_10_10_REV:
98 return INT_2_10_10_10_REV_BIT;
99 default:
100 return 0;
101 }
102 }
103
104
105 /**
106 * Does error checking and updates the format in an attrib array.
107 *
108 * Called by update_array().
109 *
110 * \param func Name of calling function used for error reporting
111 * \param attrib The index of the attribute array
112 * \param legalTypes Bitmask of *_BIT above indicating legal datatypes
113 * \param sizeMin Min allowable size value
114 * \param sizeMax Max allowable size value (may also be BGRA_OR_4)
115 * \param size Components per element (1, 2, 3 or 4)
116 * \param type Datatype of each component (GL_FLOAT, GL_INT, etc)
117 * \param normalized Whether integer types are converted to floats in [-1, 1]
118 * \param integer Integer-valued values (will not be normalized to [-1, 1])
119 */
120 static bool
121 update_array_format(struct gl_context *ctx,
122 const char *func,
123 GLuint attrib, GLbitfield legalTypesMask,
124 GLint sizeMin, GLint sizeMax,
125 GLint size, GLenum type,
126 GLboolean normalized, GLboolean integer)
127 {
128 struct gl_client_array *array;
129 GLbitfield typeBit;
130 GLuint elementSize;
131 GLenum format = GL_RGBA;
132
133 if (_mesa_is_gles(ctx)) {
134 legalTypesMask &= ~(FIXED_GL_BIT | DOUBLE_BIT);
135
136 /* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until
137 * 3.0. The 2_10_10_10 types are added in OpenGL ES 3.0 or
138 * GL_OES_vertex_type_10_10_10_2. GL_HALF_FLOAT data is not allowed
139 * until 3.0 or with the GL_OES_vertex_half float extension, which isn't
140 * quite as trivial as we'd like because it uses a different enum value
141 * for GL_HALF_FLOAT_OES.
142 */
143 if (ctx->Version < 30) {
144 legalTypesMask &= ~(UNSIGNED_INT_BIT
145 | INT_BIT
146 | UNSIGNED_INT_2_10_10_10_REV_BIT
147 | INT_2_10_10_10_REV_BIT
148 | HALF_BIT);
149 }
150
151 /* BGRA ordering is not supported in ES contexts.
152 */
153 if (sizeMax == BGRA_OR_4)
154 sizeMax = 4;
155 } else {
156 legalTypesMask &= ~FIXED_ES_BIT;
157
158 if (!ctx->Extensions.ARB_ES2_compatibility)
159 legalTypesMask &= ~FIXED_GL_BIT;
160
161 if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev)
162 legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT |
163 INT_2_10_10_10_REV_BIT);
164 }
165
166 typeBit = type_to_bit(ctx, type);
167 if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) {
168 _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)",
169 func, _mesa_lookup_enum_by_nr(type));
170 return false;
171 }
172
173 /* Do size parameter checking.
174 * If sizeMax = BGRA_OR_4 it means that size = GL_BGRA is legal and
175 * must be handled specially.
176 */
177 if (ctx->Extensions.EXT_vertex_array_bgra &&
178 sizeMax == BGRA_OR_4 &&
179 size == GL_BGRA) {
180 /* Page 298 of the PDF of the OpenGL 4.3 (Core Profile) spec says:
181 *
182 * "An INVALID_OPERATION error is generated under any of the following
183 * conditions:
184 * ...
185 * • size is BGRA and type is not UNSIGNED_BYTE, INT_2_10_10_10_REV
186 * or UNSIGNED_INT_2_10_10_10_REV;
187 * ...
188 * • size is BGRA and normalized is FALSE;"
189 */
190 bool bgra_error = false;
191
192 if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) {
193 if (type != GL_UNSIGNED_INT_2_10_10_10_REV &&
194 type != GL_INT_2_10_10_10_REV &&
195 type != GL_UNSIGNED_BYTE)
196 bgra_error = true;
197 } else if (type != GL_UNSIGNED_BYTE)
198 bgra_error = true;
199
200 if (bgra_error) {
201 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=GL_BGRA and type=%s)",
202 func, _mesa_lookup_enum_by_nr(type));
203 return false;
204 }
205
206 if (!normalized) {
207 _mesa_error(ctx, GL_INVALID_OPERATION,
208 "%s(size=GL_BGRA and normalized=GL_FALSE)", func);
209 return false;
210 }
211
212 format = GL_BGRA;
213 size = 4;
214 }
215 else if (size < sizeMin || size > sizeMax || size > 4) {
216 _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size);
217 return false;
218 }
219
220 if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev &&
221 (type == GL_UNSIGNED_INT_2_10_10_10_REV ||
222 type == GL_INT_2_10_10_10_REV) && size != 4) {
223 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size);
224 return false;
225 }
226
227 ASSERT(size <= 4);
228
229 elementSize = _mesa_bytes_per_vertex_attrib(size, type);
230 assert(elementSize != -1);
231
232 array = &ctx->Array.ArrayObj->_VertexAttrib[attrib];
233 array->Size = size;
234 array->Type = type;
235 array->Format = format;
236 array->Normalized = normalized;
237 array->Integer = integer;
238 array->_ElementSize = elementSize;
239
240 return true;
241 }
242
243
244 /**
245 * Do error checking and update state for glVertex/Color/TexCoord/...Pointer
246 * functions.
247 *
248 * \param func name of calling function used for error reporting
249 * \param attrib the attribute array index to update
250 * \param legalTypes bitmask of *_BIT above indicating legal datatypes
251 * \param sizeMin min allowable size value
252 * \param sizeMax max allowable size value (may also be BGRA_OR_4)
253 * \param size components per element (1, 2, 3 or 4)
254 * \param type datatype of each component (GL_FLOAT, GL_INT, etc)
255 * \param stride stride between elements, in elements
256 * \param normalized are integer types converted to floats in [-1, 1]?
257 * \param integer integer-valued values (will not be normalized to [-1,1])
258 * \param ptr the address (or offset inside VBO) of the array data
259 */
260 static void
261 update_array(struct gl_context *ctx,
262 const char *func,
263 GLuint attrib, GLbitfield legalTypesMask,
264 GLint sizeMin, GLint sizeMax,
265 GLint size, GLenum type, GLsizei stride,
266 GLboolean normalized, GLboolean integer,
267 const GLvoid *ptr)
268 {
269 struct gl_client_array *array;
270
271 /* Page 407 (page 423 of the PDF) of the OpenGL 3.0 spec says:
272 *
273 * "Client vertex arrays - all vertex array attribute pointers must
274 * refer to buffer objects (section 2.9.2). The default vertex array
275 * object (the name zero) is also deprecated. Calling
276 * VertexAttribPointer when no buffer object or no vertex array object
277 * is bound will generate an INVALID_OPERATION error..."
278 *
279 * The check for VBOs is handled below.
280 */
281 if (ctx->API == API_OPENGL_CORE
282 && (ctx->Array.ArrayObj == ctx->Array.DefaultArrayObj)) {
283 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no array object bound)",
284 func);
285 return;
286 }
287
288 if (!update_array_format(ctx, func, attrib, legalTypesMask, sizeMin, sizeMax,
289 size, type, normalized, integer)) {
290 return;
291 }
292
293 if (stride < 0) {
294 _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride );
295 return;
296 }
297
298 /* Page 29 (page 44 of the PDF) of the OpenGL 3.3 spec says:
299 *
300 * "An INVALID_OPERATION error is generated under any of the following
301 * conditions:
302 *
303 * ...
304 *
305 * * any of the *Pointer commands specifying the location and
306 * organization of vertex array data are called while zero is bound
307 * to the ARRAY_BUFFER buffer object binding point (see section
308 * 2.9.6), and the pointer argument is not NULL."
309 */
310 if (ptr != NULL && ctx->Array.ArrayObj->ARBsemantics &&
311 !_mesa_is_bufferobj(ctx->Array.ArrayBufferObj)) {
312 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func);
313 return;
314 }
315
316 array = &ctx->Array.ArrayObj->_VertexAttrib[attrib];
317 array->Stride = stride;
318 array->StrideB = stride ? stride : array->_ElementSize;
319 array->Ptr = (const GLubyte *) ptr;
320
321 _mesa_reference_buffer_object(ctx, &array->BufferObj,
322 ctx->Array.ArrayBufferObj);
323
324 ctx->NewState |= _NEW_ARRAY;
325 ctx->Array.ArrayObj->NewArrays |= VERT_BIT(attrib);
326 }
327
328
329 void GLAPIENTRY
330 _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
331 {
332 GET_CURRENT_CONTEXT(ctx);
333 GLbitfield legalTypes = (ctx->API == API_OPENGLES)
334 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
335 : (SHORT_BIT | INT_BIT | FLOAT_BIT |
336 DOUBLE_BIT | HALF_BIT |
337 UNSIGNED_INT_2_10_10_10_REV_BIT |
338 INT_2_10_10_10_REV_BIT);
339
340 FLUSH_VERTICES(ctx, 0);
341
342 update_array(ctx, "glVertexPointer", VERT_ATTRIB_POS,
343 legalTypes, 2, 4,
344 size, type, stride, GL_FALSE, GL_FALSE, ptr);
345 }
346
347
348 void GLAPIENTRY
349 _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
350 {
351 GET_CURRENT_CONTEXT(ctx);
352 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
353 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
354 : (BYTE_BIT | SHORT_BIT | INT_BIT |
355 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
356 UNSIGNED_INT_2_10_10_10_REV_BIT |
357 INT_2_10_10_10_REV_BIT);
358
359 FLUSH_VERTICES(ctx, 0);
360
361 update_array(ctx, "glNormalPointer", VERT_ATTRIB_NORMAL,
362 legalTypes, 3, 3,
363 3, type, stride, GL_TRUE, GL_FALSE, ptr);
364 }
365
366
367 void GLAPIENTRY
368 _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
369 {
370 GET_CURRENT_CONTEXT(ctx);
371 const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
372 ? (UNSIGNED_BYTE_BIT | HALF_BIT | FLOAT_BIT | FIXED_ES_BIT)
373 : (BYTE_BIT | UNSIGNED_BYTE_BIT |
374 SHORT_BIT | UNSIGNED_SHORT_BIT |
375 INT_BIT | UNSIGNED_INT_BIT |
376 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
377 UNSIGNED_INT_2_10_10_10_REV_BIT |
378 INT_2_10_10_10_REV_BIT);
379 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 4 : 3;
380
381 FLUSH_VERTICES(ctx, 0);
382
383 update_array(ctx, "glColorPointer", VERT_ATTRIB_COLOR0,
384 legalTypes, sizeMin, BGRA_OR_4,
385 size, type, stride, GL_TRUE, GL_FALSE, ptr);
386 }
387
388
389 void GLAPIENTRY
390 _mesa_FogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
391 {
392 const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT);
393 GET_CURRENT_CONTEXT(ctx);
394
395 FLUSH_VERTICES(ctx, 0);
396
397 update_array(ctx, "glFogCoordPointer", VERT_ATTRIB_FOG,
398 legalTypes, 1, 1,
399 1, type, stride, GL_FALSE, GL_FALSE, ptr);
400 }
401
402
403 void GLAPIENTRY
404 _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
405 {
406 const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT |
407 FLOAT_BIT | DOUBLE_BIT);
408 GET_CURRENT_CONTEXT(ctx);
409
410 FLUSH_VERTICES(ctx, 0);
411
412 update_array(ctx, "glIndexPointer", VERT_ATTRIB_COLOR_INDEX,
413 legalTypes, 1, 1,
414 1, type, stride, GL_FALSE, GL_FALSE, ptr);
415 }
416
417
418 void GLAPIENTRY
419 _mesa_SecondaryColorPointer(GLint size, GLenum type,
420 GLsizei stride, const GLvoid *ptr)
421 {
422 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
423 SHORT_BIT | UNSIGNED_SHORT_BIT |
424 INT_BIT | UNSIGNED_INT_BIT |
425 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
426 UNSIGNED_INT_2_10_10_10_REV_BIT |
427 INT_2_10_10_10_REV_BIT);
428 GET_CURRENT_CONTEXT(ctx);
429
430 FLUSH_VERTICES(ctx, 0);
431
432 update_array(ctx, "glSecondaryColorPointer", VERT_ATTRIB_COLOR1,
433 legalTypes, 3, BGRA_OR_4,
434 size, type, stride, GL_TRUE, GL_FALSE, ptr);
435 }
436
437
438 void GLAPIENTRY
439 _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
440 const GLvoid *ptr)
441 {
442 GET_CURRENT_CONTEXT(ctx);
443 GLbitfield legalTypes = (ctx->API == API_OPENGLES)
444 ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
445 : (SHORT_BIT | INT_BIT |
446 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
447 UNSIGNED_INT_2_10_10_10_REV_BIT |
448 INT_2_10_10_10_REV_BIT);
449 const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1;
450 const GLuint unit = ctx->Array.ActiveTexture;
451
452 FLUSH_VERTICES(ctx, 0);
453
454 update_array(ctx, "glTexCoordPointer", VERT_ATTRIB_TEX(unit),
455 legalTypes, sizeMin, 4,
456 size, type, stride, GL_FALSE, GL_FALSE,
457 ptr);
458 }
459
460
461 void GLAPIENTRY
462 _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
463 {
464 const GLbitfield legalTypes = UNSIGNED_BYTE_BIT;
465 /* see table 2.4 edits in GL_EXT_gpu_shader4 spec: */
466 const GLboolean integer = GL_TRUE;
467 GET_CURRENT_CONTEXT(ctx);
468
469 FLUSH_VERTICES(ctx, 0);
470
471 update_array(ctx, "glEdgeFlagPointer", VERT_ATTRIB_EDGEFLAG,
472 legalTypes, 1, 1,
473 1, GL_UNSIGNED_BYTE, stride, GL_FALSE, integer, ptr);
474 }
475
476
477 void GLAPIENTRY
478 _mesa_PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *ptr)
479 {
480 const GLbitfield legalTypes = (FLOAT_BIT | FIXED_ES_BIT);
481 GET_CURRENT_CONTEXT(ctx);
482
483 FLUSH_VERTICES(ctx, 0);
484
485 if (ctx->API != API_OPENGLES) {
486 _mesa_error(ctx, GL_INVALID_OPERATION,
487 "glPointSizePointer(ES 1.x only)");
488 return;
489 }
490
491 update_array(ctx, "glPointSizePointer", VERT_ATTRIB_POINT_SIZE,
492 legalTypes, 1, 1,
493 1, type, stride, GL_FALSE, GL_FALSE, ptr);
494 }
495
496
497 /**
498 * Set a generic vertex attribute array.
499 * Note that these arrays DO NOT alias the conventional GL vertex arrays
500 * (position, normal, color, fog, texcoord, etc).
501 */
502 void GLAPIENTRY
503 _mesa_VertexAttribPointer(GLuint index, GLint size, GLenum type,
504 GLboolean normalized,
505 GLsizei stride, const GLvoid *ptr)
506 {
507 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
508 SHORT_BIT | UNSIGNED_SHORT_BIT |
509 INT_BIT | UNSIGNED_INT_BIT |
510 HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
511 FIXED_ES_BIT | FIXED_GL_BIT |
512 UNSIGNED_INT_2_10_10_10_REV_BIT |
513 INT_2_10_10_10_REV_BIT);
514 GET_CURRENT_CONTEXT(ctx);
515
516 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
517 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)");
518 return;
519 }
520
521 update_array(ctx, "glVertexAttribPointer", VERT_ATTRIB_GENERIC(index),
522 legalTypes, 1, BGRA_OR_4,
523 size, type, stride, normalized, GL_FALSE, ptr);
524 }
525
526
527 /**
528 * GL_EXT_gpu_shader4 / GL 3.0.
529 * Set an integer-valued vertex attribute array.
530 * Note that these arrays DO NOT alias the conventional GL vertex arrays
531 * (position, normal, color, fog, texcoord, etc).
532 */
533 void GLAPIENTRY
534 _mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type,
535 GLsizei stride, const GLvoid *ptr)
536 {
537 const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
538 SHORT_BIT | UNSIGNED_SHORT_BIT |
539 INT_BIT | UNSIGNED_INT_BIT);
540 const GLboolean normalized = GL_FALSE;
541 const GLboolean integer = GL_TRUE;
542 GET_CURRENT_CONTEXT(ctx);
543
544 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
545 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIPointer(index)");
546 return;
547 }
548
549 update_array(ctx, "glVertexAttribIPointer", VERT_ATTRIB_GENERIC(index),
550 legalTypes, 1, 4,
551 size, type, stride, normalized, integer, ptr);
552 }
553
554
555
556 void GLAPIENTRY
557 _mesa_EnableVertexAttribArray(GLuint index)
558 {
559 struct gl_array_object *arrayObj;
560 GET_CURRENT_CONTEXT(ctx);
561
562 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
563 _mesa_error(ctx, GL_INVALID_VALUE,
564 "glEnableVertexAttribArrayARB(index)");
565 return;
566 }
567
568 arrayObj = ctx->Array.ArrayObj;
569
570 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(arrayObj->_VertexAttrib));
571
572 if (!arrayObj->_VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled) {
573 /* was disabled, now being enabled */
574 FLUSH_VERTICES(ctx, _NEW_ARRAY);
575 arrayObj->_VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_TRUE;
576 arrayObj->_Enabled |= VERT_BIT_GENERIC(index);
577 arrayObj->NewArrays |= VERT_BIT_GENERIC(index);
578 }
579 }
580
581
582 void GLAPIENTRY
583 _mesa_DisableVertexAttribArray(GLuint index)
584 {
585 struct gl_array_object *arrayObj;
586 GET_CURRENT_CONTEXT(ctx);
587
588 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
589 _mesa_error(ctx, GL_INVALID_VALUE,
590 "glDisableVertexAttribArrayARB(index)");
591 return;
592 }
593
594 arrayObj = ctx->Array.ArrayObj;
595
596 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(arrayObj->_VertexAttrib));
597
598 if (arrayObj->_VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled) {
599 /* was enabled, now being disabled */
600 FLUSH_VERTICES(ctx, _NEW_ARRAY);
601 arrayObj->_VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_FALSE;
602 arrayObj->_Enabled &= ~VERT_BIT_GENERIC(index);
603 arrayObj->NewArrays |= VERT_BIT_GENERIC(index);
604 }
605 }
606
607
608 /**
609 * Return info for a vertex attribute array (no alias with legacy
610 * vertex attributes (pos, normal, color, etc)). This function does
611 * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query.
612 */
613 static GLuint
614 get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname,
615 const char *caller)
616 {
617 const struct gl_client_array *array;
618
619 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
620 _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index);
621 return 0;
622 }
623
624 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->_VertexAttrib));
625
626 array = &ctx->Array.ArrayObj->_VertexAttrib[VERT_ATTRIB_GENERIC(index)];
627
628 switch (pname) {
629 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
630 return array->Enabled;
631 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
632 return array->Size;
633 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
634 return array->Stride;
635 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
636 return array->Type;
637 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
638 return array->Normalized;
639 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
640 return array->BufferObj->Name;
641 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
642 if ((_mesa_is_desktop_gl(ctx)
643 && (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))
644 || _mesa_is_gles3(ctx)) {
645 return array->Integer;
646 }
647 goto error;
648 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB:
649 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_instanced_arrays)
650 || _mesa_is_gles3(ctx)) {
651 return array->InstanceDivisor;
652 }
653 goto error;
654 default:
655 ; /* fall-through */
656 }
657
658 error:
659 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname);
660 return 0;
661 }
662
663
664 static const GLfloat *
665 get_current_attrib(struct gl_context *ctx, GLuint index, const char *function)
666 {
667 if (index == 0) {
668 /* In OpenGL 3.1 attribute 0 becomes non-magic, just like in OpenGL ES
669 * 2.0. Note that we cannot just check for API_OPENGL_CORE here because
670 * that will erroneously allow this usage in a 3.0 forward-compatible
671 * context too.
672 */
673 if ((ctx->API != API_OPENGL_CORE || ctx->Version < 31)
674 && ctx->API != API_OPENGLES2) {
675 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function);
676 return NULL;
677 }
678 }
679 else if (index >= ctx->Const.VertexProgram.MaxAttribs) {
680 _mesa_error(ctx, GL_INVALID_VALUE,
681 "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function);
682 return NULL;
683 }
684
685 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->_VertexAttrib));
686
687 FLUSH_CURRENT(ctx, 0);
688 return ctx->Current.Attrib[VERT_ATTRIB_GENERIC(index)];
689 }
690
691 void GLAPIENTRY
692 _mesa_GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
693 {
694 GET_CURRENT_CONTEXT(ctx);
695
696 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
697 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv");
698 if (v != NULL) {
699 COPY_4V(params, v);
700 }
701 }
702 else {
703 params[0] = (GLfloat) get_vertex_array_attrib(ctx, index, pname,
704 "glGetVertexAttribfv");
705 }
706 }
707
708
709 void GLAPIENTRY
710 _mesa_GetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params)
711 {
712 GET_CURRENT_CONTEXT(ctx);
713
714 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
715 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv");
716 if (v != NULL) {
717 params[0] = (GLdouble) v[0];
718 params[1] = (GLdouble) v[1];
719 params[2] = (GLdouble) v[2];
720 params[3] = (GLdouble) v[3];
721 }
722 }
723 else {
724 params[0] = (GLdouble) get_vertex_array_attrib(ctx, index, pname,
725 "glGetVertexAttribdv");
726 }
727 }
728
729
730 void GLAPIENTRY
731 _mesa_GetVertexAttribiv(GLuint index, GLenum pname, GLint *params)
732 {
733 GET_CURRENT_CONTEXT(ctx);
734
735 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
736 const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv");
737 if (v != NULL) {
738 /* XXX should floats in[0,1] be scaled to full int range? */
739 params[0] = (GLint) v[0];
740 params[1] = (GLint) v[1];
741 params[2] = (GLint) v[2];
742 params[3] = (GLint) v[3];
743 }
744 }
745 else {
746 params[0] = (GLint) get_vertex_array_attrib(ctx, index, pname,
747 "glGetVertexAttribiv");
748 }
749 }
750
751
752 /** GL 3.0 */
753 void GLAPIENTRY
754 _mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
755 {
756 GET_CURRENT_CONTEXT(ctx);
757
758 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
759 const GLint *v = (const GLint *)
760 get_current_attrib(ctx, index, "glGetVertexAttribIiv");
761 if (v != NULL) {
762 COPY_4V(params, v);
763 }
764 }
765 else {
766 params[0] = (GLint) get_vertex_array_attrib(ctx, index, pname,
767 "glGetVertexAttribIiv");
768 }
769 }
770
771
772 /** GL 3.0 */
773 void GLAPIENTRY
774 _mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
775 {
776 GET_CURRENT_CONTEXT(ctx);
777
778 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
779 const GLuint *v = (const GLuint *)
780 get_current_attrib(ctx, index, "glGetVertexAttribIuiv");
781 if (v != NULL) {
782 COPY_4V(params, v);
783 }
784 }
785 else {
786 params[0] = get_vertex_array_attrib(ctx, index, pname,
787 "glGetVertexAttribIuiv");
788 }
789 }
790
791
792 void GLAPIENTRY
793 _mesa_GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)
794 {
795 GET_CURRENT_CONTEXT(ctx);
796
797 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
798 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
799 return;
800 }
801
802 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
803 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
804 return;
805 }
806
807 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->_VertexAttrib));
808
809 *pointer = (GLvoid *) ctx->Array.ArrayObj->_VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr;
810 }
811
812
813 void GLAPIENTRY
814 _mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
815 GLsizei count, const GLvoid *ptr)
816 {
817 (void) count;
818 _mesa_VertexPointer(size, type, stride, ptr);
819 }
820
821
822 void GLAPIENTRY
823 _mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
824 const GLvoid *ptr)
825 {
826 (void) count;
827 _mesa_NormalPointer(type, stride, ptr);
828 }
829
830
831 void GLAPIENTRY
832 _mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
833 const GLvoid *ptr)
834 {
835 (void) count;
836 _mesa_ColorPointer(size, type, stride, ptr);
837 }
838
839
840 void GLAPIENTRY
841 _mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
842 const GLvoid *ptr)
843 {
844 (void) count;
845 _mesa_IndexPointer(type, stride, ptr);
846 }
847
848
849 void GLAPIENTRY
850 _mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
851 GLsizei count, const GLvoid *ptr)
852 {
853 (void) count;
854 _mesa_TexCoordPointer(size, type, stride, ptr);
855 }
856
857
858 void GLAPIENTRY
859 _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
860 {
861 (void) count;
862 _mesa_EdgeFlagPointer(stride, ptr);
863 }
864
865
866 void GLAPIENTRY
867 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
868 {
869 GET_CURRENT_CONTEXT(ctx);
870 GLboolean tflag, cflag, nflag; /* enable/disable flags */
871 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
872 GLenum ctype = 0; /* color type */
873 GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
874 const GLint toffset = 0; /* always zero */
875 GLint defstride; /* default stride */
876 GLint c, f;
877
878 FLUSH_VERTICES(ctx, 0);
879
880 f = sizeof(GLfloat);
881 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
882
883 if (stride < 0) {
884 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
885 return;
886 }
887
888 switch (format) {
889 case GL_V2F:
890 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
891 tcomps = 0; ccomps = 0; vcomps = 2;
892 voffset = 0;
893 defstride = 2*f;
894 break;
895 case GL_V3F:
896 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
897 tcomps = 0; ccomps = 0; vcomps = 3;
898 voffset = 0;
899 defstride = 3*f;
900 break;
901 case GL_C4UB_V2F:
902 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
903 tcomps = 0; ccomps = 4; vcomps = 2;
904 ctype = GL_UNSIGNED_BYTE;
905 coffset = 0;
906 voffset = c;
907 defstride = c + 2*f;
908 break;
909 case GL_C4UB_V3F:
910 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
911 tcomps = 0; ccomps = 4; vcomps = 3;
912 ctype = GL_UNSIGNED_BYTE;
913 coffset = 0;
914 voffset = c;
915 defstride = c + 3*f;
916 break;
917 case GL_C3F_V3F:
918 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
919 tcomps = 0; ccomps = 3; vcomps = 3;
920 ctype = GL_FLOAT;
921 coffset = 0;
922 voffset = 3*f;
923 defstride = 6*f;
924 break;
925 case GL_N3F_V3F:
926 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
927 tcomps = 0; ccomps = 0; vcomps = 3;
928 noffset = 0;
929 voffset = 3*f;
930 defstride = 6*f;
931 break;
932 case GL_C4F_N3F_V3F:
933 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
934 tcomps = 0; ccomps = 4; vcomps = 3;
935 ctype = GL_FLOAT;
936 coffset = 0;
937 noffset = 4*f;
938 voffset = 7*f;
939 defstride = 10*f;
940 break;
941 case GL_T2F_V3F:
942 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
943 tcomps = 2; ccomps = 0; vcomps = 3;
944 voffset = 2*f;
945 defstride = 5*f;
946 break;
947 case GL_T4F_V4F:
948 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
949 tcomps = 4; ccomps = 0; vcomps = 4;
950 voffset = 4*f;
951 defstride = 8*f;
952 break;
953 case GL_T2F_C4UB_V3F:
954 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
955 tcomps = 2; ccomps = 4; vcomps = 3;
956 ctype = GL_UNSIGNED_BYTE;
957 coffset = 2*f;
958 voffset = c+2*f;
959 defstride = c+5*f;
960 break;
961 case GL_T2F_C3F_V3F:
962 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
963 tcomps = 2; ccomps = 3; vcomps = 3;
964 ctype = GL_FLOAT;
965 coffset = 2*f;
966 voffset = 5*f;
967 defstride = 8*f;
968 break;
969 case GL_T2F_N3F_V3F:
970 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
971 tcomps = 2; ccomps = 0; vcomps = 3;
972 noffset = 2*f;
973 voffset = 5*f;
974 defstride = 8*f;
975 break;
976 case GL_T2F_C4F_N3F_V3F:
977 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
978 tcomps = 2; ccomps = 4; vcomps = 3;
979 ctype = GL_FLOAT;
980 coffset = 2*f;
981 noffset = 6*f;
982 voffset = 9*f;
983 defstride = 12*f;
984 break;
985 case GL_T4F_C4F_N3F_V4F:
986 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
987 tcomps = 4; ccomps = 4; vcomps = 4;
988 ctype = GL_FLOAT;
989 coffset = 4*f;
990 noffset = 8*f;
991 voffset = 11*f;
992 defstride = 15*f;
993 break;
994 default:
995 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
996 return;
997 }
998
999 if (stride==0) {
1000 stride = defstride;
1001 }
1002
1003 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
1004 _mesa_DisableClientState( GL_INDEX_ARRAY );
1005 /* XXX also disable secondary color and generic arrays? */
1006
1007 /* Texcoords */
1008 if (tflag) {
1009 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
1010 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
1011 (GLubyte *) pointer + toffset );
1012 }
1013 else {
1014 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
1015 }
1016
1017 /* Color */
1018 if (cflag) {
1019 _mesa_EnableClientState( GL_COLOR_ARRAY );
1020 _mesa_ColorPointer( ccomps, ctype, stride,
1021 (GLubyte *) pointer + coffset );
1022 }
1023 else {
1024 _mesa_DisableClientState( GL_COLOR_ARRAY );
1025 }
1026
1027
1028 /* Normals */
1029 if (nflag) {
1030 _mesa_EnableClientState( GL_NORMAL_ARRAY );
1031 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset );
1032 }
1033 else {
1034 _mesa_DisableClientState( GL_NORMAL_ARRAY );
1035 }
1036
1037 /* Vertices */
1038 _mesa_EnableClientState( GL_VERTEX_ARRAY );
1039 _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
1040 (GLubyte *) pointer + voffset );
1041 }
1042
1043
1044 void GLAPIENTRY
1045 _mesa_LockArraysEXT(GLint first, GLsizei count)
1046 {
1047 GET_CURRENT_CONTEXT(ctx);
1048
1049 FLUSH_VERTICES(ctx, 0);
1050
1051 if (MESA_VERBOSE & VERBOSE_API)
1052 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
1053
1054 if (first < 0) {
1055 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" );
1056 return;
1057 }
1058 if (count <= 0) {
1059 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" );
1060 return;
1061 }
1062 if (ctx->Array.LockCount != 0) {
1063 _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" );
1064 return;
1065 }
1066
1067 ctx->Array.LockFirst = first;
1068 ctx->Array.LockCount = count;
1069
1070 ctx->NewState |= _NEW_ARRAY;
1071 }
1072
1073
1074 void GLAPIENTRY
1075 _mesa_UnlockArraysEXT( void )
1076 {
1077 GET_CURRENT_CONTEXT(ctx);
1078
1079 FLUSH_VERTICES(ctx, 0);
1080
1081 if (MESA_VERBOSE & VERBOSE_API)
1082 _mesa_debug(ctx, "glUnlockArrays\n");
1083
1084 if (ctx->Array.LockCount == 0) {
1085 _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" );
1086 return;
1087 }
1088
1089 ctx->Array.LockFirst = 0;
1090 ctx->Array.LockCount = 0;
1091 ctx->NewState |= _NEW_ARRAY;
1092 }
1093
1094
1095 /* GL_EXT_multi_draw_arrays */
1096 void GLAPIENTRY
1097 _mesa_MultiDrawArrays( GLenum mode, const GLint *first,
1098 const GLsizei *count, GLsizei primcount )
1099 {
1100 GET_CURRENT_CONTEXT(ctx);
1101 GLint i;
1102
1103 FLUSH_VERTICES(ctx, 0);
1104
1105 for (i = 0; i < primcount; i++) {
1106 if (count[i] > 0) {
1107 CALL_DrawArrays(ctx->Exec, (mode, first[i], count[i]));
1108 }
1109 }
1110 }
1111
1112
1113 /* GL_IBM_multimode_draw_arrays */
1114 void GLAPIENTRY
1115 _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
1116 const GLsizei * count,
1117 GLsizei primcount, GLint modestride )
1118 {
1119 GET_CURRENT_CONTEXT(ctx);
1120 GLint i;
1121
1122 FLUSH_VERTICES(ctx, 0);
1123
1124 for ( i = 0 ; i < primcount ; i++ ) {
1125 if ( count[i] > 0 ) {
1126 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1127 CALL_DrawArrays(ctx->Exec, ( m, first[i], count[i] ));
1128 }
1129 }
1130 }
1131
1132
1133 /* GL_IBM_multimode_draw_arrays */
1134 void GLAPIENTRY
1135 _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
1136 GLenum type, const GLvoid * const * indices,
1137 GLsizei primcount, GLint modestride )
1138 {
1139 GET_CURRENT_CONTEXT(ctx);
1140 GLint i;
1141
1142 FLUSH_VERTICES(ctx, 0);
1143
1144 /* XXX not sure about ARB_vertex_buffer_object handling here */
1145
1146 for ( i = 0 ; i < primcount ; i++ ) {
1147 if ( count[i] > 0 ) {
1148 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1149 CALL_DrawElements(ctx->Exec, ( m, count[i], type, indices[i] ));
1150 }
1151 }
1152 }
1153
1154
1155 /**
1156 * GL_NV_primitive_restart and GL 3.1
1157 */
1158 void GLAPIENTRY
1159 _mesa_PrimitiveRestartIndex(GLuint index)
1160 {
1161 GET_CURRENT_CONTEXT(ctx);
1162
1163 if (!ctx->Extensions.NV_primitive_restart && ctx->Version < 31) {
1164 _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()");
1165 return;
1166 }
1167
1168 if (ctx->Array.RestartIndex != index) {
1169 FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
1170 ctx->Array.RestartIndex = index;
1171 }
1172 }
1173
1174
1175 /**
1176 * See GL_ARB_instanced_arrays.
1177 * Note that the instance divisor only applies to generic arrays, not
1178 * the legacy vertex arrays.
1179 */
1180 void GLAPIENTRY
1181 _mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
1182 {
1183 struct gl_client_array *array;
1184 GET_CURRENT_CONTEXT(ctx);
1185
1186 if (!ctx->Extensions.ARB_instanced_arrays) {
1187 _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
1188 return;
1189 }
1190
1191 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
1192 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribDivisor(index = %u)",
1193 index);
1194 return;
1195 }
1196
1197 ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->_VertexAttrib));
1198
1199 array = &ctx->Array.ArrayObj->_VertexAttrib[VERT_ATTRIB_GENERIC(index)];
1200 if (array->InstanceDivisor != divisor) {
1201 FLUSH_VERTICES(ctx, _NEW_ARRAY);
1202 array->InstanceDivisor = divisor;
1203 ctx->Array.ArrayObj->NewArrays |= VERT_BIT(VERT_ATTRIB_GENERIC(index));
1204 }
1205 }
1206
1207
1208 unsigned
1209 _mesa_primitive_restart_index(const struct gl_context *ctx, GLenum ib_type)
1210 {
1211 /* From the OpenGL 4.3 core specification, page 302:
1212 * "If both PRIMITIVE_RESTART and PRIMITIVE_RESTART_FIXED_INDEX are
1213 * enabled, the index value determined by PRIMITIVE_RESTART_FIXED_INDEX
1214 * is used."
1215 */
1216 if (ctx->Array.PrimitiveRestartFixedIndex) {
1217 switch (ib_type) {
1218 case GL_UNSIGNED_BYTE:
1219 return 0xff;
1220 case GL_UNSIGNED_SHORT:
1221 return 0xffff;
1222 case GL_UNSIGNED_INT:
1223 return 0xffffffff;
1224 default:
1225 assert(!"_mesa_primitive_restart_index: Invalid index buffer type.");
1226 }
1227 }
1228
1229 return ctx->Array.RestartIndex;
1230 }
1231
1232
1233 /**
1234 * GL_ARB_vertex_attrib_binding
1235 */
1236 void GLAPIENTRY
1237 _mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset,
1238 GLsizei stride)
1239 {
1240 }
1241
1242
1243 void GLAPIENTRY
1244 _mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type,
1245 GLboolean normalized, GLuint relativeOffset)
1246 {
1247 }
1248
1249
1250 void GLAPIENTRY
1251 _mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type,
1252 GLuint relativeOffset)
1253 {
1254 }
1255
1256
1257 void GLAPIENTRY
1258 _mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type,
1259 GLuint relativeOffset)
1260 {
1261 }
1262
1263
1264 void GLAPIENTRY
1265 _mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
1266 {
1267 }
1268
1269
1270 void GLAPIENTRY
1271 _mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
1272 {
1273 }
1274
1275
1276 /**
1277 * Copy one client vertex array to another.
1278 */
1279 void
1280 _mesa_copy_client_array(struct gl_context *ctx,
1281 struct gl_client_array *dst,
1282 struct gl_client_array *src)
1283 {
1284 dst->Size = src->Size;
1285 dst->Type = src->Type;
1286 dst->Format = src->Format;
1287 dst->Stride = src->Stride;
1288 dst->StrideB = src->StrideB;
1289 dst->Ptr = src->Ptr;
1290 dst->Enabled = src->Enabled;
1291 dst->Normalized = src->Normalized;
1292 dst->Integer = src->Integer;
1293 dst->InstanceDivisor = src->InstanceDivisor;
1294 dst->_ElementSize = src->_ElementSize;
1295 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
1296 dst->_MaxElement = src->_MaxElement;
1297 }
1298
1299
1300
1301 /**
1302 * Print vertex array's fields.
1303 */
1304 static void
1305 print_array(const char *name, GLint index, const struct gl_client_array *array)
1306 {
1307 if (index >= 0)
1308 printf(" %s[%d]: ", name, index);
1309 else
1310 printf(" %s: ", name);
1311 printf("Ptr=%p, Type=0x%x, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %lu), MaxElem=%u\n",
1312 array->Ptr, array->Type, array->Size,
1313 array->_ElementSize, array->StrideB,
1314 array->BufferObj->Name, (unsigned long) array->BufferObj->Size,
1315 array->_MaxElement);
1316 }
1317
1318
1319 /**
1320 * Print current vertex object/array info. For debug.
1321 */
1322 void
1323 _mesa_print_arrays(struct gl_context *ctx)
1324 {
1325 struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
1326 GLuint i;
1327
1328 _mesa_update_array_object_max_element(ctx, arrayObj);
1329
1330 printf("Array Object %u\n", arrayObj->Name);
1331 if (arrayObj->_VertexAttrib[VERT_ATTRIB_POS].Enabled)
1332 print_array("Vertex", -1, &arrayObj->_VertexAttrib[VERT_ATTRIB_POS]);
1333 if (arrayObj->_VertexAttrib[VERT_ATTRIB_NORMAL].Enabled)
1334 print_array("Normal", -1, &arrayObj->_VertexAttrib[VERT_ATTRIB_NORMAL]);
1335 if (arrayObj->_VertexAttrib[VERT_ATTRIB_COLOR0].Enabled)
1336 print_array("Color", -1, &arrayObj->_VertexAttrib[VERT_ATTRIB_COLOR0]);
1337 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
1338 if (arrayObj->_VertexAttrib[VERT_ATTRIB_TEX(i)].Enabled)
1339 print_array("TexCoord", i, &arrayObj->_VertexAttrib[VERT_ATTRIB_TEX(i)]);
1340 for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++)
1341 if (arrayObj->_VertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
1342 print_array("Attrib", i, &arrayObj->_VertexAttrib[VERT_ATTRIB_GENERIC(i)]);
1343 printf(" _MaxElement = %u\n", arrayObj->_MaxElement);
1344 }
1345
1346
1347 /**
1348 * Initialize vertex array state for given context.
1349 */
1350 void
1351 _mesa_init_varray(struct gl_context *ctx)
1352 {
1353 ctx->Array.DefaultArrayObj = ctx->Driver.NewArrayObject(ctx, 0);
1354 _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj,
1355 ctx->Array.DefaultArrayObj);
1356 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
1357
1358 ctx->Array.Objects = _mesa_NewHashTable();
1359 }
1360
1361
1362 /**
1363 * Callback for deleting an array object. Called by _mesa_HashDeleteAll().
1364 */
1365 static void
1366 delete_arrayobj_cb(GLuint id, void *data, void *userData)
1367 {
1368 struct gl_array_object *arrayObj = (struct gl_array_object *) data;
1369 struct gl_context *ctx = (struct gl_context *) userData;
1370 _mesa_delete_array_object(ctx, arrayObj);
1371 }
1372
1373
1374 /**
1375 * Free vertex array state for given context.
1376 */
1377 void
1378 _mesa_free_varray_data(struct gl_context *ctx)
1379 {
1380 _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx);
1381 _mesa_DeleteHashTable(ctx->Array.Objects);
1382 }