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