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