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++) {
42997e2f625b8bcba96acde29dcd017031e036f4a24Marek Olšák	 inputs[VERT_ATTRIB_GENERIC(i)] =
43097e2f625b8bcba96acde29dcd017031e036f4a24Marek Olšák	    &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+i];
431ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich         const_inputs |= VERT_BIT_GENERIC(i);
432fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
4335a652f595716a82ebd79e33011f6082199c4b0d0Keith Whitwell
4345a652f595716a82ebd79e33011f6082199c4b0d0Keith Whitwell      /* Could use just about anything, just to fill in the empty
4355a652f595716a82ebd79e33011f6082199c4b0d0Keith Whitwell       * slots:
4365a652f595716a82ebd79e33011f6082199c4b0d0Keith Whitwell       */
437ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich      for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_GENERIC_MAX; i++) {
4388c990de0d682bbedfd7e1988d4f8948ea99b0cc3Marek Olšák	 inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i];
439ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich         const_inputs |= VERT_BIT_GENERIC(i);
4401680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      }
441fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
4423bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul
443fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case VP_NV:
444fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* NV_vertex_program - attribute arrays alias and override
445fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * conventional, legacy arrays.  No materials, and the generic
446fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * slots are vacant.
447fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
448ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich      for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) {
449ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich	 if (i < VERT_ATTRIB_GENERIC_MAX
45091d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich             && vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
45191d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	    inputs[i] = &vertexAttrib[VERT_ATTRIB_GENERIC(i)];
45291d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	 else if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled)
45391d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	    inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)];
4541680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell	 else {
455fa48137f292bbf8cbcd65e9caf33633cddc96600Marek Olšák	    inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i];
456ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich            const_inputs |= VERT_BIT_FF(i);
4571680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell         }
458fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
459301acdf34ad01315f41c14638d92aa7fe0c2d2dcKeith Whitwell
460301acdf34ad01315f41c14638d92aa7fe0c2d2dcKeith Whitwell      /* Could use just about anything, just to fill in the empty
461301acdf34ad01315f41c14638d92aa7fe0c2d2dcKeith Whitwell       * slots:
462301acdf34ad01315f41c14638d92aa7fe0c2d2dcKeith Whitwell       */
463ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich      for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) {
4648c990de0d682bbedfd7e1988d4f8948ea99b0cc3Marek Olšák	 inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i];
465ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich         const_inputs |= VERT_BIT_GENERIC(i);
4661680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      }
467fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
4683bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul
469fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case VP_ARB:
4703bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul      /* GL_ARB_vertex_program or GLSL vertex shader - Only the generic[0]
4713bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul       * attribute array aliases and overrides the legacy position array.
472fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       *
473fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * Otherwise, legacy attributes available in the legacy slots,
474fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * generic attributes in the generic slots and materials are not
475fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * available as per-vertex attributes.
476fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
47791d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich      if (vertexAttrib[VERT_ATTRIB_GENERIC0].Enabled)
47891d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	 inputs[0] = &vertexAttrib[VERT_ATTRIB_GENERIC0];
47991d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich      else if (vertexAttrib[VERT_ATTRIB_POS].Enabled)
48091d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	 inputs[0] = &vertexAttrib[VERT_ATTRIB_POS];
4811680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      else {
482fa48137f292bbf8cbcd65e9caf33633cddc96600Marek Olšák	 inputs[0] = &vbo->currval[VBO_ATTRIB_POS];
483ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich         const_inputs |= VERT_BIT_POS;
4841680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      }
485fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
486ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich      for (i = 1; i < VERT_ATTRIB_FF_MAX; i++) {
48791d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	 if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled)
48891d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	    inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)];
4891680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell	 else {
490fa48137f292bbf8cbcd65e9caf33633cddc96600Marek Olšák	    inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i];
491ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich            const_inputs |= VERT_BIT_FF(i);
4921680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell         }
493fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
494fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
495ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich      for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) {
49691d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	 if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
49791d950bad1f1b94fb1751109ae8c139376f38156Mathias Fröhlich	    inputs[VERT_ATTRIB_GENERIC(i)] = &vertexAttrib[VERT_ATTRIB_GENERIC(i)];
4981680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell	 else {
4998c990de0d682bbedfd7e1988d4f8948ea99b0cc3Marek Olšák	    inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i];
500ed42c2580717527b2005580940fc766d95bb6b0bMathias Fröhlich            const_inputs |= VERT_BIT_GENERIC(i);
5011680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell         }
502fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
503ef58598c1cf2ac689f67c75b2f477f2c404fce98Marek Olšák
504c19f8ab2796a68d5e0c3c6334e7597f7f1c4c757Ian Romanick      inputs[VERT_ATTRIB_GENERIC0] = inputs[0];
505fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
506fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
5071680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell
508dca6a28a14f22d77273d79d44f57b0d853c0242dMathias Fröhlich   _mesa_set_varying_vp_inputs( ctx, VERT_BIT_ALL & (~const_inputs) );
509c5e473fbe25b20cb27aac44ff6e269701abd33a8Marek Olšák   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
510fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
511fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
5123bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul
5135ce9183c1c535d924a79c2b6b280c6a2648cec19Brian Paul/**
5145ce9183c1c535d924a79c2b6b280c6a2648cec19Brian Paul * Examine the enabled vertex arrays to set the exec->array.inputs[] values.
5155ce9183c1c535d924a79c2b6b280c6a2648cec19Brian Paul * These will point to the arrays to actually use for drawing.  Some will
5165ce9183c1c535d924a79c2b6b280c6a2648cec19Brian Paul * be user-provided arrays, other will be zero-stride const-valued arrays.
517576c8c592a4be7047a00b0c8fe3851b09f10d8d4Marek Olšák * Note that this might set the _NEW_VARYING_VP_INPUTS dirty flag so state
518576c8c592a4be7047a00b0c8fe3851b09f10d8d4Marek Olšák * validation must be done after this call.
5195ce9183c1c535d924a79c2b6b280c6a2648cec19Brian Paul */
5208c7c589c4e70d7cdcceb350aa4edd3d9eec4403eChad Versacevoid
5218c7c589c4e70d7cdcceb350aa4edd3d9eec4403eChad Versacevbo_bind_arrays(struct gl_context *ctx)
522fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
523784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák   struct vbo_context *vbo = vbo_context(ctx);
524784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák   struct vbo_exec_context *exec = &vbo->exec;
525784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák
526a7ac9c9c7dc7401ca6143d1e7476df5e3c2758b7Marek Olšák   vbo_draw_method(vbo, DRAW_ARRAYS);
527cfaf217135d8a8e903b3fbf380f18170df018f0cMarek Olšák
528784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák   if (exec->array.recalculate_inputs) {
529784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák      recalculate_input_bindings(ctx);
530784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák
531784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák      /* Again... because we may have changed the bitmask of per-vertex varying
532784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák       * attributes.  If we regenerate the fixed-function vertex program now
533784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák       * we may be able to prune down the number of vertex attributes which we
534784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák       * need in the shader.
535784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák       */
536784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák      if (ctx->NewState) {
537784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák         _mesa_update_state(ctx);
538784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák      }
539784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák
540784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák      exec->array.recalculate_inputs = GL_FALSE;
541784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák   }
542fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
543fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
544fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
545be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul/**
546862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen * Handle a draw case that potentially has primitive restart enabled.
547862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen *
548862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen * If primitive restart is enabled, and PrimitiveRestartInSoftware is
549862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen * set, then vbo_sw_primitive_restart is used to handle the primitive
550862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen * restart case in software.
551862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen */
552862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justenstatic void
553862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justenvbo_handle_primitive_restart(struct gl_context *ctx,
554862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen                             const struct _mesa_prim *prim,
555862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen                             GLuint nr_prims,
556862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen                             const struct _mesa_index_buffer *ib,
557862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen                             GLboolean index_bounds_valid,
558862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen                             GLuint min_index,
559862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen                             GLuint max_index)
560862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen{
561862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen   struct vbo_context *vbo = vbo_context(ctx);
562862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen
563862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen   if ((ib != NULL) &&
564862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen       ctx->Const.PrimitiveRestartInSoftware &&
565862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen       ctx->Array.PrimitiveRestart) {
566862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen      /* Handle primitive restart in software */
567862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen      vbo_sw_primitive_restart(ctx, prim, nr_prims, ib);
568862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen   } else {
569862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen      /* Call driver directly for draw_prims */
570862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen      vbo->draw_prims(ctx, prim, nr_prims, ib,
571862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen                      index_bounds_valid, min_index, max_index, NULL);
572862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen   }
573862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen}
574862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen
575862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen
576862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen/**
577be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul * Helper function called by the other DrawArrays() functions below.
578be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul * This is where we handle primitive restart for drawing non-indexed
579be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul * arrays.  If primitive restart is enabled, it typically means
580be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul * splitting one DrawArrays() into two.
581be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul */
582be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paulstatic void
583be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paulvbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
584ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                GLsizei count, GLuint numInstances, GLuint baseInstance)
585be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul{
586be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   struct vbo_context *vbo = vbo_context(ctx);
587be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   struct vbo_exec_context *exec = &vbo->exec;
588be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   struct _mesa_prim prim[2];
589be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
5908c7c589c4e70d7cdcceb350aa4edd3d9eec4403eChad Versace   vbo_bind_arrays(ctx);
591be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
5920630593c5fb22fe0f98f2c815c4a315056a9e3d2Brian Paul   /* init most fields to zero */
5930630593c5fb22fe0f98f2c815c4a315056a9e3d2Brian Paul   memset(prim, 0, sizeof(prim));
594be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   prim[0].begin = 1;
595be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   prim[0].end = 1;
596be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   prim[0].mode = mode;
597be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   prim[0].num_instances = numInstances;
598ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   prim[0].base_instance = baseInstance;
599be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
600be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   /* Implement the primitive restart index */
601be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   if (ctx->Array.PrimitiveRestart && ctx->Array.RestartIndex < count) {
602be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      GLuint primCount = 0;
603be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
604be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      if (ctx->Array.RestartIndex == start) {
605be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         /* special case: RestartIndex at beginning */
606be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         if (count > 1) {
607be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            prim[0].start = start + 1;
608be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            prim[0].count = count - 1;
609be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            primCount = 1;
610be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         }
611be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      }
612be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      else if (ctx->Array.RestartIndex == start + count - 1) {
613be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         /* special case: RestartIndex at end */
614be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         if (count > 1) {
615be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            prim[0].start = start;
616be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            prim[0].count = count - 1;
617be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul            primCount = 1;
618be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         }
619be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      }
620be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      else {
621be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         /* general case: RestartIndex in middle, split into two prims */
622be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         prim[0].start = start;
623be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         prim[0].count = ctx->Array.RestartIndex - start;
624be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
625be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         prim[1] = prim[0];
626be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         prim[1].start = ctx->Array.RestartIndex + 1;
627be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         prim[1].count = count - prim[1].start;
628be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
629be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         primCount = 2;
630be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      }
631be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
632be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      if (primCount > 0) {
633be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul         /* draw one or two prims */
6347ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul         check_buffers_are_unmapped(exec->array.inputs);
63550f7e75f9e945cfbb2ae868cc961a2205a0b6e73Marek Olšák         vbo->draw_prims(ctx, prim, primCount, NULL,
63614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák                         GL_TRUE, start, start + count - 1, NULL);
637be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      }
638be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   }
639be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   else {
640be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      /* no prim restart */
641be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      prim[0].start = start;
642be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      prim[0].count = count;
643be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
6447ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul      check_buffers_are_unmapped(exec->array.inputs);
64550f7e75f9e945cfbb2ae868cc961a2205a0b6e73Marek Olšák      vbo->draw_prims(ctx, prim, 1, NULL,
64614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák                      GL_TRUE, start, start + count - 1,
64714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák                      NULL);
648be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   }
649014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul
650014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
651014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul      _mesa_flush(ctx);
652014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul   }
653be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul}
654be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
655be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
656fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
657b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
658b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Called from glDrawArrays when in immediate mode (not display list mode).
659fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
660fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY
661fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellvbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
662fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
663fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
664fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
665ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul   if (MESA_VERBOSE & VERBOSE_DRAW)
666ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul      _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n",
667ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  _mesa_lookup_enum_by_nr(mode), start, count);
668ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul
669fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
670fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
671fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
672be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   if (0)
673be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      check_draw_arrays_data(ctx, start, count);
674fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
675ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   vbo_draw_arrays(ctx, mode, start, count, 1, 0);
676a3b7db0326337117ccdea526818040d2c24d83b4Brian Paul
677be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   if (0)
678be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      print_draw_arrays(ctx, mode, start, count);
679fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
680fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
681fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
682b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
683b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Called from glDrawArraysInstanced when in immediate mode (not
684b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * display list mode).
685b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
6863b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paulstatic void GLAPIENTRY
6873b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paulvbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
68872f2551017e03f888d63fa9040120740c6d40620Brian Paul                             GLsizei numInstances)
6893b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul{
6903b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   GET_CURRENT_CONTEXT(ctx);
6913b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
6923b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   if (MESA_VERBOSE & VERBOSE_DRAW)
6933b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul      _mesa_debug(ctx, "glDrawArraysInstanced(%s, %d, %d, %d)\n",
69472f2551017e03f888d63fa9040120740c6d40620Brian Paul                  _mesa_lookup_enum_by_nr(mode), start, count, numInstances);
6953b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
69672f2551017e03f888d63fa9040120740c6d40620Brian Paul   if (!_mesa_validate_DrawArraysInstanced(ctx, mode, start, count, numInstances))
6973b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul      return;
6983b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
699be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   if (0)
700be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      check_draw_arrays_data(ctx, start, count);
7013b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
702ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   vbo_draw_arrays(ctx, mode, start, count, numInstances, 0);
7033b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
704be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   if (0)
705be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul      print_draw_arrays(ctx, mode, start, count);
7063b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul}
7073b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
7083b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
709c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul/**
710ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund * Called from glDrawArraysInstancedBaseInstance when in immediate mode.
711ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund */
712ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglundstatic void GLAPIENTRY
713ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglundvbo_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count,
714ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                                         GLsizei numInstances, GLuint baseInstance)
715ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund{
716ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   GET_CURRENT_CONTEXT(ctx);
717ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
718ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   if (MESA_VERBOSE & VERBOSE_DRAW)
719ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund      _mesa_debug(ctx, "glDrawArraysInstancedBaseInstance(%s, %d, %d, %d, %d)\n",
720ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                  _mesa_lookup_enum_by_nr(mode), first, count,
721ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                  numInstances, baseInstance);
722ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
723d9eb1a12254add75f6842fdebe5b78512855d04dMarek Olšák   if (!_mesa_validate_DrawArraysInstanced(ctx, mode, first, count,
724d9eb1a12254add75f6842fdebe5b78512855d04dMarek Olšák                                           numInstances))
725ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund      return;
726ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
727ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   if (0)
728ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund      check_draw_arrays_data(ctx, first, count);
729ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
730ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   vbo_draw_arrays(ctx, mode, first, count, numInstances, baseInstance);
731ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
732ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   if (0)
733ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund      print_draw_arrays(ctx, mode, first, count);
734ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund}
735ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
736ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
737ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
738ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund/**
739c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul * Map GL_ELEMENT_ARRAY_BUFFER and print contents.
740b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * For debugging.
741c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul */
742f9be8543aab9005c30b38331b9f7250a01720942Kenneth Graunke#if 0
743c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paulstatic void
744f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergdump_element_buffer(struct gl_context *ctx, GLenum type)
745c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul{
74628249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick   const GLvoid *map =
74728249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick      ctx->Driver.MapBufferRange(ctx, 0,
748a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu				 ctx->Array.ArrayObj->ElementArrayBufferObj->Size,
74928249bd260f4c52badf3eb61ade2744604b21bcaIan Romanick				 GL_MAP_READ_BIT,
750a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu				 ctx->Array.ArrayObj->ElementArrayBufferObj);
751c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   switch (type) {
752c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   case GL_UNSIGNED_BYTE:
753c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      {
754c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         const GLubyte *us = (const GLubyte *) map;
755dd89ac249c56d04bbc23ecd9877426af9f09269cBrian Paul         GLint i;
756a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu         for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size; i++) {
757298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg            printf("%02x ", us[i]);
758c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul            if (i % 32 == 31)
759298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg               printf("\n");
760c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         }
761298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg         printf("\n");
762c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      }
763c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      break;
764c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   case GL_UNSIGNED_SHORT:
765c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      {
766c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         const GLushort *us = (const GLushort *) map;
767dd89ac249c56d04bbc23ecd9877426af9f09269cBrian Paul         GLint i;
768a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu         for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 2; i++) {
769298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg            printf("%04x ", us[i]);
770c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul            if (i % 16 == 15)
771298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg               printf("\n");
772c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         }
773298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg         printf("\n");
774c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      }
775c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      break;
776c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   case GL_UNSIGNED_INT:
777c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      {
778c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         const GLuint *us = (const GLuint *) map;
779dd89ac249c56d04bbc23ecd9877426af9f09269cBrian Paul         GLint i;
780a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu         for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 4; i++) {
781298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg            printf("%08x ", us[i]);
782c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul            if (i % 8 == 7)
783298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg               printf("\n");
784c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         }
785298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg         printf("\n");
786c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      }
787c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      break;
788c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   default:
789c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      ;
790c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   }
791c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul
792a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu   ctx->Driver.UnmapBuffer(ctx, ctx->Array.ArrayObj->ElementArrayBufferObj);
793c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul}
794f9be8543aab9005c30b38331b9f7250a01720942Kenneth Graunke#endif
795c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul
796f9784072fee016e14e0319c705420becb2490bf9Brian Paul
797b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
798b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements.
799b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Do the rendering for a glDrawElements or glDrawRangeElements call after
800b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * we've validated buffer bounds, etc.
801b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
8022708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholtstatic void
803f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
8042708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt				GLboolean index_bounds_valid,
8052708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt				GLuint start, GLuint end,
8062708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt				GLsizei count, GLenum type,
80792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				const GLvoid *indices,
808ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund				GLint basevertex, GLint numInstances,
809ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund				GLuint baseInstance)
810fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
811fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_context *vbo = vbo_context(ctx);
812fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_exec_context *exec = &vbo->exec;
813fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct _mesa_index_buffer ib;
814fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct _mesa_prim prim[1];
815fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
816784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák   vbo_bind_arrays(ctx);
8171680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell
818fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ib.count = count;
8192708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   ib.type = type;
820a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu   ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
821fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ib.ptr = indices;
822fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
823fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].begin = 1;
824fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].end = 1;
825fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].weak = 0;
826fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].pad = 0;
827fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].mode = mode;
828fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].start = 0;
829fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].count = count;
830fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].indexed = 1;
83192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   prim[0].basevertex = basevertex;
83272f2551017e03f888d63fa9040120740c6d40620Brian Paul   prim[0].num_instances = numInstances;
833ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   prim[0].base_instance = baseInstance;
834fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
835893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   /* Need to give special consideration to rendering a range of
836893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * indices starting somewhere above zero.  Typically the
837893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * application is issuing multiple DrawRangeElements() to draw
838893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * successive primitives layed out linearly in the vertex arrays.
839893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * Unless the vertex arrays are all in a VBO (or locked as with
840893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * CVA), the OpenGL semantics imply that we need to re-read or
841893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * re-upload the vertex data on each draw call.
842893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
843893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * In the case of hardware tnl, we want to avoid starting the
844893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * upload at zero, as it will mean every draw call uploads an
845893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * increasing amount of not-used vertex data.  Worse - in the
846893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * software tnl module, all those vertices might be transformed and
847893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * lit but never rendered.
848893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
849893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * If we just upload or transform the vertices in start..end,
850893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * however, the indices will be incorrect.
851893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
852893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * At this level, we don't know exactly what the requirements of
853893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * the backend are going to be, though it will likely boil down to
854893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * either:
855893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
856893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * 1) Do nothing, everything is in a VBO and is processed once
857893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *       only.
858893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
859893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * 2) Adjust the indices and vertex arrays so that start becomes
860893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *    zero.
861893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
862893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * Rather than doing anything here, I'll provide a helper function
863893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * for the latter case elsewhere.
864893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    */
865fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8667ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul   check_buffers_are_unmapped(exec->array.inputs);
867862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen   vbo_handle_primitive_restart(ctx, prim, 1, &ib,
868862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen                                index_bounds_valid, start, end);
869014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul
870014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
871014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul      _mesa_flush(ctx);
872014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul   }
873893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell}
874fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
875b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul
876b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
877b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Called by glDrawRangeElementsBaseVertex() in immediate mode.
878b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
879fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY
88092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
88192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     GLuint start, GLuint end,
88292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     GLsizei count, GLenum type,
88392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     const GLvoid *indices,
88492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     GLint basevertex)
885fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
886f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke   static GLuint warnCount = 0;
887112b02c32402d96fd7d526ab84877bb66dc12de4Kenneth Graunke   GLboolean index_bounds_valid = GL_TRUE;
888fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
889fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
890ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul   if (MESA_VERBOSE & VERBOSE_DRAW)
891ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul      _mesa_debug(ctx,
892ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n",
893ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                _mesa_lookup_enum_by_nr(mode), start, end, count,
894ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                _mesa_lookup_enum_by_nr(type), indices, basevertex);
895ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul
8962708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count,
89792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt                                          type, indices, basevertex ))
898fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
899fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
900f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke   if ((int) end + basevertex < 0 ||
901f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke       start + basevertex >= ctx->Array.ArrayObj->_MaxElement) {
902f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke      /* The application requested we draw using a range of indices that's
903f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke       * outside the bounds of the current VBO.  This is invalid and appears
904f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke       * to give undefined results.  The safest thing to do is to simply
905f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke       * ignore the range, in case the application botched their range tracking
906f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke       * but did provide valid indices.  Also issue a warning indicating that
907f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke       * the application is broken.
908f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke       */
909f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke      if (warnCount++ < 10) {
910f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke         _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, "
911f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke                       "basevertex %d, count %d, type 0x%x, indices=%p):\n"
912f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke                       "\trange is outside VBO bounds (max=%u); ignoring.\n"
913f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke                       "\tThis should be fixed in the application.",
914f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke                       start, end, basevertex, count, type, indices,
915f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke                       ctx->Array.ArrayObj->_MaxElement - 1);
916f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke      }
9176e738d35c5c88769ececbadd5f4ac14d36647168Kenneth Graunke      index_bounds_valid = GL_FALSE;
918f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke   }
919f00c97b23f78f3ccd1ea554ceebe7a33de7f81cfKenneth Graunke
92094a020cfe6cb1da04695897eed38b530af31f524Brian Paul   /* NOTE: It's important that 'end' is a reasonable value.
92194a020cfe6cb1da04695897eed38b530af31f524Brian Paul    * in _tnl_draw_prims(), we use end to determine how many vertices
92294a020cfe6cb1da04695897eed38b530af31f524Brian Paul    * to transform.  If it's too large, we can unnecessarily split prims
92394a020cfe6cb1da04695897eed38b530af31f524Brian Paul    * or we can read/write out of memory in several different places!
92494a020cfe6cb1da04695897eed38b530af31f524Brian Paul    */
92594a020cfe6cb1da04695897eed38b530af31f524Brian Paul
926645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul   /* Catch/fix some potential user errors */
927645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul   if (type == GL_UNSIGNED_BYTE) {
928645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul      start = MIN2(start, 0xff);
929645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul      end = MIN2(end, 0xff);
930645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul   }
931645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul   else if (type == GL_UNSIGNED_SHORT) {
932645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul      start = MIN2(start, 0xffff);
933645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul      end = MIN2(end, 0xffff);
934645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul   }
935645e297a0019eb2f7513bd801ffdaac03187f29fBrian Paul
93623d75936a72b9a9b9e1d04a901a86a75d93dbffbJosé Fonseca   if (0) {
937298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg      printf("glDraw[Range]Elements{,BaseVertex}"
938298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	     "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, "
939298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	     "base %d\n",
940298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	     start, end, type, count,
941a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu	     ctx->Array.ArrayObj->ElementArrayBufferObj->Name,
942298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	     basevertex);
9432708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   }
944d758479b9fbff803bdac15f3f39d32ef9064db71Brian Paul
945112b02c32402d96fd7d526ab84877bb66dc12de4Kenneth Graunke   if ((int) start + basevertex < 0 ||
946112b02c32402d96fd7d526ab84877bb66dc12de4Kenneth Graunke       end + basevertex >= ctx->Array.ArrayObj->_MaxElement)
947112b02c32402d96fd7d526ab84877bb66dc12de4Kenneth Graunke      index_bounds_valid = GL_FALSE;
948112b02c32402d96fd7d526ab84877bb66dc12de4Kenneth Graunke
9492708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt#if 0
9502708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   check_draw_elements_data(ctx, count, type, indices);
9512708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt#else
9522708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   (void) check_draw_elements_data;
9532708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt#endif
9542708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
955112b02c32402d96fd7d526ab84877bb66dc12de4Kenneth Graunke   vbo_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end,
956ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund				   count, type, indices, basevertex, 1, 0);
95792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
95892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
959f9784072fee016e14e0319c705420becb2490bf9Brian Paul
960b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
961b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Called by glDrawRangeElements() in immediate mode.
962b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
96392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtstatic void GLAPIENTRY
964f9784072fee016e14e0319c705420becb2490bf9Brian Paulvbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
965f9784072fee016e14e0319c705420becb2490bf9Brian Paul                           GLsizei count, GLenum type, const GLvoid *indices)
96692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
967b6df603e650527d5fa7f0fc1448be1bb57f47fbbDave Airlie   if (MESA_VERBOSE & VERBOSE_DRAW) {
968b6df603e650527d5fa7f0fc1448be1bb57f47fbbDave Airlie      GET_CURRENT_CONTEXT(ctx);
969ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul      _mesa_debug(ctx,
970ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n",
971ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  _mesa_lookup_enum_by_nr(mode), start, end, count,
972ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  _mesa_lookup_enum_by_nr(type), indices);
973b6df603e650527d5fa7f0fc1448be1bb57f47fbbDave Airlie   }
974ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul
97592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
97692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt					indices, 0);
9772708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt}
978fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
979fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
980b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
981b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Called by glDrawElements() in immediate mode.
982b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
9832708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholtstatic void GLAPIENTRY
9842708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholtvbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
9852708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt                      const GLvoid *indices)
9862708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt{
9872708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   GET_CURRENT_CONTEXT(ctx);
9882708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
989ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul   if (MESA_VERBOSE & VERBOSE_DRAW)
990ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul      _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n",
991ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  _mesa_lookup_enum_by_nr(mode), count,
992ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  _mesa_lookup_enum_by_nr(type), indices);
993ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul
99492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))
99592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      return;
99692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
99792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
998ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund				   count, type, indices, 0, 1, 0);
99992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
100092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
1001f9784072fee016e14e0319c705420becb2490bf9Brian Paul
1002b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
1003b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Called by glDrawElementsBaseVertex() in immediate mode.
1004b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
100592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtstatic void GLAPIENTRY
100692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
100792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				const GLvoid *indices, GLint basevertex)
100892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
100992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GET_CURRENT_CONTEXT(ctx);
101092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
1011ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul   if (MESA_VERBOSE & VERBOSE_DRAW)
1012ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul      _mesa_debug(ctx, "glDrawElementsBaseVertex(%s, %d, %s, %p, %d)\n",
1013ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  _mesa_lookup_enum_by_nr(mode), count,
1014ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul                  _mesa_lookup_enum_by_nr(type), indices, basevertex);
1015ade1cc992410c8696fdfe0f84fb613fd0dc8099fBrian Paul
101692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices,
101792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     basevertex ))
10182708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt      return;
1019fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
10202708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1021ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund				   count, type, indices, basevertex, 1, 0);
10223b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul}
10233b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
10243b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
1025b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
1026b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Called by glDrawElementsInstanced() in immediate mode.
1027b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
10283b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paulstatic void GLAPIENTRY
10293b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paulvbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
103072f2551017e03f888d63fa9040120740c6d40620Brian Paul                               const GLvoid *indices, GLsizei numInstances)
10313b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul{
10323b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   GET_CURRENT_CONTEXT(ctx);
10333b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
10343b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   if (MESA_VERBOSE & VERBOSE_DRAW)
10353b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul      _mesa_debug(ctx, "glDrawElementsInstanced(%s, %d, %s, %p, %d)\n",
10363b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul                  _mesa_lookup_enum_by_nr(mode), count,
103772f2551017e03f888d63fa9040120740c6d40620Brian Paul                  _mesa_lookup_enum_by_nr(type), indices, numInstances);
10383b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
10393b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
104009201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer                                             numInstances, 0))
10413b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul      return;
10423b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul
10433b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1044ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund				   count, type, indices, 0, numInstances, 0);
1045fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1046fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1047ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
104809201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer/**
104909201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer * Called by glDrawElementsInstancedBaseVertex() in immediate mode.
105009201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer */
105109201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayerstatic void GLAPIENTRY
105209201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayervbo_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type,
105309201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer                               const GLvoid *indices, GLsizei numInstances,
105409201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer                               GLint basevertex)
105509201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer{
105609201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer   GET_CURRENT_CONTEXT(ctx);
105709201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer
105809201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer   if (MESA_VERBOSE & VERBOSE_DRAW)
105909201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer      _mesa_debug(ctx, "glDrawElementsInstancedBaseVertex(%s, %d, %s, %p, %d; %d)\n",
106009201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer                  _mesa_lookup_enum_by_nr(mode), count,
106109201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer                  _mesa_lookup_enum_by_nr(type), indices,
106209201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer                  numInstances, basevertex);
106309201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer
106409201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer   if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
106509201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer                                             numInstances, basevertex))
106609201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer      return;
106709201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer
106809201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer   vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1069ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund				   count, type, indices, basevertex, numInstances, 0);
1070ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund}
1071ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
1072ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
1073ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund/**
1074ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund * Called by glDrawElementsInstancedBaseInstance() in immediate mode.
1075ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund */
1076ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglundstatic void GLAPIENTRY
1077ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglundvbo_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type,
1078ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                                           const GLvoid *indices, GLsizei numInstances,
1079ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                                           GLuint baseInstance)
1080ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund{
1081ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   GET_CURRENT_CONTEXT(ctx);
1082ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
1083ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   if (MESA_VERBOSE & VERBOSE_DRAW)
1084ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund      _mesa_debug(ctx, "glDrawElementsInstancedBaseInstance(%s, %d, %s, %p, %d, %d)\n",
1085ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                  _mesa_lookup_enum_by_nr(mode), count,
1086ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                  _mesa_lookup_enum_by_nr(type), indices,
1087ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                  numInstances, baseInstance);
1088ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
1089ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1090ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                                             numInstances, 0))
1091ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund      return;
1092ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
1093ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1094ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                                   count, type, indices, 0, numInstances,
1095ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                                   baseInstance);
1096ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund}
1097ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
1098ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
1099ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund/**
1100ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode.
1101ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund */
1102ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglundstatic void GLAPIENTRY
1103ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglundvbo_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type,
1104ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                                                     const GLvoid *indices, GLsizei numInstances,
1105ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                                                     GLint basevertex, GLuint baseInstance)
1106ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund{
1107ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   GET_CURRENT_CONTEXT(ctx);
1108ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
1109ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   if (MESA_VERBOSE & VERBOSE_DRAW)
1110ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund      _mesa_debug(ctx, "glDrawElementsInstancedBaseVertexBaseInstance(%s, %d, %s, %p, %d, %d, %d)\n",
1111ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                  _mesa_lookup_enum_by_nr(mode), count,
1112ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                  _mesa_lookup_enum_by_nr(type), indices,
1113ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                  numInstances, basevertex, baseInstance);
1114ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
1115ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
1116ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                                             numInstances, basevertex))
1117ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund      return;
1118ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund
1119ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
1120ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                                   count, type, indices, basevertex, numInstances,
1121ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund                                   baseInstance);
112209201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer}
112309201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer
1124f9784072fee016e14e0319c705420becb2490bf9Brian Paul
1125b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
1126b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Inner support for both _mesa_MultiDrawElements() and
1127b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * _mesa_MultiDrawRangeElements().
1128b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * This does the actual rendering after we've checked array indexes, etc.
1129b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
113060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholtstatic void
1131f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
113260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt				const GLsizei *count, GLenum type,
11339881bf6e69b52efc1eb57a4027d9a8817ef8cbcbBrian Paul				const GLvoid * const *indices,
11349881bf6e69b52efc1eb57a4027d9a8817ef8cbcbBrian Paul				GLsizei primcount,
113592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				const GLint *basevertex)
113660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt{
113760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   struct vbo_context *vbo = vbo_context(ctx);
113860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   struct vbo_exec_context *exec = &vbo->exec;
113960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   struct _mesa_index_buffer ib;
114060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   struct _mesa_prim *prim;
1141efa1fac2158c9146b87f0d4340a864661721de21Yuanhan Liu   unsigned int index_type_size = vbo_sizeof_ib_type(type);
114260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   uintptr_t min_index_ptr, max_index_ptr;
114360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   GLboolean fallback = GL_FALSE;
114460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   int i;
114560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
114660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (primcount == 0)
114760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      return;
114860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
114932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   prim = calloc(1, primcount * sizeof(*prim));
115060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (prim == NULL) {
115160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements");
115260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      return;
115360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
115460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
1155784dd51198433e5c299da4a7742c68d21d68d1c1Marek Olšák   vbo_bind_arrays(ctx);
11565ce9183c1c535d924a79c2b6b280c6a2648cec19Brian Paul
115760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   min_index_ptr = (uintptr_t)indices[0];
115860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   max_index_ptr = 0;
115960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   for (i = 0; i < primcount; i++) {
116060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      min_index_ptr = MIN2(min_index_ptr, (uintptr_t)indices[i]);
116160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      max_index_ptr = MAX2(max_index_ptr, (uintptr_t)indices[i] +
116260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt			   index_type_size * count[i]);
116360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
116460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
116560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   /* Check if we can handle this thing as a bunch of index offsets from the
116660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    * same index pointer.  If we can't, then we have to fall back to doing
116760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    * a draw_prims per primitive.
1168be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul    * Check that the difference between each prim's indexes is a multiple of
1169be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul    * the index/element size.
117060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    */
117160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (index_type_size != 1) {
117260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      for (i = 0; i < primcount; i++) {
117360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 if ((((uintptr_t)indices[i] - min_index_ptr) % index_type_size) != 0) {
117460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	    fallback = GL_TRUE;
117560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	    break;
117660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 }
117760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      }
117860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
117960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
118060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   /* If the index buffer isn't in a VBO, then treating the application's
118160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    * subranges of the index buffer as one large index buffer may lead to
118260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    * us reading unmapped memory.
118360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    */
1184a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu   if (!_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj))
118560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      fallback = GL_TRUE;
118660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
118760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (!fallback) {
118860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      ib.count = (max_index_ptr - min_index_ptr) / index_type_size;
118960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      ib.type = type;
1190a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu      ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
119160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      ib.ptr = (void *)min_index_ptr;
119260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
119360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      for (i = 0; i < primcount; i++) {
119460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].begin = (i == 0);
119560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].end = (i == primcount - 1);
119660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].weak = 0;
119760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].pad = 0;
119860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].mode = mode;
119960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].start = ((uintptr_t)indices[i] - min_index_ptr) / index_type_size;
120060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].count = count[i];
120160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].indexed = 1;
12023b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul         prim[i].num_instances = 1;
1203ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund         prim[i].base_instance = 0;
120492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 if (basevertex != NULL)
120592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    prim[i].basevertex = basevertex[i];
120692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 else
120792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    prim[i].basevertex = 0;
120860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      }
120960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
12107ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul      check_buffers_are_unmapped(exec->array.inputs);
1211862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen      vbo_handle_primitive_restart(ctx, prim, primcount, &ib,
1212862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen                                   GL_FALSE, ~0, ~0);
121360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   } else {
121436a54885a4b2eb2b23361f2add3d66e385a322cfBrian Paul      /* render one prim at a time */
121560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      for (i = 0; i < primcount; i++) {
121660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 ib.count = count[i];
121760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 ib.type = type;
1218a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu	 ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
121960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 ib.ptr = indices[i];
122060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
122160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].begin = 1;
122260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].end = 1;
122360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].weak = 0;
122460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].pad = 0;
122560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].mode = mode;
122660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].start = 0;
122760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].count = count[i];
122860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].indexed = 1;
12293b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul         prim[0].num_instances = 1;
1230ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund         prim[0].base_instance = 0;
123192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 if (basevertex != NULL)
123292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    prim[0].basevertex = basevertex[i];
123392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 else
123492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    prim[0].basevertex = 0;
123560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
12367ea729a1855e93b3c41c72781950f8612221fd5cBrian Paul         check_buffers_are_unmapped(exec->array.inputs);
1237862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen         vbo_handle_primitive_restart(ctx, prim, 1, &ib,
1238862667b6d96022d75046c765aa1e9d8846b9d313Jordan Justen                                      GL_FALSE, ~0, ~0);
123936a54885a4b2eb2b23361f2add3d66e385a322cfBrian Paul      }
124060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
124136a54885a4b2eb2b23361f2add3d66e385a322cfBrian Paul
124232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   free(prim);
1243014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul
1244014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1245014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul      _mesa_flush(ctx);
1246014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul   }
124760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt}
124860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
1249f9784072fee016e14e0319c705420becb2490bf9Brian Paul
125060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholtstatic void GLAPIENTRY
125160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholtvbo_exec_MultiDrawElements(GLenum mode,
125260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt			   const GLsizei *count, GLenum type,
125360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt			   const GLvoid **indices,
125460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt			   GLsizei primcount)
125560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt{
125660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   GET_CURRENT_CONTEXT(ctx);
125760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
1258fcebb157f0eb6c2f374dee609a01b0b14856e7fcMarek Olšák   if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1259fcebb157f0eb6c2f374dee609a01b0b14856e7fcMarek Olšák                                         primcount, NULL))
1260fcebb157f0eb6c2f374dee609a01b0b14856e7fcMarek Olšák      return;
126160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
126292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
126392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				   NULL);
126460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt}
126560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
1266f9784072fee016e14e0319c705420becb2490bf9Brian Paul
126792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtstatic void GLAPIENTRY
126892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
126992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     const GLsizei *count, GLenum type,
12709881bf6e69b52efc1eb57a4027d9a8817ef8cbcbBrian Paul				     const GLvoid * const *indices,
127192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     GLsizei primcount,
127292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     const GLsizei *basevertex)
127392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
127492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GET_CURRENT_CONTEXT(ctx);
127592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
1276fcebb157f0eb6c2f374dee609a01b0b14856e7fcMarek Olšák   if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices,
1277fcebb157f0eb6c2f374dee609a01b0b14856e7fcMarek Olšák                                         primcount, basevertex))
1278fcebb157f0eb6c2f374dee609a01b0b14856e7fcMarek Olšák      return;
127992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
128092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
128192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				   basevertex);
128292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
128360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
128414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák#if FEATURE_EXT_transform_feedback
128514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
128614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšákstatic void
128714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšákvbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
128814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák                            struct gl_transform_feedback_object *obj,
1289db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák                            GLuint stream, GLuint numInstances)
129014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák{
129114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   struct vbo_context *vbo = vbo_context(ctx);
129214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   struct vbo_exec_context *exec = &vbo->exec;
129314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   struct _mesa_prim prim[2];
129414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
1295db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream,
1296db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák                                             numInstances)) {
1297db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák      return;
1298db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   }
1299db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák
130014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   vbo_bind_arrays(ctx);
130114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
130214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   /* init most fields to zero */
130314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   memset(prim, 0, sizeof(prim));
130414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   prim[0].begin = 1;
130514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   prim[0].end = 1;
130614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   prim[0].mode = mode;
130714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   prim[0].num_instances = numInstances;
1308ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   prim[0].base_instance = 0;
130914bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
131014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   /* Maybe we should do some primitive splitting for primitive restart
131114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák    * (like in DrawArrays), but we have no way to know how many vertices
131214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák    * will be rendered. */
131314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
131414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   check_buffers_are_unmapped(exec->array.inputs);
131550f7e75f9e945cfbb2ae868cc961a2205a0b6e73Marek Olšák   vbo->draw_prims(ctx, prim, 1, NULL,
131614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák                   GL_TRUE, 0, 0, obj);
1317014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul
1318014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
1319014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul      _mesa_flush(ctx);
1320014306578be1f7aeb883e7b22eb255eda82fa011Brian Paul   }
132114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák}
132214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
132314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák/**
132414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák * Like DrawArrays, but take the count from a transform feedback object.
132514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák * \param mode  GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc.
132614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák * \param name  the transform feedback object
132714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák * User still has to setup of the vertex attribute info with
132814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák * glVertexPointer, glColorPointer, etc.
132914bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák * Part of GL_ARB_transform_feedback2.
133014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák */
133114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšákstatic void GLAPIENTRY
133214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšákvbo_exec_DrawTransformFeedback(GLenum mode, GLuint name)
133314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák{
133414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   GET_CURRENT_CONTEXT(ctx);
133514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   struct gl_transform_feedback_object *obj =
133614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák      _mesa_lookup_transform_feedback_object(ctx, name);
133714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
133814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   if (MESA_VERBOSE & VERBOSE_DRAW)
133914bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák      _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n",
134014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák                  _mesa_lookup_enum_by_nr(mode), name);
134114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
1342db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   vbo_draw_transform_feedback(ctx, mode, obj, 0, 1);
1343db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák}
1344db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák
1345db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšákstatic void GLAPIENTRY
1346db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšákvbo_exec_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream)
1347db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák{
1348db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   GET_CURRENT_CONTEXT(ctx);
1349db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   struct gl_transform_feedback_object *obj =
1350db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák      _mesa_lookup_transform_feedback_object(ctx, name);
1351db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák
1352db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   if (MESA_VERBOSE & VERBOSE_DRAW)
1353db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák      _mesa_debug(ctx, "glDrawTransformFeedbackStream(%s, %u, %u)\n",
1354db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák                  _mesa_lookup_enum_by_nr(mode), name, stream);
1355db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák
1356db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   vbo_draw_transform_feedback(ctx, mode, obj, stream, 1);
1357db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák}
1358db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák
1359db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšákstatic void GLAPIENTRY
1360db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšákvbo_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name,
1361db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák                                        GLsizei primcount)
1362db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák{
1363db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   GET_CURRENT_CONTEXT(ctx);
1364db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   struct gl_transform_feedback_object *obj =
1365db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák      _mesa_lookup_transform_feedback_object(ctx, name);
1366db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák
1367db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   if (MESA_VERBOSE & VERBOSE_DRAW)
1368db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák      _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n",
1369db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák                  _mesa_lookup_enum_by_nr(mode), name);
1370db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák
1371db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   vbo_draw_transform_feedback(ctx, mode, obj, 0, primcount);
1372db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák}
1373db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák
1374db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšákstatic void GLAPIENTRY
1375db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšákvbo_exec_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name,
1376db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák                                              GLuint stream, GLsizei primcount)
1377db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák{
1378db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   GET_CURRENT_CONTEXT(ctx);
1379db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   struct gl_transform_feedback_object *obj =
1380db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák      _mesa_lookup_transform_feedback_object(ctx, name);
1381db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák
1382db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   if (MESA_VERBOSE & VERBOSE_DRAW)
1383db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák      _mesa_debug(ctx, "glDrawTransformFeedbackStreamInstanced"
1384db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák                  "(%s, %u, %u, %i)\n",
1385db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák                  _mesa_lookup_enum_by_nr(mode), name, stream, primcount);
138614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
1387db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   vbo_draw_transform_feedback(ctx, mode, obj, stream, primcount);
138814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák}
138914bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
139014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák#endif
1391fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1392b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
1393b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * Plug in the immediate-mode vertex array drawing commands into the
1394b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * givven vbo_exec_context object.
1395fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
13960b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulvoid
13970b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulvbo_exec_array_init( struct vbo_exec_context *exec )
1398fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1399fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   exec->vtxfmt.DrawArrays = vbo_exec_DrawArrays;
1400fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   exec->vtxfmt.DrawElements = vbo_exec_DrawElements;
1401fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   exec->vtxfmt.DrawRangeElements = vbo_exec_DrawRangeElements;
140260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   exec->vtxfmt.MultiDrawElementsEXT = vbo_exec_MultiDrawElements;
140392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   exec->vtxfmt.DrawElementsBaseVertex = vbo_exec_DrawElementsBaseVertex;
140492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   exec->vtxfmt.DrawRangeElementsBaseVertex = vbo_exec_DrawRangeElementsBaseVertex;
140592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   exec->vtxfmt.MultiDrawElementsBaseVertex = vbo_exec_MultiDrawElementsBaseVertex;
14063b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   exec->vtxfmt.DrawArraysInstanced = vbo_exec_DrawArraysInstanced;
1407ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   exec->vtxfmt.DrawArraysInstancedBaseInstance = vbo_exec_DrawArraysInstancedBaseInstance;
14083b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   exec->vtxfmt.DrawElementsInstanced = vbo_exec_DrawElementsInstanced;
1409ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   exec->vtxfmt.DrawElementsInstancedBaseInstance = vbo_exec_DrawElementsInstancedBaseInstance;
141009201cc7a0c4c50871bb8aa5d00ac70aa4e9e670Pierre-Eric Pelloux-Prayer   exec->vtxfmt.DrawElementsInstancedBaseVertex = vbo_exec_DrawElementsInstancedBaseVertex;
1411ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   exec->vtxfmt.DrawElementsInstancedBaseVertexBaseInstance = vbo_exec_DrawElementsInstancedBaseVertexBaseInstance;
1412f8be4f33d31d004bfcf090fa7d4aa37b750e43afChih-Wei Huang#if FEATURE_EXT_transform_feedback
141314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   exec->vtxfmt.DrawTransformFeedback = vbo_exec_DrawTransformFeedback;
1414db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   exec->vtxfmt.DrawTransformFeedbackStream =
1415db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák         vbo_exec_DrawTransformFeedbackStream;
1416db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   exec->vtxfmt.DrawTransformFeedbackInstanced =
1417db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák         vbo_exec_DrawTransformFeedbackInstanced;
1418db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   exec->vtxfmt.DrawTransformFeedbackStreamInstanced =
1419db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák         vbo_exec_DrawTransformFeedbackStreamInstanced;
1420f8be4f33d31d004bfcf090fa7d4aa37b750e43afChih-Wei Huang#endif
1421fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1422fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1423fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
14240b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulvoid
14250b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulvbo_exec_array_destroy( struct vbo_exec_context *exec )
1426fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1427584def75ad8dd13add5b4ed7e364d13202539539Keith Whitwell   /* nothing to do */
1428fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1429feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1430feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1431b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul
1432b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul/**
1433b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * The following functions are only used for OpenGL ES 1/2 support.
1434b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul * And some aren't even supported (yet) in ES 1/2.
1435b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul */
1436b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul
1437b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul
1438feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paulvoid GLAPIENTRY
1439feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul_mesa_DrawArrays(GLenum mode, GLint first, GLsizei count)
1440feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul{
1441feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul   vbo_exec_DrawArrays(mode, first, count);
1442feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul}
1443feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1444feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1445feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paulvoid GLAPIENTRY
1446feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
1447feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul                   const GLvoid *indices)
1448feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul{
1449feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul   vbo_exec_DrawElements(mode, count, type, indices);
1450feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul}
1451feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1452b6187057be07a9652e807e2cfab872eb410c1fa7Brian Paul
145392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvoid GLAPIENTRY
145492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
145592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt			     const GLvoid *indices, GLint basevertex)
145692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
145792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex);
145892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
145992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
1460feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1461feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paulvoid GLAPIENTRY
1462feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
1463feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul                        GLenum type, const GLvoid *indices)
1464feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul{
1465feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul   vbo_exec_DrawRangeElements(mode, start, end, count, type, indices);
1466feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul}
146760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
1468f9784072fee016e14e0319c705420becb2490bf9Brian Paul
146992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvoid GLAPIENTRY
147092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
147192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				  GLsizei count, GLenum type,
147292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				  const GLvoid *indices, GLint basevertex)
147392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
147492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
147592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt					indices, basevertex);
147692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
147792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
1478f9784072fee016e14e0319c705420becb2490bf9Brian Paul
147960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholtvoid GLAPIENTRY
148060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,
148160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt			   const GLvoid **indices, GLsizei primcount)
148260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt{
148360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   vbo_exec_MultiDrawElements(mode, count, type, indices, primcount);
148460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt}
148592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
1486f9784072fee016e14e0319c705420becb2490bf9Brian Paul
148792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvoid GLAPIENTRY
148892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt_mesa_MultiDrawElementsBaseVertex(GLenum mode,
148992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				  const GLsizei *count, GLenum type,
149092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				  const GLvoid **indices, GLsizei primcount,
149192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				  const GLint *basevertex)
149292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
149392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices,
149492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt					primcount, basevertex);
149592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
149614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
149714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák#if FEATURE_EXT_transform_feedback
149814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
149914bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšákvoid GLAPIENTRY
150014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák_mesa_DrawTransformFeedback(GLenum mode, GLuint name)
150114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák{
150214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   vbo_exec_DrawTransformFeedback(mode, name);
150314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák}
150414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
150514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák#endif
1506