vbo_exec_array.c revision fa48137f292bbf8cbcd65e9caf33633cddc96600
1fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/**************************************************************************
2fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *
3fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul * Copyright 2009 VMware, Inc.
5fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * All Rights Reserved.
6fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *
7fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
8fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * copy of this software and associated documentation files (the
9fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * "Software"), to deal in the Software without restriction, including
10fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * without limitation the rights to use, copy, modify, merge, publish,
11fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * distribute, sub license, and/or sell copies of the Software, and to
12fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * permit persons to whom the Software is furnished to do so, subject to
13fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * the following conditions:
14fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *
15fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * The above copyright notice and this permission notice (including the
16fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * next paragraph) shall be included in all copies or substantial portions
17fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * of the Software.
18fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *
19fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *
27fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell **************************************************************************/
28fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
29c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/glheader.h"
30c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/context.h"
31c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/state.h"
32c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/api_validate.h"
33feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul#include "main/varray.h"
34a3b7db0326337117ccdea526818040d2c24d83b4Brian Paul#include "main/bufferobj.h"
35ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul#include "main/enums.h"
3660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt#include "main/macros.h"
3714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák#include "main/transformfeedback.h"
38fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
39fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "vbo_context.h"
40fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
410b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paul
423bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul/**
437ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul * All vertex buffers should be in an unmapped state when we're about
447ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul * to draw.  This debug function checks that.
457ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul */
467ea729a1855e93b3c41c72781950f8612221fd5cBrian Paulstatic void
477ea729a1855e93b3c41c72781950f8612221fd5cBrian Paulcheck_buffers_are_unmapped(const struct gl_client_array **inputs)
487ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul{
497ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul#ifdef DEBUG
507ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul   GLuint i;
517ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul
527ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
537ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul      if (inputs[i]) {
547ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul         struct gl_buffer_object *obj = inputs[i]->BufferObj;
557ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul         assert(!_mesa_bufferobj_mapped(obj));
567b3bec87dfb02e8ee43f64da12c928d76883aa61Brian Paul         (void) obj;
577ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul      }
587ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul   }
597ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul#endif
607ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul}
617ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul
627ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul
637ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul/**
646d1f28d6c045f768da2eee779006535acf382cceBrian Paul * A debug function that may be called from other parts of Mesa as
656d1f28d6c045f768da2eee779006535acf382cceBrian Paul * needed during debugging.
666d1f28d6c045f768da2eee779006535acf382cceBrian Paul */
676d1f28d6c045f768da2eee779006535acf382cceBrian Paulvoid
686d1f28d6c045f768da2eee779006535acf382cceBrian Paulvbo_check_buffers_are_unmapped(struct gl_context *ctx)
696d1f28d6c045f768da2eee779006535acf382cceBrian Paul{
706d1f28d6c045f768da2eee779006535acf382cceBrian Paul   struct vbo_context *vbo = vbo_context(ctx);
716d1f28d6c045f768da2eee779006535acf382cceBrian Paul   struct vbo_exec_context *exec = &vbo->exec;
726d1f28d6c045f768da2eee779006535acf382cceBrian Paul   /* check the current vertex arrays */
736d1f28d6c045f768da2eee779006535acf382cceBrian Paul   check_buffers_are_unmapped(exec->array.inputs);
746d1f28d6c045f768da2eee779006535acf382cceBrian Paul   /* check the current glBegin/glVertex/glEnd-style VBO */
756d1f28d6c045f768da2eee779006535acf382cceBrian Paul   assert(!_mesa_bufferobj_mapped(exec->vtx.bufferobj));
766d1f28d6c045f768da2eee779006535acf382cceBrian Paul}
776d1f28d6c045f768da2eee779006535acf382cceBrian Paul
786d1f28d6c045f768da2eee779006535acf382cceBrian Paul
796d1f28d6c045f768da2eee779006535acf382cceBrian Paul
806d1f28d6c045f768da2eee779006535acf382cceBrian Paul/**
81b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Compute min and max elements by scanning the index buffer for
82b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * glDraw[Range]Elements() calls.
83be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul * If primitive restart is enabled, we need to ignore restart
84be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul * indexes when computing min/max.
85893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell */
8642d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liustatic void
87f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_get_minmax_index(struct gl_context *ctx,
882708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt		     const struct _mesa_prim *prim,
892708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt		     const struct _mesa_index_buffer *ib,
9042d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu		     GLuint *min_index, GLuint *max_index,
9142d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu		     const GLuint count)
92fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
93be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   const GLboolean restart = ctx->Array.PrimitiveRestart;
94be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   const GLuint restartIndex = ctx->Array.RestartIndex;
95bbc74ffad6551272a4551f8dd9de5b34916c0ac2Brian Paul   const int index_size = vbo_sizeof_ib_type(ib->type);
96bbc74ffad6551272a4551f8dd9de5b34916c0ac2Brian Paul   const char *indices;
97be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   GLuint i;
982708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
99bbc74ffad6551272a4551f8dd9de5b34916c0ac2Brian Paul   indices = (char *) ib->ptr + prim->start * index_size;
100bd4c6a2e503db43e81ef41f77d876308badd93ebBrian Paul   if (_mesa_is_bufferobj(ib->obj)) {
10190d654b09d98fc597ca273c65c2b1b00a9c35f09Brian Paul      GLsizeiptr size = MIN2(count * index_size, ib->obj->Size);
102bbc74ffad6551272a4551f8dd9de5b34916c0ac2Brian Paul      indices = ctx->Driver.MapBufferRange(ctx, (GLintptr) indices, size,
10342d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu                                           GL_MAP_READ_BIT, ib->obj);
1042708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   }
105fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1062708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   switch (ib->type) {
107fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_INT: {
108855374a76a6e83cc0ad4af143b74e655e7b77d5eBrian Paul      const GLuint *ui_indices = (const GLuint *)indices;
109be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      GLuint max_ui = 0;
110be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      GLuint min_ui = ~0U;
111be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      if (restart) {
112be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         for (i = 0; i < count; i++) {
113be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            if (ui_indices[i] != restartIndex) {
114be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul               if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
115be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul               if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
116be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            }
117be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         }
118be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      }
119be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      else {
120be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         for (i = 0; i < count; i++) {
121be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
122be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
123be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         }
124893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      }
125893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      *min_index = min_ui;
126893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      *max_index = max_ui;
127893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      break;
128fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
129fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_SHORT: {
130fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      const GLushort *us_indices = (const GLushort *)indices;
131be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      GLuint max_us = 0;
132be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      GLuint min_us = ~0U;
133be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      if (restart) {
134be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         for (i = 0; i < count; i++) {
135be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            if (us_indices[i] != restartIndex) {
136be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul               if (us_indices[i] > max_us) max_us = us_indices[i];
137be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul               if (us_indices[i] < min_us) min_us = us_indices[i];
138be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            }
139be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         }
140be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      }
141be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      else {
142be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         for (i = 0; i < count; i++) {
143be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            if (us_indices[i] > max_us) max_us = us_indices[i];
144be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            if (us_indices[i] < min_us) min_us = us_indices[i];
145be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         }
146893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      }
147893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      *min_index = min_us;
148893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      *max_index = max_us;
149893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      break;
150fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
151fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_BYTE: {
152fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      const GLubyte *ub_indices = (const GLubyte *)indices;
153be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      GLuint max_ub = 0;
154be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      GLuint min_ub = ~0U;
155be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      if (restart) {
156be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         for (i = 0; i < count; i++) {
157be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            if (ub_indices[i] != restartIndex) {
158be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul               if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
159be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul               if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
160be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            }
161be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         }
162be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      }
163be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      else {
164be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         for (i = 0; i < count; i++) {
165be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
166be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
167be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         }
168893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      }
169893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      *min_index = min_ub;
170893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      *max_index = max_ub;
171893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      break;
172fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
173fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   default:
174893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      assert(0);
175893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      break;
176fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1772708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
178bd4c6a2e503db43e81ef41f77d876308badd93ebBrian Paul   if (_mesa_is_bufferobj(ib->obj)) {
17956f0c00f125ee75caeadc1c9e8cab8a488635e5eIan Romanick      ctx->Driver.UnmapBuffer(ctx, ib->obj);
1802708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   }
181fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
182fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
18342d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu/**
18442d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu * Compute min and max elements for nr_prims
18542d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu */
18642d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liuvoid
18742d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liuvbo_get_minmax_indices(struct gl_context *ctx,
18842d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu                       const struct _mesa_prim *prims,
18942d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu                       const struct _mesa_index_buffer *ib,
19042d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu                       GLuint *min_index,
19142d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu                       GLuint *max_index,
19242d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu                       GLuint nr_prims)
19342d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu{
19442d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu   GLuint tmp_min, tmp_max;
19542d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu   GLuint i;
19642d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu   GLuint count;
19742d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu
19842d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu   *min_index = ~0;
19942d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu   *max_index = 0;
20042d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu
20142d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu   for (i = 0; i < nr_prims; i++) {
20242d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu      const struct _mesa_prim *start_prim;
20342d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu
20442d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu      start_prim = &prims[i];
20542d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu      count = start_prim->count;
20642d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu      /* Do combination if possible to reduce map/unmap count */
20742d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu      while ((i + 1 < nr_prims) &&
20842d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu             (prims[i].start + prims[i].count == prims[i+1].start)) {
20942d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu         count += prims[i+1].count;
21042d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu         i++;
21142d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu      }
21242d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu      vbo_get_minmax_index(ctx, start_prim, ib, &tmp_min, &tmp_max, count);
21342d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu      *min_index = MIN2(*min_index, tmp_min);
21442d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu      *max_index = MAX2(*max_index, tmp_max);
21542d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu   }
21642d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu}
21742d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu
218fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
2193bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul/**
22013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul * Check that element 'j' of the array has reasonable data.
22113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul * Map VBO if needed.
222b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * For debugging purposes; not normally used.
22313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul */
22413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paulstatic void
225f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergcheck_array_data(struct gl_context *ctx, struct gl_client_array *array,
22613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                 GLuint attrib, GLuint j)
22713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul{
22813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   if (array->Enabled) {
22913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      const void *data = array->Ptr;
230bd4c6a2e503db43e81ef41f77d876308badd93ebBrian Paul      if (_mesa_is_bufferobj(array->BufferObj)) {
23113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         if (!array->BufferObj->Pointer) {
23213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul            /* need to map now */
233f9784072fee016e14e0319c705420becb2490bf9Brian Paul            array->BufferObj->Pointer =
23428249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick               ctx->Driver.MapBufferRange(ctx, 0, array->BufferObj->Size,
23528249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick					  GL_MAP_READ_BIT, array->BufferObj);
23613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         }
23713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         data = ADD_POINTERS(data, array->BufferObj->Pointer);
23813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      }
23913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      switch (array->Type) {
24013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      case GL_FLOAT:
24113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         {
24213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul            GLfloat *f = (GLfloat *) ((GLubyte *) data + array->StrideB * j);
243dd89ac249c56d04bbc23ecd9877426af9f09269cBrian Paul            GLint k;
24413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul            for (k = 0; k < array->Size; k++) {
24513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul               if (IS_INF_OR_NAN(f[k]) ||
24613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                   f[k] >= 1.0e20 || f[k] <= -1.0e10) {
247298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg                  printf("Bad array data:\n");
248298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg                  printf("  Element[%u].%u = %f\n", j, k, f[k]);
249298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg                  printf("  Array %u at %p\n", attrib, (void* ) array);
250298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg                  printf("  Type 0x%x, Size %d, Stride %d\n",
251298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg			 array->Type, array->Size, array->Stride);
252298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg                  printf("  Address/offset %p in Buffer Object %u\n",
253298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg			 array->Ptr, array->BufferObj->Name);
25413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                  f[k] = 1.0; /* XXX replace the bad value! */
25513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul               }
256133501bef2933395f14b2ebdfeda84279be93c60Brian Paul               /*assert(!IS_INF_OR_NAN(f[k]));*/
25713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul            }
25813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         }
25913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         break;
26013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      default:
26113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         ;
26213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      }
26313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   }
26413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul}
26513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
26613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
26713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul/**
26813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul * Unmap the buffer object referenced by given array, if mapped.
26913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul */
27013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paulstatic void
271f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergunmap_array_buffer(struct gl_context *ctx, struct gl_client_array *array)
27213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul{
27313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   if (array->Enabled &&
274bd4c6a2e503db43e81ef41f77d876308badd93ebBrian Paul       _mesa_is_bufferobj(array->BufferObj) &&
275bd4c6a2e503db43e81ef41f77d876308badd93ebBrian Paul       _mesa_bufferobj_mapped(array->BufferObj)) {
27656f0c00f125ee75caeadc1c9e8cab8a488635e5eIan Romanick      ctx->Driver.UnmapBuffer(ctx, array->BufferObj);
27713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   }
27813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul}
27913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
28013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
28113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul/**
28213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul * Examine the array's data for NaNs, etc.
283b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * For debug purposes; not normally used.
28413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul */
28513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paulstatic void
286f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergcheck_draw_elements_data(struct gl_context *ctx, GLsizei count, GLenum elemType,
28792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt                         const void *elements, GLint basevertex)
28813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul{
28913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
29013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   const void *elemMap;
29113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   GLint i, k;
29213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
293a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu   if (_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj)) {
29428249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick      elemMap = ctx->Driver.MapBufferRange(ctx, 0,
295a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu					   ctx->Array.ArrayObj->ElementArrayBufferObj->Size,
29628249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick					   GL_MAP_READ_BIT,
297a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu					   ctx->Array.ArrayObj->ElementArrayBufferObj);
29813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      elements = ADD_POINTERS(elements, elemMap);
29913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   }
30013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
30113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   for (i = 0; i < count; i++) {
30213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      GLuint j;
30313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
30413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      /* j = element[i] */
30513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      switch (elemType) {
30613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      case GL_UNSIGNED_BYTE:
30713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         j = ((const GLubyte *) elements)[i];
30813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         break;
30913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      case GL_UNSIGNED_SHORT:
31013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         j = ((const GLushort *) elements)[i];
31113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         break;
31213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      case GL_UNSIGNED_INT:
31313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         j = ((const GLuint *) elements)[i];
31413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         break;
31513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      default:
31613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         assert(0);
31713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      }
31813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
31913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      /* check element j of each enabled array */
32013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) {
321762c9766c93697af8d7fbaa729aed118789dbe8eMathias Fröhlich         check_array_data(ctx, &arrayObj->VertexAttrib[k], k, j);
32213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      }
32313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   }
32413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
325a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu   if (_mesa_is_bufferobj(arrayObj->ElementArrayBufferObj)) {
326a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu      ctx->Driver.UnmapBuffer(ctx, ctx->Array.ArrayObj->ElementArrayBufferObj);
32713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   }
32813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
32913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) {
33013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      unmap_array_buffer(ctx, &arrayObj->VertexAttrib[k]);
33113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   }
33213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul}
33313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
33413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
33513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul/**
33613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul * Check array data, looking for NaNs, etc.
33713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul */
33813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paulstatic void
339f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergcheck_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count)
34013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul{
34113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   /* TO DO */
34213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul}
34313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
34413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
34513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul/**
346b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Print info/data for glDrawArrays(), for debugging.
347aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul */
348aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paulstatic void
349be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paulprint_draw_arrays(struct gl_context *ctx,
350aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul                  GLenum mode, GLint start, GLsizei count)
351aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul{
352be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   struct vbo_context *vbo = vbo_context(ctx);
353be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   struct vbo_exec_context *exec = &vbo->exec;
35491d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich   struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
355aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul   int i;
356aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul
357298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg   printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n",
358298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	  mode, start, count);
359aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul
360aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul   for (i = 0; i < 32; i++) {
3618852e35e29ff941172540e1ec7158b9259f46c3cBrian Paul      struct gl_buffer_object *bufObj = exec->array.inputs[i]->BufferObj;
3628852e35e29ff941172540e1ec7158b9259f46c3cBrian Paul      GLuint bufName = bufObj->Name;
363aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul      GLint stride = exec->array.inputs[i]->Stride;
364298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("attr %2d: size %d stride %d  enabled %d  "
365298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	     "ptr %p  Bufobj %u\n",
366298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	     i,
367298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	     exec->array.inputs[i]->Size,
368298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	     stride,
369298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	     /*exec->array.inputs[i]->Enabled,*/
37091d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	     arrayObj->VertexAttrib[VERT_ATTRIB_FF(i)].Enabled,
371298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	     exec->array.inputs[i]->Ptr,
372298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	     bufName);
373aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul
374aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul      if (bufName) {
37528249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick         GLubyte *p = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size,
37628249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick						 GL_MAP_READ_BIT, bufObj);
377aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         int offset = (int) (GLintptr) exec->array.inputs[i]->Ptr;
378aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         float *f = (float *) (p + offset);
379aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         int *k = (int *) f;
380aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         int i;
381aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         int n = (count * stride) / 4;
382aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         if (n > 32)
383aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul            n = 32;
384298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg         printf("  Data at offset %d:\n", offset);
385aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         for (i = 0; i < n; i++) {
386298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg            printf("    float[%d] = 0x%08x %f\n", i, k[i], f[i]);
387aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         }
38856f0c00f125ee75caeadc1c9e8cab8a488635e5eIan Romanick         ctx->Driver.UnmapBuffer(ctx, bufObj);
389aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul      }
390aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul   }
391aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul}
392aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul
393aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul
394aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul/**
395b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Set the vbo->exec->inputs[] pointers to point to the enabled
396b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * vertex arrays.  This depends on the current vertex program/shader
397b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * being executed because of whether or not generic vertex arrays
398b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * alias the conventional vertex arrays.
399b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * For arrays that aren't enabled, we set the input[attrib] pointer
400b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * to point at a zero-stride current value "array".
401b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
4020b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulstatic void
403f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergrecalculate_input_bindings(struct gl_context *ctx)
404fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
40599efde461d3b8615863bdb7308e05289e0db0422Keith Whitwell   struct vbo_context *vbo = vbo_context(ctx);
40699efde461d3b8615863bdb7308e05289e0db0422Keith Whitwell   struct vbo_exec_context *exec = &vbo->exec;
40791d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich   struct gl_client_array *vertexAttrib = ctx->Array.ArrayObj->VertexAttrib;
408fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   const struct gl_client_array **inputs = &exec->array.inputs[0];
409dca6a28a14f22d77273d79d44f57b0d853c0242dMathias Fröhlich   GLbitfield64 const_inputs = 0x0;
410fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
411fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
412409748ac0b92aacae6ad9c2bcedca4fef8986eeaMathias Froehlich   switch (get_program_mode(ctx)) {
413fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case VP_NONE:
4143bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul      /* When no vertex program is active (or the vertex program is generated
4153bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul       * from fixed-function state).  We put the material values into the
4163bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul       * generic slots.  This is the only situation where material values
4173bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul       * are available as per-vertex attributes.
418fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
419ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich      for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) {
42091d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	 if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled)
42191d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	    inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)];
4221680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell	 else {
423fa48137f292bbf8cbcd65e9caf33633cddc96600Marek Olšák	    inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i];
424ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich            const_inputs |= VERT_BIT(i);
4251680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell         }
426fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
427fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
428fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0; i < MAT_ATTRIB_MAX; i++) {
429ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich	 inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->mat_currval[i];
430ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich         const_inputs |= VERT_BIT_GENERIC(i);
431fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
4325a652f595716a82ebd79e33011f6082199c4b0d0Keith Whitwell
4335a652f595716a82ebd79e33011f6082199c4b0d0Keith Whitwell      /* Could use just about anything, just to fill in the empty
4345a652f595716a82ebd79e33011f6082199c4b0d0Keith Whitwell       * slots:
4355a652f595716a82ebd79e33011f6082199c4b0d0Keith Whitwell       */
436ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich      for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_GENERIC_MAX; i++) {
437ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich	 inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->generic_currval[i];
438ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich         const_inputs |= VERT_BIT_GENERIC(i);
4391680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      }
440ef58598c1cf2ac689f67c75b2f477f2c404fce98Marek Olšák
441ef58598c1cf2ac689f67c75b2f477f2c404fce98Marek Olšák      /* There is no need to make _NEW_ARRAY dirty here for the TnL program,
442ef58598c1cf2ac689f67c75b2f477f2c404fce98Marek Olšák       * because it already takes care of invalidating the state necessary
443ef58598c1cf2ac689f67c75b2f477f2c404fce98Marek Olšák       * to revalidate vertex arrays. Not marking the state as dirty also
444ef58598c1cf2ac689f67c75b2f477f2c404fce98Marek Olšák       * improves performance (quite significantly in some apps).
445ef58598c1cf2ac689f67c75b2f477f2c404fce98Marek Olšák       */
446ef58598c1cf2ac689f67c75b2f477f2c404fce98Marek Olšák      if (!ctx->VertexProgram._MaintainTnlProgram)
447ef58598c1cf2ac689f67c75b2f477f2c404fce98Marek Olšák         ctx->NewState |= _NEW_ARRAY;
448fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
4493bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul
450fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case VP_NV:
451fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* NV_vertex_program - attribute arrays alias and override
452fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * conventional, legacy arrays.  No materials, and the generic
453fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * slots are vacant.
454fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
455ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich      for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) {
456ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich	 if (i < VERT_ATTRIB_GENERIC_MAX
45791d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich             && vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
45891d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	    inputs[i] = &vertexAttrib[VERT_ATTRIB_GENERIC(i)];
45991d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	 else if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled)
46091d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	    inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)];
4611680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell	 else {
462fa48137f292bbf8cbcd65e9caf33633cddc96600Marek Olšák	    inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i];
463ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich            const_inputs |= VERT_BIT_FF(i);
4641680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell         }
465fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
466301acdf34ad01315f41c14638d92aa7fe0c2d2dcKeith Whitwell
467301acdf34ad01315f41c14638d92aa7fe0c2d2dcKeith Whitwell      /* Could use just about anything, just to fill in the empty
468301acdf34ad01315f41c14638d92aa7fe0c2d2dcKeith Whitwell       * slots:
469301acdf34ad01315f41c14638d92aa7fe0c2d2dcKeith Whitwell       */
470ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich      for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) {
471ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich	 inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->generic_currval[i];
472ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich         const_inputs |= VERT_BIT_GENERIC(i);
4731680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      }
474ef58598c1cf2ac689f67c75b2f477f2c404fce98Marek Olšák
475ef58598c1cf2ac689f67c75b2f477f2c404fce98Marek Olšák      ctx->NewState |= _NEW_ARRAY;
476fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
4773bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul
478fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case VP_ARB:
4793bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul      /* GL_ARB_vertex_program or GLSL vertex shader - Only the generic[0]
4803bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul       * attribute array aliases and overrides the legacy position array.
481fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       *
482fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * Otherwise, legacy attributes available in the legacy slots,
483fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * generic attributes in the generic slots and materials are not
484fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * available as per-vertex attributes.
485fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
48691d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich      if (vertexAttrib[VERT_ATTRIB_GENERIC0].Enabled)
48791d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	 inputs[0] = &vertexAttrib[VERT_ATTRIB_GENERIC0];
48891d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich      else if (vertexAttrib[VERT_ATTRIB_POS].Enabled)
48991d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	 inputs[0] = &vertexAttrib[VERT_ATTRIB_POS];
4901680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      else {
491fa48137f292bbf8cbcd65e9caf33633cddc96600Marek Olšák	 inputs[0] = &vbo->currval[VBO_ATTRIB_POS];
492ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich         const_inputs |= VERT_BIT_POS;
4931680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      }
494fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
495ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich      for (i = 1; i < VERT_ATTRIB_FF_MAX; i++) {
49691d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	 if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled)
49791d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	    inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)];
4981680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell	 else {
499fa48137f292bbf8cbcd65e9caf33633cddc96600Marek Olšák	    inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i];
500ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich            const_inputs |= VERT_BIT_FF(i);
5011680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell         }
502fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
503fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
504ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich      for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) {
50591d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	 if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
50691d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	    inputs[VERT_ATTRIB_GENERIC(i)] = &vertexAttrib[VERT_ATTRIB_GENERIC(i)];
5071680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell	 else {
508ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich	    inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->generic_currval[i];
509ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich            const_inputs |= VERT_BIT_GENERIC(i);
5101680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell         }
511fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
512ef58598c1cf2ac689f67c75b2f477f2c404fce98Marek Olšák
513c19f8ab2796a68d5e0c3c6334e7597f7f1c4c757Ian Romanick      inputs[VERT_ATTRIB_GENERIC0] = inputs[0];
514ef58598c1cf2ac689f67c75b2f477f2c404fce98Marek Olšák      ctx->NewState |= _NEW_ARRAY;
515fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
516fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
5171680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell
518dca6a28a14f22d77273d79d44f57b0d853c0242dMathias Fröhlich   _mesa_set_varying_vp_inputs( ctx, VERT_BIT_ALL & (~const_inputs) );
519fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
520fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
5213bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul
5225ce9183c1c535d924a79c2b6b280c6a2648cec19Brian Paul/**
5235ce9183c1c535d924a79c2b6b280c6a2648cec19Brian Paul * Examine the enabled vertex arrays to set the exec->array.inputs[] values.
5245ce9183c1c535d924a79c2b6b280c6a2648cec19Brian Paul * These will point to the arrays to actually use for drawing.  Some will
5255ce9183c1c535d924a79c2b6b280c6a2648cec19Brian Paul * be user-provided arrays, other will be zero-stride const-valued arrays.
526576c8c592a4be7047a00b0c8fe3851b09f10d8d4Marek Olšák * Note that this might set the _NEW_VARYING_VP_INPUTS dirty flag so state
527576c8c592a4be7047a00b0c8fe3851b09f10d8d4Marek Olšák * validation must be done after this call.
5285ce9183c1c535d924a79c2b6b280c6a2648cec19Brian Paul */
5298c7c589c4e70d7cdcceb350aa4edd3d9eec4403eChad Versacevoid
5308c7c589c4e70d7cdcceb350aa4edd3d9eec4403eChad Versacevbo_bind_arrays(struct gl_context *ctx)
531fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
532784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák   struct vbo_context *vbo = vbo_context(ctx);
533784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák   struct vbo_exec_context *exec = &vbo->exec;
534784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák
535784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák   vbo_draw_method(exec, DRAW_ARRAYS);
536cfaf217135d8a8e903b3fbf380f18170df018f0cMarek Olšák
537784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák   if (exec->array.recalculate_inputs) {
538784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák      recalculate_input_bindings(ctx);
539784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák
540784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák      /* Again... because we may have changed the bitmask of per-vertex varying
541784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák       * attributes.  If we regenerate the fixed-function vertex program now
542784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák       * we may be able to prune down the number of vertex attributes which we
543784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák       * need in the shader.
544784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák       */
545784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák      if (ctx->NewState) {
546784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák         _mesa_update_state(ctx);
547784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák      }
548784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák
549784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák      exec->array.recalculate_inputs = GL_FALSE;
550784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák   }
551fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
552fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
553fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
554be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul/**
555be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul * Helper function called by the other DrawArrays() functions below.
556be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul * This is where we handle primitive restart for drawing non-indexed
557be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul * arrays.  If primitive restart is enabled, it typically means
558be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul * splitting one DrawArrays() into two.
559be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul */
560be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paulstatic void
561be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paulvbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
562be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul                GLsizei count, GLuint numInstances)
563be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul{
564be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   struct vbo_context *vbo = vbo_context(ctx);
565be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   struct vbo_exec_context *exec = &vbo->exec;
566be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   struct _mesa_prim prim[2];
567be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
5688c7c589c4e70d7cdcceb350aa4edd3d9eec4403eChad Versace   vbo_bind_arrays(ctx);
569be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
5700630593c5fb22fe0f98f2c815c4a315056a9e3d2Brian Paul   /* init most fields to zero */
5710630593c5fb22fe0f98f2c815c4a315056a9e3d2Brian Paul   memset(prim, 0, sizeof(prim));
572be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   prim[0].begin = 1;
573be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   prim[0].end = 1;
574be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   prim[0].mode = mode;
575be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   prim[0].num_instances = numInstances;
576be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
577be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   /* Implement the primitive restart index */
578be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   if (ctx->Array.PrimitiveRestart && ctx->Array.RestartIndex < count) {
579be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      GLuint primCount = 0;
580be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
581be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      if (ctx->Array.RestartIndex == start) {
582be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         /* special case: RestartIndex at beginning */
583be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         if (count > 1) {
584be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            prim[0].start = start + 1;
585be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            prim[0].count = count - 1;
586be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            primCount = 1;
587be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         }
588be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      }
589be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      else if (ctx->Array.RestartIndex == start + count - 1) {
590be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         /* special case: RestartIndex at end */
591be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         if (count > 1) {
592be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            prim[0].start = start;
593be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            prim[0].count = count - 1;
594be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            primCount = 1;
595be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         }
596be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      }
597be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      else {
598be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         /* general case: RestartIndex in middle, split into two prims */
599be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         prim[0].start = start;
600be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         prim[0].count = ctx->Array.RestartIndex - start;
601be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
602be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         prim[1] = prim[0];
603be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         prim[1].start = ctx->Array.RestartIndex + 1;
604be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         prim[1].count = count - prim[1].start;
605be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
606be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         primCount = 2;
607be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      }
608be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
609be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      if (primCount > 0) {
610be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         /* draw one or two prims */
6117ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul         check_buffers_are_unmapped(exec->array.inputs);
612be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         vbo->draw_prims(ctx, exec->array.inputs, prim, primCount, NULL,
61314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák                         GL_TRUE, start, start + count - 1, NULL);
614be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      }
615be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   }
616be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   else {
617be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      /* no prim restart */
618be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      prim[0].start = start;
619be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      prim[0].count = count;
620be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
6217ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul      check_buffers_are_unmapped(exec->array.inputs);
622be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      vbo->draw_prims(ctx, exec->array.inputs, prim, 1, NULL,
62314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák                      GL_TRUE, start, start + count - 1,
62414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák                      NULL);
625be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   }
626be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul}
627be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
628be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
629fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
630b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
631b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Called from glDrawArrays when in immediate mode (not display list mode).
632fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
633fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY
634fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellvbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
635fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
636fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
637fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
638ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul   if (MESA_VERBOSE & VERBOSE_DRAW)
639ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul      _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n",
640ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  _mesa_lookup_enum_by_nr(mode), start, count);
641ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul
642fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
643fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
644fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
645fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   FLUSH_CURRENT( ctx, 0 );
646fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
647be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   if (0)
648be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      check_draw_arrays_data(ctx, start, count);
649fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
650be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   vbo_draw_arrays(ctx, mode, start, count, 1);
651a3b7db0326337117ccdea526818040d2c24d83b4Brian Paul
652be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   if (0)
653be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      print_draw_arrays(ctx, mode, start, count);
654fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
655fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
656fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
657b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
658b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Called from glDrawArraysInstanced when in immediate mode (not
659b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * display list mode).
660b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
6613b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paulstatic void GLAPIENTRY
6623b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paulvbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
66372f2551017e03f888d63fa9040120740c6d40620Brian Paul                             GLsizei numInstances)
6643b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul{
6653b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   GET_CURRENT_CONTEXT(ctx);
6663b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
6673b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   if (MESA_VERBOSE & VERBOSE_DRAW)
6683b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul      _mesa_debug(ctx, "glDrawArraysInstanced(%s, %d, %d, %d)\n",
66972f2551017e03f888d63fa9040120740c6d40620Brian Paul                  _mesa_lookup_enum_by_nr(mode), start, count, numInstances);
6703b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
67172f2551017e03f888d63fa9040120740c6d40620Brian Paul   if (!_mesa_validate_DrawArraysInstanced(ctx, mode, start, count, numInstances))
6723b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul      return;
6733b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
6743b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   FLUSH_CURRENT( ctx, 0 );
6753b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
676be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   if (0)
677be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      check_draw_arrays_data(ctx, start, count);
6783b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
67972f2551017e03f888d63fa9040120740c6d40620Brian Paul   vbo_draw_arrays(ctx, mode, start, count, numInstances);
6803b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
681be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   if (0)
682be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      print_draw_arrays(ctx, mode, start, count);
6833b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul}
6843b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
6853b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
686c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul/**
687c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul * Map GL_ELEMENT_ARRAY_BUFFER and print contents.
688b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * For debugging.
689c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul */
690f9be8543aab9005c30b38331b9f7250a01720942Kenneth Graunke#if 0
691c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paulstatic void
692f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergdump_element_buffer(struct gl_context *ctx, GLenum type)
693c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul{
69428249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick   const GLvoid *map =
69528249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick      ctx->Driver.MapBufferRange(ctx, 0,
696a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu				 ctx->Array.ArrayObj->ElementArrayBufferObj->Size,
69728249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick				 GL_MAP_READ_BIT,
698a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu				 ctx->Array.ArrayObj->ElementArrayBufferObj);
699c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   switch (type) {
700c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   case GL_UNSIGNED_BYTE:
701c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      {
702c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         const GLubyte *us = (const GLubyte *) map;
703dd89ac249c56d04bbc23ecd9877426af9f09269cBrian Paul         GLint i;
704a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu         for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size; i++) {
705298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg            printf("%02x ", us[i]);
706c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul            if (i % 32 == 31)
707298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg               printf("\n");
708c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         }
709298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg         printf("\n");
710c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      }
711c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      break;
712c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   case GL_UNSIGNED_SHORT:
713c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      {
714c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         const GLushort *us = (const GLushort *) map;
715dd89ac249c56d04bbc23ecd9877426af9f09269cBrian Paul         GLint i;
716a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu         for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 2; i++) {
717298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg            printf("%04x ", us[i]);
718c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul            if (i % 16 == 15)
719298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg               printf("\n");
720c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         }
721298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg         printf("\n");
722c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      }
723c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      break;
724c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   case GL_UNSIGNED_INT:
725c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      {
726c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         const GLuint *us = (const GLuint *) map;
727dd89ac249c56d04bbc23ecd9877426af9f09269cBrian Paul         GLint i;
728a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu         for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 4; i++) {
729298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg            printf("%08x ", us[i]);
730c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul            if (i % 8 == 7)
731298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg               printf("\n");
732c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         }
733298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg         printf("\n");
734c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      }
735c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      break;
736c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   default:
737c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      ;
738c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   }
739c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul
740a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu   ctx->Driver.UnmapBuffer(ctx, ctx->Array.ArrayObj->ElementArrayBufferObj);
741c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul}
742f9be8543aab9005c30b38331b9f7250a01720942Kenneth Graunke#endif
743c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul
744f9784072fee016e14e0319c705420becb2490bf9Brian Paul
745b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
746b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements.
747b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Do the rendering for a glDrawElements or glDrawRangeElements call after
748b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * we've validated buffer bounds, etc.
749b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
7502708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholtstatic void
751f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
7522708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt				GLboolean index_bounds_valid,
7532708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt				GLuint start, GLuint end,
7542708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt				GLsizei count, GLenum type,
75592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				const GLvoid *indices,
75672f2551017e03f888d63fa9040120740c6d40620Brian Paul				GLint basevertex, GLint numInstances)
757fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
758fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_context *vbo = vbo_context(ctx);
759fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_exec_context *exec = &vbo->exec;
760fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct _mesa_index_buffer ib;
761fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct _mesa_prim prim[1];
762fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
763fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   FLUSH_CURRENT( ctx, 0 );
764fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
765784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák   vbo_bind_arrays(ctx);
7661680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell
767fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ib.count = count;
7682708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   ib.type = type;
769a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu   ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
770fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ib.ptr = indices;
771fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
772fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].begin = 1;
773fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].end = 1;
774fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].weak = 0;
775fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].pad = 0;
776fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].mode = mode;
777fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].start = 0;
778fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].count = count;
779fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].indexed = 1;
78092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   prim[0].basevertex = basevertex;
78172f2551017e03f888d63fa9040120740c6d40620Brian Paul   prim[0].num_instances = numInstances;
782fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
783893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   /* Need to give special consideration to rendering a range of
784893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * indices starting somewhere above zero.  Typically the
785893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * application is issuing multiple DrawRangeElements() to draw
786893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * successive primitives layed out linearly in the vertex arrays.
787893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * Unless the vertex arrays are all in a VBO (or locked as with
788893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * CVA), the OpenGL semantics imply that we need to re-read or
789893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * re-upload the vertex data on each draw call.
790893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
791893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * In the case of hardware tnl, we want to avoid starting the
792893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * upload at zero, as it will mean every draw call uploads an
793893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * increasing amount of not-used vertex data.  Worse - in the
794893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * software tnl module, all those vertices might be transformed and
795893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * lit but never rendered.
796893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
797893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * If we just upload or transform the vertices in start..end,
798893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * however, the indices will be incorrect.
799893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
800893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * At this level, we don't know exactly what the requirements of
801893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * the backend are going to be, though it will likely boil down to
802893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * either:
803893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
804893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * 1) Do nothing, everything is in a VBO and is processed once
805893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *       only.
806893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
807893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * 2) Adjust the indices and vertex arrays so that start becomes
808893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *    zero.
809893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
810893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * Rather than doing anything here, I'll provide a helper function
811893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * for the latter case elsewhere.
812893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    */
813fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8147ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul   check_buffers_are_unmapped(exec->array.inputs);
8152708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib,
81614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák		    index_bounds_valid, start, end, NULL );
817893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell}
818fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
819b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul
820b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
821b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Called by glDrawRangeElementsBaseVertex() in immediate mode.
822b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
823fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY
82492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
82592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     GLuint start, GLuint end,
82692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     GLsizei count, GLenum type,
82792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     const GLvoid *indices,
82892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     GLint basevertex)
829fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
830f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke   static GLuint warnCount = 0;
831112b02c32402d96fd7d526ab84877bb66dc12de4Kenneth Graunke   GLboolean index_bounds_valid = GL_TRUE;
832fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
833fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
834ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul   if (MESA_VERBOSE & VERBOSE_DRAW)
835ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul      _mesa_debug(ctx,
836ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n",
837ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                _mesa_lookup_enum_by_nr(mode), start, end, count,
838ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                _mesa_lookup_enum_by_nr(type), indices, basevertex);
839ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul
8402708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count,
84192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt                                          type, indices, basevertex ))
842fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
843fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
844f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke   if ((int) end + basevertex < 0 ||
845f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke       start + basevertex >= ctx->Array.ArrayObj->_MaxElement) {
846f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke      /* The application requested we draw using a range of indices that's
847f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke       * outside the bounds of the current VBO.  This is invalid and appears
848f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke       * to give undefined results.  The safest thing to do is to simply
849f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke       * ignore the range, in case the application botched their range tracking
850f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke       * but did provide valid indices.  Also issue a warning indicating that
851f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke       * the application is broken.
852f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke       */
853f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke      if (warnCount++ < 10) {
854f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke         _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, "
855f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke                       "basevertex %d, count %d, type 0x%x, indices=%p):\n"
856f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke                       "\trange is outside VBO bounds (max=%u); ignoring.\n"
857f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke                       "\tThis should be fixed in the application.",
858f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke                       start, end, basevertex, count, type, indices,
859f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke                       ctx->Array.ArrayObj->_MaxElement - 1);
860f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke      }
8616e738d35c5c88769ececbadd5f4ac14d36647168Kenneth Graunke      index_bounds_valid = GL_FALSE;
862f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke   }
863f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke
86494a020cfe6cb1da04695897eed38b530af31f524Brian Paul   /* NOTE: It's important that 'end' is a reasonable value.
86594a020cfe6cb1da04695897eed38b530af31f524Brian Paul    * in _tnl_draw_prims(), we use end to determine how many vertices
86694a020cfe6cb1da04695897eed38b530af31f524Brian Paul    * to transform.  If it's too large, we can unnecessarily split prims
86794a020cfe6cb1da04695897eed38b530af31f524Brian Paul    * or we can read/write out of memory in several different places!
86894a020cfe6cb1da04695897eed38b530af31f524Brian Paul    */
86994a020cfe6cb1da04695897eed38b530af31f524Brian Paul
870645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul   /* Catch/fix some potential user errors */
871645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul   if (type == GL_UNSIGNED_BYTE) {
872645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul      start = MIN2(start, 0xff);
873645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul      end = MIN2(end, 0xff);
874645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul   }
875645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul   else if (type == GL_UNSIGNED_SHORT) {
876645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul      start = MIN2(start, 0xffff);
877645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul      end = MIN2(end, 0xffff);
878645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul   }
879645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul
88023d75936a72b9a9b9e1d04a901a86a75d93dbffbJosé Fonseca   if (0) {
881298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("glDraw[Range]Elements{,BaseVertex}"
882298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	     "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, "
883298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	     "base %d\n",
884298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	     start, end, type, count,
885a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu	     ctx->Array.ArrayObj->ElementArrayBufferObj->Name,
886298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	     basevertex);
8872708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   }
888d758479b9fbff803bdac15f3f39d32ef9064db71Brian Paul
889112b02c32402d96fd7d526ab84877bb66dc12de4Kenneth Graunke   if ((int) start + basevertex < 0 ||
890112b02c32402d96fd7d526ab84877bb66dc12de4Kenneth Graunke       end + basevertex >= ctx->Array.ArrayObj->_MaxElement)
891112b02c32402d96fd7d526ab84877bb66dc12de4Kenneth Graunke      index_bounds_valid = GL_FALSE;
892112b02c32402d96fd7d526ab84877bb66dc12de4Kenneth Graunke
8932708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt#if 0
8942708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   check_draw_elements_data(ctx, count, type, indices);
8952708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt#else
8962708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   (void) check_draw_elements_data;
8972708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt#endif
8982708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
899112b02c32402d96fd7d526ab84877bb66dc12de4Kenneth Graunke   vbo_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end,
9003b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul				   count, type, indices, basevertex, 1);
90192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
90292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
903f9784072fee016e14e0319c705420becb2490bf9Brian Paul
904b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
905b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Called by glDrawRangeElements() in immediate mode.
906b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
90792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtstatic void GLAPIENTRY
908f9784072fee016e14e0319c705420becb2490bf9Brian Paulvbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
909f9784072fee016e14e0319c705420becb2490bf9Brian Paul                           GLsizei count, GLenum type, const GLvoid *indices)
91092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
911b6df603e650527d5fa7f0fc1448be1bb57f47fbbDave Airlie   if (MESA_VERBOSE & VERBOSE_DRAW) {
912b6df603e650527d5fa7f0fc1448be1bb57f47fbbDave Airlie      GET_CURRENT_CONTEXT(ctx);
913ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul      _mesa_debug(ctx,
914ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n",
915ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  _mesa_lookup_enum_by_nr(mode), start, end, count,
916ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  _mesa_lookup_enum_by_nr(type), indices);
917b6df603e650527d5fa7f0fc1448be1bb57f47fbbDave Airlie   }
918ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul
91992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
92092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt					indices, 0);
9212708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt}
922fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
923fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
924b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
925b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Called by glDrawElements() in immediate mode.
926b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
9272708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholtstatic void GLAPIENTRY
9282708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholtvbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
9292708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt                      const GLvoid *indices)
9302708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt{
9312708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   GET_CURRENT_CONTEXT(ctx);
9322708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
933ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul   if (MESA_VERBOSE & VERBOSE_DRAW)
934ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul      _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n",
935ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  _mesa_lookup_enum_by_nr(mode), count,
936ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  _mesa_lookup_enum_by_nr(type), indices);
937ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul
93892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))
93992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      return;
94092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
94192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
9423b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul				   count, type, indices, 0, 1);
94392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
94492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
945f9784072fee016e14e0319c705420becb2490bf9Brian Paul
946b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
947b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Called by glDrawElementsBaseVertex() in immediate mode.
948b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
94992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtstatic void GLAPIENTRY
95092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
95192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				const GLvoid *indices, GLint basevertex)
95292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
95392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GET_CURRENT_CONTEXT(ctx);
95492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
955ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul   if (MESA_VERBOSE & VERBOSE_DRAW)
956ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul      _mesa_debug(ctx, "glDrawElementsBaseVertex(%s, %d, %s, %p, %d)\n",
957ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  _mesa_lookup_enum_by_nr(mode), count,
958ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  _mesa_lookup_enum_by_nr(type), indices, basevertex);
959ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul
96092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices,
96192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     basevertex ))
9622708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt      return;
963fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
9642708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
9653b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul				   count, type, indices, basevertex, 1);
9663b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul}
9673b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
9683b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
969b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
970b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Called by glDrawElementsInstanced() in immediate mode.
971b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
9723b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paulstatic void GLAPIENTRY
9733b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paulvbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
97472f2551017e03f888d63fa9040120740c6d40620Brian Paul                               const GLvoid *indices, GLsizei numInstances)
9753b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul{
9763b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   GET_CURRENT_CONTEXT(ctx);
9773b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
9783b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   if (MESA_VERBOSE & VERBOSE_DRAW)
9793b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul      _mesa_debug(ctx, "glDrawElementsInstanced(%s, %d, %s, %p, %d)\n",
9803b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul                  _mesa_lookup_enum_by_nr(mode), count,
98172f2551017e03f888d63fa9040120740c6d40620Brian Paul                  _mesa_lookup_enum_by_nr(type), indices, numInstances);
9823b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
9833b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
98409201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer                                             numInstances, 0))
9853b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul      return;
9863b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
9873b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
98872f2551017e03f888d63fa9040120740c6d40620Brian Paul				   count, type, indices, 0, numInstances);
989fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
990fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
99109201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer/**
99209201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer * Called by glDrawElementsInstancedBaseVertex() in immediate mode.
99309201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer */
99409201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayerstatic void GLAPIENTRY
99509201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayervbo_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type,
99609201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer                               const GLvoid *indices, GLsizei numInstances,
99709201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer                               GLint basevertex)
99809201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer{
99909201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer   GET_CURRENT_CONTEXT(ctx);
100009201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer
100109201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer   if (MESA_VERBOSE & VERBOSE_DRAW)
100209201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer      _mesa_debug(ctx, "glDrawElementsInstancedBaseVertex(%s, %d, %s, %p, %d; %d)\n",
100309201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer                  _mesa_lookup_enum_by_nr(mode), count,
100409201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer                  _mesa_lookup_enum_by_nr(type), indices,
100509201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer                  numInstances, basevertex);
100609201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer
100709201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer   if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
100809201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer                                             numInstances, basevertex))
100909201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer      return;
101009201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer
101109201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer   vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
101209201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer				   count, type, indices, basevertex, numInstances);
101309201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer}
101409201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer
1015f9784072fee016e14e0319c705420becb2490bf9Brian Paul
1016b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
1017b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Inner support for both _mesa_MultiDrawElements() and
1018b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * _mesa_MultiDrawRangeElements().
1019b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * This does the actual rendering after we've checked array indexes, etc.
1020b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
102160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholtstatic void
1022f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
102360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt				const GLsizei *count, GLenum type,
102492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				const GLvoid **indices, GLsizei primcount,
102592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				const GLint *basevertex)
102660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt{
102760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   struct vbo_context *vbo = vbo_context(ctx);
102860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   struct vbo_exec_context *exec = &vbo->exec;
102960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   struct _mesa_index_buffer ib;
103060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   struct _mesa_prim *prim;
1031efa1fac2158c9146b87f0d4340a864661721de21Yuanhan Liu   unsigned int index_type_size = vbo_sizeof_ib_type(type);
103260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   uintptr_t min_index_ptr, max_index_ptr;
103360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   GLboolean fallback = GL_FALSE;
103460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   int i;
103560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
103660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (primcount == 0)
103760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      return;
103860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
103960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   FLUSH_CURRENT( ctx, 0 );
104060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
104132f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   prim = calloc(1, primcount * sizeof(*prim));
104260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (prim == NULL) {
104360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements");
104460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      return;
104560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
104660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
1047784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák   vbo_bind_arrays(ctx);
10485ce9183c1c535d924a79c2b6b280c6a2648cec19Brian Paul
104960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   min_index_ptr = (uintptr_t)indices[0];
105060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   max_index_ptr = 0;
105160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   for (i = 0; i < primcount; i++) {
105260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      min_index_ptr = MIN2(min_index_ptr, (uintptr_t)indices[i]);
105360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      max_index_ptr = MAX2(max_index_ptr, (uintptr_t)indices[i] +
105460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt			   index_type_size * count[i]);
105560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
105660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
105760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   /* Check if we can handle this thing as a bunch of index offsets from the
105860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    * same index pointer.  If we can't, then we have to fall back to doing
105960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    * a draw_prims per primitive.
1060be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul    * Check that the difference between each prim's indexes is a multiple of
1061be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul    * the index/element size.
106260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    */
106360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (index_type_size != 1) {
106460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      for (i = 0; i < primcount; i++) {
106560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 if ((((uintptr_t)indices[i] - min_index_ptr) % index_type_size) != 0) {
106660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	    fallback = GL_TRUE;
106760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	    break;
106860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 }
106960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      }
107060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
107160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
107260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   /* If the index buffer isn't in a VBO, then treating the application's
107360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    * subranges of the index buffer as one large index buffer may lead to
107460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    * us reading unmapped memory.
107560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    */
1076a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu   if (!_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj))
107760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      fallback = GL_TRUE;
107860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
107960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (!fallback) {
108060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      ib.count = (max_index_ptr - min_index_ptr) / index_type_size;
108160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      ib.type = type;
1082a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu      ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
108360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      ib.ptr = (void *)min_index_ptr;
108460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
108560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      for (i = 0; i < primcount; i++) {
108660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].begin = (i == 0);
108760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].end = (i == primcount - 1);
108860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].weak = 0;
108960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].pad = 0;
109060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].mode = mode;
109160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].start = ((uintptr_t)indices[i] - min_index_ptr) / index_type_size;
109260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].count = count[i];
109360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].indexed = 1;
10943b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul         prim[i].num_instances = 1;
109592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 if (basevertex != NULL)
109692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    prim[i].basevertex = basevertex[i];
109792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 else
109892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    prim[i].basevertex = 0;
109960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      }
110060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
11017ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul      check_buffers_are_unmapped(exec->array.inputs);
110260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      vbo->draw_prims(ctx, exec->array.inputs, prim, primcount, &ib,
110314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák		      GL_FALSE, ~0, ~0, NULL);
110460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   } else {
110536a54885a4b2eb2b23361f2add3d66e385a322cfBrian Paul      /* render one prim at a time */
110660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      for (i = 0; i < primcount; i++) {
110760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 ib.count = count[i];
110860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 ib.type = type;
1109a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu	 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
111060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 ib.ptr = indices[i];
111160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
111260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].begin = 1;
111360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].end = 1;
111460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].weak = 0;
111560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].pad = 0;
111660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].mode = mode;
111760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].start = 0;
111860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].count = count[i];
111960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].indexed = 1;
11203b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul         prim[0].num_instances = 1;
112192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 if (basevertex != NULL)
112292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    prim[0].basevertex = basevertex[i];
112392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 else
112492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    prim[0].basevertex = 0;
112560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
11267ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul         check_buffers_are_unmapped(exec->array.inputs);
112736a54885a4b2eb2b23361f2add3d66e385a322cfBrian Paul         vbo->draw_prims(ctx, exec->array.inputs, prim, 1, &ib,
112814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák                         GL_FALSE, ~0, ~0, NULL);
112936a54885a4b2eb2b23361f2add3d66e385a322cfBrian Paul      }
113060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
113136a54885a4b2eb2b23361f2add3d66e385a322cfBrian Paul
113232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   free(prim);
113360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt}
113460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
1135f9784072fee016e14e0319c705420becb2490bf9Brian Paul
113660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholtstatic void GLAPIENTRY
113760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholtvbo_exec_MultiDrawElements(GLenum mode,
113860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt			   const GLsizei *count, GLenum type,
113960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt			   const GLvoid **indices,
114060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt			   GLsizei primcount)
114160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt{
114260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   GET_CURRENT_CONTEXT(ctx);
114360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   GLint i;
114460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
114560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
114660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
114760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   for (i = 0; i < primcount; i++) {
114892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      if (!_mesa_validate_DrawElements(ctx, mode, count[i], type, indices[i],
114992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				       0))
115060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 return;
115160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
115260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
115392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
115492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				   NULL);
115560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt}
115660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
1157f9784072fee016e14e0319c705420becb2490bf9Brian Paul
115892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtstatic void GLAPIENTRY
115992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
116092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     const GLsizei *count, GLenum type,
116192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     const GLvoid **indices,
116292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     GLsizei primcount,
116392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     const GLsizei *basevertex)
116492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
116592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GET_CURRENT_CONTEXT(ctx);
116692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GLint i;
116792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
116892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
116992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
117092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   for (i = 0; i < primcount; i++) {
117192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      if (!_mesa_validate_DrawElements(ctx, mode, count[i], type, indices[i],
117292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				       basevertex[i]))
117392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 return;
117492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   }
117592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
117692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
117792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				   basevertex);
117892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
117960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
118014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák#if FEATURE_EXT_transform_feedback
118114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
118214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšákstatic void
118314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšákvbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
118414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák                            struct gl_transform_feedback_object *obj,
118514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák                            GLuint numInstances)
118614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák{
118714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   struct vbo_context *vbo = vbo_context(ctx);
118814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   struct vbo_exec_context *exec = &vbo->exec;
118914bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   struct _mesa_prim prim[2];
119014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
119114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   vbo_bind_arrays(ctx);
119214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
119314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   /* init most fields to zero */
119414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   memset(prim, 0, sizeof(prim));
119514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   prim[0].begin = 1;
119614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   prim[0].end = 1;
119714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   prim[0].mode = mode;
119814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   prim[0].num_instances = numInstances;
119914bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
120014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   /* Maybe we should do some primitive splitting for primitive restart
120114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák    * (like in DrawArrays), but we have no way to know how many vertices
120214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák    * will be rendered. */
120314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
120414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   check_buffers_are_unmapped(exec->array.inputs);
120514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   vbo->draw_prims(ctx, exec->array.inputs, prim, 1, NULL,
120614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák                   GL_TRUE, 0, 0, obj);
120714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák}
120814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
120914bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák/**
121014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák * Like DrawArrays, but take the count from a transform feedback object.
121114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák * \param mode  GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc.
121214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák * \param name  the transform feedback object
121314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák * User still has to setup of the vertex attribute info with
121414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák * glVertexPointer, glColorPointer, etc.
121514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák * Part of GL_ARB_transform_feedback2.
121614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák */
121714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšákstatic void GLAPIENTRY
121814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšákvbo_exec_DrawTransformFeedback(GLenum mode, GLuint name)
121914bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák{
122014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   GET_CURRENT_CONTEXT(ctx);
122114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   struct gl_transform_feedback_object *obj =
122214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák      _mesa_lookup_transform_feedback_object(ctx, name);
122314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
122414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   if (MESA_VERBOSE & VERBOSE_DRAW)
122514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák      _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n",
122614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák                  _mesa_lookup_enum_by_nr(mode), name);
122714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
122814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj)) {
122914bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák      return;
123014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   }
123114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
123214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   FLUSH_CURRENT(ctx, 0);
123314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
123414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   vbo_draw_transform_feedback(ctx, mode, obj, 1);
123514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák}
123614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
123714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák#endif
1238fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1239b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
1240b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Plug in the immediate-mode vertex array drawing commands into the
1241b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * givven vbo_exec_context object.
1242fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
12430b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulvoid
12440b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulvbo_exec_array_init( struct vbo_exec_context *exec )
1245fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1246fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   exec->vtxfmt.DrawArrays = vbo_exec_DrawArrays;
1247fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   exec->vtxfmt.DrawElements = vbo_exec_DrawElements;
1248fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   exec->vtxfmt.DrawRangeElements = vbo_exec_DrawRangeElements;
124960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   exec->vtxfmt.MultiDrawElementsEXT = vbo_exec_MultiDrawElements;
125092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   exec->vtxfmt.DrawElementsBaseVertex = vbo_exec_DrawElementsBaseVertex;
125192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   exec->vtxfmt.DrawRangeElementsBaseVertex = vbo_exec_DrawRangeElementsBaseVertex;
125292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   exec->vtxfmt.MultiDrawElementsBaseVertex = vbo_exec_MultiDrawElementsBaseVertex;
12533b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   exec->vtxfmt.DrawArraysInstanced = vbo_exec_DrawArraysInstanced;
12543b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   exec->vtxfmt.DrawElementsInstanced = vbo_exec_DrawElementsInstanced;
125509201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer   exec->vtxfmt.DrawElementsInstancedBaseVertex = vbo_exec_DrawElementsInstancedBaseVertex;
1256f8be4f33d31d004bfcf090fa7d4aa37b750e43afChih-Wei Huang#if FEATURE_EXT_transform_feedback
125714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   exec->vtxfmt.DrawTransformFeedback = vbo_exec_DrawTransformFeedback;
1258f8be4f33d31d004bfcf090fa7d4aa37b750e43afChih-Wei Huang#endif
1259fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1260fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1261fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
12620b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulvoid
12630b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulvbo_exec_array_destroy( struct vbo_exec_context *exec )
1264fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1265584def75ad8dd13add5b4ed7e364d13202539539Keith Whitwell   /* nothing to do */
1266fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1267feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1268feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1269b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul
1270b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
1271b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * The following functions are only used for OpenGL ES 1/2 support.
1272b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * And some aren't even supported (yet) in ES 1/2.
1273b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
1274b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul
1275b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul
1276feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paulvoid GLAPIENTRY
1277feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul_mesa_DrawArrays(GLenum mode, GLint first, GLsizei count)
1278feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul{
1279feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul   vbo_exec_DrawArrays(mode, first, count);
1280feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul}
1281feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1282feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1283feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paulvoid GLAPIENTRY
1284feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
1285feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul                   const GLvoid *indices)
1286feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul{
1287feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul   vbo_exec_DrawElements(mode, count, type, indices);
1288feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul}
1289feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1290b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul
129192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvoid GLAPIENTRY
129292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
129392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt			     const GLvoid *indices, GLint basevertex)
129492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
129592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex);
129692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
129792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
1298feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1299feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paulvoid GLAPIENTRY
1300feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
1301feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul                        GLenum type, const GLvoid *indices)
1302feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul{
1303feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul   vbo_exec_DrawRangeElements(mode, start, end, count, type, indices);
1304feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul}
130560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
1306f9784072fee016e14e0319c705420becb2490bf9Brian Paul
130792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvoid GLAPIENTRY
130892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
130992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				  GLsizei count, GLenum type,
131092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				  const GLvoid *indices, GLint basevertex)
131192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
131292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
131392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt					indices, basevertex);
131492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
131592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
1316f9784072fee016e14e0319c705420becb2490bf9Brian Paul
131760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholtvoid GLAPIENTRY
131860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,
131960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt			   const GLvoid **indices, GLsizei primcount)
132060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt{
132160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   vbo_exec_MultiDrawElements(mode, count, type, indices, primcount);
132260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt}
132392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
1324f9784072fee016e14e0319c705420becb2490bf9Brian Paul
132592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvoid GLAPIENTRY
132692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt_mesa_MultiDrawElementsBaseVertex(GLenum mode,
132792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				  const GLsizei *count, GLenum type,
132892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				  const GLvoid **indices, GLsizei primcount,
132992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				  const GLint *basevertex)
133092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
133192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices,
133292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt					primcount, basevertex);
133392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
133414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
133514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák#if FEATURE_EXT_transform_feedback
133614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
133714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšákvoid GLAPIENTRY
133814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák_mesa_DrawTransformFeedback(GLenum mode, GLuint name)
133914bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák{
134014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   vbo_exec_DrawTransformFeedback(mode, name);
134114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák}
134214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
134314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák#endif
1344