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