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