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