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));
330492b69f3be3e355064c67bc6f4a30d40e997ce9dMarek Olšák   memcpy(node->attrtype, save->attrtype, sizeof(node->attrtype));
331fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->vertex_size = save->vertex_size;
3327c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   node->buffer_offset =
3337c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat);
334fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->count = save->vert_count;
335fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->wrap_count = save->copied.nr;
336fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->dangling_attr_ref = save->dangling_attr_ref;
337fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim = save->prim;
338fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim_count = save->prim_count;
339fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->vertex_store = save->vertex_store;
340fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim_store = save->prim_store;
341fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
342fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->vertex_store->refcount++;
343fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim_store->refcount++;
344fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
345b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   if (node->prim[0].no_current_update) {
346b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich      node->current_size = 0;
347b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich      node->current_data = NULL;
3487c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   }
3497c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   else {
350b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich      node->current_size = node->vertex_size - node->attrsz[0];
351b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich      node->current_data = NULL;
3527c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
353b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich      if (node->current_size) {
354b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich         /* If the malloc fails, we just pull the data out of the VBO
355b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich          * later instead.
356b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich          */
3577c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         node->current_data = MALLOC(node->current_size * sizeof(GLfloat));
358b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich         if (node->current_data) {
3597c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul            const char *buffer = (const char *) save->vertex_store->buffer;
360b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich            unsigned attr_offset = node->attrsz[0] * sizeof(GLfloat);
361b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich            unsigned vertex_offset = 0;
3627c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
363b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich            if (node->count)
3647c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul               vertex_offset =
3657c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  (node->count - 1) * node->vertex_size * sizeof(GLfloat);
3667c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
3677c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul            memcpy(node->current_data,
3687c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                   buffer + node->buffer_offset + vertex_offset + attr_offset,
3697c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                   node->current_size * sizeof(GLfloat));
370b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich         }
3718b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell      }
3728b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell   }
3738b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell
3747c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   assert(node->attrsz[VBO_ATTRIB_POS] != 0 || node->count == 0);
375fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
376fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->dangling_attr_ref)
377446abc2799a143c32c4c48472f3f964f9288a623Brian      ctx->ListState.CurrentList->Flags |= DLIST_DANGLING_REFS;
378fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
379fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vertex_store->used += save->vertex_size * node->count;
380fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_store->used += node->prim_count;
381fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
382fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Copy duplicated vertices
383fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
3847c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   save->copied.nr = _save_copy_vertices(ctx, node, save->buffer);
385fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
386fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Deal with GL_COMPILE_AND_EXECUTE:
387fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
388fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->ExecuteFlag) {
389fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      struct _glapi_table *dispatch = GET_DISPATCH();
390fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
391fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _glapi_set_dispatch(ctx->Exec);
392fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
3937c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      vbo_loopback_vertex_list(ctx,
3947c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                               (const GLfloat *) ((const char *) save->
3957c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                                                  vertex_store->buffer +
3967c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                                                  node->buffer_offset),
3977c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                               node->attrsz, node->prim, node->prim_count,
3987c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                               node->wrap_count, node->vertex_size);
399fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
400fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _glapi_set_dispatch(dispatch);
401fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
402fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
403fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Decide whether the storage structs are full, or can be used for
404fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * the next vertex lists as well.
405fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
4067c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (save->vertex_store->used >
407fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       VBO_SAVE_BUFFER_SIZE - 16 * (save->vertex_size + 4)) {
408fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
409fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Unmap old store:
410fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
411781f84a3c2f7a06cb9e6cc44b8d5d08b39577c25Brian Paul      vbo_save_unmap_vertex_store(ctx, save->vertex_store);
412fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
413fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Release old reference:
414fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
4157c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      save->vertex_store->refcount--;
416fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(save->vertex_store->refcount != 0);
417fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vertex_store = NULL;
418fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
419fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Allocate and map new store:
420fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
4217c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      save->vertex_store = alloc_vertex_store(ctx);
422781f84a3c2f7a06cb9e6cc44b8d5d08b39577c25Brian Paul      save->buffer_ptr = vbo_save_map_vertex_store(ctx, save->vertex_store);
42397dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      save->out_of_memory = save->buffer_ptr == NULL;
4247c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   }
425fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
426fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->prim_store->used > VBO_SAVE_PRIM_SIZE - 6) {
4277c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      save->prim_store->refcount--;
428fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(save->prim_store->refcount != 0);
4297c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      save->prim_store = alloc_prim_store(ctx);
4307c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   }
431fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
432fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Reset our structures for the next run of vertices:
433fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
4347c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_reset_counters(ctx);
435fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
436fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
437fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
4387c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul/**
4397c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul * TODO -- If no new vertices have been stored, don't bother saving it.
440fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
4417c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
4427c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_wrap_buffers(struct gl_context *ctx)
443fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
444fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
445fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i = save->prim_count - 1;
446fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLenum mode;
447fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLboolean weak;
448b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   GLboolean no_current_update;
449fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
450fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(i < (GLint) save->prim_max);
451fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(i >= 0);
452fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
453fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Close off in-progress primitive.
454fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
4557c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   save->prim[i].count = (save->vert_count - save->prim[i].start);
456fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   mode = save->prim[i].mode;
457fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   weak = save->prim[i].weak;
458b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   no_current_update = save->prim[i].no_current_update;
4597c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
460fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* store the copied vertices, and allocate a new list.
461fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
4627c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_compile_vertex_list(ctx);
463fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
464fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Restart interrupted primitive
465fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
466fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].mode = mode;
467fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].weak = weak;
468b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   save->prim[0].no_current_update = no_current_update;
469fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].begin = 0;
470fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].end = 0;
471fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].pad = 0;
472fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].start = 0;
473fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].count = 0;
4743b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   save->prim[0].num_instances = 1;
475ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   save->prim[0].base_instance = 0;
476fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_count = 1;
477fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
478fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
479fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
4807c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul/**
4817c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul * Called only when buffers are wrapped as the result of filling the
482fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * vertex_store struct.
483fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
4847c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
4857c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_wrap_filled_vertex(struct gl_context *ctx)
486fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
487fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
488fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLfloat *data = save->copied.buffer;
489fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
490fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
491fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Emit a glEnd to close off the last vertex list.
492fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
4937c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_wrap_buffers(ctx);
4947c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
4957c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   /* Copy stored stored vertices to start of new list.
496fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
497fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(save->max_vert - save->vert_count > save->copied.nr);
498fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
4997c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   for (i = 0; i < save->copied.nr; i++) {
5007c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      memcpy(save->buffer_ptr, data, save->vertex_size * sizeof(GLfloat));
501fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      data += save->vertex_size;
502c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell      save->buffer_ptr += save->vertex_size;
503fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vert_count++;
504fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
505fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
506fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
507fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
5087c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
5097c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_copy_to_current(struct gl_context *ctx)
510fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
5117c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
512fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
513fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
5147c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
515fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (save->attrsz[i]) {
5167c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->currentsz[i][0] = save->attrsz[i];
517492b69f3be3e355064c67bc6f4a30d40e997ce9dMarek Olšák         COPY_CLEAN_4V_TYPE_AS_FLOAT(save->current[i], save->attrsz[i],
518492b69f3be3e355064c67bc6f4a30d40e997ce9dMarek Olšák                                     save->attrptr[i], save->attrtype[i]);
519fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
520fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
521fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
522fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
523fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
5247c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
5257c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_copy_from_current(struct gl_context *ctx)
526fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
5277c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
528fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
529fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
5307c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
531fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      switch (save->attrsz[i]) {
5327c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      case 4:
5337c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->attrptr[i][3] = save->current[i][3];
5347c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      case 3:
5357c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->attrptr[i][2] = save->current[i][2];
5367c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      case 2:
5377c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->attrptr[i][1] = save->current[i][1];
5387c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      case 1:
5397c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->attrptr[i][0] = save->current[i][0];
5407c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      case 0:
5417c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         break;
542fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
543fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
544fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
545fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
546fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
547fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Flush existing data, set new attrib size, replay copied vertices.
5487c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul */
5497c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
5507c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
551fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
552fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
553fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint oldsz;
554fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
555fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLfloat *tmp;
556fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
557fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Store the current run of vertices, and emit a GL_END.  Emit a
558fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * BEGIN in the new buffer.
559fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
5607c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (save->vert_count)
5617c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _save_wrap_buffers(ctx);
562fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   else
5637c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      assert(save->copied.nr == 0);
564fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
565fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
566fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * when the attribute already exists in the vertex and is having
567fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * its size increased.
568fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
5697c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_copy_to_current(ctx);
570fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
571fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Fix up sizes:
572fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
573fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   oldsz = save->attrsz[attr];
574fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->attrsz[attr] = newsz;
575fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
576fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vertex_size += newsz - oldsz;
5777c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) /
5787c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                     save->vertex_size);
579fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vert_count = 0;
580fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
581fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Recalculate all the attrptr[] values:
582fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
5837c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   for (i = 0, tmp = save->vertex; i < VBO_ATTRIB_MAX; i++) {
584fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (save->attrsz[i]) {
5857c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->attrptr[i] = tmp;
5867c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         tmp += save->attrsz[i];
5877c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      }
5887c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      else {
5897c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->attrptr[i] = NULL;       /* will not be dereferenced. */
590fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
591fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
592fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
593fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Copy from current to repopulate the vertex with correct values.
594fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
5957c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_copy_from_current(ctx);
596fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
597fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Replay stored vertices to translate them to new format here.
598fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    *
599fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * If there are copied vertices and the new (upgraded) attribute
600fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * has not been defined before, this list is somewhat degenerate,
601fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * and will need fixup at runtime.
602fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
6037c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (save->copied.nr) {
604fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLfloat *data = save->copied.buffer;
605fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLfloat *dest = save->buffer;
606fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLuint j;
607fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
608fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Need to note this and fix up at runtime (or loopback):
609fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
610dd60eaa6d9f61735141976db0e83d25176ac73c7Keith Whitwell      if (attr != VBO_ATTRIB_POS && save->currentsz[attr][0] == 0) {
6117c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         assert(oldsz == 0);
6127c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->dangling_attr_ref = GL_TRUE;
613fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
614fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
6157c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      for (i = 0; i < save->copied.nr; i++) {
6167c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         for (j = 0; j < VBO_ATTRIB_MAX; j++) {
6177c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul            if (save->attrsz[j]) {
6187c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul               if (j == attr) {
6197c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  if (oldsz) {
620492b69f3be3e355064c67bc6f4a30d40e997ce9dMarek Olšák                     COPY_CLEAN_4V_TYPE_AS_FLOAT(dest, oldsz, data,
621492b69f3be3e355064c67bc6f4a30d40e997ce9dMarek Olšák                                                 save->attrtype[j]);
6227c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                     data += oldsz;
6237c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                     dest += newsz;
6247c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  }
6257c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  else {
6267c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                     COPY_SZ_4V(dest, newsz, save->current[attr]);
6277c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                     dest += newsz;
6287c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  }
6297c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul               }
6307c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul               else {
6317c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  GLint sz = save->attrsz[j];
6327c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  COPY_SZ_4V(dest, sz, data);
6337c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  data += sz;
6347c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  dest += sz;
6357c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul               }
6367c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul            }
6377c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         }
638fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
639fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
640c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell      save->buffer_ptr = dest;
641fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vert_count += save->copied.nr;
642fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
643fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
644fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
6457c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
6467c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
6477c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulsave_fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint sz)
648fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
6497c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
650fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
651fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (sz > save->attrsz[attr]) {
652fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* New size is larger.  Need to flush existing vertices and get
653fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * an enlarged vertex format.
654fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
6557c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _save_upgrade_vertex(ctx, attr, sz);
656fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
657fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   else if (sz < save->active_sz[attr]) {
658fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLuint i;
659492b69f3be3e355064c67bc6f4a30d40e997ce9dMarek Olšák      const GLfloat *id = vbo_get_default_vals_as_float(save->attrtype[attr]);
660fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
661fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* New size is equal or smaller - just need to fill in some
662fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * zeros.
663fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
6647c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      for (i = sz; i <= save->attrsz[attr]; i++)
6657c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->attrptr[attr][i - 1] = id[i - 1];
666fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
667fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
668fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->active_sz[attr] = sz;
669fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
670fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
6717c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
6727c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
6737c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_reset_vertex(struct gl_context *ctx)
674fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
675fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
676fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
677fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
6787c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   for (i = 0; i < VBO_ATTRIB_MAX; i++) {
679fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->attrsz[i] = 0;
680fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->active_sz[i] = 0;
681fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
6827c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
683fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vertex_size = 0;
684fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
685fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
686fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
687fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
6887c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul#define ERROR(err)   _mesa_compile_error(ctx, err, __FUNCTION__);
689fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
690fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
691fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Only one size for each attribute may be active at once.  Eg. if
692fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * Color3f is installed/active, then Color4f may not be, even if the
693fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * vertex actually contains 4 color coordinates.  This is because the
694fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * 3f version won't otherwise set color[3] to 1.0 -- this is the job
695fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * of the chooser function when switching between Color4f and Color3f.
696fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
697492b69f3be3e355064c67bc6f4a30d40e997ce9dMarek Olšák#define ATTR(A, N, T, V0, V1, V2, V3)				\
698fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwelldo {								\
699fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;	\
700fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
701ae4b6e04cdea188f6b5e656a1aafb6c3343fe5a7Brian Paul   if (save->active_sz[A] != N)					\
702fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save_fixup_vertex(ctx, A, N);				\
703fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
704fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   {								\
705ae4b6e04cdea188f6b5e656a1aafb6c3343fe5a7Brian Paul      GLfloat *dest = save->attrptr[A];				\
706fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>0) dest[0] = V0;					\
707fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>1) dest[1] = V1;					\
708fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>2) dest[2] = V2;					\
709fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>3) dest[3] = V3;					\
710492b69f3be3e355064c67bc6f4a30d40e997ce9dMarek Olšák      save->attrtype[A] = T;                                    \
711fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }								\
712fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
713fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if ((A) == 0) {						\
714fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLuint i;							\
715fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
716fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0; i < save->vertex_size; i++)			\
717c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell	 save->buffer_ptr[i] = save->vertex[i];			\
718fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
719ae4b6e04cdea188f6b5e656a1aafb6c3343fe5a7Brian Paul      save->buffer_ptr += save->vertex_size;			\
720fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
721fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (++save->vert_count >= save->max_vert)			\
7227c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul	 _save_wrap_filled_vertex(ctx);				\
723fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }								\
724fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell} while (0)
725fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
726fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#define TAG(x) _save_##x
727fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
728fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "vbo_attrib_tmp.h"
729fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
730fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
731fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
7321bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul#define MAT( ATTR, N, face, params )			\
7331bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Pauldo {							\
7341bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   if (face != GL_BACK)					\
7351bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT_ATTR( ATTR, N, params ); /* front */		\
7361bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   if (face != GL_FRONT)				\
7371bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT_ATTR( ATTR + 1, N, params ); /* back */	\
7381bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul} while (0)
7391bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul
7401bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul
7411bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul/**
7421bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul * Save a glMaterial call found between glBegin/End.
7431bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul * glMaterial calls outside Begin/End are handled in dlist.c.
7441bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul */
7451bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paulstatic void GLAPIENTRY
7461bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul_save_Materialfv(GLenum face, GLenum pname, const GLfloat *params)
7471bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul{
7481bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   GET_CURRENT_CONTEXT(ctx);
7491bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul
7501bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
7511bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(face)");
7521bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      return;
7531bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   }
7541bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul
7551bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   switch (pname) {
7561bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   case GL_EMISSION:
7571bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT(VBO_ATTRIB_MAT_FRONT_EMISSION, 4, face, params);
7581bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      break;
7591bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   case GL_AMBIENT:
7601bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params);
7611bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      break;
7621bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   case GL_DIFFUSE:
7631bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params);
7641bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      break;
7651bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   case GL_SPECULAR:
7661bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT(VBO_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params);
7671bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      break;
7681bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   case GL_SHININESS:
7691bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      if (*params < 0 || *params > ctx->Const.MaxShininess) {
7701bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul         _mesa_compile_error(ctx, GL_INVALID_VALUE, "glMaterial(shininess)");
7711bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      }
7721bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      else {
7731bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul         MAT(VBO_ATTRIB_MAT_FRONT_SHININESS, 1, face, params);
7741bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      }
7751bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      break;
7761bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   case GL_COLOR_INDEXES:
7771bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT(VBO_ATTRIB_MAT_FRONT_INDEXES, 3, face, params);
7781bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      break;
7791bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   case GL_AMBIENT_AND_DIFFUSE:
7801bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params);
7811bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      MAT(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params);
7821bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      break;
7831bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   default:
7841bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(pname)");
7851bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul      return;
7861bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul   }
7871bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul}
7881bc16bf98a1b5a4cca0c0ae2a80ba7982c6e4651Brian Paul
789fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
790fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Cope with EvalCoord/CallList called within a begin/end object:
791fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *     -- Flush current buffer
792fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *     -- Fallback to opcodes for the rest of the begin/end object.
793fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
7947c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
7957c2847a972cd68107348ba8fe3667dc211b78f3eBrian Pauldlist_fallback(struct gl_context *ctx)
7961fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell{
7971fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
7981fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell
7991fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   if (save->vert_count || save->prim_count) {
800f1cdce95f606584a56eabf3b38eea19ff4c75757Brian Paul      if (save->prim_count > 0) {
801f1cdce95f606584a56eabf3b38eea19ff4c75757Brian Paul         /* Close off in-progress primitive. */
802f1cdce95f606584a56eabf3b38eea19ff4c75757Brian Paul         GLint i = save->prim_count - 1;
803f1cdce95f606584a56eabf3b38eea19ff4c75757Brian Paul         save->prim[i].count = save->vert_count - save->prim[i].start;
804f1cdce95f606584a56eabf3b38eea19ff4c75757Brian Paul      }
8051fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell
8061fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell      /* Need to replay this display list with loopback,
8071fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell       * unfortunately, otherwise this primitive won't be handled
8081fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell       * properly:
8091fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell       */
8101fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell      save->dangling_attr_ref = 1;
8117c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
8127c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _save_compile_vertex_list(ctx);
8131fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   }
8141fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell
8157c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_copy_to_current(ctx);
8167c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_reset_vertex(ctx);
8177c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_reset_counters(ctx);
81897dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (save->out_of_memory) {
81997dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
82097dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
82197dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   else {
82297dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt);
82397dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
8241fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   ctx->Driver.SaveNeedFlush = 0;
8251fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell}
826fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8277c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
8287c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8297c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalCoord1f(GLfloat u)
830fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
831fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
832f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
833aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalCoord1f(ctx->Save, (u));
834fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
835fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8367c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8377c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalCoord1fv(const GLfloat * v)
838fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
839fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
840f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
841aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalCoord1fv(ctx->Save, (v));
842fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
843fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8447c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8457c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalCoord2f(GLfloat u, GLfloat v)
846fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
847fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
848f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
849aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalCoord2f(ctx->Save, (u, v));
850fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
851fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8527c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8537c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalCoord2fv(const GLfloat * v)
854fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
855fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
856f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
857aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalCoord2fv(ctx->Save, (v));
858fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
859fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8607c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8617c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalPoint1(GLint i)
862fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
863fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
864f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
865aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalPoint1(ctx->Save, (i));
866fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
867fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8687c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8697c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalPoint2(GLint i, GLint j)
870fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
871fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
872f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
873aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalPoint2(ctx->Save, (i, j));
874fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
875fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8767c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8777c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_CallList(GLuint l)
878fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
879fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
880f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
881aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_CallList(ctx->Save, (l));
882fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
883fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8847c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
8857c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_CallLists(GLsizei n, GLenum type, const GLvoid * v)
886fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
887fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
888f1733d16de56b1fbecc2b0f22fc3270b85a813ccBrian Paul   dlist_fallback(ctx);
889aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_CallLists(ctx->Save, (n, type, v));
890fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
891fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
892fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
893fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
894fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* This begin is hooked into ...  Updating of
895fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * ctx->Driver.CurrentSavePrimitive is already taken care of.
896fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
8977c2847a972cd68107348ba8fe3667dc211b78f3eBrian PaulGLboolean
8987c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode)
899fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
9007c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
901fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
902fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i = save->prim_count++;
903fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
904fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(i < save->prim_max);
905b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   save->prim[i].mode = mode & VBO_SAVE_PRIM_MODE_MASK;
906fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].begin = 1;
907fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].end = 0;
908fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0;
9097c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   save->prim[i].no_current_update =
9107c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      (mode & VBO_SAVE_PRIM_NO_CURRENT_UPDATE) ? 1 : 0;
911fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].pad = 0;
912fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].start = save->vert_count;
9137c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   save->prim[i].count = 0;
9147c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   save->prim[i].num_instances = 1;
915ae5d7d5e8970f90b9713897387d7d46a2b4485abFredrik Höglund   save->prim[i].base_instance = 0;
916fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
91797dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (save->out_of_memory) {
91897dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
91997dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
92097dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   else {
92197dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt);
92297dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
923fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 1;
924fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return GL_TRUE;
925fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
926fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
927fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
9287c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
9297c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_End(void)
930fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
9317c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   GET_CURRENT_CONTEXT(ctx);
9327c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
933fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i = save->prim_count - 1;
934fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
935fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
936fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].end = 1;
9377c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   save->prim[i].count = (save->vert_count - save->prim[i].start);
938fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
939fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (i == (GLint) save->prim_max - 1) {
9407c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _save_compile_vertex_list(ctx);
941fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(save->copied.nr == 0);
942fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
943fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
944fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Swap out this vertex format while outside begin/end.  Any color,
945fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * etc. received between here and the next begin will be compiled
946fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * as opcodes.
9477c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul    */
94897dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (save->out_of_memory) {
94997dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
95097dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
95197dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   else {
95297dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt);
95397dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   }
954fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
955fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
956fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
957fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* These are all errors as this vtxfmt is only installed inside
958fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * begin/end pairs.
959fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
9607c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
9617c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_DrawElements(GLenum mode, GLsizei count, GLenum type,
9627c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                   const GLvoid * indices)
963fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
964fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
9657c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
9667c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) count;
9677c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) type;
9687c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) indices;
9697c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawElements");
970fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
971fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
972fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
9737c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
9747c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
9757c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                        GLsizei count, GLenum type, const GLvoid * indices)
976fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
977fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
9787c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
9797c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) start;
9807c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) end;
9817c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) count;
9827c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) type;
9837c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) indices;
9847c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawRangeElements");
985fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
986fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
9877c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
9887c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
9897c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
9907c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                             const GLvoid * indices, GLint basevertex)
99192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
99292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GET_CURRENT_CONTEXT(ctx);
9937c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
9947c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) count;
9957c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) type;
9967c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) indices;
9977c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) basevertex;
9987c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawElements");
99992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
100092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
10017c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
10027c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
10037c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_DrawRangeElementsBaseVertex(GLenum mode,
10047c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                                  GLuint start,
10057c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                                  GLuint end,
10067c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                                  GLsizei count,
10077c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                                  GLenum type,
10087c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                                  const GLvoid * indices, GLint basevertex)
100992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
101092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GET_CURRENT_CONTEXT(ctx);
10117c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
10127c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) start;
10137c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) end;
10147c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) count;
10157c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) type;
10167c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) indices;
10177c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) basevertex;
10187c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawRangeElements");
101992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
102092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
10217c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
10227c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
10237c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_DrawArrays(GLenum mode, GLint start, GLsizei count)
1024fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1025fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
10267c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
10277c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) start;
10287c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) count;
10297c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawArrays");
1030fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1031fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
10327c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
10337c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
1034cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul_save_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type,
1035cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                        const GLvoid **indices, GLsizei primcount)
1036cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul{
1037cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   GET_CURRENT_CONTEXT(ctx);
1038cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) mode;
1039cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) count;
1040cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) type;
1041cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) indices;
1042cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) primcount;
1043cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glMultiDrawElements");
1044cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul}
1045cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1046cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1047cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paulstatic void GLAPIENTRY
1048cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul_save_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count,
10499881bf6e69b52efc1eb57a4027d9a8817ef8cbcbBrian Paul                                  GLenum type, const GLvoid * const *indices,
1050cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                                  GLsizei primcount, const GLint *basevertex)
1051cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul{
1052cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   GET_CURRENT_CONTEXT(ctx);
1053cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) mode;
1054cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) count;
1055cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) type;
1056cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) indices;
1057cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) primcount;
1058cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   (void) basevertex;
1059cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION,
1060cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                       "glMultiDrawElementsBaseVertex");
1061cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul}
1062cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1063cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1064cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paulstatic void GLAPIENTRY
106514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák_save_DrawTransformFeedback(GLenum mode, GLuint name)
106614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák{
106714bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   GET_CURRENT_CONTEXT(ctx);
106814bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   (void) mode;
106914bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   (void) name;
107014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawTransformFeedback");
107114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák}
107214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
107314bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák
107414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšákstatic void GLAPIENTRY
1075db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák_save_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream)
1076db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák{
1077db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   GET_CURRENT_CONTEXT(ctx);
1078db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   (void) mode;
1079db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   (void) name;
1080db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   (void) stream;
1081db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   _mesa_compile_error(ctx, GL_INVALID_OPERATION,
1082db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák                       "glDrawTransformFeedbackStream");
1083db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák}
1084db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák
1085db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák
1086db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšákstatic void GLAPIENTRY
1087db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák_save_DrawTransformFeedbackInstanced(GLenum mode, GLuint name,
1088db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák                                     GLsizei primcount)
1089db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák{
1090db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   GET_CURRENT_CONTEXT(ctx);
1091db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   (void) mode;
1092db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   (void) name;
1093db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   (void) primcount;
1094db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   _mesa_compile_error(ctx, GL_INVALID_OPERATION,
1095db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák                       "glDrawTransformFeedbackInstanced");
1096db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák}
1097db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák
1098db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák
1099db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšákstatic void GLAPIENTRY
1100db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák_save_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name,
1101db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák                                           GLuint stream, GLsizei primcount)
1102db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák{
1103db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   GET_CURRENT_CONTEXT(ctx);
1104db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   (void) mode;
1105db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   (void) name;
1106db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   (void) stream;
1107db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   (void) primcount;
1108db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   _mesa_compile_error(ctx, GL_INVALID_OPERATION,
1109db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák                       "glDrawTransformFeedbackStreamInstanced");
1110db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák}
1111db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák
1112db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák
1113db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšákstatic void GLAPIENTRY
11147c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
1115fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1116fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
11177c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) x1;
11187c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) y1;
11197c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) x2;
11207c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) y2;
11217c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glRectf");
1122fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1123fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
11247c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
11257c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
11267c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalMesh1(GLenum mode, GLint i1, GLint i2)
1127fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1128fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
11297c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
11307c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) i1;
11317c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) i2;
11327c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glEvalMesh1");
1133fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1134fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
11357c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
11367c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
11377c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
1138fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1139fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
11407c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
11417c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) i1;
11427c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) i2;
11437c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) j1;
11447c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) j2;
11457c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glEvalMesh2");
1146fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1147fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
11487c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
11497c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
11507c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_Begin(GLenum mode)
1151fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
11527c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   GET_CURRENT_CONTEXT(ctx);
1153fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode;
11547c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_compile_error(ctx, GL_INVALID_OPERATION, "Recursive glBegin");
1155fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1156fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1157fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
11587c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
11597c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_PrimitiveRestartNV(void)
1160be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul{
1161be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   GLenum curPrim;
11627c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   GET_CURRENT_CONTEXT(ctx);
1163be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
1164be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   curPrim = ctx->Driver.CurrentSavePrimitive;
1165be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
1166be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   _save_End();
1167be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   _save_Begin(curPrim);
1168be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul}
1169be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
1170be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
1171fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Unlike the functions above, these are to be hooked into the vtxfmt
1172fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * maintained in ctx->ListState, active when the list is known or
1173fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * suspected to be outside any begin/end primitive.
1174cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul * Note: OBE = Outside Begin/End
1175fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
11767c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
11777c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_OBE_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
1178fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1179fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
11807c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   vbo_save_NotifyBegin(ctx, GL_QUADS | VBO_SAVE_PRIM_WEAK);
11817c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   CALL_Vertex2f(GET_DISPATCH(), (x1, y1));
11827c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   CALL_Vertex2f(GET_DISPATCH(), (x2, y1));
11837c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   CALL_Vertex2f(GET_DISPATCH(), (x2, y2));
11847c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   CALL_Vertex2f(GET_DISPATCH(), (x1, y2));
1185fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_End(GET_DISPATCH(), ());
1186fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1187fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1188fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
11897c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
11907c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count)
1191fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1192fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
119397dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
1194fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
1195fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
11967c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (!_mesa_validate_DrawArrays(ctx, mode, start, count))
1197fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
1198fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
119997dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (save->out_of_memory)
120097dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      return;
120197dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul
12027c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _ae_map_vbos(ctx);
1203b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
12047c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   vbo_save_NotifyBegin(ctx, (mode | VBO_SAVE_PRIM_WEAK
12057c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                              | VBO_SAVE_PRIM_NO_CURRENT_UPDATE));
12066a3fdc3a1ea6c306d9543791bf172dd1052d7382Keith Whitwell
1207fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0; i < count; i++)
12087c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      CALL_ArrayElement(GET_DISPATCH(), (start + i));
1209fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_End(GET_DISPATCH(), ());
1210b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
12117c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _ae_unmap_vbos(ctx);
1212fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1213fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
12147c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
1215fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Could do better by copying the arrays and element list intact and
1216fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * then emitting an indexed prim at runtime.
1217fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
12187c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
12197c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type,
12207c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                       const GLvoid * indices)
1221fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1222fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
122397dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
1224fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
1225fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
12267c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices, 0))
1227fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
1228fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
122997dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (save->out_of_memory)
123097dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      return;
123197dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul
12327c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _ae_map_vbos(ctx);
1233b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
1234a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu   if (_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj))
12357c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      indices =
1236a0a5bd4bb30a73c10b02c3c3b914940a03f9b790Yuanhan Liu         ADD_POINTERS(ctx->Array.ArrayObj->ElementArrayBufferObj->Pointer, indices);
1237982dcb74fd19b88208d127b8019e2a2af979cac2Xiang, Haihao
12387c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   vbo_save_NotifyBegin(ctx, (mode | VBO_SAVE_PRIM_WEAK |
12397c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                              VBO_SAVE_PRIM_NO_CURRENT_UPDATE));
1240fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1241fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   switch (type) {
1242fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_BYTE:
12437c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      for (i = 0; i < count; i++)
12447c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         CALL_ArrayElement(GET_DISPATCH(), (((GLubyte *) indices)[i]));
1245fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
1246fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_SHORT:
12477c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      for (i = 0; i < count; i++)
12487c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         CALL_ArrayElement(GET_DISPATCH(), (((GLushort *) indices)[i]));
1249fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
1250fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_INT:
12517c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      for (i = 0; i < count; i++)
12527c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         CALL_ArrayElement(GET_DISPATCH(), (((GLuint *) indices)[i]));
1253fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
1254fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   default:
12557c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(type)");
1256fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
1257fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1258fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1259fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_End(GET_DISPATCH(), ());
1260b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
12617c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _ae_unmap_vbos(ctx);
1262fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1263fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
12647c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
12657c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void GLAPIENTRY
12667c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_OBE_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
12677c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                            GLsizei count, GLenum type,
12687c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                            const GLvoid * indices)
1269fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1270fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
127197dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   struct vbo_save_context *save = &vbo_context(ctx)->save;
127297dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul
127397dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (!_mesa_validate_DrawRangeElements(ctx, mode,
127497dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul                                         start, end, count, type, indices, 0))
127597dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      return;
127697dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul
127797dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   if (save->out_of_memory)
127897dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul      return;
127997dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul
128097dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   _save_OBE_DrawElements(mode, count, type, indices);
1281fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1282fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1283fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1284cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paulstatic void GLAPIENTRY
1285cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul_save_OBE_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type,
1286cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                            const GLvoid **indices, GLsizei primcount)
1287cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul{
1288cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   GLsizei i;
1289cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1290cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   for (i = 0; i < primcount; i++) {
1291cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul      if (count[i] > 0) {
1292cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul	 CALL_DrawElements(GET_DISPATCH(), (mode, count[i], type, indices[i]));
1293cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul      }
1294cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   }
1295cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul}
1296cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1297cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1298cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paulstatic void GLAPIENTRY
1299cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul_save_OBE_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count,
1300cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                                      GLenum type,
13019881bf6e69b52efc1eb57a4027d9a8817ef8cbcbBrian Paul                                      const GLvoid * const *indices,
1302cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                                      GLsizei primcount,
1303cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul                                      const GLint *basevertex)
1304cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul{
1305cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   GLsizei i;
1306cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1307cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   for (i = 0; i < primcount; i++) {
1308cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul      if (count[i] > 0) {
1309cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul	 CALL_DrawElementsBaseVertex(GET_DISPATCH(), (mode, count[i], type,
1310cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul						      indices[i],
1311cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul						      basevertex[i]));
1312cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul      }
1313cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   }
1314cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul}
1315cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
1316cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul
13177c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
13187c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_vtxfmt_init(struct gl_context *ctx)
1319fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1320fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1321fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLvertexformat *vfmt = &save->vtxfmt;
1322fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
132380630d1fed6cd32e75f5e97e2cd27509be21d093Chia-I Wu   _MESA_INIT_ARRAYELT_VTXFMT(vfmt, _ae_);
132480630d1fed6cd32e75f5e97e2cd27509be21d093Chia-I Wu
1325fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Begin = _save_Begin;
1326fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color3f = _save_Color3f;
1327fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color3fv = _save_Color3fv;
1328fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color4f = _save_Color4f;
1329fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color4fv = _save_Color4fv;
1330fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EdgeFlag = _save_EdgeFlag;
1331fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->End = _save_End;
1332be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   vfmt->PrimitiveRestartNV = _save_PrimitiveRestartNV;
1333fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->FogCoordfEXT = _save_FogCoordfEXT;
1334fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->FogCoordfvEXT = _save_FogCoordfvEXT;
1335fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Indexf = _save_Indexf;
1336fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Indexfv = _save_Indexfv;
1337fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Materialfv = _save_Materialfv;
1338fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f;
1339fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv;
1340fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f;
1341fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv;
1342fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f;
1343fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv;
1344fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f;
1345fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv;
1346fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Normal3f = _save_Normal3f;
1347fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Normal3fv = _save_Normal3fv;
1348fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT;
1349fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT;
1350fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord1f = _save_TexCoord1f;
1351fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord1fv = _save_TexCoord1fv;
1352fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord2f = _save_TexCoord2f;
1353fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord2fv = _save_TexCoord2fv;
1354fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord3f = _save_TexCoord3f;
1355fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord3fv = _save_TexCoord3fv;
1356fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord4f = _save_TexCoord4f;
1357fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord4fv = _save_TexCoord4fv;
1358fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex2f = _save_Vertex2f;
1359fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex2fv = _save_Vertex2fv;
1360fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex3f = _save_Vertex3f;
1361fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex3fv = _save_Vertex3fv;
1362fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex4f = _save_Vertex4f;
1363fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex4fv = _save_Vertex4fv;
1364fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB;
1365fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB;
1366fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB;
1367fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB;
1368fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB;
1369fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB;
1370fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB;
1371fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB;
1372fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1373fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV;
1374fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV;
1375fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV;
1376fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV;
1377fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV;
1378fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV;
1379fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV;
1380fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV;
13817c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
1382ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   /* integer-valued */
1383ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI1i = _save_VertexAttribI1i;
1384ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI2i = _save_VertexAttribI2i;
1385ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI3i = _save_VertexAttribI3i;
1386ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI4i = _save_VertexAttribI4i;
1387ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI2iv = _save_VertexAttribI2iv;
1388ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI3iv = _save_VertexAttribI3iv;
1389ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI4iv = _save_VertexAttribI4iv;
1390ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul
1391ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   /* unsigned integer-valued */
1392ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI1ui = _save_VertexAttribI1ui;
1393ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI2ui = _save_VertexAttribI2ui;
1394ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI3ui = _save_VertexAttribI3ui;
1395ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI4ui = _save_VertexAttribI4ui;
1396ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI2uiv = _save_VertexAttribI2uiv;
1397ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI3uiv = _save_VertexAttribI3uiv;
1398ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI4uiv = _save_VertexAttribI4uiv;
1399ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul
140051fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexP2ui = _save_VertexP2ui;
140151fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexP3ui = _save_VertexP3ui;
140251fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexP4ui = _save_VertexP4ui;
140351fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexP2uiv = _save_VertexP2uiv;
140451fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexP3uiv = _save_VertexP3uiv;
140551fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexP4uiv = _save_VertexP4uiv;
140651fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
140751fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP1ui = _save_TexCoordP1ui;
140851fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP2ui = _save_TexCoordP2ui;
140951fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP3ui = _save_TexCoordP3ui;
141051fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP4ui = _save_TexCoordP4ui;
141151fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP1uiv = _save_TexCoordP1uiv;
141251fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP2uiv = _save_TexCoordP2uiv;
141351fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP3uiv = _save_TexCoordP3uiv;
141451fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->TexCoordP4uiv = _save_TexCoordP4uiv;
141551fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
141651fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP1ui = _save_MultiTexCoordP1ui;
141751fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP2ui = _save_MultiTexCoordP2ui;
141851fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP3ui = _save_MultiTexCoordP3ui;
141951fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP4ui = _save_MultiTexCoordP4ui;
142051fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP1uiv = _save_MultiTexCoordP1uiv;
142151fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP2uiv = _save_MultiTexCoordP2uiv;
142251fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP3uiv = _save_MultiTexCoordP3uiv;
142351fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->MultiTexCoordP4uiv = _save_MultiTexCoordP4uiv;
142451fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
142551fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->NormalP3ui = _save_NormalP3ui;
142651fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->NormalP3uiv = _save_NormalP3uiv;
142751fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
142851fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->ColorP3ui = _save_ColorP3ui;
142951fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->ColorP4ui = _save_ColorP4ui;
143051fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->ColorP3uiv = _save_ColorP3uiv;
143151fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->ColorP4uiv = _save_ColorP4uiv;
143251fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
143351fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->SecondaryColorP3ui = _save_SecondaryColorP3ui;
143451fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->SecondaryColorP3uiv = _save_SecondaryColorP3uiv;
143551fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
143651fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP1ui = _save_VertexAttribP1ui;
143751fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP2ui = _save_VertexAttribP2ui;
143851fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP3ui = _save_VertexAttribP3ui;
143951fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP4ui = _save_VertexAttribP4ui;
144051fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
144151fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP1uiv = _save_VertexAttribP1uiv;
144251fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP2uiv = _save_VertexAttribP2uiv;
144351fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP3uiv = _save_VertexAttribP3uiv;
144451fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie   vfmt->VertexAttribP4uiv = _save_VertexAttribP4uiv;
144551fcf080a342896ea0bc71dce01e948c810a8db9Dave Airlie
1446fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* This will all require us to fallback to saving the list as opcodes:
14477c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul    */
14487c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _MESA_INIT_DLIST_VTXFMT(vfmt, _save_);       /* inside begin/end */
1449aefa1f6ab1d9267b223b06ae205ab34c8e0d7c02Chia-I Wu
1450aefa1f6ab1d9267b223b06ae205ab34c8e0d7c02Chia-I Wu   _MESA_INIT_EVAL_VTXFMT(vfmt, _save_);
1451fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1452cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   /* These calls all generate GL_INVALID_OPERATION since this vtxfmt is
1453cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul    * only used when we're inside a glBegin/End pair.
1454fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
1455fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Begin = _save_Begin;
1456fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Rectf = _save_Rectf;
1457fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->DrawArrays = _save_DrawArrays;
1458fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->DrawElements = _save_DrawElements;
1459fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->DrawRangeElements = _save_DrawRangeElements;
146092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vfmt->DrawElementsBaseVertex = _save_DrawElementsBaseVertex;
146192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vfmt->DrawRangeElementsBaseVertex = _save_DrawRangeElementsBaseVertex;
1462cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   vfmt->MultiDrawElementsEXT = _save_MultiDrawElements;
1463cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   vfmt->MultiDrawElementsBaseVertex = _save_MultiDrawElementsBaseVertex;
1464db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   vfmt->DrawTransformFeedback = _save_DrawTransformFeedback;
1465db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   vfmt->DrawTransformFeedbackStream = _save_DrawTransformFeedbackStream;
1466db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   vfmt->DrawTransformFeedbackInstanced = _save_DrawTransformFeedbackInstanced;
1467db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák   vfmt->DrawTransformFeedbackStreamInstanced =
1468db7404defd47aa22082b52a6a31a08fb39fab626Marek Olšák         _save_DrawTransformFeedbackStreamInstanced;
1469fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1470fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1471fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
14727c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvoid
14737c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_save_SaveFlushVertices(struct gl_context *ctx)
1474fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1475fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1476fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1477fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Noop when we are actually active:
1478fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
1479fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM ||
1480fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       ctx->Driver.CurrentSavePrimitive <= GL_POLYGON)
1481fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
1482fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
14837c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (save->vert_count || save->prim_count)
14847c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _save_compile_vertex_list(ctx);
14857c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
14867c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_copy_to_current(ctx);
14877c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_reset_vertex(ctx);
14887c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_reset_counters(ctx);
1489fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 0;
1490fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1491fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
14927c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
14937c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvoid
14947c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_save_NewList(struct gl_context *ctx, GLuint list, GLenum mode)
1495fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1496fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1497fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
14987c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) list;
14997c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   (void) mode;
1500fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1501fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!save->prim_store)
15027c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      save->prim_store = alloc_prim_store(ctx);
15037c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
15047c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (!save->vertex_store)
15057c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      save->vertex_store = alloc_vertex_store(ctx);
15067c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
1507781f84a3c2f7a06cb9e6cc44b8d5d08b39577c25Brian Paul   save->buffer_ptr = vbo_save_map_vertex_store(ctx, save->vertex_store);
15087c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
15097c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_reset_vertex(ctx);
15107c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_reset_counters(ctx);
1511fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 0;
1512fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1513fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
15147c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
15157c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvoid
15167c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_save_EndList(struct gl_context *ctx)
1517fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1518fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1519bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1520bd953e872f22690bd232a758383883100d9347d0Keith Whitwell   /* EndList called inside a (saved) Begin/End pair?
1521bd953e872f22690bd232a758383883100d9347d0Keith Whitwell    */
1522bd953e872f22690bd232a758383883100d9347d0Keith Whitwell   if (ctx->Driver.CurrentSavePrimitive != PRIM_OUTSIDE_BEGIN_END) {
1523bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1524d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul      if (save->prim_count > 0) {
1525d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul         GLint i = save->prim_count - 1;
1526d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul         ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
1527d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul         save->prim[i].end = 0;
15287c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul         save->prim[i].count = (save->vert_count - save->prim[i].start);
1529d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul      }
1530bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1531bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      /* Make sure this vertex list gets replayed by the "loopback"
1532bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       * mechanism:
1533bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       */
1534bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      save->dangling_attr_ref = 1;
15357c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      vbo_save_SaveFlushVertices(ctx);
1536bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1537bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      /* Swap out this vertex format while outside begin/end.  Any color,
1538bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       * etc. received between here and the next begin will be compiled
1539bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       * as opcodes.
15407c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul       */
15417c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt);
1542bd953e872f22690bd232a758383883100d9347d0Keith Whitwell   }
1543bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1544781f84a3c2f7a06cb9e6cc44b8d5d08b39577c25Brian Paul   vbo_save_unmap_vertex_store(ctx, save->vertex_store);
1545fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1546fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(save->vertex_size == 0);
1547fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
15487c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
15497c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
15507c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvoid
15517c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_save_BeginCallList(struct gl_context *ctx, struct gl_display_list *dlist)
1552fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1553fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1554446abc2799a143c32c4c48472f3f964f9288a623Brian   save->replay_flags |= dlist->Flags;
1555fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1556fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
15577c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
15587c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvoid
15597c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_save_EndCallList(struct gl_context *ctx)
1560fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1561fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
15627c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
1563fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->ListState.CallDepth == 1) {
1564fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* This is correct: want to keep only the VBO_SAVE_FALLBACK
1565fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * flag, if it is set:
1566fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
1567fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->replay_flags &= VBO_SAVE_FALLBACK;
1568fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1569fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1570fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1571fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
15727c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
15737c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_destroy_vertex_list(struct gl_context *ctx, void *data)
1574fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
15757c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *) data;
1576fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) ctx;
1577fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
15787c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (--node->vertex_store->refcount == 0)
15797c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      free_vertex_store(ctx, node->vertex_store);
1580fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
15817c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   if (--node->prim_store->refcount == 0)
15827c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      FREE(node->prim_store);
1583ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul
1584ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul   if (node->current_data) {
1585ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul      FREE(node->current_data);
1586ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul      node->current_data = NULL;
1587ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul   }
1588fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1589fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1590fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
15917c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
15927c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_print_vertex_list(struct gl_context *ctx, void *data)
1593fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
15947c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *) data;
1595fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
1596fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) ctx;
1597fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1598298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg   printf("VBO-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n",
15997c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul          node->count, node->prim_count, node->vertex_size);
1600fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
16017c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   for (i = 0; i < node->prim_count; i++) {
1602fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      struct _mesa_prim *prim = &node->prim[i];
1603fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _mesa_debug(NULL, "   prim %d: %s%s %d..%d %s %s\n",
16047c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  i,
16057c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  _mesa_lookup_prim_by_nr(prim->mode),
16067c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  prim->weak ? " (weak)" : "",
16077c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  prim->start,
16087c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  prim->start + prim->count,
16097c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  (prim->begin) ? "BEGIN" : "(wrap)",
16107c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                  (prim->end) ? "END" : "(wrap)");
1611fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1612fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1613fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1614fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1615c55ebc3e3e556a5bf5cd78cee2807f4cbb6f626aBrian Paul/**
1616c55ebc3e3e556a5bf5cd78cee2807f4cbb6f626aBrian Paul * Called during context creation/init.
1617c55ebc3e3e556a5bf5cd78cee2807f4cbb6f626aBrian Paul */
16187c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulstatic void
16197c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul_save_current_init(struct gl_context *ctx)
1620fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1621fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1622fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
1623fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
16242421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell   for (i = VBO_ATTRIB_POS; i <= VBO_ATTRIB_GENERIC15; i++) {
16252421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      const GLuint j = i - VBO_ATTRIB_POS;
16262421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      ASSERT(j < VERT_ATTRIB_MAX);
16272421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      save->currentsz[i] = &ctx->ListState.ActiveAttribSize[j];
16282421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      save->current[i] = ctx->ListState.CurrentAttrib[j];
1629fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1630fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
16316a3fdc3a1ea6c306d9543791bf172dd1052d7382Keith Whitwell   for (i = VBO_ATTRIB_FIRST_MATERIAL; i <= VBO_ATTRIB_LAST_MATERIAL; i++) {
1632fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      const GLuint j = i - VBO_ATTRIB_FIRST_MATERIAL;
1633fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ASSERT(j < MAT_ATTRIB_MAX);
1634fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j];
1635fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->current[i] = ctx->ListState.CurrentMaterial[j];
1636fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1637fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1638fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
16397c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul
1640fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/**
1641c55ebc3e3e556a5bf5cd78cee2807f4cbb6f626aBrian Paul * Initialize the display list compiler.  Called during context creation.
1642fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
16437c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvoid
16447c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paulvbo_save_api_init(struct vbo_save_context *save)
1645fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1646f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg   struct gl_context *ctx = save->ctx;
1647fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
1648fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1649fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->opcode_vertex_list =
16507c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul      _mesa_dlist_alloc_opcode(ctx,
16517c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                               sizeof(struct vbo_save_vertex_list),
16527c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                               vbo_save_playback_vertex_list,
16537c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                               vbo_destroy_vertex_list,
16547c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul                               vbo_print_vertex_list);
1655fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1656fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.NotifySaveBegin = vbo_save_NotifyBegin;
1657fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
16587c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_vtxfmt_init(ctx);
16597c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _save_current_init(ctx);
166097dedfda5fbb4078db28519e50adeeeb8e1a1dc1Brian Paul   _mesa_noop_vtxfmt_init(&save->vtxfmt_noop);
1661fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
166237c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul   /* These will actually get set again when binding/drawing */
1663fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0; i < VBO_ATTRIB_MAX; i++)
1664fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->inputs[i] = &save->arrays[i];
1665fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1666fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Hook our array functions into the outside-begin-end vtxfmt in
1667fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * ctx->ListState.
1668fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
1669fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf;
1670fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays;
1671fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements;
1672fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements;
1673cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   ctx->ListState.ListVtxfmt.MultiDrawElementsEXT = _save_OBE_MultiDrawElements;
1674cd30c28e3b98da1e83d8c07375a4d51e1750afc2Brian Paul   ctx->ListState.ListVtxfmt.MultiDrawElementsBaseVertex = _save_OBE_MultiDrawElementsBaseVertex;
16757c2847a972cd68107348ba8fe3667dc211b78f3eBrian Paul   _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt);
1676fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1677fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
16788d5c83c467f83b44f5f2e271c4f9cca2d45af518Chia-I Wu
16798d5c83c467f83b44f5f2e271c4f9cca2d45af518Chia-I Wu#endif /* FEATURE_dlist */
1680