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