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