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