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