vbo_save_api.c revision 1bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651
1fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/**************************************************************************
2fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
337c74af01ce52b603f565a6c8a9094500d5cb87aBrian PaulCopyright 2002-2008 Tungsten Graphics Inc., Cedar Park, Texas.
4fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
5fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith WhitwellAll Rights Reserved.
6fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
7fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith WhitwellPermission is hereby granted, free of charge, to any person obtaining a
8fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellcopy of this software and associated documentation files (the "Software"),
9fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellto deal in the Software without restriction, including without limitation
10fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellon the rights to use, copy, modify, merge, publish, distribute, sub
11fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwelllicense, and/or sell copies of the Software, and to permit persons to whom
12fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellthe Software is furnished to do so, subject to the following conditions:
13fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
14fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith WhitwellThe above copyright notice and this permission notice (including the next
15fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellparagraph) shall be included in all copies or substantial portions of the
16fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith WhitwellSoftware.
17fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
18fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith WhitwellTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith WhitwellIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith WhitwellFITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith WhitwellTUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith WhitwellDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith WhitwellOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith WhitwellUSE OR OTHER DEALINGS IN THE SOFTWARE.
25fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
26fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell**************************************************************************/
27fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
28fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/*
29fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * Authors:
30fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *   Keith Whitwell <keith@tungstengraphics.com>
31fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
32fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
33fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
34fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
35fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Display list compiler attempts to store lists of vertices with the
36fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * same vertex layout.  Additionally it attempts to minimize the need
37fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * for execute-time fixup of these vertex lists, allowing them to be
38fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * cached on hardware.
39fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *
40fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * There are still some circumstances where this can be thwarted, for
41fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * example by building a list that consists of one very long primitive
42fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * (eg Begin(Triangles), 1000 vertices, End), and calling that list
43fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * from inside a different begin/end object (Begin(Lines), CallList,
44fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * End).
45fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *
46fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * In that case the code will have to replay the list as individual
47fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * commands through the Exec dispatch table, or fix up the copied
48fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * vertices at execute-time.
49fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *
50fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * The other case where fixup is required is when a vertex attribute
51fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * is introduced in the middle of a primitive.  Eg:
52fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *  Begin(Lines)
53fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *  TexCoord1f()           Vertex2f()
54fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *  TexCoord1f() Color3f() Vertex2f()
55fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *  End()
56fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *
57fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *  If the current value of Color isn't known at compile-time, this
58fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *  primitive will require fixup.
59fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *
60fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *
61fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * The list compiler currently doesn't attempt to compile lists
62fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * containing EvalCoord or EvalPoint commands.  On encountering one of
63fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * these, compilation falls back to opcodes.
64fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *
65fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * This could be improved to fallback only when a mix of EvalCoord and
66fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * Vertex commands are issued within a single primitive.
67fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
68fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
69fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
70c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/glheader.h"
7137c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul#include "main/bufferobj.h"
72c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/context.h"
73c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/dlist.h"
74c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/enums.h"
75aefa1f6ab1d9267b223b06ae205ab34c8e0d7c02Chia-I Wu#include "main/eval.h"
76c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/macros.h"
7714b36cd568b7f3ae963430248fcd7ef0b7a165f6Vinson Lee#include "main/mfeatures.h"
78c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/api_validate.h"
79c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/api_arrayelt.h"
80c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/vtxfmt.h"
812cf44390d1e819f23e1d7ceb3199276c9148c647Chia-I Wu#include "main/dispatch.h"
82fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
83fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "vbo_context.h"
8497dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul#include "vbo_noop.h"
85fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
86fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
878d5c83c467f83b44f5f2e271c4f9cca2d45af518Chia-I Wu#if FEATURE_dlist
888d5c83c467f83b44f5f2e271c4f9cca2d45af518Chia-I Wu
898d5c83c467f83b44f5f2e271c4f9cca2d45af518Chia-I Wu
9037aca21129d87946d2dc6b45fa5bacd514921550zhang#ifdef ERROR
9137aca21129d87946d2dc6b45fa5bacd514921550zhang#undef ERROR
9237aca21129d87946d2dc6b45fa5bacd514921550zhang#endif
9337aca21129d87946d2dc6b45fa5bacd514921550zhang
94fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
9537c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul/* An interesting VBO number/name to help with debugging */
9637c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul#define VBO_BUF_ID  12345
9737c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul
9837c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul
99fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/*
100fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * NOTE: Old 'parity' issue is gone, but copying can still be
101fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * wrong-footed on replay.
102fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
1037c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic GLuint
1047c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_copy_vertices(struct gl_context *ctx,
1057c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                    const struct vbo_save_vertex_list *node,
1067c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                    const GLfloat * src_buffer)
107fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1087c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
1097c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   const struct _mesa_prim *prim = &node->prim[node->prim_count - 1];
110fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint nr = prim->count;
111fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint sz = save->vertex_size;
112fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   const GLfloat *src = src_buffer + prim->start * sz;
113fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLfloat *dst = save->copied.buffer;
114fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint ovf, i;
115fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
116fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (prim->end)
117fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return 0;
1187c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
1197c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   switch (prim->mode) {
120fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_POINTS:
121fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return 0;
122fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_LINES:
1237c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      ovf = nr & 1;
1247c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      for (i = 0; i < ovf; i++)
1257c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         memcpy(dst + i * sz, src + (nr - ovf + i) * sz,
1267c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                sz * sizeof(GLfloat));
127fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return i;
128fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_TRIANGLES:
1297c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      ovf = nr % 3;
1307c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      for (i = 0; i < ovf; i++)
1317c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         memcpy(dst + i * sz, src + (nr - ovf + i) * sz,
1327c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                sz * sizeof(GLfloat));
133fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return i;
134fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_QUADS:
1357c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      ovf = nr & 3;
1367c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      for (i = 0; i < ovf; i++)
1377c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         memcpy(dst + i * sz, src + (nr - ovf + i) * sz,
1387c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                sz * sizeof(GLfloat));
139fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return i;
140fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_LINE_STRIP:
1417c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      if (nr == 0)
1427c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         return 0;
143fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      else {
1447c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         memcpy(dst, src + (nr - 1) * sz, sz * sizeof(GLfloat));
1457c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         return 1;
146fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
147fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_LINE_LOOP:
148fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_TRIANGLE_FAN:
149fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_POLYGON:
1507c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      if (nr == 0)
1517c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         return 0;
152fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      else if (nr == 1) {
1537c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         memcpy(dst, src + 0, sz * sizeof(GLfloat));
1547c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         return 1;
1557c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      }
1567c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      else {
1577c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         memcpy(dst, src + 0, sz * sizeof(GLfloat));
1587c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         memcpy(dst + sz, src + (nr - 1) * sz, sz * sizeof(GLfloat));
1597c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         return 2;
160fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
161fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_TRIANGLE_STRIP:
162fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_QUAD_STRIP:
163fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      switch (nr) {
1647c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      case 0:
1657c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         ovf = 0;
1667c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         break;
1677c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      case 1:
1687c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         ovf = 1;
1697c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         break;
1707c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      default:
1717c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         ovf = 2 + (nr & 1);
1727c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         break;
173fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
1747c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      for (i = 0; i < ovf; i++)
1757c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         memcpy(dst + i * sz, src + (nr - ovf + i) * sz,
1767c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                sz * sizeof(GLfloat));
177fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return i;
178fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   default:
179fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(0);
180fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return 0;
181fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
182fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
183fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
184fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1857c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic struct vbo_save_vertex_store *
1867c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulalloc_vertex_store(struct gl_context *ctx)
187fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
18897dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
1897c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_vertex_store *vertex_store =
1907c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      CALLOC_STRUCT(vbo_save_vertex_store);
191fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
192fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* obj->Name needs to be non-zero, but won't ever be examined more
193fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * closely than that.  In particular these buffers won't be entered
194fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * into the hash and can never be confused with ones visible to the
195fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * user.  Perhaps there could be a special number for internal
196fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * buffers:
197fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
19837c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul   vertex_store->bufferobj = ctx->Driver.NewBufferObject(ctx,
19937c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul                                                         VBO_BUF_ID,
20037c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul                                                         GL_ARRAY_BUFFER_ARB);
20197dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (vertex_store->bufferobj) {
20297dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      save->out_of_memory =
20397dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul         !ctx->Driver.BufferData(ctx,
20497dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul                                 GL_ARRAY_BUFFER_ARB,
20597dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul                                 VBO_SAVE_BUFFER_SIZE * sizeof(GLfloat),
20697dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul                                 NULL, GL_STATIC_DRAW_ARB,
20797dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul                                 vertex_store->bufferobj);
20897dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
20997dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   else {
21097dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      save->out_of_memory = GL_TRUE;
21197dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
212fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
21397dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (save->out_of_memory) {
21497dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "internal VBO allocation");
21597dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
21697dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
217fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
218fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->buffer = NULL;
219fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->used = 0;
220fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->refcount = 1;
221fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
222fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return vertex_store;
223fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
224fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
2257c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
2267c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
2277c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulfree_vertex_store(struct gl_context *ctx,
2287c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  struct vbo_save_vertex_store *vertex_store)
229fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
230fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(!vertex_store->buffer);
231fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
23237c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul   if (vertex_store->bufferobj) {
23337c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul      _mesa_reference_buffer_object(ctx, &vertex_store->bufferobj, NULL);
23437c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul   }
235fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
2367c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   FREE(vertex_store);
237fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
238fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
2397c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
240781f84a3c2f7a06cb9e6cc44b8d5d08b39577c25Brian PaulGLfloat *
241781f84a3c2f7a06cb9e6cc44b8d5d08b39577c25Brian Paulvbo_save_map_vertex_store(struct gl_context *ctx,
242781f84a3c2f7a06cb9e6cc44b8d5d08b39577c25Brian Paul                          struct vbo_save_vertex_store *vertex_store)
243fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
244fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(vertex_store->bufferobj);
245fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(!vertex_store->buffer);
24697dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (vertex_store->bufferobj->Size > 0) {
24797dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      vertex_store->buffer =
24897dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul         (GLfloat *) ctx->Driver.MapBufferRange(ctx, 0,
24997dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul                                                vertex_store->bufferobj->Size,
25097dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul                                                GL_MAP_WRITE_BIT,  /* not used */
25197dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul                                                vertex_store->bufferobj);
25297dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      assert(vertex_store->buffer);
25397dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      return vertex_store->buffer + vertex_store->used;
25497dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
25597dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   else {
25697dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      /* probably ran out of memory for buffers */
25797dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      return NULL;
25897dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
259fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
260fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
2617c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
262781f84a3c2f7a06cb9e6cc44b8d5d08b39577c25Brian Paulvoid
263781f84a3c2f7a06cb9e6cc44b8d5d08b39577c25Brian Paulvbo_save_unmap_vertex_store(struct gl_context *ctx,
264781f84a3c2f7a06cb9e6cc44b8d5d08b39577c25Brian Paul                            struct vbo_save_vertex_store *vertex_store)
265fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
26697dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (vertex_store->bufferobj->Size > 0) {
26797dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      ctx->Driver.UnmapBuffer(ctx, vertex_store->bufferobj);
26897dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
269fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->buffer = NULL;
270fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
271fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
272fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
2737c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic struct vbo_save_primitive_store *
2747c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulalloc_prim_store(struct gl_context *ctx)
275fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
2767c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_primitive_store *store =
2777c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      CALLOC_STRUCT(vbo_save_primitive_store);
278fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) ctx;
279fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   store->used = 0;
280fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   store->refcount = 1;
281fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return store;
282fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
283fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
2847c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
2857c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
2867c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_reset_counters(struct gl_context *ctx)
287fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
288fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
289fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
290fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim = save->prim_store->buffer + save->prim_store->used;
2917c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   save->buffer = save->vertex_store->buffer + save->vertex_store->used;
292fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
293c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell   assert(save->buffer == save->buffer_ptr);
294fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
295fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->vertex_size)
2967c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) /
2977c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                        save->vertex_size);
298fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   else
299fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->max_vert = 0;
300fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
301fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vert_count = 0;
302fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_count = 0;
303fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_max = VBO_SAVE_PRIM_SIZE - save->prim_store->used;
304fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->dangling_attr_ref = 0;
305fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
306fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
307fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
3087c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul/**
3097c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul * Insert the active immediate struct onto the display list currently
310fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * being built.
311fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
3127c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
3137c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_compile_vertex_list(struct gl_context *ctx)
314fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
315fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
316fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_vertex_list *node;
317fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
318fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Allocate space for this structure in the display list currently
319fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * being compiled.
320fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
321fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node = (struct vbo_save_vertex_list *)
3226e1697bee72a95f7d605e42ce60e2cb4a545106fBrian Paul      _mesa_dlist_alloc(ctx, save->opcode_vertex_list, sizeof(*node));
323fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
324fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!node)
325fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
326fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
327fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Duplicate our template, increment refcounts to the storage structs:
328fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
329c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke   memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz));
330fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->vertex_size = save->vertex_size;
3317c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   node->buffer_offset =
3327c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat);
333fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->count = save->vert_count;
334fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->wrap_count = save->copied.nr;
335fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->dangling_attr_ref = save->dangling_attr_ref;
336fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim = save->prim;
337fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim_count = save->prim_count;
338fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->vertex_store = save->vertex_store;
339fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim_store = save->prim_store;
340fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
341fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->vertex_store->refcount++;
342fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim_store->refcount++;
343fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
344b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   if (node->prim[0].no_current_update) {
345b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich      node->current_size = 0;
346b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich      node->current_data = NULL;
3477c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   }
3487c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   else {
349b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich      node->current_size = node->vertex_size - node->attrsz[0];
350b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich      node->current_data = NULL;
3517c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
352b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich      if (node->current_size) {
353b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich         /* If the malloc fails, we just pull the data out of the VBO
354b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich          * later instead.
355b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich          */
3567c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         node->current_data = MALLOC(node->current_size * sizeof(GLfloat));
357b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich         if (node->current_data) {
3587c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul            const char *buffer = (const char *) save->vertex_store->buffer;
359b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich            unsigned attr_offset = node->attrsz[0] * sizeof(GLfloat);
360b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich            unsigned vertex_offset = 0;
3617c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
362b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich            if (node->count)
3637c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul               vertex_offset =
3647c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  (node->count - 1) * node->vertex_size * sizeof(GLfloat);
3657c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
3667c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul            memcpy(node->current_data,
3677c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                   buffer + node->buffer_offset + vertex_offset + attr_offset,
3687c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                   node->current_size * sizeof(GLfloat));
369b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich         }
3708b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell      }
3718b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell   }
3728b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell
3737c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   assert(node->attrsz[VBO_ATTRIB_POS] != 0 || node->count == 0);
374fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
375fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->dangling_attr_ref)
376446abc2799a143c32c4c48472f3f964f9288a623Brian      ctx->ListState.CurrentList->Flags |= DLIST_DANGLING_REFS;
377fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
378fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vertex_store->used += save->vertex_size * node->count;
379fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_store->used += node->prim_count;
380fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
381fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Copy duplicated vertices
382fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
3837c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   save->copied.nr = _save_copy_vertices(ctx, node, save->buffer);
384fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
385fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Deal with GL_COMPILE_AND_EXECUTE:
386fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
387fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->ExecuteFlag) {
388fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      struct _glapi_table *dispatch = GET_DISPATCH();
389fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
390fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _glapi_set_dispatch(ctx->Exec);
391fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
3927c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      vbo_loopback_vertex_list(ctx,
3937c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                               (const GLfloat *) ((const char *) save->
3947c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                                                  vertex_store->buffer +
3957c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                                                  node->buffer_offset),
3967c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                               node->attrsz, node->prim, node->prim_count,
3977c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                               node->wrap_count, node->vertex_size);
398fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
399fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _glapi_set_dispatch(dispatch);
400fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
401fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
402fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Decide whether the storage structs are full, or can be used for
403fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * the next vertex lists as well.
404fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
4057c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (save->vertex_store->used >
406fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       VBO_SAVE_BUFFER_SIZE - 16 * (save->vertex_size + 4)) {
407fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
408fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Unmap old store:
409fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
410781f84a3c2f7a06cb9e6cc44b8d5d08b39577c25Brian Paul      vbo_save_unmap_vertex_store(ctx, save->vertex_store);
411fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
412fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Release old reference:
413fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
4147c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      save->vertex_store->refcount--;
415fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(save->vertex_store->refcount != 0);
416fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vertex_store = NULL;
417fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
418fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Allocate and map new store:
419fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
4207c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      save->vertex_store = alloc_vertex_store(ctx);
421781f84a3c2f7a06cb9e6cc44b8d5d08b39577c25Brian Paul      save->buffer_ptr = vbo_save_map_vertex_store(ctx, save->vertex_store);
42297dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      save->out_of_memory = save->buffer_ptr == NULL;
4237c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   }
424fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
425fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->prim_store->used > VBO_SAVE_PRIM_SIZE - 6) {
4267c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      save->prim_store->refcount--;
427fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(save->prim_store->refcount != 0);
4287c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      save->prim_store = alloc_prim_store(ctx);
4297c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   }
430fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
431fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Reset our structures for the next run of vertices:
432fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
4337c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_reset_counters(ctx);
434fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
435fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
436fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
4377c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul/**
4387c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul * TODO -- If no new vertices have been stored, don't bother saving it.
439fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
4407c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
4417c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_wrap_buffers(struct gl_context *ctx)
442fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
443fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
444fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i = save->prim_count - 1;
445fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLenum mode;
446fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLboolean weak;
447b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   GLboolean no_current_update;
448fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
449fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(i < (GLint) save->prim_max);
450fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(i >= 0);
451fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
452fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Close off in-progress primitive.
453fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
4547c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   save->prim[i].count = (save->vert_count - save->prim[i].start);
455fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   mode = save->prim[i].mode;
456fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   weak = save->prim[i].weak;
457b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   no_current_update = save->prim[i].no_current_update;
4587c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
459fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* store the copied vertices, and allocate a new list.
460fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
4617c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_compile_vertex_list(ctx);
462fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
463fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Restart interrupted primitive
464fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
465fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].mode = mode;
466fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].weak = weak;
467b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   save->prim[0].no_current_update = no_current_update;
468fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].begin = 0;
469fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].end = 0;
470fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].pad = 0;
471fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].start = 0;
472fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].count = 0;
4733b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   save->prim[0].num_instances = 1;
474fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_count = 1;
475fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
476fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
477fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
4787c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul/**
4797c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul * Called only when buffers are wrapped as the result of filling the
480fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * vertex_store struct.
481fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
4827c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
4837c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_wrap_filled_vertex(struct gl_context *ctx)
484fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
485fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
486fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLfloat *data = save->copied.buffer;
487fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
488fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
489fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Emit a glEnd to close off the last vertex list.
490fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
4917c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_wrap_buffers(ctx);
4927c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
4937c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   /* Copy stored stored vertices to start of new list.
494fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
495fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(save->max_vert - save->vert_count > save->copied.nr);
496fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
4977c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   for (i = 0; i < save->copied.nr; i++) {
4987c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      memcpy(save->buffer_ptr, data, save->vertex_size * sizeof(GLfloat));
499fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      data += save->vertex_size;
500c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell      save->buffer_ptr += save->vertex_size;
501fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vert_count++;
502fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
503fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
504fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
505fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
5067c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
5077c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_copy_to_current(struct gl_context *ctx)
508fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
5097c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
510fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
511fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
5127c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
513fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (save->attrsz[i]) {
5147c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->currentsz[i][0] = save->attrsz[i];
5157c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         COPY_CLEAN_4V(save->current[i], save->attrsz[i], save->attrptr[i]);
516fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
517fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
518fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
519fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
520fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
5217c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
5227c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_copy_from_current(struct gl_context *ctx)
523fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
5247c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
525fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
526fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
5277c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
528fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      switch (save->attrsz[i]) {
5297c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      case 4:
5307c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->attrptr[i][3] = save->current[i][3];
5317c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      case 3:
5327c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->attrptr[i][2] = save->current[i][2];
5337c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      case 2:
5347c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->attrptr[i][1] = save->current[i][1];
5357c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      case 1:
5367c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->attrptr[i][0] = save->current[i][0];
5377c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      case 0:
5387c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         break;
539fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
540fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
541fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
542fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
543fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
544fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Flush existing data, set new attrib size, replay copied vertices.
5457c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul */
5467c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
5477c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
548fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
549fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
550fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint oldsz;
551fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
552fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLfloat *tmp;
553fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
554fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Store the current run of vertices, and emit a GL_END.  Emit a
555fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * BEGIN in the new buffer.
556fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
5577c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (save->vert_count)
5587c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _save_wrap_buffers(ctx);
559fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   else
5607c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      assert(save->copied.nr == 0);
561fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
562fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
563fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * when the attribute already exists in the vertex and is having
564fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * its size increased.
565fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
5667c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_copy_to_current(ctx);
567fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
568fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Fix up sizes:
569fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
570fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   oldsz = save->attrsz[attr];
571fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->attrsz[attr] = newsz;
572fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
573fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vertex_size += newsz - oldsz;
5747c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) /
5757c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                     save->vertex_size);
576fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vert_count = 0;
577fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
578fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Recalculate all the attrptr[] values:
579fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
5807c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   for (i = 0, tmp = save->vertex; i < VBO_ATTRIB_MAX; i++) {
581fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (save->attrsz[i]) {
5827c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->attrptr[i] = tmp;
5837c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         tmp += save->attrsz[i];
5847c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      }
5857c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      else {
5867c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->attrptr[i] = NULL;       /* will not be dereferenced. */
587fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
588fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
589fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
590fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Copy from current to repopulate the vertex with correct values.
591fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
5927c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_copy_from_current(ctx);
593fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
594fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Replay stored vertices to translate them to new format here.
595fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    *
596fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * If there are copied vertices and the new (upgraded) attribute
597fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * has not been defined before, this list is somewhat degenerate,
598fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * and will need fixup at runtime.
599fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
6007c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (save->copied.nr) {
601fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLfloat *data = save->copied.buffer;
602fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLfloat *dest = save->buffer;
603fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLuint j;
604fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
605fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Need to note this and fix up at runtime (or loopback):
606fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
607dd60eaa6d9f61735141976db0e83d25176ac73c7Keith Whitwell      if (attr != VBO_ATTRIB_POS && save->currentsz[attr][0] == 0) {
6087c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         assert(oldsz == 0);
6097c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->dangling_attr_ref = GL_TRUE;
610fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
611fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
6127c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      for (i = 0; i < save->copied.nr; i++) {
6137c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         for (j = 0; j < VBO_ATTRIB_MAX; j++) {
6147c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul            if (save->attrsz[j]) {
6157c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul               if (j == attr) {
6167c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  if (oldsz) {
6177c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                     COPY_CLEAN_4V(dest, oldsz, data);
6187c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                     data += oldsz;
6197c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                     dest += newsz;
6207c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  }
6217c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  else {
6227c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                     COPY_SZ_4V(dest, newsz, save->current[attr]);
6237c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                     dest += newsz;
6247c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  }
6257c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul               }
6267c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul               else {
6277c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  GLint sz = save->attrsz[j];
6287c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  COPY_SZ_4V(dest, sz, data);
6297c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  data += sz;
6307c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  dest += sz;
6317c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul               }
6327c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul            }
6337c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         }
634fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
635fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
636c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell      save->buffer_ptr = dest;
637fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vert_count += save->copied.nr;
638fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
639fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
640fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
6417c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
6427c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
6437c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulsave_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint sz)
644fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
6457c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
646fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
647fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (sz > save->attrsz[attr]) {
648fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* New size is larger.  Need to flush existing vertices and get
649fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * an enlarged vertex format.
650fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
6517c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _save_upgrade_vertex(ctx, attr, sz);
652fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
653fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   else if (sz < save->active_sz[attr]) {
654fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      static GLfloat id[4] = { 0, 0, 0, 1 };
655fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLuint i;
656fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
657fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* New size is equal or smaller - just need to fill in some
658fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * zeros.
659fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
6607c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      for (i = sz; i <= save->attrsz[attr]; i++)
6617c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->attrptr[attr][i - 1] = id[i - 1];
662fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
663fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
664fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->active_sz[attr] = sz;
665fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
666fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
6677c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
6687c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
6697c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_reset_vertex(struct gl_context *ctx)
670fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
671fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
672fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
673fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
6747c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   for (i = 0; i < VBO_ATTRIB_MAX; i++) {
675fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->attrsz[i] = 0;
676fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->active_sz[i] = 0;
677fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
6787c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
679fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vertex_size = 0;
680fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
681fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
682fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
683fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
6847c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul#define ERROR(err)   _mesa_compile_error(ctx, err, __FUNCTION__);
685fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
686fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
687fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Only one size for each attribute may be active at once.  Eg. if
688fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * Color3f is installed/active, then Color4f may not be, even if the
689fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * vertex actually contains 4 color coordinates.  This is because the
690fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * 3f version won't otherwise set color[3] to 1.0 -- this is the job
691fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * of the chooser function when switching between Color4f and Color3f.
692fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
6937c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul#define ATTR(A, N, V0, V1, V2, V3)				\
694fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwelldo {								\
695fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;	\
696fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
697ae4b6e04cdea188f6b5e656a1aafb6c3343fe5a7Brian Paul   if (save->active_sz[A] != N)					\
698fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save_fixup_vertex(ctx, A, N);				\
699fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
700fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   {								\
701ae4b6e04cdea188f6b5e656a1aafb6c3343fe5a7Brian Paul      GLfloat *dest = save->attrptr[A];				\
702fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>0) dest[0] = V0;					\
703fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>1) dest[1] = V1;					\
704fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>2) dest[2] = V2;					\
705fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>3) dest[3] = V3;					\
706fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }								\
707fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
708fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if ((A) == 0) {						\
709fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLuint i;							\
710fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
711fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0; i < save->vertex_size; i++)			\
712c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell	 save->buffer_ptr[i] = save->vertex[i];			\
713fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
714ae4b6e04cdea188f6b5e656a1aafb6c3343fe5a7Brian Paul      save->buffer_ptr += save->vertex_size;			\
715fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
716fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (++save->vert_count >= save->max_vert)			\
7177c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul	 _save_wrap_filled_vertex(ctx);				\
718fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }								\
719fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell} while (0)
720fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
721fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#define TAG(x) _save_##x
722fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
723fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "vbo_attrib_tmp.h"
724fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
725fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
726fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
7271bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul#define MAT( ATTR, N, face, params )			\
7281bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Pauldo {							\
7291bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   if (face != GL_BACK)					\
7301bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT_ATTR( ATTR, N, params ); /* front */		\
7311bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   if (face != GL_FRONT)				\
7321bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT_ATTR( ATTR + 1, N, params ); /* back */	\
7331bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul} while (0)
7341bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul
7351bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul
7361bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul/**
7371bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul * Save a glMaterial call found between glBegin/End.
7381bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul * glMaterial calls outside Begin/End are handled in dlist.c.
7391bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul */
7401bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paulstatic void GLAPIENTRY
7411bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul_save_Materialfv(GLenum face, GLenum pname, const GLfloat *params)
7421bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul{
7431bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   GET_CURRENT_CONTEXT(ctx);
7441bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul
7451bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
7461bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(face)");
7471bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      return;
7481bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   }
7491bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul
7501bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   switch (pname) {
7511bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   case GL_EMISSION:
7521bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT(VBO_ATTRIB_MAT_FRONT_EMISSION, 4, face, params);
7531bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      break;
7541bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   case GL_AMBIENT:
7551bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params);
7561bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      break;
7571bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   case GL_DIFFUSE:
7581bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params);
7591bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      break;
7601bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   case GL_SPECULAR:
7611bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT(VBO_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params);
7621bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      break;
7631bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   case GL_SHININESS:
7641bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      if (*params < 0 || *params > ctx->Const.MaxShininess) {
7651bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul         _mesa_compile_error(ctx, GL_INVALID_VALUE, "glMaterial(shininess)");
7661bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      }
7671bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      else {
7681bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul         MAT(VBO_ATTRIB_MAT_FRONT_SHININESS, 1, face, params);
7691bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      }
7701bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      break;
7711bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   case GL_COLOR_INDEXES:
7721bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT(VBO_ATTRIB_MAT_FRONT_INDEXES, 3, face, params);
7731bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      break;
7741bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   case GL_AMBIENT_AND_DIFFUSE:
7751bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params);
7761bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params);
7771bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      break;
7781bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   default:
7791bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(pname)");
7801bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      return;
7811bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   }
7821bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul}
7831bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul
784fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
785fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Cope with EvalCoord/CallList called within a begin/end object:
786fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *     -- Flush current buffer
787fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *     -- Fallback to opcodes for the rest of the begin/end object.
788fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
7897c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
7907c2847a972cd68107348ba8fe3667dc211b78f3eBrian Pauldlist_fallback(struct gl_context *ctx)
7911fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell{
7921fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
7931fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell
7941fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   if (save->vert_count || save->prim_count) {
795f1cdce95f606584a56eabf3b38eea19ff4c75757Brian Paul      if (save->prim_count > 0) {
796f1cdce95f606584a56eabf3b38eea19ff4c75757Brian Paul         /* Close off in-progress primitive. */
797f1cdce95f606584a56eabf3b38eea19ff4c75757Brian Paul         GLint i = save->prim_count - 1;
798f1cdce95f606584a56eabf3b38eea19ff4c75757Brian Paul         save->prim[i].count = save->vert_count - save->prim[i].start;
799f1cdce95f606584a56eabf3b38eea19ff4c75757Brian Paul      }
8001fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell
8011fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell      /* Need to replay this display list with loopback,
8021fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell       * unfortunately, otherwise this primitive won't be handled
8031fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell       * properly:
8041fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell       */
8051fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell      save->dangling_attr_ref = 1;
8067c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
8077c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _save_compile_vertex_list(ctx);
8081fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   }
8091fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell
8107c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_copy_to_current(ctx);
8117c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_reset_vertex(ctx);
8127c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_reset_counters(ctx);
81397dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (save->out_of_memory) {
81497dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
81597dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
81697dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   else {
81797dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt);
81897dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
8191fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   ctx->Driver.SaveNeedFlush = 0;
8201fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell}
821fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8227c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
8237c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8247c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalCoord1f(GLfloat u)
825fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
826fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
827f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
828aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalCoord1f(ctx->Save, (u));
829fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
830fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8317c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8327c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalCoord1fv(const GLfloat * v)
833fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
834fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
835f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
836aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalCoord1fv(ctx->Save, (v));
837fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
838fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8397c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8407c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalCoord2f(GLfloat u, GLfloat v)
841fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
842fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
843f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
844aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalCoord2f(ctx->Save, (u, v));
845fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
846fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8477c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8487c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalCoord2fv(const GLfloat * v)
849fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
850fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
851f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
852aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalCoord2fv(ctx->Save, (v));
853fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
854fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8557c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8567c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalPoint1(GLint i)
857fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
858fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
859f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
860aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalPoint1(ctx->Save, (i));
861fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
862fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8637c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8647c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalPoint2(GLint i, GLint j)
865fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
866fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
867f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
868aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalPoint2(ctx->Save, (i, j));
869fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
870fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8717c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8727c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_CallList(GLuint l)
873fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
874fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
875f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
876aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_CallList(ctx->Save, (l));
877fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
878fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8797c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8807c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_CallLists(GLsizei n, GLenum type, const GLvoid * v)
881fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
882fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
883f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
884aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_CallLists(ctx->Save, (n, type, v));
885fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
886fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
887fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
888fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
889fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* This begin is hooked into ...  Updating of
890fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * ctx->Driver.CurrentSavePrimitive is already taken care of.
891fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
8927c2847a972cd68107348ba8fe3667dc211b78f3eBrian PaulGLboolean
8937c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode)
894fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
8957c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
896fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
897fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i = save->prim_count++;
898fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
899fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(i < save->prim_max);
900b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   save->prim[i].mode = mode & VBO_SAVE_PRIM_MODE_MASK;
901fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].begin = 1;
902fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].end = 0;
903fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0;
9047c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   save->prim[i].no_current_update =
9057c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      (mode & VBO_SAVE_PRIM_NO_CURRENT_UPDATE) ? 1 : 0;
906fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].pad = 0;
907fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].start = save->vert_count;
9087c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   save->prim[i].count = 0;
9097c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   save->prim[i].num_instances = 1;
910fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
91197dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (save->out_of_memory) {
91297dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
91397dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
91497dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   else {
91597dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt);
91697dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
917fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 1;
918fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return GL_TRUE;
919fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
920fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
921fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
9227c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
9237c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_End(void)
924fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
9257c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   GET_CURRENT_CONTEXT(ctx);
9267c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
927fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i = save->prim_count - 1;
928fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
929fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
930fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].end = 1;
9317c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   save->prim[i].count = (save->vert_count - save->prim[i].start);
932fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
933fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (i == (GLint) save->prim_max - 1) {
9347c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _save_compile_vertex_list(ctx);
935fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(save->copied.nr == 0);
936fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
937fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
938fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Swap out this vertex format while outside begin/end.  Any color,
939fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * etc. received between here and the next begin will be compiled
940fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * as opcodes.
9417c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul    */
94297dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (save->out_of_memory) {
94397dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
94497dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
94597dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   else {
94697dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt);
94797dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
948fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
949fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
950fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
951fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* These are all errors as this vtxfmt is only installed inside
952fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * begin/end pairs.
953fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
9547c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
9557c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_DrawElements(GLenum mode, GLsizei count, GLenum type,
9567c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                   const GLvoid * indices)
957fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
958fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
9597c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
9607c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) count;
9617c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) type;
9627c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) indices;
9637c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawElements");
964fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
965fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
966fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
9677c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
9687c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
9697c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                        GLsizei count, GLenum type, const GLvoid * indices)
970fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
971fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
9727c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
9737c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) start;
9747c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) end;
9757c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) count;
9767c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) type;
9777c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) indices;
9787c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawRangeElements");
979fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
980fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
9817c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
9827c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
9837c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
9847c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                             const GLvoid * indices, GLint basevertex)
98592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
98692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GET_CURRENT_CONTEXT(ctx);
9877c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
9887c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) count;
9897c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) type;
9907c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) indices;
9917c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) basevertex;
9927c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawElements");
99392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
99492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
9957c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
9967c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
9977c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_DrawRangeElementsBaseVertex(GLenum mode,
9987c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                                  GLuint start,
9997c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                                  GLuint end,
10007c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                                  GLsizei count,
10017c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                                  GLenum type,
10027c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                                  const GLvoid * indices, GLint basevertex)
100392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
100492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GET_CURRENT_CONTEXT(ctx);
10057c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
10067c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) start;
10077c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) end;
10087c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) count;
10097c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) type;
10107c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) indices;
10117c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) basevertex;
10127c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawRangeElements");
101392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
101492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
10157c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
10167c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
10177c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_DrawArrays(GLenum mode, GLint start, GLsizei count)
1018fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1019fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
10207c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
10217c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) start;
10227c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) count;
10237c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawArrays");
1024fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1025fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
10267c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
10277c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
1028cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul_save_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type,
1029cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                        const GLvoid **indices, GLsizei primcount)
1030cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul{
1031cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   GET_CURRENT_CONTEXT(ctx);
1032cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) mode;
1033cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) count;
1034cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) type;
1035cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) indices;
1036cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) primcount;
1037cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glMultiDrawElements");
1038cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul}
1039cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1040cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1041cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paulstatic void GLAPIENTRY
1042cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul_save_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count,
1043cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                                  GLenum type, const GLvoid **indices,
1044cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                                  GLsizei primcount, const GLint *basevertex)
1045cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul{
1046cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   GET_CURRENT_CONTEXT(ctx);
1047cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) mode;
1048cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) count;
1049cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) type;
1050cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) indices;
1051cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) primcount;
1052cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) basevertex;
1053cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION,
1054cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                       "glMultiDrawElementsBaseVertex");
1055cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul}
1056cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1057cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1058cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paulstatic void GLAPIENTRY
105914bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák_save_DrawTransformFeedback(GLenum mode, GLuint name)
106014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák{
106114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   GET_CURRENT_CONTEXT(ctx);
106214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   (void) mode;
106314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   (void) name;
106414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawTransformFeedback");
106514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák}
106614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
106714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
106814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšákstatic void GLAPIENTRY
10697c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
1070fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1071fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
10727c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) x1;
10737c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) y1;
10747c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) x2;
10757c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) y2;
10767c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glRectf");
1077fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1078fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
10797c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
10807c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
10817c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalMesh1(GLenum mode, GLint i1, GLint i2)
1082fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1083fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
10847c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
10857c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) i1;
10867c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) i2;
10877c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glEvalMesh1");
1088fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1089fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
10907c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
10917c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
10927c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
1093fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1094fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
10957c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
10967c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) i1;
10977c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) i2;
10987c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) j1;
10997c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) j2;
11007c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glEvalMesh2");
1101fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1102fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
11037c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
11047c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
11057c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_Begin(GLenum mode)
1106fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
11077c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   GET_CURRENT_CONTEXT(ctx);
1108fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode;
11097c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "Recursive glBegin");
1110fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1111fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1112fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
11137c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
11147c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_PrimitiveRestartNV(void)
1115be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul{
1116be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   GLenum curPrim;
11177c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   GET_CURRENT_CONTEXT(ctx);
1118be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
1119be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   curPrim = ctx->Driver.CurrentSavePrimitive;
1120be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
1121be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   _save_End();
1122be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   _save_Begin(curPrim);
1123be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul}
1124be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
1125be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
1126fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Unlike the functions above, these are to be hooked into the vtxfmt
1127fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * maintained in ctx->ListState, active when the list is known or
1128fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * suspected to be outside any begin/end primitive.
1129cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul * Note: OBE = Outside Begin/End
1130fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
11317c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
11327c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_OBE_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
1133fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1134fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
11357c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   vbo_save_NotifyBegin(ctx, GL_QUADS | VBO_SAVE_PRIM_WEAK);
11367c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   CALL_Vertex2f(GET_DISPATCH(), (x1, y1));
11377c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   CALL_Vertex2f(GET_DISPATCH(), (x2, y1));
11387c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   CALL_Vertex2f(GET_DISPATCH(), (x2, y2));
11397c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   CALL_Vertex2f(GET_DISPATCH(), (x1, y2));
1140fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_End(GET_DISPATCH(), ());
1141fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1142fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1143fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
11447c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
11457c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count)
1146fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1147fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
114897dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
1149fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
1150fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
11517c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (!_mesa_validate_DrawArrays(ctx, mode, start, count))
1152fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
1153fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
115497dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (save->out_of_memory)
115597dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      return;
115697dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul
11577c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _ae_map_vbos(ctx);
1158b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
11597c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   vbo_save_NotifyBegin(ctx, (mode | VBO_SAVE_PRIM_WEAK
11607c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                              | VBO_SAVE_PRIM_NO_CURRENT_UPDATE));
11616a3fdc3a1ea6c306d9543791bf172dd1052d7382Keith Whitwell
1162fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0; i < count; i++)
11637c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      CALL_ArrayElement(GET_DISPATCH(), (start + i));
1164fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_End(GET_DISPATCH(), ());
1165b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
11667c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _ae_unmap_vbos(ctx);
1167fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1168fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
11697c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
1170fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Could do better by copying the arrays and element list intact and
1171fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * then emitting an indexed prim at runtime.
1172fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
11737c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
11747c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type,
11757c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                       const GLvoid * indices)
1176fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1177fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
117897dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
1179fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
1180fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
11817c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices, 0))
1182fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
1183fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
118497dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (save->out_of_memory)
118597dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      return;
118697dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul
11877c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _ae_map_vbos(ctx);
1188b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
1189a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu   if (_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj))
11907c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      indices =
1191a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu         ADD_POINTERS(ctx->Array.ArrayObj->ElementArrayBufferObj->Pointer, indices);
1192982dcb74fd19b88208d127b8019e2a2af979cac2Xiang, Haihao
11937c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   vbo_save_NotifyBegin(ctx, (mode | VBO_SAVE_PRIM_WEAK |
11947c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                              VBO_SAVE_PRIM_NO_CURRENT_UPDATE));
1195fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1196fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   switch (type) {
1197fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_BYTE:
11987c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      for (i = 0; i < count; i++)
11997c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         CALL_ArrayElement(GET_DISPATCH(), (((GLubyte *) indices)[i]));
1200fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
1201fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_SHORT:
12027c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      for (i = 0; i < count; i++)
12037c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         CALL_ArrayElement(GET_DISPATCH(), (((GLushort *) indices)[i]));
1204fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
1205fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_INT:
12067c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      for (i = 0; i < count; i++)
12077c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         CALL_ArrayElement(GET_DISPATCH(), (((GLuint *) indices)[i]));
1208fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
1209fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   default:
12107c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(type)");
1211fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
1212fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1213fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1214fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_End(GET_DISPATCH(), ());
1215b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
12167c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _ae_unmap_vbos(ctx);
1217fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1218fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
12197c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
12207c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
12217c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_OBE_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
12227c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                            GLsizei count, GLenum type,
12237c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                            const GLvoid * indices)
1224fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1225fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
122697dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
122797dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul
122897dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (!_mesa_validate_DrawRangeElements(ctx, mode,
122997dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul                                         start, end, count, type, indices, 0))
123097dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      return;
123197dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul
123297dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (save->out_of_memory)
123397dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      return;
123497dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul
123597dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   _save_OBE_DrawElements(mode, count, type, indices);
1236fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1237fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1238fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1239cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paulstatic void GLAPIENTRY
1240cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul_save_OBE_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type,
1241cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                            const GLvoid **indices, GLsizei primcount)
1242cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul{
1243cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   GLsizei i;
1244cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1245cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   for (i = 0; i < primcount; i++) {
1246cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul      if (count[i] > 0) {
1247cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul	 CALL_DrawElements(GET_DISPATCH(), (mode, count[i], type, indices[i]));
1248cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul      }
1249cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   }
1250cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul}
1251cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1252cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1253cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paulstatic void GLAPIENTRY
1254cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul_save_OBE_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count,
1255cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                                      GLenum type,
1256cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                                      const GLvoid **indices,
1257cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                                      GLsizei primcount,
1258cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                                      const GLint *basevertex)
1259cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul{
1260cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   GLsizei i;
1261cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1262cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   for (i = 0; i < primcount; i++) {
1263cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul      if (count[i] > 0) {
1264cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul	 CALL_DrawElementsBaseVertex(GET_DISPATCH(), (mode, count[i], type,
1265cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul						      indices[i],
1266cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul						      basevertex[i]));
1267cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul      }
1268cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   }
1269cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul}
1270cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1271cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
12727c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
12737c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_vtxfmt_init(struct gl_context *ctx)
1274fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1275fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1276fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLvertexformat *vfmt = &save->vtxfmt;
1277fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
127880630d1fed6cd32e75f5e97e2cd27509be21d093Chia-I Wu   _MESA_INIT_ARRAYELT_VTXFMT(vfmt, _ae_);
127980630d1fed6cd32e75f5e97e2cd27509be21d093Chia-I Wu
1280fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Begin = _save_Begin;
1281fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color3f = _save_Color3f;
1282fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color3fv = _save_Color3fv;
1283fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color4f = _save_Color4f;
1284fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color4fv = _save_Color4fv;
1285fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EdgeFlag = _save_EdgeFlag;
1286fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->End = _save_End;
1287be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   vfmt->PrimitiveRestartNV = _save_PrimitiveRestartNV;
1288fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->FogCoordfEXT = _save_FogCoordfEXT;
1289fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->FogCoordfvEXT = _save_FogCoordfvEXT;
1290fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Indexf = _save_Indexf;
1291fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Indexfv = _save_Indexfv;
1292fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Materialfv = _save_Materialfv;
1293fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f;
1294fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv;
1295fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f;
1296fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv;
1297fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f;
1298fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv;
1299fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f;
1300fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv;
1301fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Normal3f = _save_Normal3f;
1302fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Normal3fv = _save_Normal3fv;
1303fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT;
1304fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT;
1305fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord1f = _save_TexCoord1f;
1306fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord1fv = _save_TexCoord1fv;
1307fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord2f = _save_TexCoord2f;
1308fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord2fv = _save_TexCoord2fv;
1309fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord3f = _save_TexCoord3f;
1310fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord3fv = _save_TexCoord3fv;
1311fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord4f = _save_TexCoord4f;
1312fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord4fv = _save_TexCoord4fv;
1313fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex2f = _save_Vertex2f;
1314fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex2fv = _save_Vertex2fv;
1315fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex3f = _save_Vertex3f;
1316fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex3fv = _save_Vertex3fv;
1317fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex4f = _save_Vertex4f;
1318fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex4fv = _save_Vertex4fv;
1319fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB;
1320fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB;
1321fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB;
1322fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB;
1323fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB;
1324fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB;
1325fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB;
1326fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB;
1327fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1328fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV;
1329fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV;
1330fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV;
1331fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV;
1332fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV;
1333fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV;
1334fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV;
1335fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV;
13367c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
1337ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   /* integer-valued */
1338ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI1i = _save_VertexAttribI1i;
1339ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI2i = _save_VertexAttribI2i;
1340ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI3i = _save_VertexAttribI3i;
1341ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI4i = _save_VertexAttribI4i;
1342ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI2iv = _save_VertexAttribI2iv;
1343ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI3iv = _save_VertexAttribI3iv;
1344ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI4iv = _save_VertexAttribI4iv;
1345ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul
1346ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   /* unsigned integer-valued */
1347ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI1ui = _save_VertexAttribI1ui;
1348ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI2ui = _save_VertexAttribI2ui;
1349ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI3ui = _save_VertexAttribI3ui;
1350ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI4ui = _save_VertexAttribI4ui;
1351ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI2uiv = _save_VertexAttribI2uiv;
1352ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI3uiv = _save_VertexAttribI3uiv;
1353ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI4uiv = _save_VertexAttribI4uiv;
1354ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul
135551fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexP2ui = _save_VertexP2ui;
135651fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexP3ui = _save_VertexP3ui;
135751fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexP4ui = _save_VertexP4ui;
135851fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexP2uiv = _save_VertexP2uiv;
135951fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexP3uiv = _save_VertexP3uiv;
136051fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexP4uiv = _save_VertexP4uiv;
136151fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
136251fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP1ui = _save_TexCoordP1ui;
136351fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP2ui = _save_TexCoordP2ui;
136451fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP3ui = _save_TexCoordP3ui;
136551fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP4ui = _save_TexCoordP4ui;
136651fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP1uiv = _save_TexCoordP1uiv;
136751fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP2uiv = _save_TexCoordP2uiv;
136851fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP3uiv = _save_TexCoordP3uiv;
136951fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP4uiv = _save_TexCoordP4uiv;
137051fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
137151fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP1ui = _save_MultiTexCoordP1ui;
137251fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP2ui = _save_MultiTexCoordP2ui;
137351fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP3ui = _save_MultiTexCoordP3ui;
137451fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP4ui = _save_MultiTexCoordP4ui;
137551fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP1uiv = _save_MultiTexCoordP1uiv;
137651fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP2uiv = _save_MultiTexCoordP2uiv;
137751fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP3uiv = _save_MultiTexCoordP3uiv;
137851fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP4uiv = _save_MultiTexCoordP4uiv;
137951fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
138051fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->NormalP3ui = _save_NormalP3ui;
138151fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->NormalP3uiv = _save_NormalP3uiv;
138251fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
138351fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->ColorP3ui = _save_ColorP3ui;
138451fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->ColorP4ui = _save_ColorP4ui;
138551fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->ColorP3uiv = _save_ColorP3uiv;
138651fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->ColorP4uiv = _save_ColorP4uiv;
138751fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
138851fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->SecondaryColorP3ui = _save_SecondaryColorP3ui;
138951fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->SecondaryColorP3uiv = _save_SecondaryColorP3uiv;
139051fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
139151fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP1ui = _save_VertexAttribP1ui;
139251fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP2ui = _save_VertexAttribP2ui;
139351fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP3ui = _save_VertexAttribP3ui;
139451fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP4ui = _save_VertexAttribP4ui;
139551fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
139651fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP1uiv = _save_VertexAttribP1uiv;
139751fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP2uiv = _save_VertexAttribP2uiv;
139851fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP3uiv = _save_VertexAttribP3uiv;
139951fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP4uiv = _save_VertexAttribP4uiv;
140051fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
1401fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* This will all require us to fallback to saving the list as opcodes:
14027c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul    */
14037c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _MESA_INIT_DLIST_VTXFMT(vfmt, _save_);       /* inside begin/end */
1404aefa1f6ab1d9267b223b06ae205ab34c8e0d7c02Chia-I Wu
1405aefa1f6ab1d9267b223b06ae205ab34c8e0d7c02Chia-I Wu   _MESA_INIT_EVAL_VTXFMT(vfmt, _save_);
1406fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1407cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   /* These calls all generate GL_INVALID_OPERATION since this vtxfmt is
1408cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul    * only used when we're inside a glBegin/End pair.
1409fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
1410fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Begin = _save_Begin;
1411fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Rectf = _save_Rectf;
1412fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->DrawArrays = _save_DrawArrays;
1413fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->DrawElements = _save_DrawElements;
1414fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->DrawRangeElements = _save_DrawRangeElements;
141592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vfmt->DrawElementsBaseVertex = _save_DrawElementsBaseVertex;
141692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vfmt->DrawRangeElementsBaseVertex = _save_DrawRangeElementsBaseVertex;
141714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   vfmt->DrawTransformFeedback = _save_DrawTransformFeedback;
1418cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   vfmt->MultiDrawElementsEXT = _save_MultiDrawElements;
1419cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   vfmt->MultiDrawElementsBaseVertex = _save_MultiDrawElementsBaseVertex;
1420fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1421fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1422fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
14237c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvoid
14247c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_save_SaveFlushVertices(struct gl_context *ctx)
1425fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1426fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1427fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1428fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Noop when we are actually active:
1429fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
1430fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM ||
1431fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       ctx->Driver.CurrentSavePrimitive <= GL_POLYGON)
1432fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
1433fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
14347c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (save->vert_count || save->prim_count)
14357c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _save_compile_vertex_list(ctx);
14367c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
14377c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_copy_to_current(ctx);
14387c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_reset_vertex(ctx);
14397c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_reset_counters(ctx);
1440fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 0;
1441fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1442fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
14437c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
14447c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvoid
14457c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_save_NewList(struct gl_context *ctx, GLuint list, GLenum mode)
1446fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1447fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1448fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
14497c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) list;
14507c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
1451fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1452fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!save->prim_store)
14537c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      save->prim_store = alloc_prim_store(ctx);
14547c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
14557c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (!save->vertex_store)
14567c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      save->vertex_store = alloc_vertex_store(ctx);
14577c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
1458781f84a3c2f7a06cb9e6cc44b8d5d08b39577c25Brian Paul   save->buffer_ptr = vbo_save_map_vertex_store(ctx, save->vertex_store);
14597c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
14607c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_reset_vertex(ctx);
14617c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_reset_counters(ctx);
1462fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 0;
1463fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1464fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
14657c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
14667c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvoid
14677c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_save_EndList(struct gl_context *ctx)
1468fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1469fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1470bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1471bd953e872f22690bd232a758383883100d9347d0Keith Whitwell   /* EndList called inside a (saved) Begin/End pair?
1472bd953e872f22690bd232a758383883100d9347d0Keith Whitwell    */
1473bd953e872f22690bd232a758383883100d9347d0Keith Whitwell   if (ctx->Driver.CurrentSavePrimitive != PRIM_OUTSIDE_BEGIN_END) {
1474bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1475d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul      if (save->prim_count > 0) {
1476d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul         GLint i = save->prim_count - 1;
1477d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul         ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
1478d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul         save->prim[i].end = 0;
14797c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->prim[i].count = (save->vert_count - save->prim[i].start);
1480d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul      }
1481bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1482bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      /* Make sure this vertex list gets replayed by the "loopback"
1483bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       * mechanism:
1484bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       */
1485bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      save->dangling_attr_ref = 1;
14867c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      vbo_save_SaveFlushVertices(ctx);
1487bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1488bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      /* Swap out this vertex format while outside begin/end.  Any color,
1489bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       * etc. received between here and the next begin will be compiled
1490bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       * as opcodes.
14917c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul       */
14927c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt);
1493bd953e872f22690bd232a758383883100d9347d0Keith Whitwell   }
1494bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1495781f84a3c2f7a06cb9e6cc44b8d5d08b39577c25Brian Paul   vbo_save_unmap_vertex_store(ctx, save->vertex_store);
1496fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1497fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(save->vertex_size == 0);
1498fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
14997c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
15007c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
15017c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvoid
15027c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_save_BeginCallList(struct gl_context *ctx, struct gl_display_list *dlist)
1503fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1504fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1505446abc2799a143c32c4c48472f3f964f9288a623Brian   save->replay_flags |= dlist->Flags;
1506fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1507fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
15087c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
15097c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvoid
15107c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_save_EndCallList(struct gl_context *ctx)
1511fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1512fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
15137c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
1514fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->ListState.CallDepth == 1) {
1515fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* This is correct: want to keep only the VBO_SAVE_FALLBACK
1516fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * flag, if it is set:
1517fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
1518fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->replay_flags &= VBO_SAVE_FALLBACK;
1519fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1520fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1521fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1522fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
15237c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
15247c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_destroy_vertex_list(struct gl_context *ctx, void *data)
1525fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
15267c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *) data;
1527fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) ctx;
1528fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
15297c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (--node->vertex_store->refcount == 0)
15307c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      free_vertex_store(ctx, node->vertex_store);
1531fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
15327c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (--node->prim_store->refcount == 0)
15337c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      FREE(node->prim_store);
1534ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul
1535ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul   if (node->current_data) {
1536ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul      FREE(node->current_data);
1537ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul      node->current_data = NULL;
1538ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul   }
1539fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1540fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1541fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
15427c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
15437c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_print_vertex_list(struct gl_context *ctx, void *data)
1544fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
15457c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *) data;
1546fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
1547fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) ctx;
1548fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1549298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg   printf("VBO-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n",
15507c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul          node->count, node->prim_count, node->vertex_size);
1551fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
15527c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   for (i = 0; i < node->prim_count; i++) {
1553fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      struct _mesa_prim *prim = &node->prim[i];
1554fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _mesa_debug(NULL, "   prim %d: %s%s %d..%d %s %s\n",
15557c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  i,
15567c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  _mesa_lookup_prim_by_nr(prim->mode),
15577c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  prim->weak ? " (weak)" : "",
15587c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  prim->start,
15597c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  prim->start + prim->count,
15607c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  (prim->begin) ? "BEGIN" : "(wrap)",
15617c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  (prim->end) ? "END" : "(wrap)");
1562fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1563fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1564fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1565fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1566c55ebc3e3e556a5bf5cd78cee2807f4cbb6f626aBrian Paul/**
1567c55ebc3e3e556a5bf5cd78cee2807f4cbb6f626aBrian Paul * Called during context creation/init.
1568c55ebc3e3e556a5bf5cd78cee2807f4cbb6f626aBrian Paul */
15697c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
15707c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_current_init(struct gl_context *ctx)
1571fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1572fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1573fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
1574fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
15752421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell   for (i = VBO_ATTRIB_POS; i <= VBO_ATTRIB_GENERIC15; i++) {
15762421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      const GLuint j = i - VBO_ATTRIB_POS;
15772421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      ASSERT(j < VERT_ATTRIB_MAX);
15782421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      save->currentsz[i] = &ctx->ListState.ActiveAttribSize[j];
15792421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      save->current[i] = ctx->ListState.CurrentAttrib[j];
1580fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1581fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
15826a3fdc3a1ea6c306d9543791bf172dd1052d7382Keith Whitwell   for (i = VBO_ATTRIB_FIRST_MATERIAL; i <= VBO_ATTRIB_LAST_MATERIAL; i++) {
1583fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      const GLuint j = i - VBO_ATTRIB_FIRST_MATERIAL;
1584fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ASSERT(j < MAT_ATTRIB_MAX);
1585fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j];
1586fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->current[i] = ctx->ListState.CurrentMaterial[j];
1587fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1588fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1589fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
15907c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
1591fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/**
1592c55ebc3e3e556a5bf5cd78cee2807f4cbb6f626aBrian Paul * Initialize the display list compiler.  Called during context creation.
1593fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
15947c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvoid
15957c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_save_api_init(struct vbo_save_context *save)
1596fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1597f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg   struct gl_context *ctx = save->ctx;
1598fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
1599fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1600fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->opcode_vertex_list =
16017c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _mesa_dlist_alloc_opcode(ctx,
16027c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                               sizeof(struct vbo_save_vertex_list),
16037c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                               vbo_save_playback_vertex_list,
16047c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                               vbo_destroy_vertex_list,
16057c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                               vbo_print_vertex_list);
1606fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1607fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.NotifySaveBegin = vbo_save_NotifyBegin;
1608fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
16097c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_vtxfmt_init(ctx);
16107c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_current_init(ctx);
161197dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   _mesa_noop_vtxfmt_init(&save->vtxfmt_noop);
1612fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
161337c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul   /* These will actually get set again when binding/drawing */
1614fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0; i < VBO_ATTRIB_MAX; i++)
1615fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->inputs[i] = &save->arrays[i];
1616fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1617fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Hook our array functions into the outside-begin-end vtxfmt in
1618fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * ctx->ListState.
1619fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
1620fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf;
1621fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays;
1622fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements;
1623fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements;
1624cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   ctx->ListState.ListVtxfmt.MultiDrawElementsEXT = _save_OBE_MultiDrawElements;
1625cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   ctx->ListState.ListVtxfmt.MultiDrawElementsBaseVertex = _save_OBE_MultiDrawElementsBaseVertex;
16267c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt);
1627fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1628fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
16298d5c83c467f83b44f5f2e271c4f9cca2d45af518Chia-I Wu
16308d5c83c467f83b44f5f2e271c4f9cca2d45af518Chia-I Wu#endif /* FEATURE_dlist */
1631