18011ec125e7e96f60bbfbefc08e2792f55d875c
[mesa.git] / src / mesa / vbo / vbo_exec_array.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
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 TUNGSTEN GRAPHICS 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_bufferobj_mapped(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_bufferobj_mapped(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 = ctx->Array._RestartIndex;
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 }
106
107 switch (ib->type) {
108 case GL_UNSIGNED_INT: {
109 const GLuint *ui_indices = (const GLuint *)indices;
110 GLuint max_ui = 0;
111 GLuint min_ui = ~0U;
112 if (restart) {
113 for (i = 0; i < count; i++) {
114 if (ui_indices[i] != restartIndex) {
115 if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
116 if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
117 }
118 }
119 }
120 else {
121 for (i = 0; i < count; i++) {
122 if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
123 if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
124 }
125 }
126 *min_index = min_ui;
127 *max_index = max_ui;
128 break;
129 }
130 case GL_UNSIGNED_SHORT: {
131 const GLushort *us_indices = (const GLushort *)indices;
132 GLuint max_us = 0;
133 GLuint min_us = ~0U;
134 if (restart) {
135 for (i = 0; i < count; i++) {
136 if (us_indices[i] != restartIndex) {
137 if (us_indices[i] > max_us) max_us = us_indices[i];
138 if (us_indices[i] < min_us) min_us = us_indices[i];
139 }
140 }
141 }
142 else {
143 for (i = 0; i < count; i++) {
144 if (us_indices[i] > max_us) max_us = us_indices[i];
145 if (us_indices[i] < min_us) min_us = us_indices[i];
146 }
147 }
148 *min_index = min_us;
149 *max_index = max_us;
150 break;
151 }
152 case GL_UNSIGNED_BYTE: {
153 const GLubyte *ub_indices = (const GLubyte *)indices;
154 GLuint max_ub = 0;
155 GLuint min_ub = ~0U;
156 if (restart) {
157 for (i = 0; i < count; i++) {
158 if (ub_indices[i] != restartIndex) {
159 if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
160 if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
161 }
162 }
163 }
164 else {
165 for (i = 0; i < count; i++) {
166 if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
167 if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
168 }
169 }
170 *min_index = min_ub;
171 *max_index = max_ub;
172 break;
173 }
174 default:
175 assert(0);
176 break;
177 }
178
179 if (_mesa_is_bufferobj(ib->obj)) {
180 ctx->Driver.UnmapBuffer(ctx, ib->obj);
181 }
182 }
183
184 /**
185 * Compute min and max elements for nr_prims
186 */
187 void
188 vbo_get_minmax_indices(struct gl_context *ctx,
189 const struct _mesa_prim *prims,
190 const struct _mesa_index_buffer *ib,
191 GLuint *min_index,
192 GLuint *max_index,
193 GLuint nr_prims)
194 {
195 GLuint tmp_min, tmp_max;
196 GLuint i;
197 GLuint count;
198
199 *min_index = ~0;
200 *max_index = 0;
201
202 for (i = 0; i < nr_prims; i++) {
203 const struct _mesa_prim *start_prim;
204
205 start_prim = &prims[i];
206 count = start_prim->count;
207 /* Do combination if possible to reduce map/unmap count */
208 while ((i + 1 < nr_prims) &&
209 (prims[i].start + prims[i].count == prims[i+1].start)) {
210 count += prims[i+1].count;
211 i++;
212 }
213 vbo_get_minmax_index(ctx, start_prim, ib, &tmp_min, &tmp_max, count);
214 *min_index = MIN2(*min_index, tmp_min);
215 *max_index = MAX2(*max_index, tmp_max);
216 }
217 }
218
219
220 /**
221 * Check that element 'j' of the array has reasonable data.
222 * Map VBO if needed.
223 * For debugging purposes; not normally used.
224 */
225 static void
226 check_array_data(struct gl_context *ctx, struct gl_client_array *array,
227 GLuint attrib, GLuint j)
228 {
229 if (array->Enabled) {
230 const void *data = array->Ptr;
231 if (_mesa_is_bufferobj(array->BufferObj)) {
232 if (!array->BufferObj->Pointer) {
233 /* need to map now */
234 array->BufferObj->Pointer =
235 ctx->Driver.MapBufferRange(ctx, 0, array->BufferObj->Size,
236 GL_MAP_READ_BIT, array->BufferObj);
237 }
238 data = ADD_POINTERS(data, array->BufferObj->Pointer);
239 }
240 switch (array->Type) {
241 case GL_FLOAT:
242 {
243 GLfloat *f = (GLfloat *) ((GLubyte *) data + array->StrideB * j);
244 GLint k;
245 for (k = 0; k < array->Size; k++) {
246 if (IS_INF_OR_NAN(f[k]) ||
247 f[k] >= 1.0e20 || f[k] <= -1.0e10) {
248 printf("Bad array data:\n");
249 printf(" Element[%u].%u = %f\n", j, k, f[k]);
250 printf(" Array %u at %p\n", attrib, (void* ) array);
251 printf(" Type 0x%x, Size %d, Stride %d\n",
252 array->Type, array->Size, array->Stride);
253 printf(" Address/offset %p in Buffer Object %u\n",
254 array->Ptr, array->BufferObj->Name);
255 f[k] = 1.0; /* XXX replace the bad value! */
256 }
257 /*assert(!IS_INF_OR_NAN(f[k]));*/
258 }
259 }
260 break;
261 default:
262 ;
263 }
264 }
265 }
266
267
268 /**
269 * Unmap the buffer object referenced by given array, if mapped.
270 */
271 static void
272 unmap_array_buffer(struct gl_context *ctx, struct gl_client_array *array)
273 {
274 if (array->Enabled &&
275 _mesa_is_bufferobj(array->BufferObj) &&
276 _mesa_bufferobj_mapped(array->BufferObj)) {
277 ctx->Driver.UnmapBuffer(ctx, array->BufferObj);
278 }
279 }
280
281
282 /**
283 * Examine the array's data for NaNs, etc.
284 * For debug purposes; not normally used.
285 */
286 static void
287 check_draw_elements_data(struct gl_context *ctx, GLsizei count, GLenum elemType,
288 const void *elements, GLint basevertex)
289 {
290 struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
291 const void *elemMap;
292 GLint i, k;
293
294 if (_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj)) {
295 elemMap = ctx->Driver.MapBufferRange(ctx, 0,
296 ctx->Array.ArrayObj->ElementArrayBufferObj->Size,
297 GL_MAP_READ_BIT,
298 ctx->Array.ArrayObj->ElementArrayBufferObj);
299 elements = ADD_POINTERS(elements, elemMap);
300 }
301
302 for (i = 0; i < count; i++) {
303 GLuint j;
304
305 /* j = element[i] */
306 switch (elemType) {
307 case GL_UNSIGNED_BYTE:
308 j = ((const GLubyte *) elements)[i];
309 break;
310 case GL_UNSIGNED_SHORT:
311 j = ((const GLushort *) elements)[i];
312 break;
313 case GL_UNSIGNED_INT:
314 j = ((const GLuint *) elements)[i];
315 break;
316 default:
317 assert(0);
318 }
319
320 /* check element j of each enabled array */
321 for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) {
322 check_array_data(ctx, &arrayObj->VertexAttrib[k], k, j);
323 }
324 }
325
326 if (_mesa_is_bufferobj(arrayObj->ElementArrayBufferObj)) {
327 ctx->Driver.UnmapBuffer(ctx, ctx->Array.ArrayObj->ElementArrayBufferObj);
328 }
329
330 for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) {
331 unmap_array_buffer(ctx, &arrayObj->VertexAttrib[k]);
332 }
333 }
334
335
336 /**
337 * Check array data, looking for NaNs, etc.
338 */
339 static void
340 check_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count)
341 {
342 /* TO DO */
343 }
344
345
346 /**
347 * Print info/data for glDrawArrays(), for debugging.
348 */
349 static void
350 print_draw_arrays(struct gl_context *ctx,
351 GLenum mode, GLint start, GLsizei count)
352 {
353 struct vbo_context *vbo = vbo_context(ctx);
354 struct vbo_exec_context *exec = &vbo->exec;
355 struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
356 int i;
357
358 printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n",
359 mode, start, count);
360
361 for (i = 0; i < 32; i++) {
362 struct gl_buffer_object *bufObj = exec->array.inputs[i]->BufferObj;
363 GLuint bufName = bufObj->Name;
364 GLint stride = exec->array.inputs[i]->Stride;
365 printf("attr %2d: size %d stride %d enabled %d "
366 "ptr %p Bufobj %u\n",
367 i,
368 exec->array.inputs[i]->Size,
369 stride,
370 /*exec->array.inputs[i]->Enabled,*/
371 arrayObj->VertexAttrib[VERT_ATTRIB_FF(i)].Enabled,
372 exec->array.inputs[i]->Ptr,
373 bufName);
374
375 if (bufName) {
376 GLubyte *p = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size,
377 GL_MAP_READ_BIT, bufObj);
378 int offset = (int) (GLintptr) exec->array.inputs[i]->Ptr;
379 float *f = (float *) (p + offset);
380 int *k = (int *) f;
381 int i;
382 int n = (count * stride) / 4;
383 if (n > 32)
384 n = 32;
385 printf(" Data at offset %d:\n", offset);
386 for (i = 0; i < n; i++) {
387 printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]);
388 }
389 ctx->Driver.UnmapBuffer(ctx, bufObj);
390 }
391 }
392 }
393
394
395 /**
396 * Set the vbo->exec->inputs[] pointers to point to the enabled
397 * vertex arrays. This depends on the current vertex program/shader
398 * being executed because of whether or not generic vertex arrays
399 * alias the conventional vertex arrays.
400 * For arrays that aren't enabled, we set the input[attrib] pointer
401 * to point at a zero-stride current value "array".
402 */
403 static void
404 recalculate_input_bindings(struct gl_context *ctx)
405 {
406 struct vbo_context *vbo = vbo_context(ctx);
407 struct vbo_exec_context *exec = &vbo->exec;
408 struct gl_client_array *vertexAttrib = ctx->Array.ArrayObj->VertexAttrib;
409 const struct gl_client_array **inputs = &exec->array.inputs[0];
410 GLbitfield64 const_inputs = 0x0;
411 GLuint i;
412
413 switch (get_program_mode(ctx)) {
414 case VP_NONE:
415 /* When no vertex program is active (or the vertex program is generated
416 * from fixed-function state). We put the material values into the
417 * generic slots. This is the only situation where material values
418 * are available as per-vertex attributes.
419 */
420 for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) {
421 if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled)
422 inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)];
423 else {
424 inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i];
425 const_inputs |= VERT_BIT(i);
426 }
427 }
428
429 for (i = 0; i < MAT_ATTRIB_MAX; i++) {
430 inputs[VERT_ATTRIB_GENERIC(i)] =
431 &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+i];
432 const_inputs |= VERT_BIT_GENERIC(i);
433 }
434
435 /* Could use just about anything, just to fill in the empty
436 * slots:
437 */
438 for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_GENERIC_MAX; i++) {
439 inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i];
440 const_inputs |= VERT_BIT_GENERIC(i);
441 }
442 break;
443
444 case VP_ARB:
445 /* GL_ARB_vertex_program or GLSL vertex shader - Only the generic[0]
446 * attribute array aliases and overrides the legacy position array.
447 *
448 * Otherwise, legacy attributes available in the legacy slots,
449 * generic attributes in the generic slots and materials are not
450 * available as per-vertex attributes.
451 */
452 if (vertexAttrib[VERT_ATTRIB_GENERIC0].Enabled)
453 inputs[0] = &vertexAttrib[VERT_ATTRIB_GENERIC0];
454 else if (vertexAttrib[VERT_ATTRIB_POS].Enabled)
455 inputs[0] = &vertexAttrib[VERT_ATTRIB_POS];
456 else {
457 inputs[0] = &vbo->currval[VBO_ATTRIB_POS];
458 const_inputs |= VERT_BIT_POS;
459 }
460
461 for (i = 1; i < VERT_ATTRIB_FF_MAX; i++) {
462 if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled)
463 inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)];
464 else {
465 inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i];
466 const_inputs |= VERT_BIT_FF(i);
467 }
468 }
469
470 for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) {
471 if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
472 inputs[VERT_ATTRIB_GENERIC(i)] = &vertexAttrib[VERT_ATTRIB_GENERIC(i)];
473 else {
474 inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i];
475 const_inputs |= VERT_BIT_GENERIC(i);
476 }
477 }
478
479 inputs[VERT_ATTRIB_GENERIC0] = inputs[0];
480 break;
481 }
482
483 _mesa_set_varying_vp_inputs( ctx, VERT_BIT_ALL & (~const_inputs) );
484 ctx->NewDriverState |= ctx->DriverFlags.NewArray;
485 }
486
487
488 /**
489 * Examine the enabled vertex arrays to set the exec->array.inputs[] values.
490 * These will point to the arrays to actually use for drawing. Some will
491 * be user-provided arrays, other will be zero-stride const-valued arrays.
492 * Note that this might set the _NEW_VARYING_VP_INPUTS dirty flag so state
493 * validation must be done after this call.
494 */
495 void
496 vbo_bind_arrays(struct gl_context *ctx)
497 {
498 struct vbo_context *vbo = vbo_context(ctx);
499 struct vbo_exec_context *exec = &vbo->exec;
500
501 vbo_draw_method(vbo, DRAW_ARRAYS);
502
503 if (exec->array.recalculate_inputs) {
504 recalculate_input_bindings(ctx);
505 exec->array.recalculate_inputs = GL_FALSE;
506
507 /* Again... because we may have changed the bitmask of per-vertex varying
508 * attributes. If we regenerate the fixed-function vertex program now
509 * we may be able to prune down the number of vertex attributes which we
510 * need in the shader.
511 */
512 if (ctx->NewState) {
513 /* Setting "validating" to TRUE prevents _mesa_update_state from
514 * invalidating what we just did.
515 */
516 exec->validating = GL_TRUE;
517 _mesa_update_state(ctx);
518 exec->validating = GL_FALSE;
519 }
520 }
521 }
522
523
524 /**
525 * Handle a draw case that potentially has primitive restart enabled.
526 *
527 * If primitive restart is enabled, and PrimitiveRestartInSoftware is
528 * set, then vbo_sw_primitive_restart is used to handle the primitive
529 * restart case in software.
530 */
531 static void
532 vbo_handle_primitive_restart(struct gl_context *ctx,
533 const struct _mesa_prim *prim,
534 GLuint nr_prims,
535 const struct _mesa_index_buffer *ib,
536 GLboolean index_bounds_valid,
537 GLuint min_index,
538 GLuint max_index)
539 {
540 struct vbo_context *vbo = vbo_context(ctx);
541
542 if ((ib != NULL) &&
543 ctx->Const.PrimitiveRestartInSoftware &&
544 ctx->Array._PrimitiveRestart) {
545 /* Handle primitive restart in software */
546 vbo_sw_primitive_restart(ctx, prim, nr_prims, ib);
547 } else {
548 /* Call driver directly for draw_prims */
549 vbo->draw_prims(ctx, prim, nr_prims, ib,
550 index_bounds_valid, min_index, max_index, NULL);
551 }
552 }
553
554
555 /**
556 * Helper function called by the other DrawArrays() functions below.
557 * This is where we handle primitive restart for drawing non-indexed
558 * arrays. If primitive restart is enabled, it typically means
559 * splitting one DrawArrays() into two.
560 */
561 static void
562 vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
563 GLsizei count, GLuint numInstances, GLuint baseInstance)
564 {
565 struct vbo_context *vbo = vbo_context(ctx);
566 struct vbo_exec_context *exec = &vbo->exec;
567 struct _mesa_prim prim[2];
568
569 vbo_bind_arrays(ctx);
570
571 /* init most fields to zero */
572 memset(prim, 0, sizeof(prim));
573 prim[0].begin = 1;
574 prim[0].end = 1;
575 prim[0].mode = mode;
576 prim[0].num_instances = numInstances;
577 prim[0].base_instance = baseInstance;
578
579 /* Implement the primitive restart index */
580 if (ctx->Array._PrimitiveRestart && ctx->Array._RestartIndex < count) {
581 GLuint primCount = 0;
582
583 if (ctx->Array._RestartIndex == start) {
584 /* special case: RestartIndex at beginning */
585 if (count > 1) {
586 prim[0].start = start + 1;
587 prim[0].count = count - 1;
588 primCount = 1;
589 }
590 }
591 else if (ctx->Array._RestartIndex == start + count - 1) {
592 /* special case: RestartIndex at end */
593 if (count > 1) {
594 prim[0].start = start;
595 prim[0].count = count - 1;
596 primCount = 1;
597 }
598 }
599 else {
600 /* general case: RestartIndex in middle, split into two prims */
601 prim[0].start = start;
602 prim[0].count = ctx->Array._RestartIndex - start;
603
604 prim[1] = prim[0];
605 prim[1].start = ctx->Array._RestartIndex + 1;
606 prim[1].count = count - prim[1].start;
607
608 primCount = 2;
609 }
610
611 if (primCount > 0) {
612 /* draw one or two prims */
613 check_buffers_are_unmapped(exec->array.inputs);
614 vbo->draw_prims(ctx, prim, primCount, NULL,
615 GL_TRUE, start, start + count - 1, NULL);
616 }
617 }
618 else {
619 /* no prim restart */
620 prim[0].start = start;
621 prim[0].count = count;
622
623 check_buffers_are_unmapped(exec->array.inputs);
624 vbo->draw_prims(ctx, prim, 1, NULL,
625 GL_TRUE, start, start + count - 1,
626 NULL);
627 }
628
629 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
630 _mesa_flush(ctx);
631 }
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_lookup_enum_by_nr(mode), start, count);
647
648 if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
649 return;
650
651 if (0)
652 check_draw_arrays_data(ctx, start, count);
653
654 vbo_draw_arrays(ctx, mode, start, count, 1, 0);
655
656 if (0)
657 print_draw_arrays(ctx, mode, start, count);
658 }
659
660
661 /**
662 * Called from glDrawArraysInstanced when in immediate mode (not
663 * display list mode).
664 */
665 static void GLAPIENTRY
666 vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
667 GLsizei numInstances)
668 {
669 GET_CURRENT_CONTEXT(ctx);
670
671 if (MESA_VERBOSE & VERBOSE_DRAW)
672 _mesa_debug(ctx, "glDrawArraysInstanced(%s, %d, %d, %d)\n",
673 _mesa_lookup_enum_by_nr(mode), start, count, numInstances);
674
675 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, start, count, numInstances))
676 return;
677
678 if (0)
679 check_draw_arrays_data(ctx, start, count);
680
681 vbo_draw_arrays(ctx, mode, start, count, numInstances, 0);
682
683 if (0)
684 print_draw_arrays(ctx, mode, start, count);
685 }
686
687
688 /**
689 * Called from glDrawArraysInstancedBaseInstance when in immediate mode.
690 */
691 static void GLAPIENTRY
692 vbo_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count,
693 GLsizei numInstances, GLuint baseInstance)
694 {
695 GET_CURRENT_CONTEXT(ctx);
696
697 if (MESA_VERBOSE & VERBOSE_DRAW)
698 _mesa_debug(ctx, "glDrawArraysInstancedBaseInstance(%s, %d, %d, %d, %d)\n",
699 _mesa_lookup_enum_by_nr(mode), first, count,
700 numInstances, baseInstance);
701
702 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, first, count,
703 numInstances))
704 return;
705
706 if (0)
707 check_draw_arrays_data(ctx, first, count);
708
709 vbo_draw_arrays(ctx, mode, first, count, numInstances, baseInstance);
710
711 if (0)
712 print_draw_arrays(ctx, mode, first, count);
713 }
714
715
716
717 /**
718 * Map GL_ELEMENT_ARRAY_BUFFER and print contents.
719 * For debugging.
720 */
721 #if 0
722 static void
723 dump_element_buffer(struct gl_context *ctx, GLenum type)
724 {
725 const GLvoid *map =
726 ctx->Driver.MapBufferRange(ctx, 0,
727 ctx->Array.ArrayObj->ElementArrayBufferObj->Size,
728 GL_MAP_READ_BIT,
729 ctx->Array.ArrayObj->ElementArrayBufferObj);
730 switch (type) {
731 case GL_UNSIGNED_BYTE:
732 {
733 const GLubyte *us = (const GLubyte *) map;
734 GLint i;
735 for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size; i++) {
736 printf("%02x ", us[i]);
737 if (i % 32 == 31)
738 printf("\n");
739 }
740 printf("\n");
741 }
742 break;
743 case GL_UNSIGNED_SHORT:
744 {
745 const GLushort *us = (const GLushort *) map;
746 GLint i;
747 for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 2; i++) {
748 printf("%04x ", us[i]);
749 if (i % 16 == 15)
750 printf("\n");
751 }
752 printf("\n");
753 }
754 break;
755 case GL_UNSIGNED_INT:
756 {
757 const GLuint *us = (const GLuint *) map;
758 GLint i;
759 for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 4; i++) {
760 printf("%08x ", us[i]);
761 if (i % 8 == 7)
762 printf("\n");
763 }
764 printf("\n");
765 }
766 break;
767 default:
768 ;
769 }
770
771 ctx->Driver.UnmapBuffer(ctx, ctx->Array.ArrayObj->ElementArrayBufferObj);
772 }
773 #endif
774
775
776 /**
777 * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements.
778 * Do the rendering for a glDrawElements or glDrawRangeElements call after
779 * we've validated buffer bounds, etc.
780 */
781 static void
782 vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
783 GLboolean index_bounds_valid,
784 GLuint start, GLuint end,
785 GLsizei count, GLenum type,
786 const GLvoid *indices,
787 GLint basevertex, GLuint numInstances,
788 GLuint baseInstance)
789 {
790 struct vbo_context *vbo = vbo_context(ctx);
791 struct vbo_exec_context *exec = &vbo->exec;
792 struct _mesa_index_buffer ib;
793 struct _mesa_prim prim[1];
794
795 vbo_bind_arrays(ctx);
796
797 ib.count = count;
798 ib.type = type;
799 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
800 ib.ptr = indices;
801
802 prim[0].begin = 1;
803 prim[0].end = 1;
804 prim[0].weak = 0;
805 prim[0].pad = 0;
806 prim[0].mode = mode;
807 prim[0].start = 0;
808 prim[0].count = count;
809 prim[0].indexed = 1;
810 prim[0].basevertex = basevertex;
811 prim[0].num_instances = numInstances;
812 prim[0].base_instance = baseInstance;
813
814 /* Need to give special consideration to rendering a range of
815 * indices starting somewhere above zero. Typically the
816 * application is issuing multiple DrawRangeElements() to draw
817 * successive primitives layed out linearly in the vertex arrays.
818 * Unless the vertex arrays are all in a VBO (or locked as with
819 * CVA), the OpenGL semantics imply that we need to re-read or
820 * re-upload the vertex data on each draw call.
821 *
822 * In the case of hardware tnl, we want to avoid starting the
823 * upload at zero, as it will mean every draw call uploads an
824 * increasing amount of not-used vertex data. Worse - in the
825 * software tnl module, all those vertices might be transformed and
826 * lit but never rendered.
827 *
828 * If we just upload or transform the vertices in start..end,
829 * however, the indices will be incorrect.
830 *
831 * At this level, we don't know exactly what the requirements of
832 * the backend are going to be, though it will likely boil down to
833 * either:
834 *
835 * 1) Do nothing, everything is in a VBO and is processed once
836 * only.
837 *
838 * 2) Adjust the indices and vertex arrays so that start becomes
839 * zero.
840 *
841 * Rather than doing anything here, I'll provide a helper function
842 * for the latter case elsewhere.
843 */
844
845 check_buffers_are_unmapped(exec->array.inputs);
846 vbo_handle_primitive_restart(ctx, prim, 1, &ib,
847 index_bounds_valid, start, end);
848
849 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
850 _mesa_flush(ctx);
851 }
852 }
853
854
855 /**
856 * Called by glDrawRangeElementsBaseVertex() in immediate mode.
857 */
858 static void GLAPIENTRY
859 vbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
860 GLuint start, GLuint end,
861 GLsizei count, GLenum type,
862 const GLvoid *indices,
863 GLint basevertex)
864 {
865 static GLuint warnCount = 0;
866 GLboolean index_bounds_valid = GL_TRUE;
867 GET_CURRENT_CONTEXT(ctx);
868
869 if (MESA_VERBOSE & VERBOSE_DRAW)
870 _mesa_debug(ctx,
871 "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n",
872 _mesa_lookup_enum_by_nr(mode), start, end, count,
873 _mesa_lookup_enum_by_nr(type), indices, basevertex);
874
875 if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count,
876 type, indices, basevertex ))
877 return;
878
879 if ((int) end + basevertex < 0 ||
880 start + basevertex >= ctx->Array.ArrayObj->_MaxElement) {
881 /* The application requested we draw using a range of indices that's
882 * outside the bounds of the current VBO. This is invalid and appears
883 * to give undefined results. The safest thing to do is to simply
884 * ignore the range, in case the application botched their range tracking
885 * but did provide valid indices. Also issue a warning indicating that
886 * the application is broken.
887 */
888 if (warnCount++ < 10) {
889 _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, "
890 "basevertex %d, count %d, type 0x%x, indices=%p):\n"
891 "\trange is outside VBO bounds (max=%u); ignoring.\n"
892 "\tThis should be fixed in the application.",
893 start, end, basevertex, count, type, indices,
894 ctx->Array.ArrayObj->_MaxElement - 1);
895 }
896 index_bounds_valid = GL_FALSE;
897 }
898
899 /* NOTE: It's important that 'end' is a reasonable value.
900 * in _tnl_draw_prims(), we use end to determine how many vertices
901 * to transform. If it's too large, we can unnecessarily split prims
902 * or we can read/write out of memory in several different places!
903 */
904
905 /* Catch/fix some potential user errors */
906 if (type == GL_UNSIGNED_BYTE) {
907 start = MIN2(start, 0xff);
908 end = MIN2(end, 0xff);
909 }
910 else if (type == GL_UNSIGNED_SHORT) {
911 start = MIN2(start, 0xffff);
912 end = MIN2(end, 0xffff);
913 }
914
915 if (0) {
916 printf("glDraw[Range]Elements{,BaseVertex}"
917 "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, "
918 "base %d\n",
919 start, end, type, count,
920 ctx->Array.ArrayObj->ElementArrayBufferObj->Name,
921 basevertex);
922 }
923
924 if ((int) start + basevertex < 0 ||
925 end + basevertex >= ctx->Array.ArrayObj->_MaxElement)
926 index_bounds_valid = GL_FALSE;
927
928 #if 0
929 check_draw_elements_data(ctx, count, type, indices);
930 #else
931 (void) check_draw_elements_data;
932 #endif
933
934 vbo_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end,
935 count, type, indices, basevertex, 1, 0);
936 }
937
938
939 /**
940 * Called by glDrawRangeElements() in immediate mode.
941 */
942 static void GLAPIENTRY
943 vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
944 GLsizei count, GLenum type, const GLvoid *indices)
945 {
946 if (MESA_VERBOSE & VERBOSE_DRAW) {
947 GET_CURRENT_CONTEXT(ctx);
948 _mesa_debug(ctx,
949 "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n",
950 _mesa_lookup_enum_by_nr(mode), start, end, count,
951 _mesa_lookup_enum_by_nr(type), indices);
952 }
953
954 vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
955 indices, 0);
956 }
957
958
959 /**
960 * Called by glDrawElements() in immediate mode.
961 */
962 static void GLAPIENTRY
963 vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
964 const GLvoid *indices)
965 {
966 GET_CURRENT_CONTEXT(ctx);
967
968 if (MESA_VERBOSE & VERBOSE_DRAW)
969 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n",
970 _mesa_lookup_enum_by_nr(mode), count,
971 _mesa_lookup_enum_by_nr(type), indices);
972
973 if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))
974 return;
975
976 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
977 count, type, indices, 0, 1, 0);
978 }
979
980
981 /**
982 * Called by glDrawElementsBaseVertex() in immediate mode.
983 */
984 static void GLAPIENTRY
985 vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
986 const GLvoid *indices, GLint basevertex)
987 {
988 GET_CURRENT_CONTEXT(ctx);
989
990 if (MESA_VERBOSE & VERBOSE_DRAW)
991 _mesa_debug(ctx, "glDrawElementsBaseVertex(%s, %d, %s, %p, %d)\n",
992 _mesa_lookup_enum_by_nr(mode), count,
993 _mesa_lookup_enum_by_nr(type), indices, basevertex);
994
995 if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices,
996 basevertex ))
997 return;
998
999 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1000 count, type, indices, basevertex, 1, 0);
1001 }
1002
1003
1004 /**
1005 * Called by glDrawElementsInstanced() in immediate mode.
1006 */
1007 static void GLAPIENTRY
1008 vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
1009 const GLvoid *indices, GLsizei numInstances)
1010 {
1011 GET_CURRENT_CONTEXT(ctx);
1012
1013 if (MESA_VERBOSE & VERBOSE_DRAW)
1014 _mesa_debug(ctx, "glDrawElementsInstanced(%s, %d, %s, %p, %d)\n",
1015 _mesa_lookup_enum_by_nr(mode), count,
1016 _mesa_lookup_enum_by_nr(type), indices, numInstances);
1017
1018 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1019 numInstances, 0))
1020 return;
1021
1022 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1023 count, type, indices, 0, numInstances, 0);
1024 }
1025
1026
1027 /**
1028 * Called by glDrawElementsInstancedBaseVertex() in immediate mode.
1029 */
1030 static void GLAPIENTRY
1031 vbo_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type,
1032 const GLvoid *indices, GLsizei numInstances,
1033 GLint basevertex)
1034 {
1035 GET_CURRENT_CONTEXT(ctx);
1036
1037 if (MESA_VERBOSE & VERBOSE_DRAW)
1038 _mesa_debug(ctx, "glDrawElementsInstancedBaseVertex(%s, %d, %s, %p, %d; %d)\n",
1039 _mesa_lookup_enum_by_nr(mode), count,
1040 _mesa_lookup_enum_by_nr(type), indices,
1041 numInstances, basevertex);
1042
1043 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1044 numInstances, basevertex))
1045 return;
1046
1047 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1048 count, type, indices, basevertex, numInstances, 0);
1049 }
1050
1051
1052 /**
1053 * Called by glDrawElementsInstancedBaseInstance() in immediate mode.
1054 */
1055 static void GLAPIENTRY
1056 vbo_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type,
1057 const GLvoid *indices, GLsizei numInstances,
1058 GLuint baseInstance)
1059 {
1060 GET_CURRENT_CONTEXT(ctx);
1061
1062 if (MESA_VERBOSE & VERBOSE_DRAW)
1063 _mesa_debug(ctx, "glDrawElementsInstancedBaseInstance(%s, %d, %s, %p, %d, %d)\n",
1064 _mesa_lookup_enum_by_nr(mode), count,
1065 _mesa_lookup_enum_by_nr(type), indices,
1066 numInstances, baseInstance);
1067
1068 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1069 numInstances, 0))
1070 return;
1071
1072 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1073 count, type, indices, 0, numInstances,
1074 baseInstance);
1075 }
1076
1077
1078 /**
1079 * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode.
1080 */
1081 static void GLAPIENTRY
1082 vbo_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type,
1083 const GLvoid *indices, GLsizei numInstances,
1084 GLint basevertex, GLuint baseInstance)
1085 {
1086 GET_CURRENT_CONTEXT(ctx);
1087
1088 if (MESA_VERBOSE & VERBOSE_DRAW)
1089 _mesa_debug(ctx, "glDrawElementsInstancedBaseVertexBaseInstance(%s, %d, %s, %p, %d, %d, %d)\n",
1090 _mesa_lookup_enum_by_nr(mode), count,
1091 _mesa_lookup_enum_by_nr(type), indices,
1092 numInstances, basevertex, baseInstance);
1093
1094 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1095 numInstances, basevertex))
1096 return;
1097
1098 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1099 count, type, indices, basevertex, numInstances,
1100 baseInstance);
1101 }
1102
1103
1104 /**
1105 * Inner support for both _mesa_MultiDrawElements() and
1106 * _mesa_MultiDrawRangeElements().
1107 * This does the actual rendering after we've checked array indexes, etc.
1108 */
1109 static void
1110 vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
1111 const GLsizei *count, GLenum type,
1112 const GLvoid * const *indices,
1113 GLsizei primcount,
1114 const GLint *basevertex)
1115 {
1116 struct vbo_context *vbo = vbo_context(ctx);
1117 struct vbo_exec_context *exec = &vbo->exec;
1118 struct _mesa_index_buffer ib;
1119 struct _mesa_prim *prim;
1120 unsigned int index_type_size = vbo_sizeof_ib_type(type);
1121 uintptr_t min_index_ptr, max_index_ptr;
1122 GLboolean fallback = GL_FALSE;
1123 int i;
1124
1125 if (primcount == 0)
1126 return;
1127
1128 prim = calloc(1, primcount * sizeof(*prim));
1129 if (prim == NULL) {
1130 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements");
1131 return;
1132 }
1133
1134 vbo_bind_arrays(ctx);
1135
1136 min_index_ptr = (uintptr_t)indices[0];
1137 max_index_ptr = 0;
1138 for (i = 0; i < primcount; i++) {
1139 min_index_ptr = MIN2(min_index_ptr, (uintptr_t)indices[i]);
1140 max_index_ptr = MAX2(max_index_ptr, (uintptr_t)indices[i] +
1141 index_type_size * count[i]);
1142 }
1143
1144 /* Check if we can handle this thing as a bunch of index offsets from the
1145 * same index pointer. If we can't, then we have to fall back to doing
1146 * a draw_prims per primitive.
1147 * Check that the difference between each prim's indexes is a multiple of
1148 * the index/element size.
1149 */
1150 if (index_type_size != 1) {
1151 for (i = 0; i < primcount; i++) {
1152 if ((((uintptr_t)indices[i] - min_index_ptr) % index_type_size) != 0) {
1153 fallback = GL_TRUE;
1154 break;
1155 }
1156 }
1157 }
1158
1159 /* If the index buffer isn't in a VBO, then treating the application's
1160 * subranges of the index buffer as one large index buffer may lead to
1161 * us reading unmapped memory.
1162 */
1163 if (!_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj))
1164 fallback = GL_TRUE;
1165
1166 if (!fallback) {
1167 ib.count = (max_index_ptr - min_index_ptr) / index_type_size;
1168 ib.type = type;
1169 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
1170 ib.ptr = (void *)min_index_ptr;
1171
1172 for (i = 0; i < primcount; i++) {
1173 prim[i].begin = (i == 0);
1174 prim[i].end = (i == primcount - 1);
1175 prim[i].weak = 0;
1176 prim[i].pad = 0;
1177 prim[i].mode = mode;
1178 prim[i].start = ((uintptr_t)indices[i] - min_index_ptr) / index_type_size;
1179 prim[i].count = count[i];
1180 prim[i].indexed = 1;
1181 prim[i].num_instances = 1;
1182 prim[i].base_instance = 0;
1183 if (basevertex != NULL)
1184 prim[i].basevertex = basevertex[i];
1185 else
1186 prim[i].basevertex = 0;
1187 }
1188
1189 check_buffers_are_unmapped(exec->array.inputs);
1190 vbo_handle_primitive_restart(ctx, prim, primcount, &ib,
1191 GL_FALSE, ~0, ~0);
1192 } else {
1193 /* render one prim at a time */
1194 for (i = 0; i < primcount; i++) {
1195 ib.count = count[i];
1196 ib.type = type;
1197 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
1198 ib.ptr = indices[i];
1199
1200 prim[0].begin = 1;
1201 prim[0].end = 1;
1202 prim[0].weak = 0;
1203 prim[0].pad = 0;
1204 prim[0].mode = mode;
1205 prim[0].start = 0;
1206 prim[0].count = count[i];
1207 prim[0].indexed = 1;
1208 prim[0].num_instances = 1;
1209 prim[0].base_instance = 0;
1210 if (basevertex != NULL)
1211 prim[0].basevertex = basevertex[i];
1212 else
1213 prim[0].basevertex = 0;
1214
1215 check_buffers_are_unmapped(exec->array.inputs);
1216 vbo_handle_primitive_restart(ctx, prim, 1, &ib,
1217 GL_FALSE, ~0, ~0);
1218 }
1219 }
1220
1221 free(prim);
1222
1223 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1224 _mesa_flush(ctx);
1225 }
1226 }
1227
1228
1229 static void GLAPIENTRY
1230 vbo_exec_MultiDrawElements(GLenum mode,
1231 const GLsizei *count, GLenum type,
1232 const GLvoid **indices,
1233 GLsizei primcount)
1234 {
1235 GET_CURRENT_CONTEXT(ctx);
1236
1237 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1238 primcount, NULL))
1239 return;
1240
1241 vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
1242 NULL);
1243 }
1244
1245
1246 static void GLAPIENTRY
1247 vbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
1248 const GLsizei *count, GLenum type,
1249 const GLvoid * const *indices,
1250 GLsizei primcount,
1251 const GLsizei *basevertex)
1252 {
1253 GET_CURRENT_CONTEXT(ctx);
1254
1255 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1256 primcount, basevertex))
1257 return;
1258
1259 vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
1260 basevertex);
1261 }
1262
1263 static void
1264 vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
1265 struct gl_transform_feedback_object *obj,
1266 GLuint stream, GLuint numInstances)
1267 {
1268 struct vbo_context *vbo = vbo_context(ctx);
1269 struct vbo_exec_context *exec = &vbo->exec;
1270 struct _mesa_prim prim[2];
1271
1272 if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream,
1273 numInstances)) {
1274 return;
1275 }
1276
1277 vbo_bind_arrays(ctx);
1278
1279 /* init most fields to zero */
1280 memset(prim, 0, sizeof(prim));
1281 prim[0].begin = 1;
1282 prim[0].end = 1;
1283 prim[0].mode = mode;
1284 prim[0].num_instances = numInstances;
1285 prim[0].base_instance = 0;
1286
1287 /* Maybe we should do some primitive splitting for primitive restart
1288 * (like in DrawArrays), but we have no way to know how many vertices
1289 * will be rendered. */
1290
1291 check_buffers_are_unmapped(exec->array.inputs);
1292 vbo->draw_prims(ctx, prim, 1, NULL,
1293 GL_TRUE, 0, 0, obj);
1294
1295 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1296 _mesa_flush(ctx);
1297 }
1298 }
1299
1300 /**
1301 * Like DrawArrays, but take the count from a transform feedback object.
1302 * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc.
1303 * \param name the transform feedback object
1304 * User still has to setup of the vertex attribute info with
1305 * glVertexPointer, glColorPointer, etc.
1306 * Part of GL_ARB_transform_feedback2.
1307 */
1308 static void GLAPIENTRY
1309 vbo_exec_DrawTransformFeedback(GLenum mode, GLuint name)
1310 {
1311 GET_CURRENT_CONTEXT(ctx);
1312 struct gl_transform_feedback_object *obj =
1313 _mesa_lookup_transform_feedback_object(ctx, name);
1314
1315 if (MESA_VERBOSE & VERBOSE_DRAW)
1316 _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n",
1317 _mesa_lookup_enum_by_nr(mode), name);
1318
1319 vbo_draw_transform_feedback(ctx, mode, obj, 0, 1);
1320 }
1321
1322 static void GLAPIENTRY
1323 vbo_exec_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream)
1324 {
1325 GET_CURRENT_CONTEXT(ctx);
1326 struct gl_transform_feedback_object *obj =
1327 _mesa_lookup_transform_feedback_object(ctx, name);
1328
1329 if (MESA_VERBOSE & VERBOSE_DRAW)
1330 _mesa_debug(ctx, "glDrawTransformFeedbackStream(%s, %u, %u)\n",
1331 _mesa_lookup_enum_by_nr(mode), name, stream);
1332
1333 vbo_draw_transform_feedback(ctx, mode, obj, stream, 1);
1334 }
1335
1336 static void GLAPIENTRY
1337 vbo_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name,
1338 GLsizei primcount)
1339 {
1340 GET_CURRENT_CONTEXT(ctx);
1341 struct gl_transform_feedback_object *obj =
1342 _mesa_lookup_transform_feedback_object(ctx, name);
1343
1344 if (MESA_VERBOSE & VERBOSE_DRAW)
1345 _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n",
1346 _mesa_lookup_enum_by_nr(mode), name);
1347
1348 vbo_draw_transform_feedback(ctx, mode, obj, 0, primcount);
1349 }
1350
1351 static void GLAPIENTRY
1352 vbo_exec_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name,
1353 GLuint stream, GLsizei primcount)
1354 {
1355 GET_CURRENT_CONTEXT(ctx);
1356 struct gl_transform_feedback_object *obj =
1357 _mesa_lookup_transform_feedback_object(ctx, name);
1358
1359 if (MESA_VERBOSE & VERBOSE_DRAW)
1360 _mesa_debug(ctx, "glDrawTransformFeedbackStreamInstanced"
1361 "(%s, %u, %u, %i)\n",
1362 _mesa_lookup_enum_by_nr(mode), name, stream, primcount);
1363
1364 vbo_draw_transform_feedback(ctx, mode, obj, stream, primcount);
1365 }
1366
1367
1368 /**
1369 * Initialize the dispatch table with the VBO functions for drawing.
1370 */
1371 void
1372 vbo_initialize_exec_dispatch(const struct gl_context *ctx,
1373 struct _glapi_table *exec)
1374 {
1375 SET_DrawArrays(exec, vbo_exec_DrawArrays);
1376 SET_DrawElements(exec, vbo_exec_DrawElements);
1377
1378 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1379 SET_DrawRangeElements(exec, vbo_exec_DrawRangeElements);
1380 }
1381
1382 SET_MultiDrawElementsEXT(exec, vbo_exec_MultiDrawElements);
1383
1384 if (_mesa_is_desktop_gl(ctx)) {
1385 SET_DrawElementsBaseVertex(exec, vbo_exec_DrawElementsBaseVertex);
1386 SET_DrawRangeElementsBaseVertex(exec, vbo_exec_DrawRangeElementsBaseVertex);
1387 SET_MultiDrawElementsBaseVertex(exec, vbo_exec_MultiDrawElementsBaseVertex);
1388 SET_DrawArraysInstancedBaseInstance(exec, vbo_exec_DrawArraysInstancedBaseInstance);
1389 SET_DrawElementsInstancedBaseInstance(exec, vbo_exec_DrawElementsInstancedBaseInstance);
1390 SET_DrawElementsInstancedBaseVertex(exec, vbo_exec_DrawElementsInstancedBaseVertex);
1391 SET_DrawElementsInstancedBaseVertexBaseInstance(exec, vbo_exec_DrawElementsInstancedBaseVertexBaseInstance);
1392 }
1393
1394 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1395 SET_DrawArraysInstancedARB(exec, vbo_exec_DrawArraysInstanced);
1396 SET_DrawElementsInstancedARB(exec, vbo_exec_DrawElementsInstanced);
1397 }
1398
1399 if (_mesa_is_desktop_gl(ctx)) {
1400 SET_DrawTransformFeedback(exec, vbo_exec_DrawTransformFeedback);
1401 SET_DrawTransformFeedbackStream(exec, vbo_exec_DrawTransformFeedbackStream);
1402 SET_DrawTransformFeedbackInstanced(exec, vbo_exec_DrawTransformFeedbackInstanced);
1403 SET_DrawTransformFeedbackStreamInstanced(exec, vbo_exec_DrawTransformFeedbackStreamInstanced);
1404 }
1405 }
1406
1407
1408
1409 /**
1410 * The following functions are only used for OpenGL ES 1/2 support.
1411 * And some aren't even supported (yet) in ES 1/2.
1412 */
1413
1414
1415 void GLAPIENTRY
1416 _mesa_DrawArrays(GLenum mode, GLint first, GLsizei count)
1417 {
1418 vbo_exec_DrawArrays(mode, first, count);
1419 }
1420
1421
1422 void GLAPIENTRY
1423 _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
1424 const GLvoid *indices)
1425 {
1426 vbo_exec_DrawElements(mode, count, type, indices);
1427 }
1428
1429
1430 void GLAPIENTRY
1431 _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
1432 const GLvoid *indices, GLint basevertex)
1433 {
1434 vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex);
1435 }
1436
1437
1438 void GLAPIENTRY
1439 _mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
1440 GLenum type, const GLvoid *indices)
1441 {
1442 vbo_exec_DrawRangeElements(mode, start, end, count, type, indices);
1443 }
1444
1445
1446 void GLAPIENTRY
1447 _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
1448 GLsizei count, GLenum type,
1449 const GLvoid *indices, GLint basevertex)
1450 {
1451 vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
1452 indices, basevertex);
1453 }
1454
1455
1456 void GLAPIENTRY
1457 _mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,
1458 const GLvoid **indices, GLsizei primcount)
1459 {
1460 vbo_exec_MultiDrawElements(mode, count, type, indices, primcount);
1461 }
1462
1463
1464 void GLAPIENTRY
1465 _mesa_MultiDrawElementsBaseVertex(GLenum mode,
1466 const GLsizei *count, GLenum type,
1467 const GLvoid **indices, GLsizei primcount,
1468 const GLint *basevertex)
1469 {
1470 vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices,
1471 primcount, basevertex);
1472 }
1473
1474 void GLAPIENTRY
1475 _mesa_DrawTransformFeedback(GLenum mode, GLuint name)
1476 {
1477 vbo_exec_DrawTransformFeedback(mode, name);
1478 }