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