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