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