vbo_save_api.c revision f1cdce95f606584a56eabf3b38eea19ff4c75757
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"
7860b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt#include "main/api_noop.h"
79c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/api_validate.h"
80c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/api_arrayelt.h"
81c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/vtxfmt.h"
822cf44390d1e819f23e1d7ceb3199276c9148c647Chia-I Wu#include "main/dispatch.h"
83fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
84fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "vbo_context.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 */
103f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic GLuint _save_copy_vertices( struct gl_context *ctx,
104fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				   const struct vbo_save_vertex_list *node,
105fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				   const GLfloat *src_buffer)
106fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
107fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context( ctx )->save;
108fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   const struct _mesa_prim *prim = &node->prim[node->prim_count-1];
109fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint nr = prim->count;
110fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint sz = save->vertex_size;
111fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   const GLfloat *src = src_buffer + prim->start * sz;
112fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLfloat *dst = save->copied.buffer;
113fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint ovf, i;
114fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
115fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (prim->end)
116fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return 0;
117fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
118fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   switch( prim->mode )
119fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   {
120fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_POINTS:
121fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return 0;
122fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_LINES:
123fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ovf = nr&1;
124fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < ovf ; i++)
125c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke	 memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
126fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return i;
127fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_TRIANGLES:
128fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ovf = nr%3;
129fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < ovf ; i++)
130c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke	 memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
131fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return i;
132fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_QUADS:
133fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ovf = nr&3;
134fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < ovf ; i++)
135c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke	 memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
136fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return i;
137fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_LINE_STRIP:
138fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (nr == 0)
139fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 return 0;
140fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      else {
141c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke	 memcpy( dst, src+(nr-1)*sz, sz*sizeof(GLfloat) );
142fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 return 1;
143fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
144fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_LINE_LOOP:
145fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_TRIANGLE_FAN:
146fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_POLYGON:
147fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (nr == 0)
148fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 return 0;
149fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      else if (nr == 1) {
150c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke	 memcpy( dst, src+0, sz*sizeof(GLfloat) );
151fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 return 1;
152fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      } else {
153c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke	 memcpy( dst, src+0, sz*sizeof(GLfloat) );
154c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke	 memcpy( dst+sz, src+(nr-1)*sz, sz*sizeof(GLfloat) );
155fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 return 2;
156fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
157fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_TRIANGLE_STRIP:
158fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_QUAD_STRIP:
159fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      switch (nr) {
160fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 0: ovf = 0; break;
161fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 1: ovf = 1; break;
162fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      default: ovf = 2 + (nr&1); break;
163fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
164fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < ovf ; i++)
165c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke	 memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
166fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return i;
167fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   default:
168fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(0);
169fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return 0;
170fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
171fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
172fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
173fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
174f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic struct vbo_save_vertex_store *alloc_vertex_store( struct gl_context *ctx )
175fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
176fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_vertex_store *vertex_store = CALLOC_STRUCT(vbo_save_vertex_store);
177fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
178fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* obj->Name needs to be non-zero, but won't ever be examined more
179fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * closely than that.  In particular these buffers won't be entered
180fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * into the hash and can never be confused with ones visible to the
181fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * user.  Perhaps there could be a special number for internal
182fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * buffers:
183fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
18437c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul   vertex_store->bufferobj = ctx->Driver.NewBufferObject(ctx,
18537c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul                                                         VBO_BUF_ID,
18637c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul                                                         GL_ARRAY_BUFFER_ARB);
187fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
188fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.BufferData( ctx,
189fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			   GL_ARRAY_BUFFER_ARB,
190fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			   VBO_SAVE_BUFFER_SIZE * sizeof(GLfloat),
191fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			   NULL,
192fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			   GL_STATIC_DRAW_ARB,
193fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			   vertex_store->bufferobj);
194fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
195fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->buffer = NULL;
196fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->used = 0;
197fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->refcount = 1;
198fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
199fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return vertex_store;
200fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
201fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
202f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void free_vertex_store( struct gl_context *ctx, struct vbo_save_vertex_store *vertex_store )
203fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
204fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(!vertex_store->buffer);
205fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
20637c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul   if (vertex_store->bufferobj) {
20737c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul      _mesa_reference_buffer_object(ctx, &vertex_store->bufferobj, NULL);
20837c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul   }
209fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
210fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   FREE( vertex_store );
211fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
212fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
213f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic GLfloat *map_vertex_store( struct gl_context *ctx, struct vbo_save_vertex_store *vertex_store )
214fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
215fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(vertex_store->bufferobj);
216fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(!vertex_store->buffer);
217fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->buffer = (GLfloat *)ctx->Driver.MapBuffer(ctx,
218fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell							   GL_ARRAY_BUFFER_ARB,	/* not used */
2192cb3594af9cd1434aa2c408cd6f8d51bcd12e8eaAapo Tahkola							   GL_WRITE_ONLY, /* not used */
220fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell							   vertex_store->bufferobj);
221fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
222fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(vertex_store->buffer);
223fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return vertex_store->buffer + vertex_store->used;
224fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
225fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
226f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void unmap_vertex_store( struct gl_context *ctx, struct vbo_save_vertex_store *vertex_store )
227fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
228fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.UnmapBuffer( ctx, GL_ARRAY_BUFFER_ARB, vertex_store->bufferobj );
229fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->buffer = NULL;
230fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
231fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
232fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
233f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic struct vbo_save_primitive_store *alloc_prim_store( struct gl_context *ctx )
234fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
235fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_primitive_store *store = CALLOC_STRUCT(vbo_save_primitive_store);
236fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) ctx;
237fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   store->used = 0;
238fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   store->refcount = 1;
239fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return store;
240fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
241fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
242f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void _save_reset_counters( struct gl_context *ctx )
243fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
244fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
245fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
246fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim = save->prim_store->buffer + save->prim_store->used;
247fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->buffer = (save->vertex_store->buffer +
248fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		   save->vertex_store->used);
249fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
250c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell   assert(save->buffer == save->buffer_ptr);
251fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
252fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->vertex_size)
253fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) /
254fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			 save->vertex_size);
255fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   else
256fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->max_vert = 0;
257fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
258fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vert_count = 0;
259fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_count = 0;
260fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_max = VBO_SAVE_PRIM_SIZE - save->prim_store->used;
261fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->dangling_attr_ref = 0;
262fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
263fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
264fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
265fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Insert the active immediate struct onto the display list currently
266fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * being built.
267fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
268f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void _save_compile_vertex_list( struct gl_context *ctx )
269fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
270fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
271fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_vertex_list *node;
272fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
273fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Allocate space for this structure in the display list currently
274fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * being compiled.
275fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
276fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node = (struct vbo_save_vertex_list *)
2776e1697bee72a95f7d605e42ce60e2cb4a545106fBrian Paul      _mesa_dlist_alloc(ctx, save->opcode_vertex_list, sizeof(*node));
278fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
279fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!node)
280fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
281fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
282fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Duplicate our template, increment refcounts to the storage structs:
283fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
284c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke   memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz));
285fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->vertex_size = save->vertex_size;
286fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->buffer_offset = (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat);
287fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->count = save->vert_count;
288fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->wrap_count = save->copied.nr;
289fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->dangling_attr_ref = save->dangling_attr_ref;
290fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim = save->prim;
291fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim_count = save->prim_count;
292fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->vertex_store = save->vertex_store;
293fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim_store = save->prim_store;
294fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
295fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->vertex_store->refcount++;
296fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim_store->refcount++;
297fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
298b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   if (node->prim[0].no_current_update) {
299b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich      node->current_size = 0;
300b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich      node->current_data = NULL;
301b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   } else {
302b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich      node->current_size = node->vertex_size - node->attrsz[0];
303b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich      node->current_data = NULL;
304b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich
305b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich      if (node->current_size) {
306b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich         /* If the malloc fails, we just pull the data out of the VBO
307b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich          * later instead.
308b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich          */
309b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich         node->current_data = MALLOC( node->current_size * sizeof(GLfloat) );
310b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich         if (node->current_data) {
311b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich            const char *buffer = (const char *)save->vertex_store->buffer;
312b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich            unsigned attr_offset = node->attrsz[0] * sizeof(GLfloat);
313b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich            unsigned vertex_offset = 0;
314b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich
315b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich            if (node->count)
316b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich               vertex_offset = (node->count-1) * node->vertex_size * sizeof(GLfloat);
317b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich
318b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich            memcpy( node->current_data,
319b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich                    buffer + node->buffer_offset + vertex_offset + attr_offset,
320b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich                    node->current_size * sizeof(GLfloat) );
321b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich         }
3228b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell      }
3238b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell   }
3248b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell
3258b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell
3268b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell
327fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(node->attrsz[VBO_ATTRIB_POS] != 0 ||
328fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	  node->count == 0);
329fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
330fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->dangling_attr_ref)
331446abc2799a143c32c4c48472f3f964f9288a623Brian      ctx->ListState.CurrentList->Flags |= DLIST_DANGLING_REFS;
332fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
333fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vertex_store->used += save->vertex_size * node->count;
334fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_store->used += node->prim_count;
335fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
336fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
337fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Copy duplicated vertices
338fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
339fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->copied.nr = _save_copy_vertices( ctx, node, save->buffer );
340fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
341fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
342fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Deal with GL_COMPILE_AND_EXECUTE:
343fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
344fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->ExecuteFlag) {
345fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      struct _glapi_table *dispatch = GET_DISPATCH();
346fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
347fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _glapi_set_dispatch(ctx->Exec);
348fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
349fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      vbo_loopback_vertex_list( ctx,
350fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				(const GLfloat *)((const char *)save->vertex_store->buffer +
351fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell						  node->buffer_offset),
352fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				node->attrsz,
353fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				node->prim,
354fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				node->prim_count,
355fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				node->wrap_count,
356fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				node->vertex_size);
357fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
358fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _glapi_set_dispatch(dispatch);
359fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
360fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
361fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
362fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Decide whether the storage structs are full, or can be used for
363fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * the next vertex lists as well.
364fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
365fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->vertex_store->used >
366fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       VBO_SAVE_BUFFER_SIZE - 16 * (save->vertex_size + 4)) {
367fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
368fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Unmap old store:
369fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
370fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      unmap_vertex_store( ctx, save->vertex_store );
371fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
372fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Release old reference:
373fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
374fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vertex_store->refcount--;
375fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(save->vertex_store->refcount != 0);
376fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vertex_store = NULL;
377fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
378fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Allocate and map new store:
379fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
380fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vertex_store = alloc_vertex_store( ctx );
381c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell      save->buffer_ptr = map_vertex_store( ctx, save->vertex_store );
382fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
383fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
384fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->prim_store->used > VBO_SAVE_PRIM_SIZE - 6) {
385fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->prim_store->refcount--;
386fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(save->prim_store->refcount != 0);
387fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->prim_store = alloc_prim_store( ctx );
388fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
389fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
390fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Reset our structures for the next run of vertices:
391fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
392fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_counters( ctx );
393fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
394fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
395fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
396fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* TODO -- If no new vertices have been stored, don't bother saving
397fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * it.
398fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
399f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void _save_wrap_buffers( struct gl_context *ctx )
400fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
401fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
402fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i = save->prim_count - 1;
403fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLenum mode;
404fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLboolean weak;
405b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   GLboolean no_current_update;
406fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
407fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(i < (GLint) save->prim_max);
408fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(i >= 0);
409fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
410fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Close off in-progress primitive.
411fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
412fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].count = (save->vert_count -
413fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			  save->prim[i].start);
414fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   mode = save->prim[i].mode;
415fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   weak = save->prim[i].weak;
416b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   no_current_update = save->prim[i].no_current_update;
417fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
418fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* store the copied vertices, and allocate a new list.
419fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
420fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_compile_vertex_list( ctx );
421fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
422fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Restart interrupted primitive
423fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
424fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].mode = mode;
425fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].weak = weak;
426b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   save->prim[0].no_current_update = no_current_update;
427fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].begin = 0;
428fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].end = 0;
429fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].pad = 0;
430fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].start = 0;
431fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].count = 0;
4323b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   save->prim[0].num_instances = 1;
433fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_count = 1;
434fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
435fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
436fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
437fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
438fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Called only when buffers are wrapped as the result of filling the
439fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * vertex_store struct.
440fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
441f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void _save_wrap_filled_vertex( struct gl_context *ctx )
442fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
443fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
444fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLfloat *data = save->copied.buffer;
445fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
446fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
447fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Emit a glEnd to close off the last vertex list.
448fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
449fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_wrap_buffers( ctx );
450fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
451fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    /* Copy stored stored vertices to start of new list.
452fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
453fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(save->max_vert - save->vert_count > save->copied.nr);
454fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
455fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0 ; i < save->copied.nr ; i++) {
456c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke      memcpy( save->buffer_ptr, data, save->vertex_size * sizeof(GLfloat));
457fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      data += save->vertex_size;
458c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell      save->buffer_ptr += save->vertex_size;
459fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vert_count++;
460fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
461fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
462fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
463fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
464f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void _save_copy_to_current( struct gl_context *ctx )
465fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
466fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
467fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
468fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
4692421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell   for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
470fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (save->attrsz[i]) {
471fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->currentsz[i][0] = save->attrsz[i];
472fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 COPY_CLEAN_4V(save->current[i],
4732421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell		       save->attrsz[i],
4742421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell		       save->attrptr[i]);
475fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
476fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
477fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
478fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
479fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
480f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void _save_copy_from_current( struct gl_context *ctx )
481fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
482fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
483fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
484fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
4852421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell   for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
486fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      switch (save->attrsz[i]) {
487fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 4: save->attrptr[i][3] = save->current[i][3];
488fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 3: save->attrptr[i][2] = save->current[i][2];
489fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 2: save->attrptr[i][1] = save->current[i][1];
490fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 1: save->attrptr[i][0] = save->current[i][0];
491fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 0: break;
492fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
493fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
494fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
495fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
496fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
497fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
498fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
499fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Flush existing data, set new attrib size, replay copied vertices.
500fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
501f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void _save_upgrade_vertex( struct gl_context *ctx,
502fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				 GLuint attr,
503fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				 GLuint newsz )
504fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
505fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
506fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint oldsz;
507fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
508fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLfloat *tmp;
509fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
510fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Store the current run of vertices, and emit a GL_END.  Emit a
511fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * BEGIN in the new buffer.
512fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
513fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->vert_count)
514fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_wrap_buffers( ctx );
515fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   else
516fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert( save->copied.nr == 0 );
517fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
518fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
519fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * when the attribute already exists in the vertex and is having
520fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * its size increased.
521fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
522fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_copy_to_current( ctx );
523fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
524fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Fix up sizes:
525fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
526fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   oldsz = save->attrsz[attr];
527fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->attrsz[attr] = newsz;
528fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
529fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vertex_size += newsz - oldsz;
530fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) /
531fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		      save->vertex_size);
532fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vert_count = 0;
533fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
534fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Recalculate all the attrptr[] values:
535fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
536fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0, tmp = save->vertex ; i < VBO_ATTRIB_MAX ; i++) {
537fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (save->attrsz[i]) {
538fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->attrptr[i] = tmp;
539fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 tmp += save->attrsz[i];
540fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
541fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      else
542fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->attrptr[i] = NULL; /* will not be dereferenced. */
543fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
544fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
545fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Copy from current to repopulate the vertex with correct values.
546fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
547fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_copy_from_current( ctx );
548fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
549fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Replay stored vertices to translate them to new format here.
550fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    *
551fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * If there are copied vertices and the new (upgraded) attribute
552fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * has not been defined before, this list is somewhat degenerate,
553fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * and will need fixup at runtime.
554fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
555fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->copied.nr)
556fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   {
557fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLfloat *data = save->copied.buffer;
558fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLfloat *dest = save->buffer;
559fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLuint j;
560fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
561fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Need to note this and fix up at runtime (or loopback):
562fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
563dd60eaa6d9f61735141976db0e83d25176ac73c7Keith Whitwell      if (attr != VBO_ATTRIB_POS && save->currentsz[attr][0] == 0) {
564fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 assert(oldsz == 0);
565fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->dangling_attr_ref = GL_TRUE;
566fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
567fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
568fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < save->copied.nr ; i++) {
569fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) {
570fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	    if (save->attrsz[j]) {
571fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	       if (j == attr) {
572fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  if (oldsz) {
573fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		     COPY_CLEAN_4V( dest, oldsz, data );
574fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		     data += oldsz;
575fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		     dest += newsz;
576fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  }
577fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  else {
578fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		     COPY_SZ_4V( dest, newsz, save->current[attr] );
579fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		     dest += newsz;
580fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  }
581fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	       }
582fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	       else {
583fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  GLint sz = save->attrsz[j];
584fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  COPY_SZ_4V( dest, sz, data );
585fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  data += sz;
586fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  dest += sz;
587fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	       }
588fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	    }
589fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 }
590fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
591fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
592c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell      save->buffer_ptr = dest;
593fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vert_count += save->copied.nr;
594fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
595fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
596fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
597f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void save_fixup_vertex( struct gl_context *ctx, GLuint attr, GLuint sz )
598fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
599fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
600fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
601fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (sz > save->attrsz[attr]) {
602fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* New size is larger.  Need to flush existing vertices and get
603fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * an enlarged vertex format.
604fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
605fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_upgrade_vertex( ctx, attr, sz );
606fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
607fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   else if (sz < save->active_sz[attr]) {
608fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      static GLfloat id[4] = { 0, 0, 0, 1 };
609fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLuint i;
610fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
611fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* New size is equal or smaller - just need to fill in some
612fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * zeros.
613fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
614fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = sz ; i <= save->attrsz[attr] ; i++)
615fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->attrptr[attr][i-1] = id[i-1];
616fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
617fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
618fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->active_sz[attr] = sz;
619fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
620fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
621f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void _save_reset_vertex( struct gl_context *ctx )
622fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
623fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
624fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
625fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
626fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
627fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->attrsz[i] = 0;
628fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->active_sz[i] = 0;
629fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
630fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
631fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vertex_size = 0;
632fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
633fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
634fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
635fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
63669c6e21ceb6c2eb0c4b0fae0228027d665027b4eBrian Paul#define ERROR(err)   _mesa_compile_error( ctx, err, __FUNCTION__ );
637fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
638fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
639fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Only one size for each attribute may be active at once.  Eg. if
640fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * Color3f is installed/active, then Color4f may not be, even if the
641fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * vertex actually contains 4 color coordinates.  This is because the
642fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * 3f version won't otherwise set color[3] to 1.0 -- this is the job
643fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * of the chooser function when switching between Color4f and Color3f.
644fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
645fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#define ATTR( A, N, V0, V1, V2, V3 )				\
646fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwelldo {								\
647fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;	\
648fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
649ae4b6e04cdea188f6b5e656a1aafb6c3343fe5a7Brian Paul   if (save->active_sz[A] != N)					\
650fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save_fixup_vertex(ctx, A, N);				\
651fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
652fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   {								\
653ae4b6e04cdea188f6b5e656a1aafb6c3343fe5a7Brian Paul      GLfloat *dest = save->attrptr[A];				\
654fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>0) dest[0] = V0;					\
655fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>1) dest[1] = V1;					\
656fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>2) dest[2] = V2;					\
657fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>3) dest[3] = V3;					\
658fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }								\
659fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
660fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if ((A) == 0) {						\
661fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLuint i;							\
662fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
663fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0; i < save->vertex_size; i++)			\
664c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell	 save->buffer_ptr[i] = save->vertex[i];			\
665fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
666ae4b6e04cdea188f6b5e656a1aafb6c3343fe5a7Brian Paul      save->buffer_ptr += save->vertex_size;			\
667fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
668fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (++save->vert_count >= save->max_vert)			\
669fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _save_wrap_filled_vertex( ctx );			\
670fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }								\
671fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell} while (0)
672fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
673fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#define TAG(x) _save_##x
674fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
675fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "vbo_attrib_tmp.h"
676fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
677fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
678fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
679fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
680fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Cope with EvalCoord/CallList called within a begin/end object:
681fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *     -- Flush current buffer
682fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *     -- Fallback to opcodes for the rest of the begin/end object.
683fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
684f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void DO_FALLBACK( struct gl_context *ctx )
6851fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell{
6861fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
6871fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell
6881fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   if (save->vert_count || save->prim_count) {
689f1cdce95f606584a56eabf3b38eea19ff4c75757Brian Paul      if (save->prim_count > 0) {
690f1cdce95f606584a56eabf3b38eea19ff4c75757Brian Paul         /* Close off in-progress primitive. */
691f1cdce95f606584a56eabf3b38eea19ff4c75757Brian Paul         GLint i = save->prim_count - 1;
692f1cdce95f606584a56eabf3b38eea19ff4c75757Brian Paul         save->prim[i].count = save->vert_count - save->prim[i].start;
693f1cdce95f606584a56eabf3b38eea19ff4c75757Brian Paul      }
6941fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell
6951fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell      /* Need to replay this display list with loopback,
6961fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell       * unfortunately, otherwise this primitive won't be handled
6971fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell       * properly:
6981fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell       */
6991fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell      save->dangling_attr_ref = 1;
7001fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell
7011fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell      _save_compile_vertex_list( ctx );
7021fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   }
7031fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell
7041fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   _save_copy_to_current( ctx );
7051fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   _save_reset_vertex( ctx );
7061fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   _save_reset_counters( ctx );
7071fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
7081fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   ctx->Driver.SaveNeedFlush = 0;
7091fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell}
710fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
711fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalCoord1f( GLfloat u )
712fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
713fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
714fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
715aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalCoord1f(ctx->Save, (u));
716fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
717fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
718fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalCoord1fv( const GLfloat *v )
719fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
720fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
721fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
722aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalCoord1fv(ctx->Save, (v));
723fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
724fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
725fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalCoord2f( GLfloat u, GLfloat v )
726fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
727fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
728fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
729aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalCoord2f(ctx->Save, (u, v));
730fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
731fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
732fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalCoord2fv( const GLfloat *v )
733fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
734fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
735fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
736aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalCoord2fv(ctx->Save, (v));
737fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
738fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
739fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalPoint1( GLint i )
740fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
741fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
742fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
743aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalPoint1(ctx->Save, (i));
744fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
745fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
746fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalPoint2( GLint i, GLint j )
747fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
748fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
749fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
750aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_EvalPoint2(ctx->Save, (i, j));
751fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
752fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
753fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_CallList( GLuint l )
754fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
755fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
756fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
757aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_CallList(ctx->Save, (l));
758fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
759fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
760fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_CallLists( GLsizei n, GLenum type, const GLvoid *v )
761fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
762fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
763fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
764aefd4f76ea52d0480d63e053d2e2c768dd40a470Chia-I Wu   CALL_CallLists(ctx->Save, (n, type, v));
765fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
766fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
767fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
768fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
769fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
770fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* This begin is hooked into ...  Updating of
771fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * ctx->Driver.CurrentSavePrimitive is already taken care of.
772fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
773f9995b30756140724f41daf963fa06167912be7fKristian HøgsbergGLboolean vbo_save_NotifyBegin( struct gl_context *ctx, GLenum mode )
774fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
775fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
776fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
777fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i = save->prim_count++;
778fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
779fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(i < save->prim_max);
780b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   save->prim[i].mode = mode & VBO_SAVE_PRIM_MODE_MASK;
781fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].begin = 1;
782fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].end = 0;
783fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0;
784b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   save->prim[i].no_current_update = (mode & VBO_SAVE_PRIM_NO_CURRENT_UPDATE) ? 1 : 0;
785fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].pad = 0;
786fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].start = save->vert_count;
787fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].count = 0;
7883b7ac45162412a79c3cd4d4dbc16bd54db597608Brian Paul   save->prim[i].num_instances = 1;
789fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
790fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_install_save_vtxfmt( ctx, &save->vtxfmt );
791fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 1;
792fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return GL_TRUE;
793fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
794fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
795fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
796fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
797fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_End( void )
798fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
799fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT( ctx );
800fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
801fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i = save->prim_count - 1;
802fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
803fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
804fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].end = 1;
805fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].count = (save->vert_count -
806fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			  save->prim[i].start);
807fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
808fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (i == (GLint) save->prim_max - 1) {
809fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_compile_vertex_list( ctx );
810fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(save->copied.nr == 0);
811fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
812fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
813fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Swap out this vertex format while outside begin/end.  Any color,
814fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * etc. received between here and the next begin will be compiled
815fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * as opcodes.
816fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
817fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
818fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
819fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
820fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
821fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* These are all errors as this vtxfmt is only installed inside
822fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * begin/end pairs.
823fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
824fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_DrawElements(GLenum mode, GLsizei count, GLenum type,
825fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			       const GLvoid *indices)
826fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
827fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
828fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode; (void) count; (void) type; (void) indices;
829fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" );
830fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
831fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
832fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
833fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_DrawRangeElements(GLenum mode,
834fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				    GLuint start, GLuint end,
835fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				    GLsizei count, GLenum type,
836fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				    const GLvoid *indices)
837fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
838fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
839fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode; (void) start; (void) end; (void) count; (void) type; (void) indices;
840fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" );
841fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
842fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
84392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtstatic void GLAPIENTRY _save_DrawElementsBaseVertex(GLenum mode,
84492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt						    GLsizei count,
84592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt						    GLenum type,
84692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt						    const GLvoid *indices,
84792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt						    GLint basevertex)
84892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
84992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GET_CURRENT_CONTEXT(ctx);
85092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   (void) mode; (void) count; (void) type; (void) indices; (void)basevertex;
85192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
85292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" );
85392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
85492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
85592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtstatic void GLAPIENTRY _save_DrawRangeElementsBaseVertex(GLenum mode,
85692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt							 GLuint start,
85792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt							 GLuint end,
85892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt							 GLsizei count,
85992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt							 GLenum type,
86092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt							 const GLvoid *indices,
86192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt							 GLint basevertex)
86292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
86392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GET_CURRENT_CONTEXT(ctx);
86492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   (void) mode; (void) start; (void) end; (void) count; (void) type;
86592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   (void) indices; (void)basevertex;
86692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
86792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" );
86892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
86992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
870fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count)
871fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
872fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
873fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode; (void) start; (void) count;
874fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" );
875fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
876fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
877fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
878fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
879fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
880fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) x1; (void) y1; (void) x2; (void) y2;
881fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glRectf" );
882fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
883fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
884fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
885fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
886fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
887fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode; (void) i1; (void) i2;
888fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh1" );
889fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
890fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
891fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalMesh2( GLenum mode, GLint i1, GLint i2,
892fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				  GLint j1, GLint j2 )
893fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
894fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
895fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode; (void) i1; (void) i2; (void) j1; (void) j2;
896fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh2" );
897fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
898fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
899fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_Begin( GLenum mode )
900fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
901fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT( ctx );
902fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode;
903fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "Recursive glBegin" );
904fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
905fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
906fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
907be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paulstatic void GLAPIENTRY _save_PrimitiveRestartNV( void )
908be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul{
909be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   GLenum curPrim;
910be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   GET_CURRENT_CONTEXT( ctx );
911be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
912be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   curPrim = ctx->Driver.CurrentSavePrimitive;
913be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
914be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   _save_End();
915be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   _save_Begin(curPrim);
916be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul}
917be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
918be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul
919fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Unlike the functions above, these are to be hooked into the vtxfmt
920fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * maintained in ctx->ListState, active when the list is known or
921fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * suspected to be outside any begin/end primitive.
922fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
923fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
924fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
925fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
926fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vbo_save_NotifyBegin( ctx, GL_QUADS | VBO_SAVE_PRIM_WEAK );
927fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_Vertex2f(GET_DISPATCH(), ( x1, y1 ));
928fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_Vertex2f(GET_DISPATCH(), ( x2, y1 ));
929fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_Vertex2f(GET_DISPATCH(), ( x2, y2 ));
930fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_Vertex2f(GET_DISPATCH(), ( x1, y2 ));
931fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_End(GET_DISPATCH(), ());
932fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
933fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
934fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
935fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count)
936fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
937fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
938fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
939fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
940fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
941fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
942fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
943b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell   _ae_map_vbos( ctx );
944b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
945b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK | VBO_SAVE_PRIM_NO_CURRENT_UPDATE);
9466a3fdc3a1ea6c306d9543791bf172dd1052d7382Keith Whitwell
947fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0; i < count; i++)
948fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       CALL_ArrayElement(GET_DISPATCH(), (start + i));
949fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_End(GET_DISPATCH(), ());
950b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
951b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell   _ae_unmap_vbos( ctx );
952fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
953fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
954fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Could do better by copying the arrays and element list intact and
955fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * then emitting an indexed prim at runtime.
956fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
957fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type,
958fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				   const GLvoid *indices)
959fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
960fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
961fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
962fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
96392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))
964fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
965fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
966b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell   _ae_map_vbos( ctx );
967b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
968bd4c6a2e503db43e81ef41f77d876308badd93ebBrian Paul   if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj))
969982dcb74fd19b88208d127b8019e2a2af979cac2Xiang, Haihao      indices = ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Pointer, indices);
970982dcb74fd19b88208d127b8019e2a2af979cac2Xiang, Haihao
971b3d2ec9942303d1d03e28a25b030eb060415abfbMathias Fröhlich   vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK | VBO_SAVE_PRIM_NO_CURRENT_UPDATE );
972fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
973fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   switch (type) {
974fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_BYTE:
975fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < count ; i++)
976fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	  CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] ));
977fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
978fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_SHORT:
979fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < count ; i++)
980fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	  CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] ));
981fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
982fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_INT:
983fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < count ; i++)
984fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	  CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] ));
985fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
986fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   default:
987fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
988fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
989fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
990fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
991fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_End(GET_DISPATCH(), ());
992b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
993b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell   _ae_unmap_vbos( ctx );
994fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
995fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
996fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode,
997fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell					GLuint start, GLuint end,
998fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell					GLsizei count, GLenum type,
999fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell					const GLvoid *indices)
1000fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1001fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
1002fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (_mesa_validate_DrawRangeElements( ctx, mode,
1003fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell					 start, end,
100492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt					 count, type, indices, 0 ))
1005fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_OBE_DrawElements( mode, count, type, indices );
1006fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1007fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1008fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1009fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1010fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1011fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1012f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void _save_vtxfmt_init( struct gl_context *ctx )
1013fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1014fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1015fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLvertexformat *vfmt = &save->vtxfmt;
1016fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
101780630d1fed6cd32e75f5e97e2cd27509be21d093Chia-I Wu   _MESA_INIT_ARRAYELT_VTXFMT(vfmt, _ae_);
101880630d1fed6cd32e75f5e97e2cd27509be21d093Chia-I Wu
1019fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Begin = _save_Begin;
1020fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color3f = _save_Color3f;
1021fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color3fv = _save_Color3fv;
1022fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color4f = _save_Color4f;
1023fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color4fv = _save_Color4fv;
1024fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EdgeFlag = _save_EdgeFlag;
1025fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->End = _save_End;
1026be45255ab1f63c10fefcf2f399ac7d1c9294cf6aBrian Paul   vfmt->PrimitiveRestartNV = _save_PrimitiveRestartNV;
1027fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->FogCoordfEXT = _save_FogCoordfEXT;
1028fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->FogCoordfvEXT = _save_FogCoordfvEXT;
1029fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Indexf = _save_Indexf;
1030fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Indexfv = _save_Indexfv;
1031fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Materialfv = _save_Materialfv;
1032fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f;
1033fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv;
1034fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f;
1035fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv;
1036fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f;
1037fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv;
1038fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f;
1039fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv;
1040fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Normal3f = _save_Normal3f;
1041fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Normal3fv = _save_Normal3fv;
1042fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT;
1043fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT;
1044fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord1f = _save_TexCoord1f;
1045fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord1fv = _save_TexCoord1fv;
1046fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord2f = _save_TexCoord2f;
1047fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord2fv = _save_TexCoord2fv;
1048fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord3f = _save_TexCoord3f;
1049fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord3fv = _save_TexCoord3fv;
1050fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord4f = _save_TexCoord4f;
1051fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord4fv = _save_TexCoord4fv;
1052fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex2f = _save_Vertex2f;
1053fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex2fv = _save_Vertex2fv;
1054fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex3f = _save_Vertex3f;
1055fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex3fv = _save_Vertex3fv;
1056fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex4f = _save_Vertex4f;
1057fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex4fv = _save_Vertex4fv;
1058fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB;
1059fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB;
1060fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB;
1061fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB;
1062fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB;
1063fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB;
1064fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB;
1065fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB;
1066fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1067fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV;
1068fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV;
1069fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV;
1070fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV;
1071fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV;
1072fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV;
1073fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV;
1074fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV;
1075fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1076ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   /* integer-valued */
1077ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI1i = _save_VertexAttribI1i;
1078ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI2i = _save_VertexAttribI2i;
1079ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI3i = _save_VertexAttribI3i;
1080ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI4i = _save_VertexAttribI4i;
1081ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI2iv = _save_VertexAttribI2iv;
1082ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI3iv = _save_VertexAttribI3iv;
1083ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI4iv = _save_VertexAttribI4iv;
1084ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul
1085ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   /* unsigned integer-valued */
1086ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI1ui = _save_VertexAttribI1ui;
1087ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI2ui = _save_VertexAttribI2ui;
1088ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI3ui = _save_VertexAttribI3ui;
1089ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI4ui = _save_VertexAttribI4ui;
1090ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI2uiv = _save_VertexAttribI2uiv;
1091ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI3uiv = _save_VertexAttribI3uiv;
1092ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul   vfmt->VertexAttribI4uiv = _save_VertexAttribI4uiv;
1093ca2618f4b632bf4b357a539a8fb7dafc99b35976Brian Paul
1094fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* This will all require us to fallback to saving the list as opcodes:
1095fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
1096a73ba2d31b87e974f6846a8aaced704634f6f657Chia-I Wu   _MESA_INIT_DLIST_VTXFMT(vfmt, _save_); /* inside begin/end */
1097aefa1f6ab1d9267b223b06ae205ab34c8e0d7c02Chia-I Wu
1098aefa1f6ab1d9267b223b06ae205ab34c8e0d7c02Chia-I Wu   _MESA_INIT_EVAL_VTXFMT(vfmt, _save_);
1099fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1100fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* These are all errors as we at least know we are in some sort of
1101fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * begin/end pair:
1102fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
1103fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Begin = _save_Begin;
1104fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Rectf = _save_Rectf;
1105fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->DrawArrays = _save_DrawArrays;
1106fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->DrawElements = _save_DrawElements;
1107fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->DrawRangeElements = _save_DrawRangeElements;
110892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vfmt->DrawElementsBaseVertex = _save_DrawElementsBaseVertex;
110992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vfmt->DrawRangeElementsBaseVertex = _save_DrawRangeElementsBaseVertex;
111060b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   /* Loops back into vfmt->DrawElements */
111160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   vfmt->MultiDrawElementsEXT = _mesa_noop_MultiDrawElements;
111292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vfmt->MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;
1113fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1114fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1115fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1116f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvoid vbo_save_SaveFlushVertices( struct gl_context *ctx )
1117fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1118fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1119fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1120fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Noop when we are actually active:
1121fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
1122fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM ||
1123fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       ctx->Driver.CurrentSavePrimitive <= GL_POLYGON)
1124fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
1125fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1126fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->vert_count ||
1127fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       save->prim_count)
1128fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_compile_vertex_list( ctx );
1129fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1130fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_copy_to_current( ctx );
1131fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_vertex( ctx );
1132fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_counters( ctx );
1133fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 0;
1134fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1135fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1136f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvoid vbo_save_NewList( struct gl_context *ctx, GLuint list, GLenum mode )
1137fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1138fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1139fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1140fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) list; (void) mode;
1141fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1142fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!save->prim_store)
1143fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->prim_store = alloc_prim_store( ctx );
1144fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1145fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!save->vertex_store)
1146fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vertex_store = alloc_vertex_store( ctx );
1147fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1148c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell   save->buffer_ptr = map_vertex_store( ctx, save->vertex_store );
1149fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1150fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_vertex( ctx );
1151fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_counters( ctx );
1152fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 0;
1153fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1154fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1155f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvoid vbo_save_EndList( struct gl_context *ctx )
1156fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1157fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1158bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1159bd953e872f22690bd232a758383883100d9347d0Keith Whitwell   /* EndList called inside a (saved) Begin/End pair?
1160bd953e872f22690bd232a758383883100d9347d0Keith Whitwell    */
1161bd953e872f22690bd232a758383883100d9347d0Keith Whitwell   if (ctx->Driver.CurrentSavePrimitive != PRIM_OUTSIDE_BEGIN_END) {
1162bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1163d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul      if (save->prim_count > 0) {
1164d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul         GLint i = save->prim_count - 1;
1165d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul         ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
1166d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul         save->prim[i].end = 0;
1167d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul         save->prim[i].count = (save->vert_count -
1168d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul                                save->prim[i].start);
1169d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul      }
1170bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1171bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      /* Make sure this vertex list gets replayed by the "loopback"
1172bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       * mechanism:
1173bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       */
1174bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      save->dangling_attr_ref = 1;
1175bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      vbo_save_SaveFlushVertices( ctx );
1176bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1177bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      /* Swap out this vertex format while outside begin/end.  Any color,
1178bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       * etc. received between here and the next begin will be compiled
1179bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       * as opcodes.
1180bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       */
1181bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
1182bd953e872f22690bd232a758383883100d9347d0Keith Whitwell   }
1183bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1184fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   unmap_vertex_store( ctx, save->vertex_store );
1185fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1186fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(save->vertex_size == 0);
1187fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1188fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1189f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvoid vbo_save_BeginCallList( struct gl_context *ctx, struct gl_display_list *dlist )
1190fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1191fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1192446abc2799a143c32c4c48472f3f964f9288a623Brian   save->replay_flags |= dlist->Flags;
1193fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1194fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1195f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvoid vbo_save_EndCallList( struct gl_context *ctx )
1196fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1197fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1198fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1199fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->ListState.CallDepth == 1) {
1200fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* This is correct: want to keep only the VBO_SAVE_FALLBACK
1201fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * flag, if it is set:
1202fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
1203fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->replay_flags &= VBO_SAVE_FALLBACK;
1204fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1205fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1206fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1207fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1208f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void vbo_destroy_vertex_list( struct gl_context *ctx, void *data )
1209fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1210fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *)data;
1211fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) ctx;
1212fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1213fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if ( --node->vertex_store->refcount == 0 )
1214fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      free_vertex_store( ctx, node->vertex_store );
1215fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1216fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if ( --node->prim_store->refcount == 0 )
1217fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      FREE( node->prim_store );
1218ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul
1219ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul   if (node->current_data) {
1220ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul      FREE(node->current_data);
1221ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul      node->current_data = NULL;
1222ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul   }
1223fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1224fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1225fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1226f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void vbo_print_vertex_list( struct gl_context *ctx, void *data )
1227fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1228fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *)data;
1229fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
1230fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) ctx;
1231fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1232298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg   printf("VBO-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n",
1233298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	  node->count,
1234298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	  node->prim_count,
1235298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg	  node->vertex_size);
1236fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1237fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0 ; i < node->prim_count ; i++) {
1238fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      struct _mesa_prim *prim = &node->prim[i];
1239fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _mesa_debug(NULL, "   prim %d: %s%s %d..%d %s %s\n",
1240fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  i,
12410846c88ec3a63ac5e4096aedcdc107cbe71f306bKeith Whitwell		  _mesa_lookup_prim_by_nr(prim->mode),
1242fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  prim->weak ? " (weak)" : "",
1243fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  prim->start,
1244fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  prim->start + prim->count,
1245fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  (prim->begin) ? "BEGIN" : "(wrap)",
1246fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  (prim->end) ? "END" : "(wrap)");
1247fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1248fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1249fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1250fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1251f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void _save_current_init( struct gl_context *ctx )
1252fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1253fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1254fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
1255fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
12562421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell   for (i = VBO_ATTRIB_POS; i <= VBO_ATTRIB_GENERIC15; i++) {
12572421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      const GLuint j = i - VBO_ATTRIB_POS;
12582421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      ASSERT(j < VERT_ATTRIB_MAX);
12592421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      save->currentsz[i] = &ctx->ListState.ActiveAttribSize[j];
12602421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      save->current[i] = ctx->ListState.CurrentAttrib[j];
1261fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1262fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
12636a3fdc3a1ea6c306d9543791bf172dd1052d7382Keith Whitwell   for (i = VBO_ATTRIB_FIRST_MATERIAL; i <= VBO_ATTRIB_LAST_MATERIAL; i++) {
1264fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      const GLuint j = i - VBO_ATTRIB_FIRST_MATERIAL;
1265fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ASSERT(j < MAT_ATTRIB_MAX);
1266fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j];
1267fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->current[i] = ctx->ListState.CurrentMaterial[j];
1268fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1269fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1270fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1271fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/**
1272fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * Initialize the display list compiler
1273fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
1274fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellvoid vbo_save_api_init( struct vbo_save_context *save )
1275fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1276f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg   struct gl_context *ctx = save->ctx;
1277fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
1278fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1279fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->opcode_vertex_list =
12806e1697bee72a95f7d605e42ce60e2cb4a545106fBrian Paul      _mesa_dlist_alloc_opcode( ctx,
12816e1697bee72a95f7d605e42ce60e2cb4a545106fBrian Paul                                sizeof(struct vbo_save_vertex_list),
12826e1697bee72a95f7d605e42ce60e2cb4a545106fBrian Paul                                vbo_save_playback_vertex_list,
12836e1697bee72a95f7d605e42ce60e2cb4a545106fBrian Paul                                vbo_destroy_vertex_list,
12846e1697bee72a95f7d605e42ce60e2cb4a545106fBrian Paul                                vbo_print_vertex_list );
1285fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1286fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.NotifySaveBegin = vbo_save_NotifyBegin;
1287fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1288fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_vtxfmt_init( ctx );
1289fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_current_init( ctx );
1290fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
129137c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul   /* These will actually get set again when binding/drawing */
1292fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0; i < VBO_ATTRIB_MAX; i++)
1293fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->inputs[i] = &save->arrays[i];
1294fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1295fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Hook our array functions into the outside-begin-end vtxfmt in
1296fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * ctx->ListState.
1297fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
1298fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf;
1299fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays;
1300fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements;
1301fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements;
130260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   /* loops back into _save_OBE_DrawElements */
130360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   ctx->ListState.ListVtxfmt.MultiDrawElementsEXT = _mesa_noop_MultiDrawElements;
130492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   ctx->ListState.ListVtxfmt.MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;
1305fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
1306fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1307fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
13088d5c83c467f83b44f5f2e271c4f9cca2d45af518Chia-I Wu
13098d5c83c467f83b44f5f2e271c4f9cca2d45af518Chia-I Wu#endif /* FEATURE_dlist */
1310