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