mesa: don't use bitfields in _mesa_prim
[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.mode = mode;
774 prim.start = 0;
775 prim.count = count;
776 prim.indexed = 1;
777 prim.basevertex = basevertex;
778 prim.num_instances = numInstances;
779 prim.base_instance = baseInstance;
780 prim.draw_id = 0;
781
782 /* Need to give special consideration to rendering a range of
783 * indices starting somewhere above zero. Typically the
784 * application is issuing multiple DrawRangeElements() to draw
785 * successive primitives layed out linearly in the vertex arrays.
786 * Unless the vertex arrays are all in a VBO (or locked as with
787 * CVA), the OpenGL semantics imply that we need to re-read or
788 * re-upload the vertex data on each draw call.
789 *
790 * In the case of hardware tnl, we want to avoid starting the
791 * upload at zero, as it will mean every draw call uploads an
792 * increasing amount of not-used vertex data. Worse - in the
793 * software tnl module, all those vertices might be transformed and
794 * lit but never rendered.
795 *
796 * If we just upload or transform the vertices in start..end,
797 * however, the indices will be incorrect.
798 *
799 * At this level, we don't know exactly what the requirements of
800 * the backend are going to be, though it will likely boil down to
801 * either:
802 *
803 * 1) Do nothing, everything is in a VBO and is processed once
804 * only.
805 *
806 * 2) Adjust the indices and vertex arrays so that start becomes
807 * zero.
808 *
809 * Rather than doing anything here, I'll provide a helper function
810 * for the latter case elsewhere.
811 */
812
813 ctx->Driver.Draw(ctx, &prim, 1, &ib,
814 index_bounds_valid, start, end, NULL, 0, NULL);
815
816 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
817 _mesa_flush(ctx);
818 }
819 }
820
821
822 /**
823 * Called by glDrawRangeElementsBaseVertex() in immediate mode.
824 */
825 void GLAPIENTRY
826 _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
827 GLsizei count, GLenum type,
828 const GLvoid * indices, GLint basevertex)
829 {
830 static GLuint warnCount = 0;
831 GLboolean index_bounds_valid = GL_TRUE;
832
833 /* This is only useful to catch invalid values in the "end" parameter
834 * like ~0.
835 */
836 GLuint max_element = 2 * 1000 * 1000 * 1000; /* just a big number */
837
838 GET_CURRENT_CONTEXT(ctx);
839
840 if (MESA_VERBOSE & VERBOSE_DRAW)
841 _mesa_debug(ctx,
842 "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n",
843 _mesa_enum_to_string(mode), start, end, count,
844 _mesa_enum_to_string(type), indices, basevertex);
845
846 FLUSH_FOR_DRAW(ctx);
847
848 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
849
850 if (_mesa_is_no_error_enabled(ctx)) {
851 if (ctx->NewState)
852 _mesa_update_state(ctx);
853 } else {
854 if (!_mesa_validate_DrawRangeElements(ctx, mode, start, end, count,
855 type, indices))
856 return;
857 }
858
859 if ((int) end + basevertex < 0 || start + basevertex >= max_element) {
860 /* The application requested we draw using a range of indices that's
861 * outside the bounds of the current VBO. This is invalid and appears
862 * to give undefined results. The safest thing to do is to simply
863 * ignore the range, in case the application botched their range tracking
864 * but did provide valid indices. Also issue a warning indicating that
865 * the application is broken.
866 */
867 if (warnCount++ < 10) {
868 _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, "
869 "basevertex %d, count %d, type 0x%x, indices=%p):\n"
870 "\trange is outside VBO bounds (max=%u); ignoring.\n"
871 "\tThis should be fixed in the application.",
872 start, end, basevertex, count, type, indices,
873 max_element - 1);
874 }
875 index_bounds_valid = GL_FALSE;
876 }
877
878 /* NOTE: It's important that 'end' is a reasonable value.
879 * in _tnl_draw_prims(), we use end to determine how many vertices
880 * to transform. If it's too large, we can unnecessarily split prims
881 * or we can read/write out of memory in several different places!
882 */
883
884 /* Catch/fix some potential user errors */
885 if (type == GL_UNSIGNED_BYTE) {
886 start = MIN2(start, 0xff);
887 end = MIN2(end, 0xff);
888 }
889 else if (type == GL_UNSIGNED_SHORT) {
890 start = MIN2(start, 0xffff);
891 end = MIN2(end, 0xffff);
892 }
893
894 if (0) {
895 printf("glDraw[Range]Elements{,BaseVertex}"
896 "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, "
897 "base %d\n",
898 start, end, type, count,
899 ctx->Array.VAO->IndexBufferObj->Name, basevertex);
900 }
901
902 if ((int) start + basevertex < 0 || end + basevertex >= max_element)
903 index_bounds_valid = GL_FALSE;
904
905 #if 0
906 check_draw_elements_data(ctx, count, type, indices, basevertex);
907 #else
908 (void) check_draw_elements_data;
909 #endif
910
911 if (!index_bounds_valid) {
912 start = 0;
913 end = ~0;
914 }
915
916 _mesa_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end,
917 count, type, indices, basevertex, 1, 0);
918 }
919
920
921 /**
922 * Called by glDrawRangeElements() in immediate mode.
923 */
924 void GLAPIENTRY
925 _mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
926 GLsizei count, GLenum type, const GLvoid * indices)
927 {
928 if (MESA_VERBOSE & VERBOSE_DRAW) {
929 GET_CURRENT_CONTEXT(ctx);
930 _mesa_debug(ctx,
931 "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n",
932 _mesa_enum_to_string(mode), start, end, count,
933 _mesa_enum_to_string(type), indices);
934 }
935
936 _mesa_DrawRangeElementsBaseVertex(mode, start, end, count, type,
937 indices, 0);
938 }
939
940
941 /**
942 * Called by glDrawElements() in immediate mode.
943 */
944 void GLAPIENTRY
945 _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
946 const GLvoid * indices)
947 {
948 GET_CURRENT_CONTEXT(ctx);
949
950 if (MESA_VERBOSE & VERBOSE_DRAW)
951 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n",
952 _mesa_enum_to_string(mode), count,
953 _mesa_enum_to_string(type), indices);
954
955 FLUSH_FOR_DRAW(ctx);
956
957 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
958
959 if (_mesa_is_no_error_enabled(ctx)) {
960 if (ctx->NewState)
961 _mesa_update_state(ctx);
962 } else {
963 if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices))
964 return;
965 }
966
967 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
968 count, type, indices, 0, 1, 0);
969 }
970
971
972 /**
973 * Called by glDrawElementsBaseVertex() in immediate mode.
974 */
975 void GLAPIENTRY
976 _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
977 const GLvoid * indices, GLint basevertex)
978 {
979 GET_CURRENT_CONTEXT(ctx);
980
981 if (MESA_VERBOSE & VERBOSE_DRAW)
982 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n",
983 _mesa_enum_to_string(mode), count,
984 _mesa_enum_to_string(type), indices);
985
986 FLUSH_FOR_DRAW(ctx);
987
988 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
989
990 if (_mesa_is_no_error_enabled(ctx)) {
991 if (ctx->NewState)
992 _mesa_update_state(ctx);
993 } else {
994 if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices))
995 return;
996 }
997
998 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
999 count, type, indices, basevertex, 1, 0);
1000 }
1001
1002
1003 /**
1004 * Called by glDrawElementsInstanced() in immediate mode.
1005 */
1006 static void GLAPIENTRY
1007 _mesa_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
1008 const GLvoid * indices, GLsizei numInstances)
1009 {
1010 GET_CURRENT_CONTEXT(ctx);
1011
1012 if (MESA_VERBOSE & VERBOSE_DRAW)
1013 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n",
1014 _mesa_enum_to_string(mode), count,
1015 _mesa_enum_to_string(type), indices);
1016
1017 FLUSH_FOR_DRAW(ctx);
1018
1019 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1020
1021 if (_mesa_is_no_error_enabled(ctx)) {
1022 if (ctx->NewState)
1023 _mesa_update_state(ctx);
1024 } else {
1025 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
1026 indices, numInstances))
1027 return;
1028 }
1029
1030 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
1031 count, type, indices, 0, numInstances, 0);
1032 }
1033
1034
1035 /**
1036 * Called by glDrawElementsInstancedBaseVertex() in immediate mode.
1037 */
1038 static void GLAPIENTRY
1039 _mesa_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count,
1040 GLenum type, const GLvoid * indices,
1041 GLsizei numInstances,
1042 GLint basevertex)
1043 {
1044 GET_CURRENT_CONTEXT(ctx);
1045
1046 if (MESA_VERBOSE & VERBOSE_DRAW)
1047 _mesa_debug(ctx,
1048 "glDrawElementsInstancedBaseVertex"
1049 "(%s, %d, %s, %p, %d; %d)\n",
1050 _mesa_enum_to_string(mode), count,
1051 _mesa_enum_to_string(type), indices,
1052 numInstances, basevertex);
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,
1069 basevertex, numInstances, 0);
1070 }
1071
1072
1073 /**
1074 * Called by glDrawElementsInstancedBaseInstance() in immediate mode.
1075 */
1076 static void GLAPIENTRY
1077 _mesa_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count,
1078 GLenum type,
1079 const GLvoid *indices,
1080 GLsizei numInstances,
1081 GLuint baseInstance)
1082 {
1083 GET_CURRENT_CONTEXT(ctx);
1084
1085 if (MESA_VERBOSE & VERBOSE_DRAW)
1086 _mesa_debug(ctx,
1087 "glDrawElementsInstancedBaseInstance"
1088 "(%s, %d, %s, %p, %d, %d)\n",
1089 _mesa_enum_to_string(mode), count,
1090 _mesa_enum_to_string(type), indices,
1091 numInstances, baseInstance);
1092
1093 FLUSH_FOR_DRAW(ctx);
1094
1095 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1096
1097 if (_mesa_is_no_error_enabled(ctx)) {
1098 if (ctx->NewState)
1099 _mesa_update_state(ctx);
1100 } else {
1101 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
1102 indices, numInstances))
1103 return;
1104 }
1105
1106 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
1107 count, type, indices, 0, numInstances,
1108 baseInstance);
1109 }
1110
1111
1112 /**
1113 * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode.
1114 */
1115 static void GLAPIENTRY
1116 _mesa_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode,
1117 GLsizei count,
1118 GLenum type,
1119 const GLvoid *indices,
1120 GLsizei numInstances,
1121 GLint basevertex,
1122 GLuint baseInstance)
1123 {
1124 GET_CURRENT_CONTEXT(ctx);
1125
1126 if (MESA_VERBOSE & VERBOSE_DRAW)
1127 _mesa_debug(ctx,
1128 "glDrawElementsInstancedBaseVertexBaseInstance"
1129 "(%s, %d, %s, %p, %d, %d, %d)\n",
1130 _mesa_enum_to_string(mode), count,
1131 _mesa_enum_to_string(type), indices,
1132 numInstances, basevertex, baseInstance);
1133
1134 FLUSH_FOR_DRAW(ctx);
1135
1136 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1137
1138 if (_mesa_is_no_error_enabled(ctx)) {
1139 if (ctx->NewState)
1140 _mesa_update_state(ctx);
1141 } else {
1142 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type,
1143 indices, numInstances))
1144 return;
1145 }
1146
1147 _mesa_validated_drawrangeelements(ctx, mode, GL_FALSE, 0, ~0,
1148 count, type, indices, basevertex,
1149 numInstances, baseInstance);
1150 }
1151
1152
1153 /**
1154 * Inner support for both _mesa_MultiDrawElements() and
1155 * _mesa_MultiDrawRangeElements().
1156 * This does the actual rendering after we've checked array indexes, etc.
1157 */
1158 static void
1159 _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
1160 const GLsizei *count, GLenum type,
1161 const GLvoid * const *indices,
1162 GLsizei primcount, const GLint *basevertex)
1163 {
1164 struct _mesa_index_buffer ib;
1165 struct _mesa_prim *prim;
1166 unsigned int index_type_size = sizeof_ib_type(type);
1167 uintptr_t min_index_ptr, max_index_ptr;
1168 GLboolean fallback = GL_FALSE;
1169 int i;
1170
1171 if (primcount == 0)
1172 return;
1173
1174 prim = calloc(primcount, sizeof(*prim));
1175 if (prim == NULL) {
1176 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements");
1177 return;
1178 }
1179
1180 min_index_ptr = (uintptr_t) indices[0];
1181 max_index_ptr = 0;
1182 for (i = 0; i < primcount; i++) {
1183 min_index_ptr = MIN2(min_index_ptr, (uintptr_t) indices[i]);
1184 max_index_ptr = MAX2(max_index_ptr, (uintptr_t) indices[i] +
1185 index_type_size * count[i]);
1186 }
1187
1188 /* Check if we can handle this thing as a bunch of index offsets from the
1189 * same index pointer. If we can't, then we have to fall back to doing
1190 * a draw_prims per primitive.
1191 * Check that the difference between each prim's indexes is a multiple of
1192 * the index/element size.
1193 */
1194 if (index_type_size != 1) {
1195 for (i = 0; i < primcount; i++) {
1196 if ((((uintptr_t) indices[i] - min_index_ptr) % index_type_size) !=
1197 0) {
1198 fallback = GL_TRUE;
1199 break;
1200 }
1201 }
1202 }
1203
1204 /* Draw primitives individually if one count is zero, so we can easily skip
1205 * that primitive.
1206 */
1207 for (i = 0; i < primcount; i++) {
1208 if (count[i] == 0) {
1209 fallback = GL_TRUE;
1210 break;
1211 }
1212 }
1213
1214 /* If the index buffer isn't in a VBO, then treating the application's
1215 * subranges of the index buffer as one large index buffer may lead to
1216 * us reading unmapped memory.
1217 */
1218 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj))
1219 fallback = GL_TRUE;
1220
1221 if (!fallback) {
1222 ib.count = (max_index_ptr - min_index_ptr) / index_type_size;
1223 ib.index_size = sizeof_ib_type(type);
1224 ib.obj = ctx->Array.VAO->IndexBufferObj;
1225 ib.ptr = (void *) min_index_ptr;
1226
1227 for (i = 0; i < primcount; i++) {
1228 prim[i].begin = (i == 0);
1229 prim[i].end = (i == primcount - 1);
1230 prim[i].mode = mode;
1231 prim[i].start =
1232 ((uintptr_t) indices[i] - min_index_ptr) / index_type_size;
1233 prim[i].count = count[i];
1234 prim[i].indexed = 1;
1235 prim[i].num_instances = 1;
1236 prim[i].base_instance = 0;
1237 prim[i].draw_id = i;
1238 if (basevertex != NULL)
1239 prim[i].basevertex = basevertex[i];
1240 else
1241 prim[i].basevertex = 0;
1242 }
1243
1244 ctx->Driver.Draw(ctx, prim, primcount, &ib,
1245 false, 0, ~0, NULL, 0, NULL);
1246 }
1247 else {
1248 /* render one prim at a time */
1249 for (i = 0; i < primcount; i++) {
1250 if (count[i] == 0)
1251 continue;
1252 ib.count = count[i];
1253 ib.index_size = sizeof_ib_type(type);
1254 ib.obj = ctx->Array.VAO->IndexBufferObj;
1255 ib.ptr = indices[i];
1256
1257 prim[0].begin = 1;
1258 prim[0].end = 1;
1259 prim[0].mode = mode;
1260 prim[0].start = 0;
1261 prim[0].count = count[i];
1262 prim[0].indexed = 1;
1263 prim[0].num_instances = 1;
1264 prim[0].base_instance = 0;
1265 prim[0].draw_id = i;
1266 if (basevertex != NULL)
1267 prim[0].basevertex = basevertex[i];
1268 else
1269 prim[0].basevertex = 0;
1270
1271 ctx->Driver.Draw(ctx, prim, 1, &ib, false, 0, ~0, NULL, 0, NULL);
1272 }
1273 }
1274
1275 free(prim);
1276
1277 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1278 _mesa_flush(ctx);
1279 }
1280 }
1281
1282
1283 void GLAPIENTRY
1284 _mesa_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type,
1285 const GLvoid * const *indices, GLsizei primcount)
1286 {
1287 GET_CURRENT_CONTEXT(ctx);
1288
1289 FLUSH_FOR_DRAW(ctx);
1290
1291 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1292
1293 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1294 primcount))
1295 return;
1296
1297 if (skip_validated_draw(ctx))
1298 return;
1299
1300 _mesa_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
1301 NULL);
1302 }
1303
1304
1305 void GLAPIENTRY
1306 _mesa_MultiDrawElementsBaseVertex(GLenum mode,
1307 const GLsizei *count, GLenum type,
1308 const GLvoid * const *indices,
1309 GLsizei primcount,
1310 const GLsizei *basevertex)
1311 {
1312 GET_CURRENT_CONTEXT(ctx);
1313
1314 FLUSH_FOR_DRAW(ctx);
1315
1316 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1317
1318 if (_mesa_is_no_error_enabled(ctx)) {
1319 if (ctx->NewState)
1320 _mesa_update_state(ctx);
1321 } else {
1322 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1323 primcount))
1324 return;
1325 }
1326
1327 if (skip_validated_draw(ctx))
1328 return;
1329
1330 _mesa_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
1331 basevertex);
1332 }
1333
1334
1335 /**
1336 * Draw a GL primitive using a vertex count obtained from transform feedback.
1337 * \param mode the type of GL primitive to draw
1338 * \param obj the transform feedback object to use
1339 * \param stream index of the transform feedback stream from which to
1340 * get the primitive count.
1341 * \param numInstances number of instances to draw
1342 */
1343 static void
1344 _mesa_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
1345 struct gl_transform_feedback_object *obj,
1346 GLuint stream, GLuint numInstances)
1347 {
1348 struct _mesa_prim prim;
1349
1350 FLUSH_FOR_DRAW(ctx);
1351
1352 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1353
1354 if (_mesa_is_no_error_enabled(ctx)) {
1355 if (ctx->NewState)
1356 _mesa_update_state(ctx);
1357 } else {
1358 if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream,
1359 numInstances)) {
1360 return;
1361 }
1362 }
1363
1364 if (ctx->Driver.GetTransformFeedbackVertexCount &&
1365 (ctx->Const.AlwaysUseGetTransformFeedbackVertexCount ||
1366 !_mesa_all_varyings_in_vbos(ctx->Array.VAO))) {
1367 GLsizei n =
1368 ctx->Driver.GetTransformFeedbackVertexCount(ctx, obj, stream);
1369 _mesa_draw_arrays(ctx, mode, 0, n, numInstances, 0, 0);
1370 return;
1371 }
1372
1373 if (skip_validated_draw(ctx))
1374 return;
1375
1376 /* init most fields to zero */
1377 memset(&prim, 0, sizeof(prim));
1378 prim.begin = 1;
1379 prim.end = 1;
1380 prim.mode = mode;
1381 prim.num_instances = numInstances;
1382 prim.base_instance = 0;
1383
1384 /* Maybe we should do some primitive splitting for primitive restart
1385 * (like in DrawArrays), but we have no way to know how many vertices
1386 * will be rendered. */
1387
1388 ctx->Driver.Draw(ctx, &prim, 1, NULL, GL_FALSE, 0, ~0, obj, stream, NULL);
1389
1390 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1391 _mesa_flush(ctx);
1392 }
1393 }
1394
1395
1396 /**
1397 * Like DrawArrays, but take the count from a transform feedback object.
1398 * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc.
1399 * \param name the transform feedback object
1400 * User still has to setup of the vertex attribute info with
1401 * glVertexPointer, glColorPointer, etc.
1402 * Part of GL_ARB_transform_feedback2.
1403 */
1404 void GLAPIENTRY
1405 _mesa_DrawTransformFeedback(GLenum mode, GLuint name)
1406 {
1407 GET_CURRENT_CONTEXT(ctx);
1408 struct gl_transform_feedback_object *obj =
1409 _mesa_lookup_transform_feedback_object(ctx, name);
1410
1411 if (MESA_VERBOSE & VERBOSE_DRAW)
1412 _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n",
1413 _mesa_enum_to_string(mode), name);
1414
1415 _mesa_draw_transform_feedback(ctx, mode, obj, 0, 1);
1416 }
1417
1418
1419 static void GLAPIENTRY
1420 _mesa_exec_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream)
1421 {
1422 GET_CURRENT_CONTEXT(ctx);
1423 struct gl_transform_feedback_object *obj =
1424 _mesa_lookup_transform_feedback_object(ctx, name);
1425
1426 if (MESA_VERBOSE & VERBOSE_DRAW)
1427 _mesa_debug(ctx, "glDrawTransformFeedbackStream(%s, %u, %u)\n",
1428 _mesa_enum_to_string(mode), name, stream);
1429
1430 _mesa_draw_transform_feedback(ctx, mode, obj, stream, 1);
1431 }
1432
1433
1434 static void GLAPIENTRY
1435 _mesa_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name,
1436 GLsizei primcount)
1437 {
1438 GET_CURRENT_CONTEXT(ctx);
1439 struct gl_transform_feedback_object *obj =
1440 _mesa_lookup_transform_feedback_object(ctx, name);
1441
1442 if (MESA_VERBOSE & VERBOSE_DRAW)
1443 _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n",
1444 _mesa_enum_to_string(mode), name);
1445
1446 _mesa_draw_transform_feedback(ctx, mode, obj, 0, primcount);
1447 }
1448
1449
1450 static void GLAPIENTRY
1451 _mesa_exec_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name,
1452 GLuint stream,
1453 GLsizei primcount)
1454 {
1455 GET_CURRENT_CONTEXT(ctx);
1456 struct gl_transform_feedback_object *obj =
1457 _mesa_lookup_transform_feedback_object(ctx, name);
1458
1459 if (MESA_VERBOSE & VERBOSE_DRAW)
1460 _mesa_debug(ctx, "glDrawTransformFeedbackStreamInstanced"
1461 "(%s, %u, %u, %i)\n",
1462 _mesa_enum_to_string(mode), name, stream, primcount);
1463
1464 _mesa_draw_transform_feedback(ctx, mode, obj, stream, primcount);
1465 }
1466
1467
1468 static void
1469 _mesa_validated_drawarraysindirect(struct gl_context *ctx,
1470 GLenum mode, const GLvoid *indirect)
1471 {
1472 ctx->Driver.DrawIndirect(ctx, mode,
1473 ctx->DrawIndirectBuffer, (GLsizeiptr) indirect,
1474 1 /* draw_count */ , 16 /* stride */ ,
1475 NULL, 0, NULL);
1476
1477 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1478 _mesa_flush(ctx);
1479 }
1480
1481
1482 static void
1483 _mesa_validated_multidrawarraysindirect(struct gl_context *ctx,
1484 GLenum mode,
1485 const GLvoid *indirect,
1486 GLsizei primcount, GLsizei stride)
1487 {
1488 GLsizeiptr offset = (GLsizeiptr) indirect;
1489
1490 if (primcount == 0)
1491 return;
1492
1493 ctx->Driver.DrawIndirect(ctx, mode, ctx->DrawIndirectBuffer, offset,
1494 primcount, stride, NULL, 0, NULL);
1495
1496 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1497 _mesa_flush(ctx);
1498 }
1499
1500
1501 static void
1502 _mesa_validated_drawelementsindirect(struct gl_context *ctx,
1503 GLenum mode, GLenum type,
1504 const GLvoid *indirect)
1505 {
1506 struct _mesa_index_buffer ib;
1507
1508 ib.count = 0; /* unknown */
1509 ib.index_size = sizeof_ib_type(type);
1510 ib.obj = ctx->Array.VAO->IndexBufferObj;
1511 ib.ptr = NULL;
1512
1513 ctx->Driver.DrawIndirect(ctx, mode,
1514 ctx->DrawIndirectBuffer, (GLsizeiptr) indirect,
1515 1 /* draw_count */ , 20 /* stride */ ,
1516 NULL, 0, &ib);
1517
1518 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1519 _mesa_flush(ctx);
1520 }
1521
1522
1523 static void
1524 _mesa_validated_multidrawelementsindirect(struct gl_context *ctx,
1525 GLenum mode, GLenum type,
1526 const GLvoid *indirect,
1527 GLsizei primcount, GLsizei stride)
1528 {
1529 struct _mesa_index_buffer ib;
1530 GLsizeiptr offset = (GLsizeiptr) indirect;
1531
1532 if (primcount == 0)
1533 return;
1534
1535 /* NOTE: IndexBufferObj is guaranteed to be a VBO. */
1536
1537 ib.count = 0; /* unknown */
1538 ib.index_size = sizeof_ib_type(type);
1539 ib.obj = ctx->Array.VAO->IndexBufferObj;
1540 ib.ptr = NULL;
1541
1542 ctx->Driver.DrawIndirect(ctx, mode,
1543 ctx->DrawIndirectBuffer, offset,
1544 primcount, stride, NULL, 0, &ib);
1545
1546 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1547 _mesa_flush(ctx);
1548 }
1549
1550
1551 /**
1552 * Like [Multi]DrawArrays/Elements, but they take most arguments from
1553 * a buffer object.
1554 */
1555 static void GLAPIENTRY
1556 _mesa_exec_DrawArraysIndirect(GLenum mode, const GLvoid *indirect)
1557 {
1558 GET_CURRENT_CONTEXT(ctx);
1559
1560 if (MESA_VERBOSE & VERBOSE_DRAW)
1561 _mesa_debug(ctx, "glDrawArraysIndirect(%s, %p)\n",
1562 _mesa_enum_to_string(mode), indirect);
1563
1564 /* From the ARB_draw_indirect spec:
1565 *
1566 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
1567 * compatibility profile, this indicates that DrawArraysIndirect and
1568 * DrawElementsIndirect are to source their arguments directly from the
1569 * pointer passed as their <indirect> parameters."
1570 */
1571 if (ctx->API == API_OPENGL_COMPAT &&
1572 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
1573 DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) indirect;
1574
1575 _mesa_exec_DrawArraysInstancedBaseInstance(mode, cmd->first, cmd->count,
1576 cmd->primCount,
1577 cmd->baseInstance);
1578 return;
1579 }
1580
1581 FLUSH_FOR_DRAW(ctx);
1582
1583 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1584
1585 if (_mesa_is_no_error_enabled(ctx)) {
1586 if (ctx->NewState)
1587 _mesa_update_state(ctx);
1588 } else {
1589 if (!_mesa_validate_DrawArraysIndirect(ctx, mode, indirect))
1590 return;
1591 }
1592
1593 if (skip_validated_draw(ctx))
1594 return;
1595
1596 _mesa_validated_drawarraysindirect(ctx, mode, indirect);
1597 }
1598
1599
1600 static void GLAPIENTRY
1601 _mesa_exec_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1602 {
1603 GET_CURRENT_CONTEXT(ctx);
1604
1605 if (MESA_VERBOSE & VERBOSE_DRAW)
1606 _mesa_debug(ctx, "glDrawElementsIndirect(%s, %s, %p)\n",
1607 _mesa_enum_to_string(mode),
1608 _mesa_enum_to_string(type), indirect);
1609
1610 /* From the ARB_draw_indirect spec:
1611 *
1612 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
1613 * compatibility profile, this indicates that DrawArraysIndirect and
1614 * DrawElementsIndirect are to source their arguments directly from the
1615 * pointer passed as their <indirect> parameters."
1616 */
1617 if (ctx->API == API_OPENGL_COMPAT &&
1618 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
1619 /*
1620 * Unlike regular DrawElementsInstancedBaseVertex commands, the indices
1621 * may not come from a client array and must come from an index buffer.
1622 * If no element array buffer is bound, an INVALID_OPERATION error is
1623 * generated.
1624 */
1625 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) {
1626 _mesa_error(ctx, GL_INVALID_OPERATION,
1627 "glDrawElementsIndirect(no buffer bound "
1628 "to GL_ELEMENT_ARRAY_BUFFER)");
1629 } else {
1630 DrawElementsIndirectCommand *cmd =
1631 (DrawElementsIndirectCommand *) indirect;
1632
1633 /* Convert offset to pointer */
1634 void *offset = (void *)
1635 (uintptr_t)((cmd->firstIndex * _mesa_sizeof_type(type)) & 0xffffffffUL);
1636
1637 _mesa_exec_DrawElementsInstancedBaseVertexBaseInstance(mode, cmd->count,
1638 type, offset,
1639 cmd->primCount,
1640 cmd->baseVertex,
1641 cmd->baseInstance);
1642 }
1643
1644 return;
1645 }
1646
1647 FLUSH_FOR_DRAW(ctx);
1648
1649 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1650
1651 if (_mesa_is_no_error_enabled(ctx)) {
1652 if (ctx->NewState)
1653 _mesa_update_state(ctx);
1654 } else {
1655 if (!_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect))
1656 return;
1657 }
1658
1659 if (skip_validated_draw(ctx))
1660 return;
1661
1662 _mesa_validated_drawelementsindirect(ctx, mode, type, indirect);
1663 }
1664
1665
1666 static void GLAPIENTRY
1667 _mesa_exec_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect,
1668 GLsizei primcount, GLsizei stride)
1669 {
1670 GET_CURRENT_CONTEXT(ctx);
1671
1672 if (MESA_VERBOSE & VERBOSE_DRAW)
1673 _mesa_debug(ctx, "glMultiDrawArraysIndirect(%s, %p, %i, %i)\n",
1674 _mesa_enum_to_string(mode), indirect, primcount, stride);
1675
1676 /* If <stride> is zero, the array elements are treated as tightly packed. */
1677 if (stride == 0)
1678 stride = sizeof(DrawArraysIndirectCommand);
1679
1680 /* From the ARB_draw_indirect spec:
1681 *
1682 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
1683 * compatibility profile, this indicates that DrawArraysIndirect and
1684 * DrawElementsIndirect are to source their arguments directly from the
1685 * pointer passed as their <indirect> parameters."
1686 */
1687 if (ctx->API == API_OPENGL_COMPAT &&
1688 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
1689
1690 if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
1691 "glMultiDrawArraysIndirect"))
1692 return;
1693
1694 const uint8_t *ptr = (const uint8_t *) indirect;
1695 for (unsigned i = 0; i < primcount; i++) {
1696 DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) ptr;
1697 _mesa_exec_DrawArraysInstancedBaseInstance(mode, cmd->first,
1698 cmd->count, cmd->primCount,
1699 cmd->baseInstance);
1700
1701 if (stride == 0) {
1702 ptr += sizeof(DrawArraysIndirectCommand);
1703 } else {
1704 ptr += stride;
1705 }
1706 }
1707
1708 return;
1709 }
1710
1711 FLUSH_FOR_DRAW(ctx);
1712
1713 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1714
1715 if (_mesa_is_no_error_enabled(ctx)) {
1716 if (ctx->NewState)
1717 _mesa_update_state(ctx);
1718 } else {
1719 if (!_mesa_validate_MultiDrawArraysIndirect(ctx, mode, indirect,
1720 primcount, stride))
1721 return;
1722 }
1723
1724 if (skip_validated_draw(ctx))
1725 return;
1726
1727 _mesa_validated_multidrawarraysindirect(ctx, mode, indirect,
1728 primcount, stride);
1729 }
1730
1731
1732 static void GLAPIENTRY
1733 _mesa_exec_MultiDrawElementsIndirect(GLenum mode, GLenum type,
1734 const GLvoid *indirect,
1735 GLsizei primcount, GLsizei stride)
1736 {
1737 GET_CURRENT_CONTEXT(ctx);
1738
1739 if (MESA_VERBOSE & VERBOSE_DRAW)
1740 _mesa_debug(ctx, "glMultiDrawElementsIndirect(%s, %s, %p, %i, %i)\n",
1741 _mesa_enum_to_string(mode),
1742 _mesa_enum_to_string(type), indirect, primcount, stride);
1743
1744 /* If <stride> is zero, the array elements are treated as tightly packed. */
1745 if (stride == 0)
1746 stride = sizeof(DrawElementsIndirectCommand);
1747
1748
1749 /* From the ARB_draw_indirect spec:
1750 *
1751 * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
1752 * compatibility profile, this indicates that DrawArraysIndirect and
1753 * DrawElementsIndirect are to source their arguments directly from the
1754 * pointer passed as their <indirect> parameters."
1755 */
1756 if (ctx->API == API_OPENGL_COMPAT &&
1757 !_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
1758 /*
1759 * Unlike regular DrawElementsInstancedBaseVertex commands, the indices
1760 * may not come from a client array and must come from an index buffer.
1761 * If no element array buffer is bound, an INVALID_OPERATION error is
1762 * generated.
1763 */
1764 if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) {
1765 _mesa_error(ctx, GL_INVALID_OPERATION,
1766 "glMultiDrawElementsIndirect(no buffer bound "
1767 "to GL_ELEMENT_ARRAY_BUFFER)");
1768
1769 return;
1770 }
1771
1772 if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
1773 "glMultiDrawArraysIndirect"))
1774 return;
1775
1776 const uint8_t *ptr = (const uint8_t *) indirect;
1777 for (unsigned i = 0; i < primcount; i++) {
1778 _mesa_exec_DrawElementsIndirect(mode, type, ptr);
1779
1780 if (stride == 0) {
1781 ptr += sizeof(DrawElementsIndirectCommand);
1782 } else {
1783 ptr += stride;
1784 }
1785 }
1786
1787 return;
1788 }
1789
1790 FLUSH_FOR_DRAW(ctx);
1791
1792 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1793
1794 if (_mesa_is_no_error_enabled(ctx)) {
1795 if (ctx->NewState)
1796 _mesa_update_state(ctx);
1797 } else {
1798 if (!_mesa_validate_MultiDrawElementsIndirect(ctx, mode, type, indirect,
1799 primcount, stride))
1800 return;
1801 }
1802
1803 if (skip_validated_draw(ctx))
1804 return;
1805
1806 _mesa_validated_multidrawelementsindirect(ctx, mode, type, indirect,
1807 primcount, stride);
1808 }
1809
1810
1811 static void
1812 _mesa_validated_multidrawarraysindirectcount(struct gl_context *ctx,
1813 GLenum mode,
1814 GLintptr indirect,
1815 GLintptr drawcount_offset,
1816 GLsizei maxdrawcount,
1817 GLsizei stride)
1818 {
1819 GLsizeiptr offset = indirect;
1820
1821 if (maxdrawcount == 0)
1822 return;
1823
1824 ctx->Driver.DrawIndirect(ctx, mode,
1825 ctx->DrawIndirectBuffer, offset,
1826 maxdrawcount, stride,
1827 ctx->ParameterBuffer, drawcount_offset, NULL);
1828
1829 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1830 _mesa_flush(ctx);
1831 }
1832
1833
1834 static void
1835 _mesa_validated_multidrawelementsindirectcount(struct gl_context *ctx,
1836 GLenum mode, GLenum type,
1837 GLintptr indirect,
1838 GLintptr drawcount_offset,
1839 GLsizei maxdrawcount,
1840 GLsizei stride)
1841 {
1842 struct _mesa_index_buffer ib;
1843 GLsizeiptr offset = (GLsizeiptr) indirect;
1844
1845 if (maxdrawcount == 0)
1846 return;
1847
1848 /* NOTE: IndexBufferObj is guaranteed to be a VBO. */
1849
1850 ib.count = 0; /* unknown */
1851 ib.index_size = sizeof_ib_type(type);
1852 ib.obj = ctx->Array.VAO->IndexBufferObj;
1853 ib.ptr = NULL;
1854
1855 ctx->Driver.DrawIndirect(ctx, mode,
1856 ctx->DrawIndirectBuffer, offset,
1857 maxdrawcount, stride,
1858 ctx->ParameterBuffer, drawcount_offset, &ib);
1859
1860 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
1861 _mesa_flush(ctx);
1862 }
1863
1864
1865 static void GLAPIENTRY
1866 _mesa_exec_MultiDrawArraysIndirectCount(GLenum mode, GLintptr indirect,
1867 GLintptr drawcount_offset,
1868 GLsizei maxdrawcount, GLsizei stride)
1869 {
1870 GET_CURRENT_CONTEXT(ctx);
1871
1872 if (MESA_VERBOSE & VERBOSE_DRAW)
1873 _mesa_debug(ctx, "glMultiDrawArraysIndirectCountARB"
1874 "(%s, %lx, %lx, %i, %i)\n",
1875 _mesa_enum_to_string(mode),
1876 (unsigned long) indirect, (unsigned long) drawcount_offset,
1877 maxdrawcount, stride);
1878
1879 /* If <stride> is zero, the array elements are treated as tightly packed. */
1880 if (stride == 0)
1881 stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */
1882
1883 FLUSH_FOR_DRAW(ctx);
1884
1885 _mesa_set_draw_vao(ctx, ctx->Array.VAO, enabled_filter(ctx));
1886
1887 if (_mesa_is_no_error_enabled(ctx)) {
1888 if (ctx->NewState)
1889 _mesa_update_state(ctx);
1890 } else {
1891 if (!_mesa_validate_MultiDrawArraysIndirectCount(ctx, mode,
1892 indirect,
1893 drawcount_offset,
1894 maxdrawcount, stride))
1895 return;
1896 }
1897
1898 if (skip_validated_draw(ctx))
1899 return;
1900
1901 _mesa_validated_multidrawarraysindirectcount(ctx, mode, indirect,
1902 drawcount_offset,
1903 maxdrawcount, stride);
1904 }
1905
1906
1907 static void GLAPIENTRY
1908 _mesa_exec_MultiDrawElementsIndirectCount(GLenum mode, GLenum type,
1909 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, "glMultiDrawElementsIndirectCountARB"
1917 "(%s, %s, %lx, %lx, %i, %i)\n",
1918 _mesa_enum_to_string(mode), _mesa_enum_to_string(type),
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 = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */
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_MultiDrawElementsIndirectCount(ctx, mode, type,
1935 indirect,
1936 drawcount_offset,
1937 maxdrawcount, stride))
1938 return;
1939 }
1940
1941 if (skip_validated_draw(ctx))
1942 return;
1943
1944 _mesa_validated_multidrawelementsindirectcount(ctx, mode, type, indirect,
1945 drawcount_offset, maxdrawcount,
1946 stride);
1947 }
1948
1949
1950 /**
1951 * Initialize the dispatch table with the VBO functions for drawing.
1952 */
1953 void
1954 _mesa_initialize_exec_dispatch(const struct gl_context *ctx,
1955 struct _glapi_table *exec)
1956 {
1957 SET_DrawArrays(exec, _mesa_DrawArrays);
1958 SET_DrawElements(exec, _mesa_DrawElements);
1959
1960 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1961 SET_DrawRangeElements(exec, _mesa_DrawRangeElements);
1962 }
1963
1964 SET_MultiDrawArrays(exec, _mesa_exec_MultiDrawArrays);
1965 SET_MultiDrawElementsEXT(exec, _mesa_MultiDrawElements);
1966
1967 if (ctx->API == API_OPENGL_COMPAT) {
1968 SET_Rectf(exec, _mesa_exec_Rectf);
1969 SET_EvalMesh1(exec, _mesa_exec_EvalMesh1);
1970 SET_EvalMesh2(exec, _mesa_exec_EvalMesh2);
1971 }
1972
1973 if (ctx->API != API_OPENGLES &&
1974 ctx->Extensions.ARB_draw_elements_base_vertex) {
1975 SET_DrawElementsBaseVertex(exec, _mesa_DrawElementsBaseVertex);
1976 SET_MultiDrawElementsBaseVertex(exec,
1977 _mesa_MultiDrawElementsBaseVertex);
1978
1979 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1980 SET_DrawRangeElementsBaseVertex(exec,
1981 _mesa_DrawRangeElementsBaseVertex);
1982 SET_DrawElementsInstancedBaseVertex(exec,
1983 _mesa_exec_DrawElementsInstancedBaseVertex);
1984 }
1985 }
1986
1987 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1988 SET_DrawArraysInstancedBaseInstance(exec,
1989 _mesa_exec_DrawArraysInstancedBaseInstance);
1990 SET_DrawElementsInstancedBaseInstance(exec,
1991 _mesa_exec_DrawElementsInstancedBaseInstance);
1992 SET_DrawElementsInstancedBaseVertexBaseInstance(exec,
1993 _mesa_exec_DrawElementsInstancedBaseVertexBaseInstance);
1994 }
1995
1996 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) {
1997 SET_DrawArraysIndirect(exec, _mesa_exec_DrawArraysIndirect);
1998 SET_DrawElementsIndirect(exec, _mesa_exec_DrawElementsIndirect);
1999 }
2000
2001 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
2002 SET_DrawArraysInstancedARB(exec, _mesa_DrawArraysInstanced);
2003 SET_DrawElementsInstancedARB(exec, _mesa_exec_DrawElementsInstanced);
2004 }
2005
2006 if (_mesa_is_desktop_gl(ctx)) {
2007 SET_DrawTransformFeedback(exec, _mesa_DrawTransformFeedback);
2008 SET_DrawTransformFeedbackStream(exec,
2009 _mesa_exec_DrawTransformFeedbackStream);
2010 SET_DrawTransformFeedbackInstanced(exec,
2011 _mesa_exec_DrawTransformFeedbackInstanced);
2012 SET_DrawTransformFeedbackStreamInstanced(exec,
2013 _mesa_exec_DrawTransformFeedbackStreamInstanced);
2014 SET_MultiDrawArraysIndirect(exec, _mesa_exec_MultiDrawArraysIndirect);
2015 SET_MultiDrawElementsIndirect(exec, _mesa_exec_MultiDrawElementsIndirect);
2016 SET_MultiDrawArraysIndirectCountARB(exec,
2017 _mesa_exec_MultiDrawArraysIndirectCount);
2018 SET_MultiDrawElementsIndirectCountARB(exec,
2019 _mesa_exec_MultiDrawElementsIndirectCount);
2020 }
2021 }
2022
2023
2024
2025 /* GL_IBM_multimode_draw_arrays */
2026 void GLAPIENTRY
2027 _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
2028 const GLsizei * count,
2029 GLsizei primcount, GLint modestride )
2030 {
2031 GET_CURRENT_CONTEXT(ctx);
2032 GLint i;
2033
2034 FLUSH_VERTICES(ctx, 0);
2035
2036 for ( i = 0 ; i < primcount ; i++ ) {
2037 if ( count[i] > 0 ) {
2038 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
2039 CALL_DrawArrays(ctx->CurrentServerDispatch, ( m, first[i], count[i] ));
2040 }
2041 }
2042 }
2043
2044
2045 /* GL_IBM_multimode_draw_arrays */
2046 void GLAPIENTRY
2047 _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
2048 GLenum type, const GLvoid * const * indices,
2049 GLsizei primcount, GLint modestride )
2050 {
2051 GET_CURRENT_CONTEXT(ctx);
2052 GLint i;
2053
2054 FLUSH_VERTICES(ctx, 0);
2055
2056 /* XXX not sure about ARB_vertex_buffer_object handling here */
2057
2058 for ( i = 0 ; i < primcount ; i++ ) {
2059 if ( count[i] > 0 ) {
2060 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
2061 CALL_DrawElements(ctx->CurrentServerDispatch, ( m, count[i], type,
2062 indices[i] ));
2063 }
2064 }
2065 }
2066
2067
2068 /*
2069 * Helper function for _mesa_draw_indirect below that additionally takes a zero
2070 * initialized array of _mesa_prim scratch space memory as the last argument.
2071 */
2072 static void
2073 draw_indirect(struct gl_context *ctx, GLuint mode,
2074 struct gl_buffer_object *indirect_data,
2075 GLsizeiptr indirect_offset, unsigned draw_count,
2076 unsigned stride,
2077 struct gl_buffer_object *indirect_draw_count_buffer,
2078 GLsizeiptr indirect_draw_count_offset,
2079 const struct _mesa_index_buffer *ib,
2080 struct _mesa_prim *prim)
2081 {
2082 prim[0].begin = 1;
2083 prim[draw_count - 1].end = 1;
2084 for (unsigned i = 0; i < draw_count; ++i, indirect_offset += stride) {
2085 prim[i].mode = mode;
2086 prim[i].indexed = !!ib;
2087 prim[i].indirect_offset = indirect_offset;
2088 prim[i].draw_id = i;
2089 }
2090
2091 /* This should always be true at this time */
2092 assert(indirect_data == ctx->DrawIndirectBuffer);
2093
2094 ctx->Driver.Draw(ctx, prim, draw_count, ib, false, 0u, ~0u,
2095 NULL, 0, indirect_data);
2096 }
2097
2098
2099 /*
2100 * Function to be put into dd_function_table::DrawIndirect as fallback.
2101 * Calls into dd_function_table::Draw past adapting call arguments.
2102 * See dd_function_table::DrawIndirect for call argument documentation.
2103 */
2104 void
2105 _mesa_draw_indirect(struct gl_context *ctx, GLuint mode,
2106 struct gl_buffer_object *indirect_data,
2107 GLsizeiptr indirect_offset, unsigned draw_count,
2108 unsigned stride,
2109 struct gl_buffer_object *indirect_draw_count_buffer,
2110 GLsizeiptr indirect_draw_count_offset,
2111 const struct _mesa_index_buffer *ib)
2112 {
2113 /* Use alloca for the prim space if we are somehow in bounds. */
2114 if (draw_count*sizeof(struct _mesa_prim) < 1024) {
2115 struct _mesa_prim *space = alloca(draw_count*sizeof(struct _mesa_prim));
2116 memset(space, 0, draw_count*sizeof(struct _mesa_prim));
2117
2118 draw_indirect(ctx, mode, indirect_data, indirect_offset, draw_count,
2119 stride, indirect_draw_count_buffer,
2120 indirect_draw_count_offset, ib, space);
2121 } else {
2122 struct _mesa_prim *space = calloc(draw_count, sizeof(struct _mesa_prim));
2123 if (space == NULL) {
2124 _mesa_error(ctx, GL_OUT_OF_MEMORY, "gl%sDraw%sIndirect%s",
2125 (draw_count > 1) ? "Multi" : "",
2126 ib ? "Elements" : "Arrays",
2127 indirect_data ? "CountARB" : "");
2128 return;
2129 }
2130
2131 draw_indirect(ctx, mode, indirect_data, indirect_offset, draw_count,
2132 stride, indirect_draw_count_buffer,
2133 indirect_draw_count_offset, ib, space);
2134
2135 free(space);
2136 }
2137 }