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