vbo: Test for VBO_SAVE_PRIM_WEAK in _mesa_prim::mode is false.
[mesa.git] / src / mesa / vbo / vbo_exec_array.c
1 /**************************************************************************
2 *
3 * Copyright 2003 VMware, Inc.
4 * Copyright 2009 VMware, Inc.
5 * 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
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 **************************************************************************/
28
29 #include <stdio.h>
30 #include "main/arrayobj.h"
31 #include "main/glheader.h"
32 #include "main/context.h"
33 #include "main/state.h"
34 #include "main/draw_validate.h"
35 #include "main/dispatch.h"
36 #include "main/varray.h"
37 #include "main/bufferobj.h"
38 #include "main/enums.h"
39 #include "main/macros.h"
40 #include "main/transformfeedback.h"
41
42 typedef struct {
43 GLuint count;
44 GLuint primCount;
45 GLuint first;
46 GLuint baseInstance;
47 } DrawArraysIndirectCommand;
48
49 typedef struct {
50 GLuint count;
51 GLuint primCount;
52 GLuint firstIndex;
53 GLint baseVertex;
54 GLuint baseInstance;
55 } DrawElementsIndirectCommand;
56
57
58 /**
59 * Check that element 'j' of the array has reasonable data.
60 * Map VBO if needed.
61 * For debugging purposes; not normally used.
62 */
63 static void
64 check_array_data(struct gl_context *ctx, struct gl_vertex_array_object *vao,
65 GLuint attrib, GLuint j)
66 {
67 const struct gl_array_attributes *array = &vao->VertexAttrib[attrib];
68 if (array->Enabled) {
69 const struct gl_vertex_buffer_binding *binding =
70 &vao->BufferBinding[array->BufferBindingIndex];
71 struct gl_buffer_object *bo = binding->BufferObj;
72 const void *data = array->Ptr;
73 if (_mesa_is_bufferobj(bo)) {
74 if (!bo->Mappings[MAP_INTERNAL].Pointer) {
75 /* need to map now */
76 bo->Mappings[MAP_INTERNAL].Pointer =
77 ctx->Driver.MapBufferRange(ctx, 0, bo->Size,
78 GL_MAP_READ_BIT, bo, MAP_INTERNAL);
79 }
80 data = ADD_POINTERS(_mesa_vertex_attrib_address(array, binding),
81 bo->Mappings[MAP_INTERNAL].Pointer);
82 }
83 switch (array->Type) {
84 case GL_FLOAT:
85 {
86 GLfloat *f = (GLfloat *) ((GLubyte *) data + binding->Stride * j);
87 GLint k;
88 for (k = 0; k < array->Size; k++) {
89 if (IS_INF_OR_NAN(f[k]) || f[k] >= 1.0e20F || f[k] <= -1.0e10F) {
90 printf("Bad array data:\n");
91 printf(" Element[%u].%u = %f\n", j, k, f[k]);
92 printf(" Array %u at %p\n", attrib, (void *) array);
93 printf(" Type 0x%x, Size %d, Stride %d\n",
94 array->Type, array->Size, binding->Stride);
95 printf(" Address/offset %p in Buffer Object %u\n",
96 array->Ptr, bo->Name);
97 f[k] = 1.0F; /* XXX replace the bad value! */
98 }
99 /*assert(!IS_INF_OR_NAN(f[k])); */
100 }
101 }
102 break;
103 default:
104 ;
105 }
106 }
107 }
108
109
110 /**
111 * Unmap the buffer object referenced by given array, if mapped.
112 */
113 static void
114 unmap_array_buffer(struct gl_context *ctx, struct gl_vertex_array_object *vao,
115 GLuint attrib)
116 {
117 const struct gl_array_attributes *array = &vao->VertexAttrib[attrib];
118 if (array->Enabled) {
119 const struct gl_vertex_buffer_binding *binding =
120 &vao->BufferBinding[array->BufferBindingIndex];
121 struct gl_buffer_object *bo = binding->BufferObj;
122 if (_mesa_is_bufferobj(bo) && _mesa_bufferobj_mapped(bo, MAP_INTERNAL)) {
123 ctx->Driver.UnmapBuffer(ctx, bo, MAP_INTERNAL);
124 }
125 }
126 }
127
128
129 static inline int
130 sizeof_ib_type(GLenum type)
131 {
132 switch (type) {
133 case GL_UNSIGNED_INT:
134 return sizeof(GLuint);
135 case GL_UNSIGNED_SHORT:
136 return sizeof(GLushort);
137 case GL_UNSIGNED_BYTE:
138 return sizeof(GLubyte);
139 default:
140 assert(!"unsupported index data type");
141 /* In case assert is turned off */
142 return 0;
143 }
144 }
145
146 /**
147 * Examine the array's data for NaNs, etc.
148 * For debug purposes; not normally used.
149 */
150 static void
151 check_draw_elements_data(struct gl_context *ctx, GLsizei count,
152 GLenum elemType, const void *elements,
153 GLint basevertex)
154 {
155 struct gl_vertex_array_object *vao = ctx->Array.VAO;
156 const void *elemMap;
157 GLint i;
158 GLuint k;
159
160 if (_mesa_is_bufferobj(vao->IndexBufferObj)) {
161 elemMap = ctx->Driver.MapBufferRange(ctx, 0,
162 vao->IndexBufferObj->Size,
163 GL_MAP_READ_BIT,
164 vao->IndexBufferObj, MAP_INTERNAL);
165 elements = ADD_POINTERS(elements, elemMap);
166 }
167
168 for (i = 0; i < count; i++) {
169 GLuint j;
170
171 /* j = element[i] */
172 switch (elemType) {
173 case GL_UNSIGNED_BYTE:
174 j = ((const GLubyte *) elements)[i];
175 break;
176 case GL_UNSIGNED_SHORT:
177 j = ((const GLushort *) elements)[i];
178 break;
179 case GL_UNSIGNED_INT:
180 j = ((const GLuint *) elements)[i];
181 break;
182 default:
183 unreachable("Unexpected index buffer type");
184 }
185
186 /* check element j of each enabled array */
187 for (k = 0; k < VERT_ATTRIB_MAX; k++) {
188 check_array_data(ctx, vao, k, j);
189 }
190 }
191
192 if (_mesa_is_bufferobj(vao->IndexBufferObj)) {
193 ctx->Driver.UnmapBuffer(ctx, vao->IndexBufferObj, MAP_INTERNAL);
194 }
195
196 for (k = 0; k < VERT_ATTRIB_MAX; k++) {
197 unmap_array_buffer(ctx, vao, k);
198 }
199 }
200
201
202 /**
203 * Check array data, looking for NaNs, etc.
204 */
205 static void
206 check_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count)
207 {
208 /* TO DO */
209 }
210
211
212 /**
213 * Check if we should skip the draw call even after validation was successful.
214 */
215 static bool
216 skip_validated_draw(struct gl_context *ctx)
217 {
218 switch (ctx->API) {
219 case API_OPENGLES2:
220 /* For ES2, we can draw if we have a vertex program/shader). */
221 return ctx->VertexProgram._Current == NULL;
222
223 case API_OPENGLES:
224 /* For OpenGL ES, only draw if we have vertex positions
225 */
226 if (!ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled)
227 return true;
228 break;
229
230 case API_OPENGL_CORE:
231 /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec
232 * says:
233 *
234 * "If there is no active program for the vertex or fragment shader
235 * stages, the results of vertex and/or fragment processing will be
236 * undefined. However, this is not an error."
237 *
238 * The fragment shader is not tested here because other state (e.g.,
239 * GL_RASTERIZER_DISCARD) affects whether or not we actually care.
240 */
241 return ctx->VertexProgram._Current == NULL;
242
243 case API_OPENGL_COMPAT:
244 if (ctx->VertexProgram._Current != NULL) {
245 /* Draw regardless of whether or not we have any vertex arrays.
246 * (Ex: could draw a point using a constant vertex pos)
247 */
248 return false;
249 } else {
250 /* Draw if we have vertex positions (GL_VERTEX_ARRAY or generic
251 * array [0]).
252 */
253 return (!ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled &&
254 !ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled);
255 }
256 break;
257
258 default:
259 unreachable("Invalid API value in check_valid_to_render()");
260 }
261
262 return false;
263 }
264
265
266 /**
267 * Print info/data for glDrawArrays(), for debugging.
268 */
269 static void
270 print_draw_arrays(struct gl_context *ctx,
271 GLenum mode, GLint start, GLsizei count)
272 {
273 const struct gl_vertex_array_object *vao = ctx->Array.VAO;
274
275 printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n",
276 mode, start, count);
277
278 unsigned i;
279 for (i = 0; i < VERT_ATTRIB_MAX; ++i) {
280 const struct gl_array_attributes *array = &vao->VertexAttrib[i];
281 if (!array->Enabled)
282 continue;
283
284 const struct gl_vertex_buffer_binding *binding =
285 &vao->BufferBinding[array->BufferBindingIndex];
286 struct gl_buffer_object *bufObj = binding->BufferObj;
287
288 printf("attr %s: size %d stride %d enabled %d "
289 "ptr %p Bufobj %u\n",
290 gl_vert_attrib_name((gl_vert_attrib) i),
291 array->Size, binding->Stride, array->Enabled,
292 array->Ptr, bufObj->Name);
293
294 if (_mesa_is_bufferobj(bufObj)) {
295 GLubyte *p = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size,
296 GL_MAP_READ_BIT, bufObj,
297 MAP_INTERNAL);
298 int offset = (int) (GLintptr)
299 _mesa_vertex_attrib_address(array, binding);
300
301 unsigned multiplier;
302 switch (array->Type) {
303 case GL_DOUBLE:
304 case GL_INT64_ARB:
305 case GL_UNSIGNED_INT64_ARB:
306 multiplier = 2;
307 break;
308 default:
309 multiplier = 1;
310 }
311
312 float *f = (float *) (p + offset);
313 int *k = (int *) f;
314 int i = 0;
315 int n = (count - 1) * (binding->Stride / (4 * multiplier))
316 + array->Size;
317 if (n > 32)
318 n = 32;
319 printf(" Data at offset %d:\n", offset);
320 do {
321 if (multiplier == 2)
322 printf(" double[%d] = 0x%016llx %lf\n", i,
323 ((unsigned long long *) k)[i], ((double *) f)[i]);
324 else
325 printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]);
326 i++;
327 } while (i < n);
328 ctx->Driver.UnmapBuffer(ctx, bufObj, MAP_INTERNAL);
329 }
330 }
331 }
332
333
334 /**
335 * Return a filter mask for the net enabled vao arrays.
336 * This is to mask out arrays that would otherwise supersed required current
337 * values for the fixed function shaders for example.
338 */
339 static GLbitfield
340 enabled_filter(const struct gl_context *ctx)
341 {
342 switch (ctx->VertexProgram._VPMode) {
343 case VP_MODE_FF:
344 /* When no vertex program is active (or the vertex program is generated
345 * from fixed-function state). We put the material values into the
346 * generic slots. Since the vao has no material arrays, mute these
347 * slots from the enabled arrays so that the current material values
348 * are pulled instead of the vao arrays.
349 */
350 return VERT_BIT_FF_ALL;
351
352 case VP_MODE_SHADER:
353 /* There are no shaders in OpenGL ES 1.x, so this code path should be
354 * impossible to reach. The meta code is careful to not use shaders in
355 * ES1.
356 */
357 assert(ctx->API != API_OPENGLES);
358
359 /* Other parts of the code assume that inputs[VERT_ATTRIB_POS] through
360 * inputs[VERT_ATTRIB_FF_MAX] will be non-NULL. However, in OpenGL
361 * ES 2.0+ or OpenGL core profile, none of these arrays should ever
362 * be enabled.
363 */
364 if (ctx->API != API_OPENGL_COMPAT)
365 return VERT_BIT_GENERIC_ALL;
366
367 return VERT_BIT_ALL;
368
369 default:
370 assert(0);
371 return 0;
372 }
373 }
374
375
376 /**
377 * Helper function called by the other DrawArrays() functions below.
378 * This is where we handle primitive restart for drawing non-indexed
379 * arrays. If primitive restart is enabled, it typically means
380 * splitting one DrawArrays() into two.
381 */
382 static void
383 vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
384 GLsizei count, GLuint numInstances, GLuint baseInstance,
385 GLuint drawID)
386 {
387 struct _mesa_prim prim;
388
389 if (skip_validated_draw(ctx))
390 return;
391
392 /* OpenGL 4.5 says that primitive restart is ignored with non-indexed
393 * draws.
394 */
395 memset(&prim, 0, sizeof(prim));
396 prim.begin = 1;
397 prim.end = 1;
398 prim.mode = mode;
399 prim.num_instances = numInstances;
400 prim.base_instance = baseInstance;
401 prim.draw_id = drawID;
402 prim.is_indirect = 0;
403 prim.start = start;
404 prim.count = count;
405
406 ctx->Driver.Draw(ctx, &prim, 1, NULL,
407 GL_TRUE, start, start + count - 1, NULL, 0, NULL);
408
409 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
410 _mesa_flush(ctx);
411 }
412 }
413
414
415 /**
416 * Execute a glRectf() function.
417 */
418 static void GLAPIENTRY
419 vbo_exec_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
420 {
421 GET_CURRENT_CONTEXT(ctx);
422 ASSERT_OUTSIDE_BEGIN_END(ctx);
423
424 CALL_Begin(GET_DISPATCH(), (GL_QUADS));
425 CALL_Vertex2f(GET_DISPATCH(), (x1, y1));
426 CALL_Vertex2f(GET_DISPATCH(), (x2, y1));
427 CALL_Vertex2f(GET_DISPATCH(), (x2, y2));
428 CALL_Vertex2f(GET_DISPATCH(), (x1, y2));
429 CALL_End(GET_DISPATCH(), ());
430 }
431
432
433 static void GLAPIENTRY
434 vbo_exec_EvalMesh1(GLenum mode, GLint i1, GLint i2)
435 {
436 GET_CURRENT_CONTEXT(ctx);
437 GLint i;
438 GLfloat u, du;
439 GLenum prim;
440
441 switch (mode) {
442 case GL_POINT:
443 prim = GL_POINTS;
444 break;
445 case GL_LINE:
446 prim = GL_LINE_STRIP;
447 break;
448 default:
449 _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)");
450 return;
451 }
452
453 /* No effect if vertex maps disabled.
454 */
455 if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3)
456 return;
457
458 du = ctx->Eval.MapGrid1du;
459 u = ctx->Eval.MapGrid1u1 + i1 * du;
460
461 CALL_Begin(GET_DISPATCH(), (prim));
462 for (i = i1; i <= i2; i++, u += du) {
463 CALL_EvalCoord1f(GET_DISPATCH(), (u));
464 }
465 CALL_End(GET_DISPATCH(), ());
466 }
467
468
469 static void GLAPIENTRY
470 vbo_exec_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
471 {
472 GET_CURRENT_CONTEXT(ctx);
473 GLfloat u, du, v, dv, v1, u1;
474 GLint i, j;
475
476 switch (mode) {
477 case GL_POINT:
478 case GL_LINE:
479 case GL_FILL:
480 break;
481 default:
482 _mesa_error(ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)");
483 return;
484 }
485
486 /* No effect if vertex maps disabled.
487 */
488 if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3)
489 return;
490
491 du = ctx->Eval.MapGrid2du;
492 dv = ctx->Eval.MapGrid2dv;
493 v1 = ctx->Eval.MapGrid2v1 + j1 * dv;
494 u1 = ctx->Eval.MapGrid2u1 + i1 * du;
495
496 switch (mode) {
497 case GL_POINT:
498 CALL_Begin(GET_DISPATCH(), (GL_POINTS));
499 for (v = v1, j = j1; j <= j2; j++, v += dv) {
500 for (u = u1, i = i1; i <= i2; i++, u += du) {
501 CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
502 }
503 }
504 CALL_End(GET_DISPATCH(), ());
505 break;
506 case GL_LINE:
507 for (v = v1, j = j1; j <= j2; j++, v += dv) {
508 CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP));
509 for (u = u1, i = i1; i <= i2; i++, u += du) {
510 CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
511 }
512 CALL_End(GET_DISPATCH(), ());
513 }
514 for (u = u1, i = i1; i <= i2; i++, u += du) {
515 CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP));
516 for (v = v1, j = j1; j <= j2; j++, v += dv) {
517 CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
518 }
519 CALL_End(GET_DISPATCH(), ());
520 }
521 break;
522 case GL_FILL:
523 for (v = v1, j = j1; j < j2; j++, v += dv) {
524 CALL_Begin(GET_DISPATCH(), (GL_TRIANGLE_STRIP));
525 for (u = u1, i = i1; i <= i2; i++, u += du) {
526 CALL_EvalCoord2f(GET_DISPATCH(), (u, v));
527 CALL_EvalCoord2f(GET_DISPATCH(), (u, v + dv));
528 }
529 CALL_End(GET_DISPATCH(), ());
530 }
531 break;
532 }
533 }
534
535
536 /**
537 * Called from glDrawArrays when in immediate mode (not display list mode).
538 */
539 static void GLAPIENTRY
540 vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
541 {
542 GET_CURRENT_CONTEXT(ctx);
543
544 if (MESA_VERBOSE & VERBOSE_DRAW)
545 _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n",
546 _mesa_enum_to_string(mode), start, count);
547
548 FLUSH_FOR_DRAW(ctx);
549
550 if (_mesa_is_no_error_enabled(ctx)) {
551 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
552
553 if (ctx->NewState)
554 _mesa_update_state(ctx);
555 } else {
556 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
557
558 if (!_mesa_validate_DrawArrays(ctx, mode, count))
559 return;
560 }
561
562 if (0)
563 check_draw_arrays_data(ctx, start, count);
564
565 vbo_draw_arrays(ctx, mode, start, count, 1, 0, 0);
566
567 if (0)
568 print_draw_arrays(ctx, mode, start, count);
569 }
570
571
572 /**
573 * Called from glDrawArraysInstanced when in immediate mode (not
574 * display list mode).
575 */
576 static void GLAPIENTRY
577 vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
578 GLsizei numInstances)
579 {
580 GET_CURRENT_CONTEXT(ctx);
581
582 if (MESA_VERBOSE & VERBOSE_DRAW)
583 _mesa_debug(ctx, "glDrawArraysInstanced(%s, %d, %d, %d)\n",
584 _mesa_enum_to_string(mode), start, count, numInstances);
585
586 FLUSH_FOR_DRAW(ctx);
587
588 if (_mesa_is_no_error_enabled(ctx)) {
589 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
590
591 if (ctx->NewState)
592 _mesa_update_state(ctx);
593 } else {
594 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
595
596 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, start, count,
597 numInstances))
598 return;
599 }
600
601 if (0)
602 check_draw_arrays_data(ctx, start, count);
603
604 vbo_draw_arrays(ctx, mode, start, count, numInstances, 0, 0);
605
606 if (0)
607 print_draw_arrays(ctx, mode, start, count);
608 }
609
610
611 /**
612 * Called from glDrawArraysInstancedBaseInstance when in immediate mode.
613 */
614 static void GLAPIENTRY
615 vbo_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first,
616 GLsizei count, GLsizei numInstances,
617 GLuint baseInstance)
618 {
619 GET_CURRENT_CONTEXT(ctx);
620
621 if (MESA_VERBOSE & VERBOSE_DRAW)
622 _mesa_debug(ctx,
623 "glDrawArraysInstancedBaseInstance(%s, %d, %d, %d, %d)\n",
624 _mesa_enum_to_string(mode), first, count,
625 numInstances, baseInstance);
626
627 FLUSH_FOR_DRAW(ctx);
628
629 if (_mesa_is_no_error_enabled(ctx)) {
630 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
631
632 if (ctx->NewState)
633 _mesa_update_state(ctx);
634 } else {
635 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
636
637 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, first, count,
638 numInstances))
639 return;
640 }
641
642 if (0)
643 check_draw_arrays_data(ctx, first, count);
644
645 vbo_draw_arrays(ctx, mode, first, count, numInstances, baseInstance, 0);
646
647 if (0)
648 print_draw_arrays(ctx, mode, first, count);
649 }
650
651
652 /**
653 * Called from glMultiDrawArrays when in immediate mode.
654 */
655 static void GLAPIENTRY
656 vbo_exec_MultiDrawArrays(GLenum mode, const GLint *first,
657 const GLsizei *count, GLsizei primcount)
658 {
659 GET_CURRENT_CONTEXT(ctx);
660 GLint i;
661
662 if (MESA_VERBOSE & VERBOSE_DRAW)
663 _mesa_debug(ctx,
664 "glMultiDrawArrays(%s, %p, %p, %d)\n",
665 _mesa_enum_to_string(mode), first, count, primcount);
666
667 FLUSH_FOR_DRAW(ctx);
668
669 if (_mesa_is_no_error_enabled(ctx)) {
670 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
671
672 if (ctx->NewState)
673 _mesa_update_state(ctx);
674 } else {
675 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
676
677 if (!_mesa_validate_MultiDrawArrays(ctx, mode, count, primcount))
678 return;
679 }
680
681 for (i = 0; i < primcount; i++) {
682 if (count[i] > 0) {
683 if (0)
684 check_draw_arrays_data(ctx, first[i], count[i]);
685
686 /* The GL_ARB_shader_draw_parameters spec adds the following after the
687 * pseudo-code describing glMultiDrawArrays:
688 *
689 * "The index of the draw (<i> in the above pseudo-code) may be
690 * read by a vertex shader as <gl_DrawIDARB>, as described in
691 * Section 11.1.3.9."
692 */
693 vbo_draw_arrays(ctx, mode, first[i], count[i], 1, 0, i);
694
695 if (0)
696 print_draw_arrays(ctx, mode, first[i], count[i]);
697 }
698 }
699 }
700
701
702
703 /**
704 * Map GL_ELEMENT_ARRAY_BUFFER and print contents.
705 * For debugging.
706 */
707 #if 0
708 static void
709 dump_element_buffer(struct gl_context *ctx, GLenum type)
710 {
711 const GLvoid *map =
712 ctx->Driver.MapBufferRange(ctx, 0,
713 ctx->Array.VAO->IndexBufferObj->Size,
714 GL_MAP_READ_BIT,
715 ctx->Array.VAO->IndexBufferObj,
716 MAP_INTERNAL);
717 switch (type) {
718 case GL_UNSIGNED_BYTE:
719 {
720 const GLubyte *us = (const GLubyte *) map;
721 GLint i;
722 for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size; i++) {
723 printf("%02x ", us[i]);
724 if (i % 32 == 31)
725 printf("\n");
726 }
727 printf("\n");
728 }
729 break;
730 case GL_UNSIGNED_SHORT:
731 {
732 const GLushort *us = (const GLushort *) map;
733 GLint i;
734 for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 2; i++) {
735 printf("%04x ", us[i]);
736 if (i % 16 == 15)
737 printf("\n");
738 }
739 printf("\n");
740 }
741 break;
742 case GL_UNSIGNED_INT:
743 {
744 const GLuint *us = (const GLuint *) map;
745 GLint i;
746 for (i = 0; i < ctx->Array.VAO->IndexBufferObj->Size / 4; i++) {
747 printf("%08x ", us[i]);
748 if (i % 8 == 7)
749 printf("\n");
750 }
751 printf("\n");
752 }
753 break;
754 default:
755 ;
756 }
757
758 ctx->Driver.UnmapBuffer(ctx, ctx->Array.VAO->IndexBufferObj, MAP_INTERNAL);
759 }
760 #endif
761
762
763 static bool
764 skip_draw_elements(struct gl_context *ctx, GLsizei count,
765 const GLvoid *indices)
766 {
767 if (count == 0)
768 return true;
769
770 /* Not using a VBO for indices, so avoid NULL pointer derefs later.
771 */
772 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj) && indices == NULL)
773 return true;
774
775 if (skip_validated_draw(ctx))
776 return true;
777
778 return false;
779 }
780
781
782 /**
783 * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements.
784 * Do the rendering for a glDrawElements or glDrawRangeElements call after
785 * we've validated buffer bounds, etc.
786 */
787 static void
788 vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
789 GLboolean index_bounds_valid,
790 GLuint start, GLuint end,
791 GLsizei count, GLenum type,
792 const GLvoid * indices,
793 GLint basevertex, GLuint numInstances,
794 GLuint baseInstance)
795 {
796 struct _mesa_index_buffer ib;
797 struct _mesa_prim prim;
798
799 if (!index_bounds_valid) {
800 assert(start == 0u);
801 assert(end == ~0u);
802 }
803
804 if (skip_draw_elements(ctx, count, indices))
805 return;
806
807 ib.count = count;
808 ib.index_size = sizeof_ib_type(type);
809 ib.obj = ctx->Array.VAO->IndexBufferObj;
810 ib.ptr = indices;
811
812 prim.begin = 1;
813 prim.end = 1;
814 prim.pad = 0;
815 prim.mode = mode;
816 prim.start = 0;
817 prim.count = count;
818 prim.indexed = 1;
819 prim.is_indirect = 0;
820 prim.basevertex = basevertex;
821 prim.num_instances = numInstances;
822 prim.base_instance = baseInstance;
823 prim.draw_id = 0;
824
825 /* Need to give special consideration to rendering a range of
826 * indices starting somewhere above zero. Typically the
827 * application is issuing multiple DrawRangeElements() to draw
828 * successive primitives layed out linearly in the vertex arrays.
829 * Unless the vertex arrays are all in a VBO (or locked as with
830 * CVA), the OpenGL semantics imply that we need to re-read or
831 * re-upload the vertex data on each draw call.
832 *
833 * In the case of hardware tnl, we want to avoid starting the
834 * upload at zero, as it will mean every draw call uploads an
835 * increasing amount of not-used vertex data. Worse - in the
836 * software tnl module, all those vertices might be transformed and
837 * lit but never rendered.
838 *
839 * If we just upload or transform the vertices in start..end,
840 * however, the indices will be incorrect.
841 *
842 * At this level, we don't know exactly what the requirements of
843 * the backend are going to be, though it will likely boil down to
844 * either:
845 *
846 * 1) Do nothing, everything is in a VBO and is processed once
847 * only.
848 *
849 * 2) Adjust the indices and vertex arrays so that start becomes
850 * zero.
851 *
852 * Rather than doing anything here, I'll provide a helper function
853 * for the latter case elsewhere.
854 */
855
856 ctx->Driver.Draw(ctx, &prim, 1, &ib,
857 index_bounds_valid, start, end, NULL, 0, NULL);
858
859 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
860 _mesa_flush(ctx);
861 }
862 }
863
864
865 /**
866 * Called by glDrawRangeElementsBaseVertex() in immediate mode.
867 */
868 static void GLAPIENTRY
869 vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
870 GLsizei count, GLenum type,
871 const GLvoid * indices, GLint basevertex)
872 {
873 static GLuint warnCount = 0;
874 GLboolean index_bounds_valid = GL_TRUE;
875
876 /* This is only useful to catch invalid values in the "end" parameter
877 * like ~0.
878 */
879 GLuint max_element = 2 * 1000 * 1000 * 1000; /* just a big number */
880
881 GET_CURRENT_CONTEXT(ctx);
882
883 if (MESA_VERBOSE & VERBOSE_DRAW)
884 _mesa_debug(ctx,
885 "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n",
886 _mesa_enum_to_string(mode), start, end, count,
887 _mesa_enum_to_string(type), indices, basevertex);
888
889 FLUSH_FOR_DRAW(ctx);
890
891 if (_mesa_is_no_error_enabled(ctx)) {
892 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
893
894 if (ctx->NewState)
895 _mesa_update_state(ctx);
896 } else {
897 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
898
899 if (!_mesa_validate_DrawRangeElements(ctx, mode, start, end, count,
900 type, indices))
901 return;
902 }
903
904 if ((int) end + basevertex < 0 || start + basevertex >= max_element) {
905 /* The application requested we draw using a range of indices that's
906 * outside the bounds of the current VBO. This is invalid and appears
907 * to give undefined results. The safest thing to do is to simply
908 * ignore the range, in case the application botched their range tracking
909 * but did provide valid indices. Also issue a warning indicating that
910 * the application is broken.
911 */
912 if (warnCount++ < 10) {
913 _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, "
914 "basevertex %d, count %d, type 0x%x, indices=%p):\n"
915 "\trange is outside VBO bounds (max=%u); ignoring.\n"
916 "\tThis should be fixed in the application.",
917 start, end, basevertex, count, type, indices,
918 max_element - 1);
919 }
920 index_bounds_valid = GL_FALSE;
921 }
922
923 /* NOTE: It's important that 'end' is a reasonable value.
924 * in _tnl_draw_prims(), we use end to determine how many vertices
925 * to transform. If it's too large, we can unnecessarily split prims
926 * or we can read/write out of memory in several different places!
927 */
928
929 /* Catch/fix some potential user errors */
930 if (type == GL_UNSIGNED_BYTE) {
931 start = MIN2(start, 0xff);
932 end = MIN2(end, 0xff);
933 }
934 else if (type == GL_UNSIGNED_SHORT) {
935 start = MIN2(start, 0xffff);
936 end = MIN2(end, 0xffff);
937 }
938
939 if (0) {
940 printf("glDraw[Range]Elements{,BaseVertex}"
941 "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, "
942 "base %d\n",
943 start, end, type, count,
944 ctx->Array.VAO->IndexBufferObj->Name, basevertex);
945 }
946
947 if ((int) start + basevertex < 0 || end + basevertex >= max_element)
948 index_bounds_valid = GL_FALSE;
949
950 #if 0
951 check_draw_elements_data(ctx, count, type, indices, basevertex);
952 #else
953 (void) check_draw_elements_data;
954 #endif
955
956 if (!index_bounds_valid) {
957 start = 0;
958 end = ~0;
959 }
960
961 vbo_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end,
962 count, type, indices, basevertex, 1, 0);
963 }
964
965
966 /**
967 * Called by glDrawRangeElements() in immediate mode.
968 */
969 static void GLAPIENTRY
970 vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
971 GLsizei count, GLenum type, const GLvoid * indices)
972 {
973 if (MESA_VERBOSE & VERBOSE_DRAW) {
974 GET_CURRENT_CONTEXT(ctx);
975 _mesa_debug(ctx,
976 "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n",
977 _mesa_enum_to_string(mode), start, end, count,
978 _mesa_enum_to_string(type), indices);
979 }
980
981 vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
982 indices, 0);
983 }
984
985
986 /**
987 * Called by glDrawElements() in immediate mode.
988 */
989 static void GLAPIENTRY
990 vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
991 const GLvoid * indices)
992 {
993 GET_CURRENT_CONTEXT(ctx);
994
995 if (MESA_VERBOSE & VERBOSE_DRAW)
996 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n",
997 _mesa_enum_to_string(mode), count,
998 _mesa_enum_to_string(type), indices);
999
1000 FLUSH_FOR_DRAW(ctx);
1001
1002 if (_mesa_is_no_error_enabled(ctx)) {
1003 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1004
1005 if (ctx->NewState)
1006 _mesa_update_state(ctx);
1007 } else {
1008 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1009
1010 if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices))
1011 return;
1012 }
1013
1014 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
1015 count, type, indices, 0, 1, 0);
1016 }
1017
1018
1019 /**
1020 * Called by glDrawElementsBaseVertex() in immediate mode.
1021 */
1022 static void GLAPIENTRY
1023 vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
1024 const GLvoid * indices, GLint basevertex)
1025 {
1026 GET_CURRENT_CONTEXT(ctx);
1027
1028 if (MESA_VERBOSE & VERBOSE_DRAW)
1029 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n",
1030 _mesa_enum_to_string(mode), count,
1031 _mesa_enum_to_string(type), indices);
1032
1033 FLUSH_FOR_DRAW(ctx);
1034
1035 if (_mesa_is_no_error_enabled(ctx)) {
1036 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1037
1038 if (ctx->NewState)
1039 _mesa_update_state(ctx);
1040 } else {
1041 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1042
1043 if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices))
1044 return;
1045 }
1046
1047 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
1048 count, type, indices, basevertex, 1, 0);
1049 }
1050
1051
1052 /**
1053 * Called by glDrawElementsInstanced() in immediate mode.
1054 */
1055 static void GLAPIENTRY
1056 vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
1057 const GLvoid * indices, GLsizei numInstances)
1058 {
1059 GET_CURRENT_CONTEXT(ctx);
1060
1061 if (MESA_VERBOSE & VERBOSE_DRAW)
1062 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n",
1063 _mesa_enum_to_string(mode), count,
1064 _mesa_enum_to_string(type), indices);
1065
1066 FLUSH_FOR_DRAW(ctx);
1067
1068 if (_mesa_is_no_error_enabled(ctx)) {
1069 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1070
1071 if (ctx->NewState)
1072 _mesa_update_state(ctx);
1073 } else {
1074 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1075
1076 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
1077 indices, numInstances))
1078 return;
1079 }
1080
1081 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
1082 count, type, indices, 0, numInstances, 0);
1083 }
1084
1085
1086 /**
1087 * Called by glDrawElementsInstancedBaseVertex() in immediate mode.
1088 */
1089 static void GLAPIENTRY
1090 vbo_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count,
1091 GLenum type, const GLvoid * indices,
1092 GLsizei numInstances,
1093 GLint basevertex)
1094 {
1095 GET_CURRENT_CONTEXT(ctx);
1096
1097 if (MESA_VERBOSE & VERBOSE_DRAW)
1098 _mesa_debug(ctx,
1099 "glDrawElementsInstancedBaseVertex"
1100 "(%s, %d, %s, %p, %d; %d)\n",
1101 _mesa_enum_to_string(mode), count,
1102 _mesa_enum_to_string(type), indices,
1103 numInstances, basevertex);
1104
1105 FLUSH_FOR_DRAW(ctx);
1106
1107 if (_mesa_is_no_error_enabled(ctx)) {
1108 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1109
1110 if (ctx->NewState)
1111 _mesa_update_state(ctx);
1112 } else {
1113 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1114
1115 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
1116 indices, numInstances))
1117 return;
1118 }
1119
1120 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
1121 count, type, indices,
1122 basevertex, numInstances, 0);
1123 }
1124
1125
1126 /**
1127 * Called by glDrawElementsInstancedBaseInstance() in immediate mode.
1128 */
1129 static void GLAPIENTRY
1130 vbo_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count,
1131 GLenum type,
1132 const GLvoid *indices,
1133 GLsizei numInstances,
1134 GLuint baseInstance)
1135 {
1136 GET_CURRENT_CONTEXT(ctx);
1137
1138 if (MESA_VERBOSE & VERBOSE_DRAW)
1139 _mesa_debug(ctx,
1140 "glDrawElementsInstancedBaseInstance"
1141 "(%s, %d, %s, %p, %d, %d)\n",
1142 _mesa_enum_to_string(mode), count,
1143 _mesa_enum_to_string(type), indices,
1144 numInstances, baseInstance);
1145
1146 FLUSH_FOR_DRAW(ctx);
1147
1148 if (_mesa_is_no_error_enabled(ctx)) {
1149 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1150
1151 if (ctx->NewState)
1152 _mesa_update_state(ctx);
1153 } else {
1154 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1155
1156 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
1157 indices, numInstances))
1158 return;
1159 }
1160
1161 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
1162 count, type, indices, 0, numInstances,
1163 baseInstance);
1164 }
1165
1166
1167 /**
1168 * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode.
1169 */
1170 static void GLAPIENTRY
1171 vbo_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode,
1172 GLsizei count,
1173 GLenum type,
1174 const GLvoid *indices,
1175 GLsizei numInstances,
1176 GLint basevertex,
1177 GLuint baseInstance)
1178 {
1179 GET_CURRENT_CONTEXT(ctx);
1180
1181 if (MESA_VERBOSE & VERBOSE_DRAW)
1182 _mesa_debug(ctx,
1183 "glDrawElementsInstancedBaseVertexBaseInstance"
1184 "(%s, %d, %s, %p, %d, %d, %d)\n",
1185 _mesa_enum_to_string(mode), count,
1186 _mesa_enum_to_string(type), indices,
1187 numInstances, basevertex, baseInstance);
1188
1189 FLUSH_FOR_DRAW(ctx);
1190
1191 if (_mesa_is_no_error_enabled(ctx)) {
1192 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1193
1194 if (ctx->NewState)
1195 _mesa_update_state(ctx);
1196 } else {
1197 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1198
1199 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
1200 indices, numInstances))
1201 return;
1202 }
1203
1204 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
1205 count, type, indices, basevertex,
1206 numInstances, baseInstance);
1207 }
1208
1209
1210 /**
1211 * Inner support for both _mesa_MultiDrawElements() and
1212 * _mesa_MultiDrawRangeElements().
1213 * This does the actual rendering after we've checked array indexes, etc.
1214 */
1215 static void
1216 vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
1217 const GLsizei *count, GLenum type,
1218 const GLvoid * const *indices,
1219 GLsizei primcount, const GLint *basevertex)
1220 {
1221 struct _mesa_index_buffer ib;
1222 struct _mesa_prim *prim;
1223 unsigned int index_type_size = sizeof_ib_type(type);
1224 uintptr_t min_index_ptr, max_index_ptr;
1225 GLboolean fallback = GL_FALSE;
1226 int i;
1227
1228 if (primcount == 0)
1229 return;
1230
1231 prim = calloc(primcount, sizeof(*prim));
1232 if (prim == NULL) {
1233 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements");
1234 return;
1235 }
1236
1237 min_index_ptr = (uintptr_t) indices[0];
1238 max_index_ptr = 0;
1239 for (i = 0; i < primcount; i++) {
1240 min_index_ptr = MIN2(min_index_ptr, (uintptr_t) indices[i]);
1241 max_index_ptr = MAX2(max_index_ptr, (uintptr_t) indices[i] +
1242 index_type_size * count[i]);
1243 }
1244
1245 /* Check if we can handle this thing as a bunch of index offsets from the
1246 * same index pointer. If we can't, then we have to fall back to doing
1247 * a draw_prims per primitive.
1248 * Check that the difference between each prim's indexes is a multiple of
1249 * the index/element size.
1250 */
1251 if (index_type_size != 1) {
1252 for (i = 0; i < primcount; i++) {
1253 if ((((uintptr_t) indices[i] - min_index_ptr) % index_type_size) !=
1254 0) {
1255 fallback = GL_TRUE;
1256 break;
1257 }
1258 }
1259 }
1260
1261 /* Draw primitives individually if one count is zero, so we can easily skip
1262 * that primitive.
1263 */
1264 for (i = 0; i < primcount; i++) {
1265 if (count[i] == 0) {
1266 fallback = GL_TRUE;
1267 break;
1268 }
1269 }
1270
1271 /* If the index buffer isn't in a VBO, then treating the application's
1272 * subranges of the index buffer as one large index buffer may lead to
1273 * us reading unmapped memory.
1274 */
1275 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj))
1276 fallback = GL_TRUE;
1277
1278 if (!fallback) {
1279 ib.count = (max_index_ptr - min_index_ptr) / index_type_size;
1280 ib.index_size = sizeof_ib_type(type);
1281 ib.obj = ctx->Array.VAO->IndexBufferObj;
1282 ib.ptr = (void *) min_index_ptr;
1283
1284 for (i = 0; i < primcount; i++) {
1285 prim[i].begin = (i == 0);
1286 prim[i].end = (i == primcount - 1);
1287 prim[i].pad = 0;
1288 prim[i].mode = mode;
1289 prim[i].start =
1290 ((uintptr_t) indices[i] - min_index_ptr) / index_type_size;
1291 prim[i].count = count[i];
1292 prim[i].indexed = 1;
1293 prim[i].num_instances = 1;
1294 prim[i].base_instance = 0;
1295 prim[i].draw_id = i;
1296 prim[i].is_indirect = 0;
1297 if (basevertex != NULL)
1298 prim[i].basevertex = basevertex[i];
1299 else
1300 prim[i].basevertex = 0;
1301 }
1302
1303 ctx->Driver.Draw(ctx, prim, primcount, &ib,
1304 false, 0, ~0, NULL, 0, NULL);
1305 }
1306 else {
1307 /* render one prim at a time */
1308 for (i = 0; i < primcount; i++) {
1309 if (count[i] == 0)
1310 continue;
1311 ib.count = count[i];
1312 ib.index_size = sizeof_ib_type(type);
1313 ib.obj = ctx->Array.VAO->IndexBufferObj;
1314 ib.ptr = indices[i];
1315
1316 prim[0].begin = 1;
1317 prim[0].end = 1;
1318 prim[0].pad = 0;
1319 prim[0].mode = mode;
1320 prim[0].start = 0;
1321 prim[0].count = count[i];
1322 prim[0].indexed = 1;
1323 prim[0].num_instances = 1;
1324 prim[0].base_instance = 0;
1325 prim[0].draw_id = i;
1326 prim[0].is_indirect = 0;
1327 if (basevertex != NULL)
1328 prim[0].basevertex = basevertex[i];
1329 else
1330 prim[0].basevertex = 0;
1331
1332 ctx->Driver.Draw(ctx, prim, 1, &ib, false, 0, ~0, NULL, 0, NULL);
1333 }
1334 }
1335
1336 free(prim);
1337
1338 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1339 _mesa_flush(ctx);
1340 }
1341 }
1342
1343
1344 static void GLAPIENTRY
1345 vbo_exec_MultiDrawElements(GLenum mode,
1346 const GLsizei *count, GLenum type,
1347 const GLvoid * const *indices, GLsizei primcount)
1348 {
1349 GET_CURRENT_CONTEXT(ctx);
1350
1351 FLUSH_FOR_DRAW(ctx);
1352
1353 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1354
1355 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1356 primcount))
1357 return;
1358
1359 if (skip_validated_draw(ctx))
1360 return;
1361
1362 vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
1363 NULL);
1364 }
1365
1366
1367 static void GLAPIENTRY
1368 vbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
1369 const GLsizei *count, GLenum type,
1370 const GLvoid * const *indices,
1371 GLsizei primcount,
1372 const GLsizei *basevertex)
1373 {
1374 GET_CURRENT_CONTEXT(ctx);
1375
1376 FLUSH_FOR_DRAW(ctx);
1377
1378 if (_mesa_is_no_error_enabled(ctx)) {
1379 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1380
1381 if (ctx->NewState)
1382 _mesa_update_state(ctx);
1383 } else {
1384 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1385
1386 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1387 primcount))
1388 return;
1389 }
1390
1391 if (skip_validated_draw(ctx))
1392 return;
1393
1394 vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
1395 basevertex);
1396 }
1397
1398
1399 /**
1400 * Draw a GL primitive using a vertex count obtained from transform feedback.
1401 * \param mode the type of GL primitive to draw
1402 * \param obj the transform feedback object to use
1403 * \param stream index of the transform feedback stream from which to
1404 * get the primitive count.
1405 * \param numInstances number of instances to draw
1406 */
1407 static void
1408 vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
1409 struct gl_transform_feedback_object *obj,
1410 GLuint stream, GLuint numInstances)
1411 {
1412 struct _mesa_prim prim;
1413
1414 FLUSH_FOR_DRAW(ctx);
1415
1416 if (_mesa_is_no_error_enabled(ctx)) {
1417 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1418
1419 if (ctx->NewState)
1420 _mesa_update_state(ctx);
1421 } else {
1422 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1423
1424 if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream,
1425 numInstances)) {
1426 return;
1427 }
1428 }
1429
1430 if (ctx->Driver.GetTransformFeedbackVertexCount &&
1431 (ctx->Const.AlwaysUseGetTransformFeedbackVertexCount ||
1432 !_mesa_all_varyings_in_vbos(ctx->Array.VAO))) {
1433 GLsizei n =
1434 ctx->Driver.GetTransformFeedbackVertexCount(ctx, obj, stream);
1435 vbo_draw_arrays(ctx, mode, 0, n, numInstances, 0, 0);
1436 return;
1437 }
1438
1439 if (skip_validated_draw(ctx))
1440 return;
1441
1442 /* init most fields to zero */
1443 memset(&prim, 0, sizeof(prim));
1444 prim.begin = 1;
1445 prim.end = 1;
1446 prim.mode = mode;
1447 prim.num_instances = numInstances;
1448 prim.base_instance = 0;
1449 prim.is_indirect = 0;
1450
1451 /* Maybe we should do some primitive splitting for primitive restart
1452 * (like in DrawArrays), but we have no way to know how many vertices
1453 * will be rendered. */
1454
1455 ctx->Driver.Draw(ctx, &prim, 1, NULL, GL_FALSE, 0, ~0, obj, stream, NULL);
1456
1457 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1458 _mesa_flush(ctx);
1459 }
1460 }
1461
1462
1463 /**
1464 * Like DrawArrays, but take the count from a transform feedback object.
1465 * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc.
1466 * \param name the transform feedback object
1467 * User still has to setup of the vertex attribute info with
1468 * glVertexPointer, glColorPointer, etc.
1469 * Part of GL_ARB_transform_feedback2.
1470 */
1471 static void GLAPIENTRY
1472 vbo_exec_DrawTransformFeedback(GLenum mode, GLuint name)
1473 {
1474 GET_CURRENT_CONTEXT(ctx);
1475 struct gl_transform_feedback_object *obj =
1476 _mesa_lookup_transform_feedback_object(ctx, name);
1477
1478 if (MESA_VERBOSE & VERBOSE_DRAW)
1479 _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n",
1480 _mesa_enum_to_string(mode), name);
1481
1482 vbo_draw_transform_feedback(ctx, mode, obj, 0, 1);
1483 }
1484
1485
1486 static void GLAPIENTRY
1487 vbo_exec_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream)
1488 {
1489 GET_CURRENT_CONTEXT(ctx);
1490 struct gl_transform_feedback_object *obj =
1491 _mesa_lookup_transform_feedback_object(ctx, name);
1492
1493 if (MESA_VERBOSE & VERBOSE_DRAW)
1494 _mesa_debug(ctx, "glDrawTransformFeedbackStream(%s, %u, %u)\n",
1495 _mesa_enum_to_string(mode), name, stream);
1496
1497 vbo_draw_transform_feedback(ctx, mode, obj, stream, 1);
1498 }
1499
1500
1501 static void GLAPIENTRY
1502 vbo_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name,
1503 GLsizei primcount)
1504 {
1505 GET_CURRENT_CONTEXT(ctx);
1506 struct gl_transform_feedback_object *obj =
1507 _mesa_lookup_transform_feedback_object(ctx, name);
1508
1509 if (MESA_VERBOSE & VERBOSE_DRAW)
1510 _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n",
1511 _mesa_enum_to_string(mode), name);
1512
1513 vbo_draw_transform_feedback(ctx, mode, obj, 0, primcount);
1514 }
1515
1516
1517 static void GLAPIENTRY
1518 vbo_exec_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name,
1519 GLuint stream,
1520 GLsizei primcount)
1521 {
1522 GET_CURRENT_CONTEXT(ctx);
1523 struct gl_transform_feedback_object *obj =
1524 _mesa_lookup_transform_feedback_object(ctx, name);
1525
1526 if (MESA_VERBOSE & VERBOSE_DRAW)
1527 _mesa_debug(ctx, "glDrawTransformFeedbackStreamInstanced"
1528 "(%s, %u, %u, %i)\n",
1529 _mesa_enum_to_string(mode), name, stream, primcount);
1530
1531 vbo_draw_transform_feedback(ctx, mode, obj, stream, primcount);
1532 }
1533
1534
1535 static void
1536 vbo_validated_drawarraysindirect(struct gl_context *ctx,
1537 GLenum mode, const GLvoid *indirect)
1538 {
1539 ctx->Driver.DrawIndirect(ctx, mode,
1540 ctx->DrawIndirectBuffer, (GLsizeiptr) indirect,
1541 1 /* draw_count */ , 16 /* stride */ ,
1542 NULL, 0, NULL);
1543
1544 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1545 _mesa_flush(ctx);
1546 }
1547
1548
1549 static void
1550 vbo_validated_multidrawarraysindirect(struct gl_context *ctx,
1551 GLenum mode,
1552 const GLvoid *indirect,
1553 GLsizei primcount, GLsizei stride)
1554 {
1555 GLsizeiptr offset = (GLsizeiptr) indirect;
1556
1557 if (primcount == 0)
1558 return;
1559
1560 ctx->Driver.DrawIndirect(ctx, mode, ctx->DrawIndirectBuffer, offset,
1561 primcount, stride, NULL, 0, NULL);
1562
1563 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1564 _mesa_flush(ctx);
1565 }
1566
1567
1568 static void
1569 vbo_validated_drawelementsindirect(struct gl_context *ctx,
1570 GLenum mode, GLenum type,
1571 const GLvoid *indirect)
1572 {
1573 struct _mesa_index_buffer ib;
1574
1575 ib.count = 0; /* unknown */
1576 ib.index_size = sizeof_ib_type(type);
1577 ib.obj = ctx->Array.VAO->IndexBufferObj;
1578 ib.ptr = NULL;
1579
1580 ctx->Driver.DrawIndirect(ctx, mode,
1581 ctx->DrawIndirectBuffer, (GLsizeiptr) indirect,
1582 1 /* draw_count */ , 20 /* stride */ ,
1583 NULL, 0, &ib);
1584
1585 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1586 _mesa_flush(ctx);
1587 }
1588
1589
1590 static void
1591 vbo_validated_multidrawelementsindirect(struct gl_context *ctx,
1592 GLenum mode, GLenum type,
1593 const GLvoid *indirect,
1594 GLsizei primcount, GLsizei stride)
1595 {
1596 struct _mesa_index_buffer ib;
1597 GLsizeiptr offset = (GLsizeiptr) indirect;
1598
1599 if (primcount == 0)
1600 return;
1601
1602 /* NOTE: IndexBufferObj is guaranteed to be a VBO. */
1603
1604 ib.count = 0; /* unknown */
1605 ib.index_size = sizeof_ib_type(type);
1606 ib.obj = ctx->Array.VAO->IndexBufferObj;
1607 ib.ptr = NULL;
1608
1609 ctx->Driver.DrawIndirect(ctx, mode,
1610 ctx->DrawIndirectBuffer, offset,
1611 primcount, stride, NULL, 0, &ib);
1612
1613 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1614 _mesa_flush(ctx);
1615 }
1616
1617
1618 /**
1619 * Like [Multi]DrawArrays/Elements, but they take most arguments from
1620 * a buffer object.
1621 */
1622 static void GLAPIENTRY
1623 vbo_exec_DrawArraysIndirect(GLenum mode, const GLvoid *indirect)
1624 {
1625 GET_CURRENT_CONTEXT(ctx);
1626
1627 if (MESA_VERBOSE & VERBOSE_DRAW)
1628 _mesa_debug(ctx, "glDrawArraysIndirect(%s, %p)\n",
1629 _mesa_enum_to_string(mode), indirect);
1630
1631 /* From the ARB_draw_indirect spec:
1632 *
1633 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
1634 * compatibility profile, this indicates that DrawArraysIndirect and
1635 * DrawElementsIndirect are to source their arguments directly from the
1636 * pointer passed as their <indirect> parameters."
1637 */
1638 if (ctx->API == API_OPENGL_COMPAT &&
1639 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
1640 DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) indirect;
1641
1642 vbo_exec_DrawArraysInstancedBaseInstance(mode, cmd->first, cmd->count,
1643 cmd->primCount,
1644 cmd->baseInstance);
1645 return;
1646 }
1647
1648 FLUSH_FOR_DRAW(ctx);
1649
1650 if (_mesa_is_no_error_enabled(ctx)) {
1651 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1652
1653 if (ctx->NewState)
1654 _mesa_update_state(ctx);
1655 } else {
1656 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1657
1658 if (!_mesa_validate_DrawArraysIndirect(ctx, mode, indirect))
1659 return;
1660 }
1661
1662 if (skip_validated_draw(ctx))
1663 return;
1664
1665 vbo_validated_drawarraysindirect(ctx, mode, indirect);
1666 }
1667
1668
1669 static void GLAPIENTRY
1670 vbo_exec_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1671 {
1672 GET_CURRENT_CONTEXT(ctx);
1673
1674 if (MESA_VERBOSE & VERBOSE_DRAW)
1675 _mesa_debug(ctx, "glDrawElementsIndirect(%s, %s, %p)\n",
1676 _mesa_enum_to_string(mode),
1677 _mesa_enum_to_string(type), indirect);
1678
1679 /* From the ARB_draw_indirect spec:
1680 *
1681 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
1682 * compatibility profile, this indicates that DrawArraysIndirect and
1683 * DrawElementsIndirect are to source their arguments directly from the
1684 * pointer passed as their <indirect> parameters."
1685 */
1686 if (ctx->API == API_OPENGL_COMPAT &&
1687 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
1688 /*
1689 * Unlike regular DrawElementsInstancedBaseVertex commands, the indices
1690 * may not come from a client array and must come from an index buffer.
1691 * If no element array buffer is bound, an INVALID_OPERATION error is
1692 * generated.
1693 */
1694 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) {
1695 _mesa_error(ctx, GL_INVALID_OPERATION,
1696 "glDrawElementsIndirect(no buffer bound "
1697 "to GL_ELEMENT_ARRAY_BUFFER)");
1698 } else {
1699 DrawElementsIndirectCommand *cmd =
1700 (DrawElementsIndirectCommand *) indirect;
1701
1702 /* Convert offset to pointer */
1703 void *offset = (void *)
1704 ((cmd->firstIndex * _mesa_sizeof_type(type)) & 0xffffffffUL);
1705
1706 vbo_exec_DrawElementsInstancedBaseVertexBaseInstance(mode, cmd->count,
1707 type, offset,
1708 cmd->primCount,
1709 cmd->baseVertex,
1710 cmd->baseInstance);
1711 }
1712
1713 return;
1714 }
1715
1716 FLUSH_FOR_DRAW(ctx);
1717
1718 if (_mesa_is_no_error_enabled(ctx)) {
1719 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1720
1721 if (ctx->NewState)
1722 _mesa_update_state(ctx);
1723 } else {
1724 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1725
1726 if (!_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect))
1727 return;
1728 }
1729
1730 if (skip_validated_draw(ctx))
1731 return;
1732
1733 vbo_validated_drawelementsindirect(ctx, mode, type, indirect);
1734 }
1735
1736
1737 static void GLAPIENTRY
1738 vbo_exec_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect,
1739 GLsizei primcount, GLsizei stride)
1740 {
1741 GET_CURRENT_CONTEXT(ctx);
1742
1743 if (MESA_VERBOSE & VERBOSE_DRAW)
1744 _mesa_debug(ctx, "glMultiDrawArraysIndirect(%s, %p, %i, %i)\n",
1745 _mesa_enum_to_string(mode), indirect, primcount, stride);
1746
1747 /* If <stride> is zero, the array elements are treated as tightly packed. */
1748 if (stride == 0)
1749 stride = sizeof(DrawArraysIndirectCommand);
1750
1751 /* From the ARB_draw_indirect spec:
1752 *
1753 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
1754 * compatibility profile, this indicates that DrawArraysIndirect and
1755 * DrawElementsIndirect are to source their arguments directly from the
1756 * pointer passed as their <indirect> parameters."
1757 */
1758 if (ctx->API == API_OPENGL_COMPAT &&
1759 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
1760
1761 if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
1762 "glMultiDrawArraysIndirect"))
1763 return;
1764
1765 const ubyte *ptr = (const ubyte *) indirect;
1766 for (unsigned i = 0; i < primcount; i++) {
1767 DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) ptr;
1768 vbo_exec_DrawArraysInstancedBaseInstance(mode, cmd->first,
1769 cmd->count, cmd->primCount,
1770 cmd->baseInstance);
1771
1772 if (stride == 0) {
1773 ptr += sizeof(DrawArraysIndirectCommand);
1774 } else {
1775 ptr += stride;
1776 }
1777 }
1778
1779 return;
1780 }
1781
1782 FLUSH_FOR_DRAW(ctx);
1783
1784 if (_mesa_is_no_error_enabled(ctx)) {
1785 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1786
1787 if (ctx->NewState)
1788 _mesa_update_state(ctx);
1789 } else {
1790 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1791
1792 if (!_mesa_validate_MultiDrawArraysIndirect(ctx, mode, indirect,
1793 primcount, stride))
1794 return;
1795 }
1796
1797 if (skip_validated_draw(ctx))
1798 return;
1799
1800 vbo_validated_multidrawarraysindirect(ctx, mode, indirect,
1801 primcount, stride);
1802 }
1803
1804
1805 static void GLAPIENTRY
1806 vbo_exec_MultiDrawElementsIndirect(GLenum mode, GLenum type,
1807 const GLvoid *indirect,
1808 GLsizei primcount, GLsizei stride)
1809 {
1810 GET_CURRENT_CONTEXT(ctx);
1811
1812 if (MESA_VERBOSE & VERBOSE_DRAW)
1813 _mesa_debug(ctx, "glMultiDrawElementsIndirect(%s, %s, %p, %i, %i)\n",
1814 _mesa_enum_to_string(mode),
1815 _mesa_enum_to_string(type), indirect, primcount, stride);
1816
1817 /* If <stride> is zero, the array elements are treated as tightly packed. */
1818 if (stride == 0)
1819 stride = sizeof(DrawElementsIndirectCommand);
1820
1821
1822 /* From the ARB_draw_indirect spec:
1823 *
1824 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
1825 * compatibility profile, this indicates that DrawArraysIndirect and
1826 * DrawElementsIndirect are to source their arguments directly from the
1827 * pointer passed as their <indirect> parameters."
1828 */
1829 if (ctx->API == API_OPENGL_COMPAT &&
1830 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
1831 /*
1832 * Unlike regular DrawElementsInstancedBaseVertex commands, the indices
1833 * may not come from a client array and must come from an index buffer.
1834 * If no element array buffer is bound, an INVALID_OPERATION error is
1835 * generated.
1836 */
1837 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) {
1838 _mesa_error(ctx, GL_INVALID_OPERATION,
1839 "glMultiDrawElementsIndirect(no buffer bound "
1840 "to GL_ELEMENT_ARRAY_BUFFER)");
1841
1842 return;
1843 }
1844
1845 if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
1846 "glMultiDrawArraysIndirect"))
1847 return;
1848
1849 const ubyte *ptr = (const ubyte *) indirect;
1850 for (unsigned i = 0; i < primcount; i++) {
1851 vbo_exec_DrawElementsIndirect(mode, type, ptr);
1852
1853 if (stride == 0) {
1854 ptr += sizeof(DrawElementsIndirectCommand);
1855 } else {
1856 ptr += stride;
1857 }
1858 }
1859
1860 return;
1861 }
1862
1863 FLUSH_FOR_DRAW(ctx);
1864
1865 if (_mesa_is_no_error_enabled(ctx)) {
1866 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1867
1868 if (ctx->NewState)
1869 _mesa_update_state(ctx);
1870 } else {
1871 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1872
1873 if (!_mesa_validate_MultiDrawElementsIndirect(ctx, mode, type, indirect,
1874 primcount, stride))
1875 return;
1876 }
1877
1878 if (skip_validated_draw(ctx))
1879 return;
1880
1881 vbo_validated_multidrawelementsindirect(ctx, mode, type, indirect,
1882 primcount, stride);
1883 }
1884
1885
1886 static void
1887 vbo_validated_multidrawarraysindirectcount(struct gl_context *ctx,
1888 GLenum mode,
1889 GLintptr indirect,
1890 GLintptr drawcount_offset,
1891 GLsizei maxdrawcount,
1892 GLsizei stride)
1893 {
1894 GLsizeiptr offset = indirect;
1895
1896 if (maxdrawcount == 0)
1897 return;
1898
1899 ctx->Driver.DrawIndirect(ctx, mode,
1900 ctx->DrawIndirectBuffer, offset,
1901 maxdrawcount, stride,
1902 ctx->ParameterBuffer, drawcount_offset, NULL);
1903
1904 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1905 _mesa_flush(ctx);
1906 }
1907
1908
1909 static void
1910 vbo_validated_multidrawelementsindirectcount(struct gl_context *ctx,
1911 GLenum mode, GLenum type,
1912 GLintptr indirect,
1913 GLintptr drawcount_offset,
1914 GLsizei maxdrawcount,
1915 GLsizei stride)
1916 {
1917 struct _mesa_index_buffer ib;
1918 GLsizeiptr offset = (GLsizeiptr) indirect;
1919
1920 if (maxdrawcount == 0)
1921 return;
1922
1923 /* NOTE: IndexBufferObj is guaranteed to be a VBO. */
1924
1925 ib.count = 0; /* unknown */
1926 ib.index_size = sizeof_ib_type(type);
1927 ib.obj = ctx->Array.VAO->IndexBufferObj;
1928 ib.ptr = NULL;
1929
1930 ctx->Driver.DrawIndirect(ctx, mode,
1931 ctx->DrawIndirectBuffer, offset,
1932 maxdrawcount, stride,
1933 ctx->ParameterBuffer, drawcount_offset, &ib);
1934
1935 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1936 _mesa_flush(ctx);
1937 }
1938
1939
1940 static void GLAPIENTRY
1941 vbo_exec_MultiDrawArraysIndirectCount(GLenum mode, GLintptr indirect,
1942 GLintptr drawcount_offset,
1943 GLsizei maxdrawcount, GLsizei stride)
1944 {
1945 GET_CURRENT_CONTEXT(ctx);
1946
1947 if (MESA_VERBOSE & VERBOSE_DRAW)
1948 _mesa_debug(ctx, "glMultiDrawArraysIndirectCountARB"
1949 "(%s, %lx, %lx, %i, %i)\n",
1950 _mesa_enum_to_string(mode),
1951 (unsigned long) indirect, (unsigned long) drawcount_offset,
1952 maxdrawcount, stride);
1953
1954 /* If <stride> is zero, the array elements are treated as tightly packed. */
1955 if (stride == 0)
1956 stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */
1957
1958 FLUSH_FOR_DRAW(ctx);
1959
1960 if (_mesa_is_no_error_enabled(ctx)) {
1961 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1962
1963 if (ctx->NewState)
1964 _mesa_update_state(ctx);
1965 } else {
1966 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1967
1968 if (!_mesa_validate_MultiDrawArraysIndirectCount(ctx, mode,
1969 indirect,
1970 drawcount_offset,
1971 maxdrawcount, stride))
1972 return;
1973 }
1974
1975 if (skip_validated_draw(ctx))
1976 return;
1977
1978 vbo_validated_multidrawarraysindirectcount(ctx, mode, indirect,
1979 drawcount_offset,
1980 maxdrawcount, stride);
1981 }
1982
1983
1984 static void GLAPIENTRY
1985 vbo_exec_MultiDrawElementsIndirectCount(GLenum mode, GLenum type,
1986 GLintptr indirect,
1987 GLintptr drawcount_offset,
1988 GLsizei maxdrawcount, GLsizei stride)
1989 {
1990 GET_CURRENT_CONTEXT(ctx);
1991
1992 if (MESA_VERBOSE & VERBOSE_DRAW)
1993 _mesa_debug(ctx, "glMultiDrawElementsIndirectCountARB"
1994 "(%s, %s, %lx, %lx, %i, %i)\n",
1995 _mesa_enum_to_string(mode), _mesa_enum_to_string(type),
1996 (unsigned long) indirect, (unsigned long) drawcount_offset,
1997 maxdrawcount, stride);
1998
1999 /* If <stride> is zero, the array elements are treated as tightly packed. */
2000 if (stride == 0)
2001 stride = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */
2002
2003 FLUSH_FOR_DRAW(ctx);
2004
2005 if (_mesa_is_no_error_enabled(ctx)) {
2006 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
2007
2008 if (ctx->NewState)
2009 _mesa_update_state(ctx);
2010 } else {
2011 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
2012
2013 if (!_mesa_validate_MultiDrawElementsIndirectCount(ctx, mode, type,
2014 indirect,
2015 drawcount_offset,
2016 maxdrawcount, stride))
2017 return;
2018 }
2019
2020 if (skip_validated_draw(ctx))
2021 return;
2022
2023 vbo_validated_multidrawelementsindirectcount(ctx, mode, type, indirect,
2024 drawcount_offset, maxdrawcount,
2025 stride);
2026 }
2027
2028
2029 /**
2030 * Initialize the dispatch table with the VBO functions for drawing.
2031 */
2032 void
2033 vbo_initialize_exec_dispatch(const struct gl_context *ctx,
2034 struct _glapi_table *exec)
2035 {
2036 SET_DrawArrays(exec, vbo_exec_DrawArrays);
2037 SET_DrawElements(exec, vbo_exec_DrawElements);
2038
2039 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
2040 SET_DrawRangeElements(exec, vbo_exec_DrawRangeElements);
2041 }
2042
2043 SET_MultiDrawArrays(exec, vbo_exec_MultiDrawArrays);
2044 SET_MultiDrawElementsEXT(exec, vbo_exec_MultiDrawElements);
2045
2046 if (ctx->API == API_OPENGL_COMPAT) {
2047 SET_Rectf(exec, vbo_exec_Rectf);
2048 SET_EvalMesh1(exec, vbo_exec_EvalMesh1);
2049 SET_EvalMesh2(exec, vbo_exec_EvalMesh2);
2050 }
2051
2052 if (ctx->API != API_OPENGLES &&
2053 ctx->Extensions.ARB_draw_elements_base_vertex) {
2054 SET_DrawElementsBaseVertex(exec, vbo_exec_DrawElementsBaseVertex);
2055 SET_MultiDrawElementsBaseVertex(exec,
2056 vbo_exec_MultiDrawElementsBaseVertex);
2057
2058 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
2059 SET_DrawRangeElementsBaseVertex(exec,
2060 vbo_exec_DrawRangeElementsBaseVertex);
2061 SET_DrawElementsInstancedBaseVertex(exec,
2062 vbo_exec_DrawElementsInstancedBaseVertex);
2063 }
2064 }
2065
2066 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
2067 SET_DrawArraysInstancedBaseInstance(exec,
2068 vbo_exec_DrawArraysInstancedBaseInstance);
2069 SET_DrawElementsInstancedBaseInstance(exec,
2070 vbo_exec_DrawElementsInstancedBaseInstance);
2071 SET_DrawElementsInstancedBaseVertexBaseInstance(exec,
2072 vbo_exec_DrawElementsInstancedBaseVertexBaseInstance);
2073 }
2074
2075 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
2076 SET_DrawArraysIndirect(exec, vbo_exec_DrawArraysIndirect);
2077 SET_DrawElementsIndirect(exec, vbo_exec_DrawElementsIndirect);
2078 }
2079
2080 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
2081 SET_DrawArraysInstancedARB(exec, vbo_exec_DrawArraysInstanced);
2082 SET_DrawElementsInstancedARB(exec, vbo_exec_DrawElementsInstanced);
2083 }
2084
2085 if (_mesa_is_desktop_gl(ctx)) {
2086 SET_DrawTransformFeedback(exec, vbo_exec_DrawTransformFeedback);
2087 SET_DrawTransformFeedbackStream(exec,
2088 vbo_exec_DrawTransformFeedbackStream);
2089 SET_DrawTransformFeedbackInstanced(exec,
2090 vbo_exec_DrawTransformFeedbackInstanced);
2091 SET_DrawTransformFeedbackStreamInstanced(exec,
2092 vbo_exec_DrawTransformFeedbackStreamInstanced);
2093 SET_MultiDrawArraysIndirect(exec, vbo_exec_MultiDrawArraysIndirect);
2094 SET_MultiDrawElementsIndirect(exec, vbo_exec_MultiDrawElementsIndirect);
2095 SET_MultiDrawArraysIndirectCountARB(exec,
2096 vbo_exec_MultiDrawArraysIndirectCount);
2097 SET_MultiDrawElementsIndirectCountARB(exec,
2098 vbo_exec_MultiDrawElementsIndirectCount);
2099 }
2100 }
2101
2102
2103
2104 /**
2105 * The following functions are only used for OpenGL ES 1/2 support.
2106 * And some aren't even supported (yet) in ES 1/2.
2107 */
2108
2109
2110 void GLAPIENTRY
2111 _mesa_DrawArrays(GLenum mode, GLint first, GLsizei count)
2112 {
2113 vbo_exec_DrawArrays(mode, first, count);
2114 }
2115
2116
2117 void GLAPIENTRY
2118 _mesa_DrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
2119 GLsizei primcount)
2120 {
2121 vbo_exec_DrawArraysInstanced(mode, first, count, primcount);
2122 }
2123
2124
2125 void GLAPIENTRY
2126 _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
2127 const GLvoid *indices)
2128 {
2129 vbo_exec_DrawElements(mode, count, type, indices);
2130 }
2131
2132
2133 void GLAPIENTRY
2134 _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
2135 const GLvoid *indices, GLint basevertex)
2136 {
2137 vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex);
2138 }
2139
2140
2141 void GLAPIENTRY
2142 _mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
2143 GLenum type, const GLvoid * indices)
2144 {
2145 vbo_exec_DrawRangeElements(mode, start, end, count, type, indices);
2146 }
2147
2148
2149 void GLAPIENTRY
2150 _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
2151 GLsizei count, GLenum type,
2152 const GLvoid *indices, GLint basevertex)
2153 {
2154 vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
2155 indices, basevertex);
2156 }
2157
2158
2159 void GLAPIENTRY
2160 _mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,
2161 const GLvoid ** indices, GLsizei primcount)
2162 {
2163 vbo_exec_MultiDrawElements(mode, count, type, indices, primcount);
2164 }
2165
2166
2167 void GLAPIENTRY
2168 _mesa_MultiDrawElementsBaseVertex(GLenum mode,
2169 const GLsizei *count, GLenum type,
2170 const GLvoid **indices, GLsizei primcount,
2171 const GLint *basevertex)
2172 {
2173 vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices,
2174 primcount, basevertex);
2175 }
2176
2177
2178 void GLAPIENTRY
2179 _mesa_DrawTransformFeedback(GLenum mode, GLuint name)
2180 {
2181 vbo_exec_DrawTransformFeedback(mode, name);
2182 }