mesa: remove GLvertexformat::Rectf()
[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 * Execute a glRectf() function.
637 */
638 static void GLAPIENTRY
639 vbo_exec_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
640 {
641 GET_CURRENT_CONTEXT(ctx);
642 ASSERT_OUTSIDE_BEGIN_END(ctx);
643
644 CALL_Begin(GET_DISPATCH(), (GL_QUADS));
645 CALL_Vertex2f(GET_DISPATCH(), (x1, y1));
646 CALL_Vertex2f(GET_DISPATCH(), (x2, y1));
647 CALL_Vertex2f(GET_DISPATCH(), (x2, y2));
648 CALL_Vertex2f(GET_DISPATCH(), (x1, y2));
649 CALL_End(GET_DISPATCH(), ());
650 }
651
652
653 /**
654 * Called from glDrawArrays when in immediate mode (not display list mode).
655 */
656 static void GLAPIENTRY
657 vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
658 {
659 GET_CURRENT_CONTEXT(ctx);
660
661 if (MESA_VERBOSE & VERBOSE_DRAW)
662 _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n",
663 _mesa_lookup_enum_by_nr(mode), start, count);
664
665 if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
666 return;
667
668 if (0)
669 check_draw_arrays_data(ctx, start, count);
670
671 vbo_draw_arrays(ctx, mode, start, count, 1, 0);
672
673 if (0)
674 print_draw_arrays(ctx, mode, start, count);
675 }
676
677
678 /**
679 * Called from glDrawArraysInstanced when in immediate mode (not
680 * display list mode).
681 */
682 static void GLAPIENTRY
683 vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
684 GLsizei numInstances)
685 {
686 GET_CURRENT_CONTEXT(ctx);
687
688 if (MESA_VERBOSE & VERBOSE_DRAW)
689 _mesa_debug(ctx, "glDrawArraysInstanced(%s, %d, %d, %d)\n",
690 _mesa_lookup_enum_by_nr(mode), start, count, numInstances);
691
692 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, start, count, numInstances))
693 return;
694
695 if (0)
696 check_draw_arrays_data(ctx, start, count);
697
698 vbo_draw_arrays(ctx, mode, start, count, numInstances, 0);
699
700 if (0)
701 print_draw_arrays(ctx, mode, start, count);
702 }
703
704
705 /**
706 * Called from glDrawArraysInstancedBaseInstance when in immediate mode.
707 */
708 static void GLAPIENTRY
709 vbo_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count,
710 GLsizei numInstances, GLuint baseInstance)
711 {
712 GET_CURRENT_CONTEXT(ctx);
713
714 if (MESA_VERBOSE & VERBOSE_DRAW)
715 _mesa_debug(ctx, "glDrawArraysInstancedBaseInstance(%s, %d, %d, %d, %d)\n",
716 _mesa_lookup_enum_by_nr(mode), first, count,
717 numInstances, baseInstance);
718
719 if (!_mesa_validate_DrawArraysInstanced(ctx, mode, first, count,
720 numInstances))
721 return;
722
723 if (0)
724 check_draw_arrays_data(ctx, first, count);
725
726 vbo_draw_arrays(ctx, mode, first, count, numInstances, baseInstance);
727
728 if (0)
729 print_draw_arrays(ctx, mode, first, count);
730 }
731
732
733
734 /**
735 * Map GL_ELEMENT_ARRAY_BUFFER and print contents.
736 * For debugging.
737 */
738 #if 0
739 static void
740 dump_element_buffer(struct gl_context *ctx, GLenum type)
741 {
742 const GLvoid *map =
743 ctx->Driver.MapBufferRange(ctx, 0,
744 ctx->Array.ArrayObj->ElementArrayBufferObj->Size,
745 GL_MAP_READ_BIT,
746 ctx->Array.ArrayObj->ElementArrayBufferObj);
747 switch (type) {
748 case GL_UNSIGNED_BYTE:
749 {
750 const GLubyte *us = (const GLubyte *) map;
751 GLint i;
752 for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size; i++) {
753 printf("%02x ", us[i]);
754 if (i % 32 == 31)
755 printf("\n");
756 }
757 printf("\n");
758 }
759 break;
760 case GL_UNSIGNED_SHORT:
761 {
762 const GLushort *us = (const GLushort *) map;
763 GLint i;
764 for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 2; i++) {
765 printf("%04x ", us[i]);
766 if (i % 16 == 15)
767 printf("\n");
768 }
769 printf("\n");
770 }
771 break;
772 case GL_UNSIGNED_INT:
773 {
774 const GLuint *us = (const GLuint *) map;
775 GLint i;
776 for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 4; i++) {
777 printf("%08x ", us[i]);
778 if (i % 8 == 7)
779 printf("\n");
780 }
781 printf("\n");
782 }
783 break;
784 default:
785 ;
786 }
787
788 ctx->Driver.UnmapBuffer(ctx, ctx->Array.ArrayObj->ElementArrayBufferObj);
789 }
790 #endif
791
792
793 /**
794 * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements.
795 * Do the rendering for a glDrawElements or glDrawRangeElements call after
796 * we've validated buffer bounds, etc.
797 */
798 static void
799 vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
800 GLboolean index_bounds_valid,
801 GLuint start, GLuint end,
802 GLsizei count, GLenum type,
803 const GLvoid *indices,
804 GLint basevertex, GLuint numInstances,
805 GLuint baseInstance)
806 {
807 struct vbo_context *vbo = vbo_context(ctx);
808 struct vbo_exec_context *exec = &vbo->exec;
809 struct _mesa_index_buffer ib;
810 struct _mesa_prim prim[1];
811
812 vbo_bind_arrays(ctx);
813
814 ib.count = count;
815 ib.type = type;
816 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
817 ib.ptr = indices;
818
819 prim[0].begin = 1;
820 prim[0].end = 1;
821 prim[0].weak = 0;
822 prim[0].pad = 0;
823 prim[0].mode = mode;
824 prim[0].start = 0;
825 prim[0].count = count;
826 prim[0].indexed = 1;
827 prim[0].basevertex = basevertex;
828 prim[0].num_instances = numInstances;
829 prim[0].base_instance = baseInstance;
830
831 /* Need to give special consideration to rendering a range of
832 * indices starting somewhere above zero. Typically the
833 * application is issuing multiple DrawRangeElements() to draw
834 * successive primitives layed out linearly in the vertex arrays.
835 * Unless the vertex arrays are all in a VBO (or locked as with
836 * CVA), the OpenGL semantics imply that we need to re-read or
837 * re-upload the vertex data on each draw call.
838 *
839 * In the case of hardware tnl, we want to avoid starting the
840 * upload at zero, as it will mean every draw call uploads an
841 * increasing amount of not-used vertex data. Worse - in the
842 * software tnl module, all those vertices might be transformed and
843 * lit but never rendered.
844 *
845 * If we just upload or transform the vertices in start..end,
846 * however, the indices will be incorrect.
847 *
848 * At this level, we don't know exactly what the requirements of
849 * the backend are going to be, though it will likely boil down to
850 * either:
851 *
852 * 1) Do nothing, everything is in a VBO and is processed once
853 * only.
854 *
855 * 2) Adjust the indices and vertex arrays so that start becomes
856 * zero.
857 *
858 * Rather than doing anything here, I'll provide a helper function
859 * for the latter case elsewhere.
860 */
861
862 check_buffers_are_unmapped(exec->array.inputs);
863 vbo_handle_primitive_restart(ctx, prim, 1, &ib,
864 index_bounds_valid, start, end);
865
866 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
867 _mesa_flush(ctx);
868 }
869 }
870
871
872 /**
873 * Called by glDrawRangeElementsBaseVertex() in immediate mode.
874 */
875 static void GLAPIENTRY
876 vbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
877 GLuint start, GLuint end,
878 GLsizei count, GLenum type,
879 const GLvoid *indices,
880 GLint basevertex)
881 {
882 static GLuint warnCount = 0;
883 GLboolean index_bounds_valid = GL_TRUE;
884 GET_CURRENT_CONTEXT(ctx);
885
886 if (MESA_VERBOSE & VERBOSE_DRAW)
887 _mesa_debug(ctx,
888 "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n",
889 _mesa_lookup_enum_by_nr(mode), start, end, count,
890 _mesa_lookup_enum_by_nr(type), indices, basevertex);
891
892 if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count,
893 type, indices, basevertex ))
894 return;
895
896 if ((int) end + basevertex < 0 ||
897 start + basevertex >= ctx->Array.ArrayObj->_MaxElement) {
898 /* The application requested we draw using a range of indices that's
899 * outside the bounds of the current VBO. This is invalid and appears
900 * to give undefined results. The safest thing to do is to simply
901 * ignore the range, in case the application botched their range tracking
902 * but did provide valid indices. Also issue a warning indicating that
903 * the application is broken.
904 */
905 if (warnCount++ < 10) {
906 _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, "
907 "basevertex %d, count %d, type 0x%x, indices=%p):\n"
908 "\trange is outside VBO bounds (max=%u); ignoring.\n"
909 "\tThis should be fixed in the application.",
910 start, end, basevertex, count, type, indices,
911 ctx->Array.ArrayObj->_MaxElement - 1);
912 }
913 index_bounds_valid = GL_FALSE;
914 }
915
916 /* NOTE: It's important that 'end' is a reasonable value.
917 * in _tnl_draw_prims(), we use end to determine how many vertices
918 * to transform. If it's too large, we can unnecessarily split prims
919 * or we can read/write out of memory in several different places!
920 */
921
922 /* Catch/fix some potential user errors */
923 if (type == GL_UNSIGNED_BYTE) {
924 start = MIN2(start, 0xff);
925 end = MIN2(end, 0xff);
926 }
927 else if (type == GL_UNSIGNED_SHORT) {
928 start = MIN2(start, 0xffff);
929 end = MIN2(end, 0xffff);
930 }
931
932 if (0) {
933 printf("glDraw[Range]Elements{,BaseVertex}"
934 "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, "
935 "base %d\n",
936 start, end, type, count,
937 ctx->Array.ArrayObj->ElementArrayBufferObj->Name,
938 basevertex);
939 }
940
941 if ((int) start + basevertex < 0 ||
942 end + basevertex >= ctx->Array.ArrayObj->_MaxElement)
943 index_bounds_valid = GL_FALSE;
944
945 #if 0
946 check_draw_elements_data(ctx, count, type, indices);
947 #else
948 (void) check_draw_elements_data;
949 #endif
950
951 vbo_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end,
952 count, type, indices, basevertex, 1, 0);
953 }
954
955
956 /**
957 * Called by glDrawRangeElements() in immediate mode.
958 */
959 static void GLAPIENTRY
960 vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
961 GLsizei count, GLenum type, const GLvoid *indices)
962 {
963 if (MESA_VERBOSE & VERBOSE_DRAW) {
964 GET_CURRENT_CONTEXT(ctx);
965 _mesa_debug(ctx,
966 "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n",
967 _mesa_lookup_enum_by_nr(mode), start, end, count,
968 _mesa_lookup_enum_by_nr(type), indices);
969 }
970
971 vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
972 indices, 0);
973 }
974
975
976 /**
977 * Called by glDrawElements() in immediate mode.
978 */
979 static void GLAPIENTRY
980 vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
981 const GLvoid *indices)
982 {
983 GET_CURRENT_CONTEXT(ctx);
984
985 if (MESA_VERBOSE & VERBOSE_DRAW)
986 _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n",
987 _mesa_lookup_enum_by_nr(mode), count,
988 _mesa_lookup_enum_by_nr(type), indices);
989
990 if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))
991 return;
992
993 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
994 count, type, indices, 0, 1, 0);
995 }
996
997
998 /**
999 * Called by glDrawElementsBaseVertex() in immediate mode.
1000 */
1001 static void GLAPIENTRY
1002 vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
1003 const GLvoid *indices, GLint basevertex)
1004 {
1005 GET_CURRENT_CONTEXT(ctx);
1006
1007 if (MESA_VERBOSE & VERBOSE_DRAW)
1008 _mesa_debug(ctx, "glDrawElementsBaseVertex(%s, %d, %s, %p, %d)\n",
1009 _mesa_lookup_enum_by_nr(mode), count,
1010 _mesa_lookup_enum_by_nr(type), indices, basevertex);
1011
1012 if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices,
1013 basevertex ))
1014 return;
1015
1016 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1017 count, type, indices, basevertex, 1, 0);
1018 }
1019
1020
1021 /**
1022 * Called by glDrawElementsInstanced() in immediate mode.
1023 */
1024 static void GLAPIENTRY
1025 vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
1026 const GLvoid *indices, GLsizei numInstances)
1027 {
1028 GET_CURRENT_CONTEXT(ctx);
1029
1030 if (MESA_VERBOSE & VERBOSE_DRAW)
1031 _mesa_debug(ctx, "glDrawElementsInstanced(%s, %d, %s, %p, %d)\n",
1032 _mesa_lookup_enum_by_nr(mode), count,
1033 _mesa_lookup_enum_by_nr(type), indices, numInstances);
1034
1035 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1036 numInstances, 0))
1037 return;
1038
1039 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1040 count, type, indices, 0, numInstances, 0);
1041 }
1042
1043
1044 /**
1045 * Called by glDrawElementsInstancedBaseVertex() in immediate mode.
1046 */
1047 static void GLAPIENTRY
1048 vbo_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type,
1049 const GLvoid *indices, GLsizei numInstances,
1050 GLint basevertex)
1051 {
1052 GET_CURRENT_CONTEXT(ctx);
1053
1054 if (MESA_VERBOSE & VERBOSE_DRAW)
1055 _mesa_debug(ctx, "glDrawElementsInstancedBaseVertex(%s, %d, %s, %p, %d; %d)\n",
1056 _mesa_lookup_enum_by_nr(mode), count,
1057 _mesa_lookup_enum_by_nr(type), indices,
1058 numInstances, basevertex);
1059
1060 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1061 numInstances, basevertex))
1062 return;
1063
1064 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1065 count, type, indices, basevertex, numInstances, 0);
1066 }
1067
1068
1069 /**
1070 * Called by glDrawElementsInstancedBaseInstance() in immediate mode.
1071 */
1072 static void GLAPIENTRY
1073 vbo_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type,
1074 const GLvoid *indices, GLsizei numInstances,
1075 GLuint baseInstance)
1076 {
1077 GET_CURRENT_CONTEXT(ctx);
1078
1079 if (MESA_VERBOSE & VERBOSE_DRAW)
1080 _mesa_debug(ctx, "glDrawElementsInstancedBaseInstance(%s, %d, %s, %p, %d, %d)\n",
1081 _mesa_lookup_enum_by_nr(mode), count,
1082 _mesa_lookup_enum_by_nr(type), indices,
1083 numInstances, baseInstance);
1084
1085 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1086 numInstances, 0))
1087 return;
1088
1089 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1090 count, type, indices, 0, numInstances,
1091 baseInstance);
1092 }
1093
1094
1095 /**
1096 * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode.
1097 */
1098 static void GLAPIENTRY
1099 vbo_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type,
1100 const GLvoid *indices, GLsizei numInstances,
1101 GLint basevertex, GLuint baseInstance)
1102 {
1103 GET_CURRENT_CONTEXT(ctx);
1104
1105 if (MESA_VERBOSE & VERBOSE_DRAW)
1106 _mesa_debug(ctx, "glDrawElementsInstancedBaseVertexBaseInstance(%s, %d, %s, %p, %d, %d, %d)\n",
1107 _mesa_lookup_enum_by_nr(mode), count,
1108 _mesa_lookup_enum_by_nr(type), indices,
1109 numInstances, basevertex, baseInstance);
1110
1111 if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1112 numInstances, basevertex))
1113 return;
1114
1115 vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1116 count, type, indices, basevertex, numInstances,
1117 baseInstance);
1118 }
1119
1120
1121 /**
1122 * Inner support for both _mesa_MultiDrawElements() and
1123 * _mesa_MultiDrawRangeElements().
1124 * This does the actual rendering after we've checked array indexes, etc.
1125 */
1126 static void
1127 vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
1128 const GLsizei *count, GLenum type,
1129 const GLvoid * const *indices,
1130 GLsizei primcount,
1131 const GLint *basevertex)
1132 {
1133 struct vbo_context *vbo = vbo_context(ctx);
1134 struct vbo_exec_context *exec = &vbo->exec;
1135 struct _mesa_index_buffer ib;
1136 struct _mesa_prim *prim;
1137 unsigned int index_type_size = vbo_sizeof_ib_type(type);
1138 uintptr_t min_index_ptr, max_index_ptr;
1139 GLboolean fallback = GL_FALSE;
1140 int i;
1141
1142 if (primcount == 0)
1143 return;
1144
1145 prim = calloc(1, primcount * sizeof(*prim));
1146 if (prim == NULL) {
1147 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements");
1148 return;
1149 }
1150
1151 vbo_bind_arrays(ctx);
1152
1153 min_index_ptr = (uintptr_t)indices[0];
1154 max_index_ptr = 0;
1155 for (i = 0; i < primcount; i++) {
1156 min_index_ptr = MIN2(min_index_ptr, (uintptr_t)indices[i]);
1157 max_index_ptr = MAX2(max_index_ptr, (uintptr_t)indices[i] +
1158 index_type_size * count[i]);
1159 }
1160
1161 /* Check if we can handle this thing as a bunch of index offsets from the
1162 * same index pointer. If we can't, then we have to fall back to doing
1163 * a draw_prims per primitive.
1164 * Check that the difference between each prim's indexes is a multiple of
1165 * the index/element size.
1166 */
1167 if (index_type_size != 1) {
1168 for (i = 0; i < primcount; i++) {
1169 if ((((uintptr_t)indices[i] - min_index_ptr) % index_type_size) != 0) {
1170 fallback = GL_TRUE;
1171 break;
1172 }
1173 }
1174 }
1175
1176 /* If the index buffer isn't in a VBO, then treating the application's
1177 * subranges of the index buffer as one large index buffer may lead to
1178 * us reading unmapped memory.
1179 */
1180 if (!_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj))
1181 fallback = GL_TRUE;
1182
1183 if (!fallback) {
1184 ib.count = (max_index_ptr - min_index_ptr) / index_type_size;
1185 ib.type = type;
1186 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
1187 ib.ptr = (void *)min_index_ptr;
1188
1189 for (i = 0; i < primcount; i++) {
1190 prim[i].begin = (i == 0);
1191 prim[i].end = (i == primcount - 1);
1192 prim[i].weak = 0;
1193 prim[i].pad = 0;
1194 prim[i].mode = mode;
1195 prim[i].start = ((uintptr_t)indices[i] - min_index_ptr) / index_type_size;
1196 prim[i].count = count[i];
1197 prim[i].indexed = 1;
1198 prim[i].num_instances = 1;
1199 prim[i].base_instance = 0;
1200 if (basevertex != NULL)
1201 prim[i].basevertex = basevertex[i];
1202 else
1203 prim[i].basevertex = 0;
1204 }
1205
1206 check_buffers_are_unmapped(exec->array.inputs);
1207 vbo_handle_primitive_restart(ctx, prim, primcount, &ib,
1208 GL_FALSE, ~0, ~0);
1209 } else {
1210 /* render one prim at a time */
1211 for (i = 0; i < primcount; i++) {
1212 ib.count = count[i];
1213 ib.type = type;
1214 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
1215 ib.ptr = indices[i];
1216
1217 prim[0].begin = 1;
1218 prim[0].end = 1;
1219 prim[0].weak = 0;
1220 prim[0].pad = 0;
1221 prim[0].mode = mode;
1222 prim[0].start = 0;
1223 prim[0].count = count[i];
1224 prim[0].indexed = 1;
1225 prim[0].num_instances = 1;
1226 prim[0].base_instance = 0;
1227 if (basevertex != NULL)
1228 prim[0].basevertex = basevertex[i];
1229 else
1230 prim[0].basevertex = 0;
1231
1232 check_buffers_are_unmapped(exec->array.inputs);
1233 vbo_handle_primitive_restart(ctx, prim, 1, &ib,
1234 GL_FALSE, ~0, ~0);
1235 }
1236 }
1237
1238 free(prim);
1239
1240 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1241 _mesa_flush(ctx);
1242 }
1243 }
1244
1245
1246 static void GLAPIENTRY
1247 vbo_exec_MultiDrawElements(GLenum mode,
1248 const GLsizei *count, GLenum type,
1249 const GLvoid **indices,
1250 GLsizei primcount)
1251 {
1252 GET_CURRENT_CONTEXT(ctx);
1253
1254 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1255 primcount, NULL))
1256 return;
1257
1258 vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
1259 NULL);
1260 }
1261
1262
1263 static void GLAPIENTRY
1264 vbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
1265 const GLsizei *count, GLenum type,
1266 const GLvoid * const *indices,
1267 GLsizei primcount,
1268 const GLsizei *basevertex)
1269 {
1270 GET_CURRENT_CONTEXT(ctx);
1271
1272 if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1273 primcount, basevertex))
1274 return;
1275
1276 vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
1277 basevertex);
1278 }
1279
1280 static void
1281 vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
1282 struct gl_transform_feedback_object *obj,
1283 GLuint stream, GLuint numInstances)
1284 {
1285 struct vbo_context *vbo = vbo_context(ctx);
1286 struct vbo_exec_context *exec = &vbo->exec;
1287 struct _mesa_prim prim[2];
1288
1289 if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream,
1290 numInstances)) {
1291 return;
1292 }
1293
1294 vbo_bind_arrays(ctx);
1295
1296 /* init most fields to zero */
1297 memset(prim, 0, sizeof(prim));
1298 prim[0].begin = 1;
1299 prim[0].end = 1;
1300 prim[0].mode = mode;
1301 prim[0].num_instances = numInstances;
1302 prim[0].base_instance = 0;
1303
1304 /* Maybe we should do some primitive splitting for primitive restart
1305 * (like in DrawArrays), but we have no way to know how many vertices
1306 * will be rendered. */
1307
1308 check_buffers_are_unmapped(exec->array.inputs);
1309 vbo->draw_prims(ctx, prim, 1, NULL,
1310 GL_TRUE, 0, 0, obj);
1311
1312 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1313 _mesa_flush(ctx);
1314 }
1315 }
1316
1317 /**
1318 * Like DrawArrays, but take the count from a transform feedback object.
1319 * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc.
1320 * \param name the transform feedback object
1321 * User still has to setup of the vertex attribute info with
1322 * glVertexPointer, glColorPointer, etc.
1323 * Part of GL_ARB_transform_feedback2.
1324 */
1325 static void GLAPIENTRY
1326 vbo_exec_DrawTransformFeedback(GLenum mode, GLuint name)
1327 {
1328 GET_CURRENT_CONTEXT(ctx);
1329 struct gl_transform_feedback_object *obj =
1330 _mesa_lookup_transform_feedback_object(ctx, name);
1331
1332 if (MESA_VERBOSE & VERBOSE_DRAW)
1333 _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n",
1334 _mesa_lookup_enum_by_nr(mode), name);
1335
1336 vbo_draw_transform_feedback(ctx, mode, obj, 0, 1);
1337 }
1338
1339 static void GLAPIENTRY
1340 vbo_exec_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream)
1341 {
1342 GET_CURRENT_CONTEXT(ctx);
1343 struct gl_transform_feedback_object *obj =
1344 _mesa_lookup_transform_feedback_object(ctx, name);
1345
1346 if (MESA_VERBOSE & VERBOSE_DRAW)
1347 _mesa_debug(ctx, "glDrawTransformFeedbackStream(%s, %u, %u)\n",
1348 _mesa_lookup_enum_by_nr(mode), name, stream);
1349
1350 vbo_draw_transform_feedback(ctx, mode, obj, stream, 1);
1351 }
1352
1353 static void GLAPIENTRY
1354 vbo_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name,
1355 GLsizei primcount)
1356 {
1357 GET_CURRENT_CONTEXT(ctx);
1358 struct gl_transform_feedback_object *obj =
1359 _mesa_lookup_transform_feedback_object(ctx, name);
1360
1361 if (MESA_VERBOSE & VERBOSE_DRAW)
1362 _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n",
1363 _mesa_lookup_enum_by_nr(mode), name);
1364
1365 vbo_draw_transform_feedback(ctx, mode, obj, 0, primcount);
1366 }
1367
1368 static void GLAPIENTRY
1369 vbo_exec_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name,
1370 GLuint stream, GLsizei primcount)
1371 {
1372 GET_CURRENT_CONTEXT(ctx);
1373 struct gl_transform_feedback_object *obj =
1374 _mesa_lookup_transform_feedback_object(ctx, name);
1375
1376 if (MESA_VERBOSE & VERBOSE_DRAW)
1377 _mesa_debug(ctx, "glDrawTransformFeedbackStreamInstanced"
1378 "(%s, %u, %u, %i)\n",
1379 _mesa_lookup_enum_by_nr(mode), name, stream, primcount);
1380
1381 vbo_draw_transform_feedback(ctx, mode, obj, stream, primcount);
1382 }
1383
1384
1385 /**
1386 * Initialize the dispatch table with the VBO functions for drawing.
1387 */
1388 void
1389 vbo_initialize_exec_dispatch(const struct gl_context *ctx,
1390 struct _glapi_table *exec)
1391 {
1392 SET_DrawArrays(exec, vbo_exec_DrawArrays);
1393 SET_DrawElements(exec, vbo_exec_DrawElements);
1394
1395 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1396 SET_DrawRangeElements(exec, vbo_exec_DrawRangeElements);
1397 }
1398
1399 SET_MultiDrawElementsEXT(exec, vbo_exec_MultiDrawElements);
1400
1401 if (ctx->API == API_OPENGL_COMPAT) {
1402 SET_Rectf(exec, vbo_exec_Rectf);
1403 }
1404
1405 if (_mesa_is_desktop_gl(ctx)) {
1406 SET_DrawElementsBaseVertex(exec, vbo_exec_DrawElementsBaseVertex);
1407 SET_DrawRangeElementsBaseVertex(exec, vbo_exec_DrawRangeElementsBaseVertex);
1408 SET_MultiDrawElementsBaseVertex(exec, vbo_exec_MultiDrawElementsBaseVertex);
1409 SET_DrawArraysInstancedBaseInstance(exec, vbo_exec_DrawArraysInstancedBaseInstance);
1410 SET_DrawElementsInstancedBaseInstance(exec, vbo_exec_DrawElementsInstancedBaseInstance);
1411 SET_DrawElementsInstancedBaseVertex(exec, vbo_exec_DrawElementsInstancedBaseVertex);
1412 SET_DrawElementsInstancedBaseVertexBaseInstance(exec, vbo_exec_DrawElementsInstancedBaseVertexBaseInstance);
1413 }
1414
1415 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1416 SET_DrawArraysInstancedARB(exec, vbo_exec_DrawArraysInstanced);
1417 SET_DrawElementsInstancedARB(exec, vbo_exec_DrawElementsInstanced);
1418 }
1419
1420 if (_mesa_is_desktop_gl(ctx)) {
1421 SET_DrawTransformFeedback(exec, vbo_exec_DrawTransformFeedback);
1422 SET_DrawTransformFeedbackStream(exec, vbo_exec_DrawTransformFeedbackStream);
1423 SET_DrawTransformFeedbackInstanced(exec, vbo_exec_DrawTransformFeedbackInstanced);
1424 SET_DrawTransformFeedbackStreamInstanced(exec, vbo_exec_DrawTransformFeedbackStreamInstanced);
1425 }
1426 }
1427
1428
1429
1430 /**
1431 * The following functions are only used for OpenGL ES 1/2 support.
1432 * And some aren't even supported (yet) in ES 1/2.
1433 */
1434
1435
1436 void GLAPIENTRY
1437 _mesa_DrawArrays(GLenum mode, GLint first, GLsizei count)
1438 {
1439 vbo_exec_DrawArrays(mode, first, count);
1440 }
1441
1442
1443 void GLAPIENTRY
1444 _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
1445 const GLvoid *indices)
1446 {
1447 vbo_exec_DrawElements(mode, count, type, indices);
1448 }
1449
1450
1451 void GLAPIENTRY
1452 _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
1453 const GLvoid *indices, GLint basevertex)
1454 {
1455 vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex);
1456 }
1457
1458
1459 void GLAPIENTRY
1460 _mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
1461 GLenum type, const GLvoid *indices)
1462 {
1463 vbo_exec_DrawRangeElements(mode, start, end, count, type, indices);
1464 }
1465
1466
1467 void GLAPIENTRY
1468 _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
1469 GLsizei count, GLenum type,
1470 const GLvoid *indices, GLint basevertex)
1471 {
1472 vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
1473 indices, basevertex);
1474 }
1475
1476
1477 void GLAPIENTRY
1478 _mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,
1479 const GLvoid **indices, GLsizei primcount)
1480 {
1481 vbo_exec_MultiDrawElements(mode, count, type, indices, primcount);
1482 }
1483
1484
1485 void GLAPIENTRY
1486 _mesa_MultiDrawElementsBaseVertex(GLenum mode,
1487 const GLsizei *count, GLenum type,
1488 const GLvoid **indices, GLsizei primcount,
1489 const GLint *basevertex)
1490 {
1491 vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices,
1492 primcount, basevertex);
1493 }
1494
1495 void GLAPIENTRY
1496 _mesa_DrawTransformFeedback(GLenum mode, GLuint name)
1497 {
1498 vbo_exec_DrawTransformFeedback(mode, name);
1499 }