vbo_exec_array.c revision 94a020cfe6cb1da04695897eed38b530af31f524
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"
33c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/api_noop.h"
34feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul#include "main/varray.h"
35a3b7db0326337117ccdea526818040d2c24d83b4Brian Paul#include "main/bufferobj.h"
3660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt#include "main/macros.h"
37c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "glapi/dispatch.h"
38fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
39fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "vbo_context.h"
40fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
410b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paul
423bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul/**
433bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul * Compute min and max elements for glDraw[Range]Elements() calls.
44893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell */
452708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholtvoid
462708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholtvbo_get_minmax_index(GLcontext *ctx,
472708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt		     const struct _mesa_prim *prim,
482708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt		     const struct _mesa_index_buffer *ib,
492708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt		     GLuint *min_index, GLuint *max_index)
50fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
5153174afeeb68a79e471185cb463c13ff90af698fJosé Fonseca   GLuint i;
522708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   GLsizei count = prim->count;
532708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   const void *indices;
542708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
55bd4c6a2e503db43e81ef41f77d876308badd93ebBrian Paul   if (_mesa_is_bufferobj(ib->obj)) {
562708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt      const GLvoid *map = ctx->Driver.MapBuffer(ctx,
572708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt                                                GL_ELEMENT_ARRAY_BUFFER_ARB,
582708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt                                                GL_READ_ONLY,
592708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt                                                ib->obj);
602708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt      indices = ADD_POINTERS(map, ib->ptr);
612708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   } else {
622708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt      indices = ib->ptr;
632708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   }
64fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
652708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   switch (ib->type) {
66fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_INT: {
67855374a76a6e83cc0ad4af143b74e655e7b77d5eBrian Paul      const GLuint *ui_indices = (const GLuint *)indices;
68026e7731e549e0777c010348460fd48b3d75a843Keith Whitwell      GLuint max_ui = ui_indices[count-1];
69893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      GLuint min_ui = ui_indices[0];
70026e7731e549e0777c010348460fd48b3d75a843Keith Whitwell      for (i = 0; i < count; i++) {
71893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell	 if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
72893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell	 if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
73893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      }
74893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      *min_index = min_ui;
75893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      *max_index = max_ui;
76893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      break;
77fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
78fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_SHORT: {
79fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      const GLushort *us_indices = (const GLushort *)indices;
80026e7731e549e0777c010348460fd48b3d75a843Keith Whitwell      GLuint max_us = us_indices[count-1];
81893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      GLuint min_us = us_indices[0];
82026e7731e549e0777c010348460fd48b3d75a843Keith Whitwell      for (i = 0; i < count; i++) {
83893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell	 if (us_indices[i] > max_us) max_us = us_indices[i];
84893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell	 if (us_indices[i] < min_us) min_us = us_indices[i];
85893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      }
86893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      *min_index = min_us;
87893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      *max_index = max_us;
88893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      break;
89fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
90fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_BYTE: {
91fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      const GLubyte *ub_indices = (const GLubyte *)indices;
92026e7731e549e0777c010348460fd48b3d75a843Keith Whitwell      GLuint max_ub = ub_indices[count-1];
93893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      GLuint min_ub = ub_indices[0];
94026e7731e549e0777c010348460fd48b3d75a843Keith Whitwell      for (i = 0; i < count; i++) {
95893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell	 if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
96893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell	 if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
97893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      }
98893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      *min_index = min_ub;
99893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      *max_index = max_ub;
100893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      break;
101fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
102fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   default:
103893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      assert(0);
104893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell      break;
105fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1062708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
107bd4c6a2e503db43e81ef41f77d876308badd93ebBrian Paul   if (_mesa_is_bufferobj(ib->obj)) {
1082708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt      ctx->Driver.UnmapBuffer(ctx,
1092708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			      GL_ELEMENT_ARRAY_BUFFER_ARB,
1102708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt			      ib->obj);
1112708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   }
112fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
113fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
114fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1153bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul/**
11613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul * Check that element 'j' of the array has reasonable data.
11713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul * Map VBO if needed.
11813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul */
11913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paulstatic void
12013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paulcheck_array_data(GLcontext *ctx, struct gl_client_array *array,
12113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                 GLuint attrib, GLuint j)
12213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul{
12313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   if (array->Enabled) {
12413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      const void *data = array->Ptr;
125bd4c6a2e503db43e81ef41f77d876308badd93ebBrian Paul      if (_mesa_is_bufferobj(array->BufferObj)) {
12613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         if (!array->BufferObj->Pointer) {
12713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul            /* need to map now */
12813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul            array->BufferObj->Pointer = ctx->Driver.MapBuffer(ctx,
12913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                                                              GL_ARRAY_BUFFER_ARB,
13013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                                                              GL_READ_ONLY,
13113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                                                              array->BufferObj);
13213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         }
13313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         data = ADD_POINTERS(data, array->BufferObj->Pointer);
13413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      }
13513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      switch (array->Type) {
13613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      case GL_FLOAT:
13713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         {
13813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul            GLfloat *f = (GLfloat *) ((GLubyte *) data + array->StrideB * j);
13913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul            GLuint k;
14013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul            for (k = 0; k < array->Size; k++) {
14113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul               if (IS_INF_OR_NAN(f[k]) ||
14213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                   f[k] >= 1.0e20 || f[k] <= -1.0e10) {
14313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                  _mesa_printf("Bad array data:\n");
14413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                  _mesa_printf("  Element[%u].%u = %f\n", j, k, f[k]);
14513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                  _mesa_printf("  Array %u at %p\n", attrib, (void* ) array);
14613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                  _mesa_printf("  Type 0x%x, Size %d, Stride %d\n",
14713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                               array->Type, array->Size, array->Stride);
14813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                  _mesa_printf("  Address/offset %p in Buffer Object %u\n",
14913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                               array->Ptr, array->BufferObj->Name);
15013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                  f[k] = 1.0; /* XXX replace the bad value! */
15113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul               }
15213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul               //assert(!IS_INF_OR_NAN(f[k]));
15313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul            }
15413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         }
15513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         break;
15613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      default:
15713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         ;
15813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      }
15913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   }
16013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul}
16113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
16213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
16313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul/**
16413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul * Unmap the buffer object referenced by given array, if mapped.
16513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul */
16613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paulstatic void
16713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paulunmap_array_buffer(GLcontext *ctx, struct gl_client_array *array)
16813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul{
16913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   if (array->Enabled &&
170bd4c6a2e503db43e81ef41f77d876308badd93ebBrian Paul       _mesa_is_bufferobj(array->BufferObj) &&
171bd4c6a2e503db43e81ef41f77d876308badd93ebBrian Paul       _mesa_bufferobj_mapped(array->BufferObj)) {
17213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      ctx->Driver.UnmapBuffer(ctx,
17313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                              GL_ARRAY_BUFFER_ARB,
17413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                              array->BufferObj);
17513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   }
17613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul}
17713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
17813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
17913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul/**
18013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul * Examine the array's data for NaNs, etc.
18113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul */
18213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paulstatic void
18313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paulcheck_draw_elements_data(GLcontext *ctx, GLsizei count, GLenum elemType,
18492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt                         const void *elements, GLint basevertex)
18513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul{
18613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
18713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   const void *elemMap;
18813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   GLint i, k;
18913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
190bd4c6a2e503db43e81ef41f77d876308badd93ebBrian Paul   if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) {
19113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      elemMap = ctx->Driver.MapBuffer(ctx,
19213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                                      GL_ELEMENT_ARRAY_BUFFER_ARB,
19313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                                      GL_READ_ONLY,
19413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul                                      ctx->Array.ElementArrayBufferObj);
19513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      elements = ADD_POINTERS(elements, elemMap);
19613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   }
19713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
19813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   for (i = 0; i < count; i++) {
19913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      GLuint j;
20013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
20113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      /* j = element[i] */
20213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      switch (elemType) {
20313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      case GL_UNSIGNED_BYTE:
20413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         j = ((const GLubyte *) elements)[i];
20513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         break;
20613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      case GL_UNSIGNED_SHORT:
20713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         j = ((const GLushort *) elements)[i];
20813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         break;
20913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      case GL_UNSIGNED_INT:
21013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         j = ((const GLuint *) elements)[i];
21113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         break;
21213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      default:
21313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         assert(0);
21413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      }
21513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
21613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      /* check element j of each enabled array */
21713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      check_array_data(ctx, &arrayObj->Vertex, VERT_ATTRIB_POS, j);
21813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      check_array_data(ctx, &arrayObj->Normal, VERT_ATTRIB_NORMAL, j);
21913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      check_array_data(ctx, &arrayObj->Color, VERT_ATTRIB_COLOR0, j);
22013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      check_array_data(ctx, &arrayObj->SecondaryColor, VERT_ATTRIB_COLOR1, j);
22113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      for (k = 0; k < Elements(arrayObj->TexCoord); k++) {
22213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         check_array_data(ctx, &arrayObj->TexCoord[k], VERT_ATTRIB_TEX0 + k, j);
22313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      }
22413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) {
22513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul         check_array_data(ctx, &arrayObj->VertexAttrib[k], VERT_ATTRIB_GENERIC0 + k, j);
22613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      }
22713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   }
22813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
229bd4c6a2e503db43e81ef41f77d876308badd93ebBrian Paul   if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) {
23013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      ctx->Driver.UnmapBuffer(ctx,
23113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul			      GL_ELEMENT_ARRAY_BUFFER_ARB,
23213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul			      ctx->Array.ElementArrayBufferObj);
23313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   }
23413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
23513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   unmap_array_buffer(ctx, &arrayObj->Vertex);
23613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   unmap_array_buffer(ctx, &arrayObj->Normal);
23713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   unmap_array_buffer(ctx, &arrayObj->Color);
23813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   for (k = 0; k < Elements(arrayObj->TexCoord); k++) {
23913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      unmap_array_buffer(ctx, &arrayObj->TexCoord[k]);
24013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   }
24113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) {
24213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul      unmap_array_buffer(ctx, &arrayObj->VertexAttrib[k]);
24313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   }
24413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul}
24513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
24613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
24713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul/**
24813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul * Check array data, looking for NaNs, etc.
24913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul */
25013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paulstatic void
25113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paulcheck_draw_arrays_data(GLcontext *ctx, GLint start, GLsizei count)
25213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul{
25313f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   /* TO DO */
25413f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul}
25513f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
25613f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
25713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul/**
258aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul * Print info/data for glDrawArrays().
259aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul */
260aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paulstatic void
261aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paulprint_draw_arrays(GLcontext *ctx, struct vbo_exec_context *exec,
262aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul                  GLenum mode, GLint start, GLsizei count)
263aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul{
264aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul   int i;
265aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul
266aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul   _mesa_printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n",
267aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul                mode, start, count);
268aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul
269aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul   for (i = 0; i < 32; i++) {
270aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul      GLuint bufName = exec->array.inputs[i]->BufferObj->Name;
271aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul      GLint stride = exec->array.inputs[i]->Stride;
272aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul      _mesa_printf("attr %2d: size %d stride %d  enabled %d  "
273aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul                   "ptr %p  Bufobj %u\n",
274aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul                   i,
275aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul                   exec->array.inputs[i]->Size,
276aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul                   stride,
277aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul                   /*exec->array.inputs[i]->Enabled,*/
278aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul                   exec->array.legacy_array[i]->Enabled,
279aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul                   exec->array.inputs[i]->Ptr,
280aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul                   bufName);
281aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul
282aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul      if (bufName) {
283aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         struct gl_buffer_object *buf = _mesa_lookup_bufferobj(ctx, bufName);
284aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         GLubyte *p = ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER_ARB,
285aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul                                            GL_READ_ONLY_ARB, buf);
286aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         int offset = (int) (GLintptr) exec->array.inputs[i]->Ptr;
287aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         float *f = (float *) (p + offset);
288aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         int *k = (int *) f;
289aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         int i;
290aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         int n = (count * stride) / 4;
291aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         if (n > 32)
292aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul            n = 32;
293aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         _mesa_printf("  Data at offset %d:\n", offset);
294aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         for (i = 0; i < n; i++) {
295aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul            _mesa_printf("    float[%d] = 0x%08x %f\n", i, k[i], f[i]);
296aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         }
297aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul         ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB, buf);
298aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul      }
299aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul   }
300aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul}
301aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul
302aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul
303aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul/**
3043bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul * Just translate the arrayobj into a sane layout.
305fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
3060b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulstatic void
3070b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulbind_array_obj(GLcontext *ctx)
308fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
3095a652f595716a82ebd79e33011f6082199c4b0d0Keith Whitwell   struct vbo_context *vbo = vbo_context(ctx);
3105a652f595716a82ebd79e33011f6082199c4b0d0Keith Whitwell   struct vbo_exec_context *exec = &vbo->exec;
3112e798e4b7e5956dbf3c7fde18f408b5d4c1b151cBrian Paul   struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
312fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
313fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
314fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* TODO: Fix the ArrayObj struct to keep legacy arrays in an array
315fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * rather than as individual named arrays.  Then this function can
316fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * go away.
317fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
3182e798e4b7e5956dbf3c7fde18f408b5d4c1b151cBrian Paul   exec->array.legacy_array[VERT_ATTRIB_POS] = &arrayObj->Vertex;
3198fa0cb2b422abaeee1b69f82ca7e9f02dc8393b9Brian Paul   exec->array.legacy_array[VERT_ATTRIB_WEIGHT] = &arrayObj->Weight;
3202e798e4b7e5956dbf3c7fde18f408b5d4c1b151cBrian Paul   exec->array.legacy_array[VERT_ATTRIB_NORMAL] = &arrayObj->Normal;
3212e798e4b7e5956dbf3c7fde18f408b5d4c1b151cBrian Paul   exec->array.legacy_array[VERT_ATTRIB_COLOR0] = &arrayObj->Color;
3222e798e4b7e5956dbf3c7fde18f408b5d4c1b151cBrian Paul   exec->array.legacy_array[VERT_ATTRIB_COLOR1] = &arrayObj->SecondaryColor;
3232e798e4b7e5956dbf3c7fde18f408b5d4c1b151cBrian Paul   exec->array.legacy_array[VERT_ATTRIB_FOG] = &arrayObj->FogCoord;
3242e798e4b7e5956dbf3c7fde18f408b5d4c1b151cBrian Paul   exec->array.legacy_array[VERT_ATTRIB_COLOR_INDEX] = &arrayObj->Index;
3252e798e4b7e5956dbf3c7fde18f408b5d4c1b151cBrian Paul   if (arrayObj->PointSize.Enabled) {
326d378f7b3dfda3b549e4b02380e492671cc34bb59Brian Paul      /* this aliases COLOR_INDEX */
3272e798e4b7e5956dbf3c7fde18f408b5d4c1b151cBrian Paul      exec->array.legacy_array[VERT_ATTRIB_POINT_SIZE] = &arrayObj->PointSize;
328d378f7b3dfda3b549e4b02380e492671cc34bb59Brian Paul   }
3292e798e4b7e5956dbf3c7fde18f408b5d4c1b151cBrian Paul   exec->array.legacy_array[VERT_ATTRIB_EDGEFLAG] = &arrayObj->EdgeFlag;
330fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
3318e3f6c0f96eb22198ec436990acc85d44aca7d8eBrian Paul   for (i = 0; i < Elements(arrayObj->TexCoord); i++)
3322e798e4b7e5956dbf3c7fde18f408b5d4c1b151cBrian Paul      exec->array.legacy_array[VERT_ATTRIB_TEX0 + i] = &arrayObj->TexCoord[i];
333fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
3348e3f6c0f96eb22198ec436990acc85d44aca7d8eBrian Paul   for (i = 0; i < Elements(arrayObj->VertexAttrib); i++) {
3358da09e6924ca22ba7951d5a7673dfab2a711a997Brian Paul      assert(i < Elements(exec->array.generic_array));
3362e798e4b7e5956dbf3c7fde18f408b5d4c1b151cBrian Paul      exec->array.generic_array[i] = &arrayObj->VertexAttrib[i];
3378da09e6924ca22ba7951d5a7673dfab2a711a997Brian Paul   }
338fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
3392e798e4b7e5956dbf3c7fde18f408b5d4c1b151cBrian Paul   exec->array.array_obj = arrayObj->Name;
340fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
341fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
3423bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul
3430b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulstatic void
3440b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulrecalculate_input_bindings(GLcontext *ctx)
345fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
34699efde461d3b8615863bdb7308e05289e0db0422Keith Whitwell   struct vbo_context *vbo = vbo_context(ctx);
34799efde461d3b8615863bdb7308e05289e0db0422Keith Whitwell   struct vbo_exec_context *exec = &vbo->exec;
348fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   const struct gl_client_array **inputs = &exec->array.inputs[0];
349239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul   GLbitfield const_inputs = 0x0;
350fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
351fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
352fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   exec->array.program_mode = get_program_mode(ctx);
353fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   exec->array.enabled_flags = ctx->Array.ArrayObj->_Enabled;
354fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
355fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   switch (exec->array.program_mode) {
356fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case VP_NONE:
3573bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul      /* When no vertex program is active (or the vertex program is generated
3583bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul       * from fixed-function state).  We put the material values into the
3593bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul       * generic slots.  This is the only situation where material values
3603bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul       * are available as per-vertex attributes.
361fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
362fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0; i <= VERT_ATTRIB_TEX7; i++) {
363fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 if (exec->array.legacy_array[i]->Enabled)
364fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	    inputs[i] = exec->array.legacy_array[i];
3651680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell	 else {
36699efde461d3b8615863bdb7308e05289e0db0422Keith Whitwell	    inputs[i] = &vbo->legacy_currval[i];
3671680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell            const_inputs |= 1 << i;
3681680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell         }
369fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
370fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
371fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0; i < MAT_ATTRIB_MAX; i++) {
37299efde461d3b8615863bdb7308e05289e0db0422Keith Whitwell	 inputs[VERT_ATTRIB_GENERIC0 + i] = &vbo->mat_currval[i];
3731680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell         const_inputs |= 1 << (VERT_ATTRIB_GENERIC0 + i);
374fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
3755a652f595716a82ebd79e33011f6082199c4b0d0Keith Whitwell
3765a652f595716a82ebd79e33011f6082199c4b0d0Keith Whitwell      /* Could use just about anything, just to fill in the empty
3775a652f595716a82ebd79e33011f6082199c4b0d0Keith Whitwell       * slots:
3785a652f595716a82ebd79e33011f6082199c4b0d0Keith Whitwell       */
3791680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_MAX - VERT_ATTRIB_GENERIC0; i++) {
380fcccf8943213a20957f305161e8aae7fef55baabZou Nan hai	 inputs[VERT_ATTRIB_GENERIC0 + i] = &vbo->generic_currval[i];
3811680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell         const_inputs |= 1 << (VERT_ATTRIB_GENERIC0 + i);
3821680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      }
383fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
3843bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul
385fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case VP_NV:
386fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* NV_vertex_program - attribute arrays alias and override
387fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * conventional, legacy arrays.  No materials, and the generic
388fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * slots are vacant.
389fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
390fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0; i <= VERT_ATTRIB_TEX7; i++) {
391fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 if (exec->array.generic_array[i]->Enabled)
392fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	    inputs[i] = exec->array.generic_array[i];
393fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 else if (exec->array.legacy_array[i]->Enabled)
394fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	    inputs[i] = exec->array.legacy_array[i];
3951680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell	 else {
39699efde461d3b8615863bdb7308e05289e0db0422Keith Whitwell	    inputs[i] = &vbo->legacy_currval[i];
3971680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell            const_inputs |= 1 << i;
3981680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell         }
399fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
400301acdf34ad01315f41c14638d92aa7fe0c2d2dcKeith Whitwell
401301acdf34ad01315f41c14638d92aa7fe0c2d2dcKeith Whitwell      /* Could use just about anything, just to fill in the empty
402301acdf34ad01315f41c14638d92aa7fe0c2d2dcKeith Whitwell       * slots:
403301acdf34ad01315f41c14638d92aa7fe0c2d2dcKeith Whitwell       */
4041680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) {
405301acdf34ad01315f41c14638d92aa7fe0c2d2dcKeith Whitwell	 inputs[i] = &vbo->generic_currval[i - VERT_ATTRIB_GENERIC0];
4061680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell         const_inputs |= 1 << i;
4071680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      }
408fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
4093bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul
410fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case VP_ARB:
4113bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul      /* GL_ARB_vertex_program or GLSL vertex shader - Only the generic[0]
4123bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul       * attribute array aliases and overrides the legacy position array.
413fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       *
414fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * Otherwise, legacy attributes available in the legacy slots,
415fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * generic attributes in the generic slots and materials are not
416fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * available as per-vertex attributes.
417fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
418fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (exec->array.generic_array[0]->Enabled)
419fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 inputs[0] = exec->array.generic_array[0];
420fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      else if (exec->array.legacy_array[0]->Enabled)
421fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 inputs[0] = exec->array.legacy_array[0];
4221680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      else {
42399efde461d3b8615863bdb7308e05289e0db0422Keith Whitwell	 inputs[0] = &vbo->legacy_currval[0];
4241680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell         const_inputs |= 1 << 0;
4251680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      }
426fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
427fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 1; i <= VERT_ATTRIB_TEX7; i++) {
428fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 if (exec->array.legacy_array[i]->Enabled)
429fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	    inputs[i] = exec->array.legacy_array[i];
4301680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell	 else {
43199efde461d3b8615863bdb7308e05289e0db0422Keith Whitwell	    inputs[i] = &vbo->legacy_currval[i];
4321680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell            const_inputs |= 1 << i;
4331680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell         }
434fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
435fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
4364a95185c9f30c2de7a03bb1a0653f51b53b1111dBrian Paul      for (i = 0; i < MAX_VERTEX_GENERIC_ATTRIBS; i++) {
4377d8ed0f5f5960a492734cb415b8a85ef4ad79846Roland Scheidegger	 if (exec->array.generic_array[i]->Enabled)
438fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	    inputs[VERT_ATTRIB_GENERIC0 + i] = exec->array.generic_array[i];
4391680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell	 else {
44099efde461d3b8615863bdb7308e05289e0db0422Keith Whitwell	    inputs[VERT_ATTRIB_GENERIC0 + i] = &vbo->generic_currval[i];
4411680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell            const_inputs |= 1 << (VERT_ATTRIB_GENERIC0 + i);
4421680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell         }
4431680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell
444fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
445fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
446fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
4471680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell
4481680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell   _mesa_set_varying_vp_inputs( ctx, ~const_inputs );
449fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
450fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
4513bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul
4520b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulstatic void
4530b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulbind_arrays(GLcontext *ctx)
454fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
455fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#if 0
456fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->Array.ArrayObj.Name != exec->array.array_obj) {
457fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      bind_array_obj(ctx);
458fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      recalculate_input_bindings(ctx);
459fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
460fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   else if (exec->array.program_mode != get_program_mode(ctx) ||
461fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	    exec->array.enabled_flags != ctx->Array.ArrayObj->_Enabled) {
462fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
463fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      recalculate_input_bindings(ctx);
464fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
465fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#else
466fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   bind_array_obj(ctx);
467fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   recalculate_input_bindings(ctx);
468fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#endif
469fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
470fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
471fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
472fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
473fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/***********************************************************************
474fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * API functions.
475fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
476fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
477fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY
478fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellvbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
479fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
480fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
481fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_context *vbo = vbo_context(ctx);
482fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_exec_context *exec = &vbo->exec;
483fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct _mesa_prim prim[1];
484fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
485fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
486fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
487fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
488fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   FLUSH_CURRENT( ctx, 0 );
489fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
490fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->NewState)
491fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _mesa_update_state( ctx );
492fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
493e3d47515f9b376b00743137529b4ca35a8436c92Brian Paul   if (!_mesa_valid_to_render(ctx, "glDrawArrays")) {
494d758479b9fbff803bdac15f3f39d32ef9064db71Brian Paul      return;
495d758479b9fbff803bdac15f3f39d32ef9064db71Brian Paul   }
496d758479b9fbff803bdac15f3f39d32ef9064db71Brian Paul
49713f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul#if 0
49813f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   check_draw_arrays_data(ctx, start, count);
49913f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul#else
50013f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul   (void) check_draw_arrays_data;
50113f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul#endif
50213f6d07521119afc4b6d9e6daa94d5091f4b9c65Brian Paul
503fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   bind_arrays( ctx );
504fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
5053bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul   /* Again... because we may have changed the bitmask of per-vertex varying
5063bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul    * attributes.  If we regenerate the fixed-function vertex program now
5073bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul    * we may be able to prune down the number of vertex attributes which we
5083bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul    * need in the shader.
5091680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell    */
5101680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell   if (ctx->NewState)
5111680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      _mesa_update_state( ctx );
5121680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell
513fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].begin = 1;
514fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].end = 1;
515fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].weak = 0;
516fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].pad = 0;
517893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   prim[0].mode = mode;
518893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   prim[0].start = start;
519893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   prim[0].count = count;
520893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   prim[0].indexed = 0;
52192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   prim[0].basevertex = 0;
522fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
5233bfe312d0136c95b2a8518d65fa32c89ed474987Brian Paul   vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL,
5242708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt                    GL_TRUE, start, start + count - 1 );
525a3b7db0326337117ccdea526818040d2c24d83b4Brian Paul
526a3b7db0326337117ccdea526818040d2c24d83b4Brian Paul#if 0
527aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul   print_draw_arrays(ctx, exec, mode, start, count);
528aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul#else
529aa18e54ac9a70883a98f803c097d45f8ee84e717Brian Paul   (void) print_draw_arrays;
530a3b7db0326337117ccdea526818040d2c24d83b4Brian Paul#endif
531fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
532fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
533fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
534c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul/**
535c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul * Map GL_ELEMENT_ARRAY_BUFFER and print contents.
536c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul */
537c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paulstatic void
538c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Pauldump_element_buffer(GLcontext *ctx, GLenum type)
539c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul{
540c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   const GLvoid *map = ctx->Driver.MapBuffer(ctx,
541c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul                                             GL_ELEMENT_ARRAY_BUFFER_ARB,
542c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul                                             GL_READ_ONLY,
543c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul                                             ctx->Array.ElementArrayBufferObj);
544c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   switch (type) {
545c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   case GL_UNSIGNED_BYTE:
546c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      {
547c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         const GLubyte *us = (const GLubyte *) map;
548c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         GLuint i;
549c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         for (i = 0; i < ctx->Array.ElementArrayBufferObj->Size; i++) {
550c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul            _mesa_printf("%02x ", us[i]);
551c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul            if (i % 32 == 31)
552c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul               _mesa_printf("\n");
553c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         }
554c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         _mesa_printf("\n");
555c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      }
556c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      break;
557c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   case GL_UNSIGNED_SHORT:
558c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      {
559c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         const GLushort *us = (const GLushort *) map;
560c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         GLuint i;
561c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         for (i = 0; i < ctx->Array.ElementArrayBufferObj->Size / 2; i++) {
562c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul            _mesa_printf("%04x ", us[i]);
563c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul            if (i % 16 == 15)
564c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul               _mesa_printf("\n");
565c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         }
566c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         _mesa_printf("\n");
567c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      }
568c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      break;
569c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   case GL_UNSIGNED_INT:
570c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      {
571c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         const GLuint *us = (const GLuint *) map;
572c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         GLuint i;
573c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         for (i = 0; i < ctx->Array.ElementArrayBufferObj->Size / 4; i++) {
574c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul            _mesa_printf("%08x ", us[i]);
575c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul            if (i % 8 == 7)
576c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul               _mesa_printf("\n");
577c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         }
578c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul         _mesa_printf("\n");
579c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      }
580c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      break;
581c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   default:
582c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul      ;
583c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   }
584c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul
585c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul   ctx->Driver.UnmapBuffer(ctx,
586c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul                           GL_ELEMENT_ARRAY_BUFFER_ARB,
587c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul                           ctx->Array.ElementArrayBufferObj);
588c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul}
589c55f1a6c9917a87cc6b29808b4132b83cf516e05Brian Paul
5902708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt/* Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */
5912708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholtstatic void
5922708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholtvbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,
5932708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt				GLboolean index_bounds_valid,
5942708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt				GLuint start, GLuint end,
5952708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt				GLsizei count, GLenum type,
59692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				const GLvoid *indices,
59792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				GLint basevertex)
598fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
599fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_context *vbo = vbo_context(ctx);
600fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_exec_context *exec = &vbo->exec;
601fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct _mesa_index_buffer ib;
602fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct _mesa_prim prim[1];
603fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
604fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   FLUSH_CURRENT( ctx, 0 );
605fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
606fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->NewState)
607fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _mesa_update_state( ctx );
608c3da1501b81a31e92f485ee9fbd99e60cc3a4337Roland Scheidegger
609e3d47515f9b376b00743137529b4ca35a8436c92Brian Paul   if (!_mesa_valid_to_render(ctx, "glDraw[Range]Elements")) {
610d758479b9fbff803bdac15f3f39d32ef9064db71Brian Paul      return;
611d758479b9fbff803bdac15f3f39d32ef9064db71Brian Paul   }
612d758479b9fbff803bdac15f3f39d32ef9064db71Brian Paul
6131680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell   if (ctx->NewState)
6141680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell      _mesa_update_state( ctx );
6151680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell
6162708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   bind_arrays( ctx );
6172708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
618fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ib.count = count;
6192708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   ib.type = type;
620fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ib.obj = ctx->Array.ElementArrayBufferObj;
621fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ib.ptr = indices;
622fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
623fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].begin = 1;
624fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].end = 1;
625fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].weak = 0;
626fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].pad = 0;
627fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].mode = mode;
628fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].start = 0;
629fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].count = count;
630fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   prim[0].indexed = 1;
63192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   prim[0].basevertex = basevertex;
632fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
633893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell   /* Need to give special consideration to rendering a range of
634893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * indices starting somewhere above zero.  Typically the
635893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * application is issuing multiple DrawRangeElements() to draw
636893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * successive primitives layed out linearly in the vertex arrays.
637893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * Unless the vertex arrays are all in a VBO (or locked as with
638893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * CVA), the OpenGL semantics imply that we need to re-read or
639893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * re-upload the vertex data on each draw call.
640893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
641893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * In the case of hardware tnl, we want to avoid starting the
642893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * upload at zero, as it will mean every draw call uploads an
643893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * increasing amount of not-used vertex data.  Worse - in the
644893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * software tnl module, all those vertices might be transformed and
645893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * lit but never rendered.
646893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
647893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * If we just upload or transform the vertices in start..end,
648893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * however, the indices will be incorrect.
649893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
650893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * At this level, we don't know exactly what the requirements of
651893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * the backend are going to be, though it will likely boil down to
652893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * either:
653893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
654893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * 1) Do nothing, everything is in a VBO and is processed once
655893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *       only.
656893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
657893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * 2) Adjust the indices and vertex arrays so that start becomes
658893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *    zero.
659893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    *
660893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * Rather than doing anything here, I'll provide a helper function
661893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    * for the latter case elsewhere.
662893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell    */
663fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
6642708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib,
6652708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt		    index_bounds_valid, start, end );
666893526b8a823fe1b88f2b46376155afb91c84016Keith Whitwell}
667fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
668fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY
66992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
67092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     GLuint start, GLuint end,
67192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     GLsizei count, GLenum type,
67292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     const GLvoid *indices,
67392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     GLint basevertex)
674fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
675fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
676fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
6772708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count,
67892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt                                          type, indices, basevertex ))
679fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
680fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
68194a020cfe6cb1da04695897eed38b530af31f524Brian Paul   /* NOTE: It's important that 'end' is a reasonable value.
68294a020cfe6cb1da04695897eed38b530af31f524Brian Paul    * in _tnl_draw_prims(), we use end to determine how many vertices
68394a020cfe6cb1da04695897eed38b530af31f524Brian Paul    * to transform.  If it's too large, we can unnecessarily split prims
68494a020cfe6cb1da04695897eed38b530af31f524Brian Paul    * or we can read/write out of memory in several different places!
68594a020cfe6cb1da04695897eed38b530af31f524Brian Paul    */
68694a020cfe6cb1da04695897eed38b530af31f524Brian Paul
6872708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   if (end >= ctx->Array.ArrayObj->_MaxElement) {
6882708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt      /* the max element is out of bounds of one or more enabled arrays */
68940603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul      _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, count %d, "
6909a3333f43600ed4b9a17e49f79004f0c8d289378Brian Paul                    "type 0x%x, indices %p, base %d)\n"
69140603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul                    "\tend is out of bounds (max=%u)  "
69240603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul                    "Element Buffer %u (size %d)\n"
69340603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul                    "\tThis should probably be fixed in the application.",
6949a3333f43600ed4b9a17e49f79004f0c8d289378Brian Paul                    start, end, count, type, indices, basevertex,
6952708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt                    ctx->Array.ArrayObj->_MaxElement - 1,
6962708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt                    ctx->Array.ElementArrayBufferObj->Name,
6972708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt                    ctx->Array.ElementArrayBufferObj->Size);
6982708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
6992708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt      if (0)
7002708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt         dump_element_buffer(ctx, type);
7012708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
7022708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt      if (0)
7032708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt         _mesa_print_arrays(ctx);
70440603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul
70540603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul#ifdef DEBUG
70640603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul      /* 'end' was out of bounds, but now let's check the actual array
70740603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul       * indexes to see if any of them are out of bounds.  If so, warn
70840603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul       * and skip the draw to avoid potential segfault, etc.
70940603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul       */
71040603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul      {
71140603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul         GLuint max = _mesa_max_buffer_index(ctx, count, type, indices,
71240603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul                                             ctx->Array.ElementArrayBufferObj);
71340603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul         if (max >= ctx->Array.ArrayObj->_MaxElement) {
71440603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul            _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, "
7159a3333f43600ed4b9a17e49f79004f0c8d289378Brian Paul                          "count %d, type 0x%x, indices %p, base %p)\n"
71640603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul                          "\tindex=%u is out of bounds (max=%u)  "
71740603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul                          "Element Buffer %u (size %d)\n"
71840603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul                          "\tSkipping the glDrawRangeElements() call",
7199a3333f43600ed4b9a17e49f79004f0c8d289378Brian Paul                          start, end, count, type, indices, basevertex,
7209a3333f43600ed4b9a17e49f79004f0c8d289378Brian Paul                          max,
72140603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul                          ctx->Array.ArrayObj->_MaxElement - 1,
72240603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul                          ctx->Array.ElementArrayBufferObj->Name,
72340603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul                          ctx->Array.ElementArrayBufferObj->Size);
72440603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul            return;
72540603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul         }
72640603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul         /* XXX we could also find the min index and compare to 'start'
72740603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul          * to see if start is correct.  But it's more likely to get the
72840603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul          * upper bound wrong.
72940603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul          */
73040603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul      }
73140603526f478a59b89a4c0a07c75a97dfe56b8c3Brian Paul#endif
732d758479b9fbff803bdac15f3f39d32ef9064db71Brian Paul   }
7332708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   else if (0) {
73492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      _mesa_printf("glDraw[Range]Elements{,BaseVertex}"
73592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt                   "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, "
73692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt		   "base %d\n",
7372708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt                   start, end, type, count,
73892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt                   ctx->Array.ElementArrayBufferObj->Name,
73992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt		   basevertex);
7402708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   }
741d758479b9fbff803bdac15f3f39d32ef9064db71Brian Paul
7422708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt#if 0
7432708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   check_draw_elements_data(ctx, count, type, indices);
7442708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt#else
7452708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   (void) check_draw_elements_data;
7462708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt#endif
7472708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
7482708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   vbo_validated_drawrangeelements(ctx, mode, GL_TRUE, start, end,
74992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				   count, type, indices, basevertex);
75092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
75192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
75292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtstatic void GLAPIENTRY
75392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvbo_exec_DrawRangeElements(GLenum mode,
75492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     GLuint start, GLuint end,
75592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     GLsizei count, GLenum type,
75692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     const GLvoid *indices)
75792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
75892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
75992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt					indices, 0);
7602708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt}
761fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
762fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
7632708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholtstatic void GLAPIENTRY
7642708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholtvbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
7652708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt                      const GLvoid *indices)
7662708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt{
7672708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   GET_CURRENT_CONTEXT(ctx);
7682708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt
76992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))
77092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      return;
77192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
77292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
77392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				   count, type, indices, 0);
77492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
77592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
77692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtstatic void GLAPIENTRY
77792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
77892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				const GLvoid *indices, GLint basevertex)
77992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
78092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GET_CURRENT_CONTEXT(ctx);
78192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
78292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices,
78392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     basevertex ))
7842708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt      return;
785fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
7862708ddfb06a36d8568e2aa130bf1f7d551fcd309Eric Anholt   vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
78792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				   count, type, indices, basevertex);
788fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
789fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
79060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt/* Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */
79160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholtstatic void
79260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholtvbo_validated_multidrawelements(GLcontext *ctx, GLenum mode,
79360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt				const GLsizei *count, GLenum type,
79492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				const GLvoid **indices, GLsizei primcount,
79592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				const GLint *basevertex)
79660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt{
79760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   struct vbo_context *vbo = vbo_context(ctx);
79860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   struct vbo_exec_context *exec = &vbo->exec;
79960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   struct _mesa_index_buffer ib;
80060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   struct _mesa_prim *prim;
80160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   unsigned int index_type_size = 0;
80260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   uintptr_t min_index_ptr, max_index_ptr;
80360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   GLboolean fallback = GL_FALSE;
80460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   int i;
80560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
80660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (primcount == 0)
80760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      return;
80860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
80960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   FLUSH_CURRENT( ctx, 0 );
81060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
81160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (ctx->NewState)
81260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      _mesa_update_state( ctx );
81360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
81460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (!_mesa_valid_to_render(ctx, "glMultiDrawElements")) {
81560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      return;
81660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
81760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
81860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (ctx->NewState)
81960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      _mesa_update_state( ctx );
82060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
82160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   prim = _mesa_calloc(primcount * sizeof(*prim));
82260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (prim == NULL) {
82360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements");
82460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      return;
82560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
82660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
82760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   /* Decide if we can do this all as one set of primitives sharing the
82860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    * same index buffer, or if we have to reset the index pointer per primitive.
82960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    */
83060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   bind_arrays( ctx );
83160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
83260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   switch (type) {
83360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   case GL_UNSIGNED_INT:
83460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      index_type_size = 4;
83560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      break;
83660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   case GL_UNSIGNED_SHORT:
83760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      index_type_size = 2;
83860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      break;
83960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   case GL_UNSIGNED_BYTE:
84060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      index_type_size = 1;
84160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      break;
84260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   default:
84360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      assert(0);
84460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
84560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
84660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   min_index_ptr = (uintptr_t)indices[0];
84760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   max_index_ptr = 0;
84860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   for (i = 0; i < primcount; i++) {
84960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      min_index_ptr = MIN2(min_index_ptr, (uintptr_t)indices[i]);
85060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      max_index_ptr = MAX2(max_index_ptr, (uintptr_t)indices[i] +
85160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt			   index_type_size * count[i]);
85260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
85360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
85460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   /* Check if we can handle this thing as a bunch of index offsets from the
85560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    * same index pointer.  If we can't, then we have to fall back to doing
85660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    * a draw_prims per primitive.
85760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    */
85860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (index_type_size != 1) {
85960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      for (i = 0; i < primcount; i++) {
86060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 if ((((uintptr_t)indices[i] - min_index_ptr) % index_type_size) != 0) {
86160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	    fallback = GL_TRUE;
86260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	    break;
86360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 }
86460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      }
86560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
86660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
86760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   /* If the index buffer isn't in a VBO, then treating the application's
86860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    * subranges of the index buffer as one large index buffer may lead to
86960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    * us reading unmapped memory.
87060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt    */
87160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (!_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj))
87260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      fallback = GL_TRUE;
87360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
87460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   if (!fallback) {
87560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      ib.count = (max_index_ptr - min_index_ptr) / index_type_size;
87660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      ib.type = type;
87760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      ib.obj = ctx->Array.ElementArrayBufferObj;
87860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      ib.ptr = (void *)min_index_ptr;
87960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
88060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      for (i = 0; i < primcount; i++) {
88160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].begin = (i == 0);
88260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].end = (i == primcount - 1);
88360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].weak = 0;
88460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].pad = 0;
88560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].mode = mode;
88660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].start = ((uintptr_t)indices[i] - min_index_ptr) / index_type_size;
88760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].count = count[i];
88860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[i].indexed = 1;
88992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 if (basevertex != NULL)
89092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    prim[i].basevertex = basevertex[i];
89192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 else
89292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    prim[i].basevertex = 0;
89360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      }
89460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
89560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      vbo->draw_prims(ctx, exec->array.inputs, prim, primcount, &ib,
89660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt		      GL_FALSE, ~0, ~0);
89760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   } else {
89860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      for (i = 0; i < primcount; i++) {
89960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 ib.count = count[i];
90060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 ib.type = type;
90160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 ib.obj = ctx->Array.ElementArrayBufferObj;
90260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 ib.ptr = indices[i];
90360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
90460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
90560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].begin = 1;
90660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].end = 1;
90760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].weak = 0;
90860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].pad = 0;
90960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].mode = mode;
91060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].start = 0;
91160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].count = count[i];
91260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 prim[0].indexed = 1;
91392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 if (basevertex != NULL)
91492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    prim[0].basevertex = basevertex[i];
91592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 else
91692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	    prim[0].basevertex = 0;
91760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      }
91860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
91960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt      vbo->draw_prims(ctx, exec->array.inputs, prim, 1, &ib,
92060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt		      GL_FALSE, ~0, ~0);
92160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
92260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   _mesa_free(prim);
92360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt}
92460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
92560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholtstatic void GLAPIENTRY
92660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholtvbo_exec_MultiDrawElements(GLenum mode,
92760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt			   const GLsizei *count, GLenum type,
92860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt			   const GLvoid **indices,
92960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt			   GLsizei primcount)
93060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt{
93160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   GET_CURRENT_CONTEXT(ctx);
93260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   GLint i;
93360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
93460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
93560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
93660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   for (i = 0; i < primcount; i++) {
93792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      if (!_mesa_validate_DrawElements(ctx, mode, count[i], type, indices[i],
93892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				       0))
93960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt	 return;
94060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   }
94160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
94292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
94392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				   NULL);
94460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt}
94560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
94692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtstatic void GLAPIENTRY
94792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
94892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     const GLsizei *count, GLenum type,
94992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     const GLvoid **indices,
95092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     GLsizei primcount,
95192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				     const GLsizei *basevertex)
95292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
95392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GET_CURRENT_CONTEXT(ctx);
95492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GLint i;
95592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
95692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
95792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
95892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   for (i = 0; i < primcount; i++) {
95992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt      if (!_mesa_validate_DrawElements(ctx, mode, count[i], type, indices[i],
96092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				       basevertex[i]))
96192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt	 return;
96292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   }
96392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
96492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
96592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				   basevertex);
96692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
96760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
968fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
969fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/***********************************************************************
970fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * Initialization
971fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
972fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
9730b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulvoid
9740b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulvbo_exec_array_init( struct vbo_exec_context *exec )
975fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
976fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#if 1
977fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   exec->vtxfmt.DrawArrays = vbo_exec_DrawArrays;
978fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   exec->vtxfmt.DrawElements = vbo_exec_DrawElements;
979fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   exec->vtxfmt.DrawRangeElements = vbo_exec_DrawRangeElements;
98060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   exec->vtxfmt.MultiDrawElementsEXT = vbo_exec_MultiDrawElements;
98192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   exec->vtxfmt.DrawElementsBaseVertex = vbo_exec_DrawElementsBaseVertex;
98292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   exec->vtxfmt.DrawRangeElementsBaseVertex = vbo_exec_DrawRangeElementsBaseVertex;
98392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   exec->vtxfmt.MultiDrawElementsBaseVertex = vbo_exec_MultiDrawElementsBaseVertex;
984fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#else
985fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   exec->vtxfmt.DrawArrays = _mesa_noop_DrawArrays;
986fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   exec->vtxfmt.DrawElements = _mesa_noop_DrawElements;
987fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   exec->vtxfmt.DrawRangeElements = _mesa_noop_DrawRangeElements;
98860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   exec->vtxfmt.MultiDrawElementsEXT = _mesa_noop_MultiDrawElements;
98992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   exec->vtxfmt.DrawElementsBaseVertex = _mesa_noop_DrawElementsBaseVertex;
99092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   exec->vtxfmt.DrawRangeElementsBaseVertex = _mesa_noop_DrawRangeElementsBaseVertex;
99192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   exec->vtxfmt.MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;
992fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#endif
993fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
994fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
995fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
9960b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulvoid
9970b6a0b367fdb575048b69d80ad4202d164a61f1eBrian Paulvbo_exec_array_destroy( struct vbo_exec_context *exec )
998fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
999584def75ad8dd13add5b4ed7e364d13202539539Keith Whitwell   /* nothing to do */
1000fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1001feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1002feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1003feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul/* This API entrypoint is not ordinarily used */
1004feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paulvoid GLAPIENTRY
1005feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul_mesa_DrawArrays(GLenum mode, GLint first, GLsizei count)
1006feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul{
1007feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul   vbo_exec_DrawArrays(mode, first, count);
1008feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul}
1009feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1010feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1011feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul/* This API entrypoint is not ordinarily used */
1012feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paulvoid GLAPIENTRY
1013feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
1014feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul                   const GLvoid *indices)
1015feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul{
1016feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul   vbo_exec_DrawElements(mode, count, type, indices);
1017feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul}
1018feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
101992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvoid GLAPIENTRY
102092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
102192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt			     const GLvoid *indices, GLint basevertex)
102292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
102392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex);
102492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
102592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
1026feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul
1027feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul/* This API entrypoint is not ordinarily used */
1028feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paulvoid GLAPIENTRY
1029feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
1030feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul                        GLenum type, const GLvoid *indices)
1031feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul{
1032feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul   vbo_exec_DrawRangeElements(mode, start, end, count, type, indices);
1033feb722fa98f04a4487b7ec4746bcc8c7296899c8Brian Paul}
103460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt
103592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvoid GLAPIENTRY
103692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
103792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				  GLsizei count, GLenum type,
103892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				  const GLvoid *indices, GLint basevertex)
103992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
104092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
104192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt					indices, basevertex);
104292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
104392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
104460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt/* GL_EXT_multi_draw_arrays */
104560b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholtvoid GLAPIENTRY
104660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,
104760b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt			   const GLvoid **indices, GLsizei primcount)
104860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt{
104960b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   vbo_exec_MultiDrawElements(mode, count, type, indices, primcount);
105060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt}
105192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
105292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtvoid GLAPIENTRY
105392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt_mesa_MultiDrawElementsBaseVertex(GLenum mode,
105492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				  const GLsizei *count, GLenum type,
105592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				  const GLvoid **indices, GLsizei primcount,
105692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt				  const GLint *basevertex)
105792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
105892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices,
105992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt					primcount, basevertex);
106092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
1061