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