vbo_save_api.c revision 92d7ed8a20d4a018ce5324e6537ae7b478b9e5bf
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"
75c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/macros.h"
7660b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt#include "main/api_noop.h"
77c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/api_validate.h"
78c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/api_arrayelt.h"
79c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "main/vtxfmt.h"
80c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "glapi/dispatch.h"
81fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
82fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "vbo_context.h"
83fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
84fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
8537aca21129d87946d2dc6b45fa5bacd514921550zhang#ifdef ERROR
8637aca21129d87946d2dc6b45fa5bacd514921550zhang#undef ERROR
8737aca21129d87946d2dc6b45fa5bacd514921550zhang#endif
8837aca21129d87946d2dc6b45fa5bacd514921550zhang
89fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
9037c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul/* An interesting VBO number/name to help with debugging */
9137c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul#define VBO_BUF_ID  12345
9237c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul
9337c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul
94fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/*
95fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * NOTE: Old 'parity' issue is gone, but copying can still be
96fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * wrong-footed on replay.
97fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
98fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic GLuint _save_copy_vertices( GLcontext *ctx,
99fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				   const struct vbo_save_vertex_list *node,
100fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				   const GLfloat *src_buffer)
101fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
102fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context( ctx )->save;
103fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   const struct _mesa_prim *prim = &node->prim[node->prim_count-1];
104fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint nr = prim->count;
105fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint sz = save->vertex_size;
106fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   const GLfloat *src = src_buffer + prim->start * sz;
107fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLfloat *dst = save->copied.buffer;
108fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint ovf, i;
109fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
110fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (prim->end)
111fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return 0;
112fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
113fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   switch( prim->mode )
114fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   {
115fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_POINTS:
116fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return 0;
117fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_LINES:
118fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ovf = nr&1;
119fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < ovf ; i++)
120fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
121fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return i;
122fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_TRIANGLES:
123fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ovf = nr%3;
124fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < ovf ; i++)
125fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
126fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return i;
127fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_QUADS:
128fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ovf = nr&3;
129fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < ovf ; i++)
130fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
131fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return i;
132fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_LINE_STRIP:
133fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (nr == 0)
134fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 return 0;
135fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      else {
136fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _mesa_memcpy( dst, src+(nr-1)*sz, sz*sizeof(GLfloat) );
137fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 return 1;
138fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
139fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_LINE_LOOP:
140fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_TRIANGLE_FAN:
141fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_POLYGON:
142fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (nr == 0)
143fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 return 0;
144fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      else if (nr == 1) {
145fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) );
146fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 return 1;
147fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      } else {
148fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) );
149fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _mesa_memcpy( dst+sz, src+(nr-1)*sz, sz*sizeof(GLfloat) );
150fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 return 2;
151fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
152fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_TRIANGLE_STRIP:
153fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_QUAD_STRIP:
154fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      switch (nr) {
155fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 0: ovf = 0; break;
156fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 1: ovf = 1; break;
157fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      default: ovf = 2 + (nr&1); break;
158fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
159fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < ovf ; i++)
160fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
161fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return i;
162fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   default:
163fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(0);
164fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return 0;
165fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
166fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
167fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
168fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
169fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic struct vbo_save_vertex_store *alloc_vertex_store( GLcontext *ctx )
170fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
171fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_vertex_store *vertex_store = CALLOC_STRUCT(vbo_save_vertex_store);
172fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
173fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* obj->Name needs to be non-zero, but won't ever be examined more
174fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * closely than that.  In particular these buffers won't be entered
175fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * into the hash and can never be confused with ones visible to the
176fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * user.  Perhaps there could be a special number for internal
177fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * buffers:
178fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
17937c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul   vertex_store->bufferobj = ctx->Driver.NewBufferObject(ctx,
18037c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul                                                         VBO_BUF_ID,
18137c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul                                                         GL_ARRAY_BUFFER_ARB);
182fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
183fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.BufferData( ctx,
184fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			   GL_ARRAY_BUFFER_ARB,
185fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			   VBO_SAVE_BUFFER_SIZE * sizeof(GLfloat),
186fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			   NULL,
187fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			   GL_STATIC_DRAW_ARB,
188fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			   vertex_store->bufferobj);
189fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
190fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->buffer = NULL;
191fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->used = 0;
192fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->refcount = 1;
193fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
194fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return vertex_store;
195fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
196fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
197fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void free_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store *vertex_store )
198fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
199fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(!vertex_store->buffer);
200fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
20137c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul   if (vertex_store->bufferobj) {
20237c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul      _mesa_reference_buffer_object(ctx, &vertex_store->bufferobj, NULL);
20337c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul   }
204fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
205fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   FREE( vertex_store );
206fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
207fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
208fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic GLfloat *map_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store *vertex_store )
209fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
210fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(vertex_store->bufferobj);
211fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(!vertex_store->buffer);
212fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->buffer = (GLfloat *)ctx->Driver.MapBuffer(ctx,
213fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell							   GL_ARRAY_BUFFER_ARB,	/* not used */
2142cb3594af9cd1434aa2c408cd6f8d51bcd12e8eaAapo Tahkola							   GL_WRITE_ONLY, /* not used */
215fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell							   vertex_store->bufferobj);
216fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
217fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(vertex_store->buffer);
218fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return vertex_store->buffer + vertex_store->used;
219fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
220fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
221fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void unmap_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store *vertex_store )
222fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
223fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.UnmapBuffer( ctx, GL_ARRAY_BUFFER_ARB, vertex_store->bufferobj );
224fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->buffer = NULL;
225fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
226fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
227fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
228fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic struct vbo_save_primitive_store *alloc_prim_store( GLcontext *ctx )
229fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
230fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_primitive_store *store = CALLOC_STRUCT(vbo_save_primitive_store);
231fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) ctx;
232fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   store->used = 0;
233fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   store->refcount = 1;
234fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return store;
235fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
236fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
237fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_reset_counters( GLcontext *ctx )
238fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
239fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
240fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
241fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim = save->prim_store->buffer + save->prim_store->used;
242fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->buffer = (save->vertex_store->buffer +
243fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		   save->vertex_store->used);
244fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
245c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell   assert(save->buffer == save->buffer_ptr);
246fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
247fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->vertex_size)
248fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) /
249fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			 save->vertex_size);
250fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   else
251fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->max_vert = 0;
252fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
253fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vert_count = 0;
254fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_count = 0;
255fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_max = VBO_SAVE_PRIM_SIZE - save->prim_store->used;
256fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->dangling_attr_ref = 0;
257fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
258fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
259fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
260fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Insert the active immediate struct onto the display list currently
261fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * being built.
262fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
263fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_compile_vertex_list( GLcontext *ctx )
264fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
265fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
266fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_vertex_list *node;
267fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
268fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Allocate space for this structure in the display list currently
269fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * being compiled.
270fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
271fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node = (struct vbo_save_vertex_list *)
272fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _mesa_alloc_instruction(ctx, save->opcode_vertex_list, sizeof(*node));
273fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
274fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!node)
275fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
276fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
277fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Duplicate our template, increment refcounts to the storage structs:
278fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
279fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz));
280fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->vertex_size = save->vertex_size;
281fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->buffer_offset = (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat);
282fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->count = save->vert_count;
283fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->wrap_count = save->copied.nr;
284fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->dangling_attr_ref = save->dangling_attr_ref;
285fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim = save->prim;
286fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim_count = save->prim_count;
287fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->vertex_store = save->vertex_store;
288fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim_store = save->prim_store;
289fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
290fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->vertex_store->refcount++;
291fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim_store->refcount++;
292fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
2938b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell
2948b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell   node->current_size = node->vertex_size - node->attrsz[0];
2958b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell   node->current_data = NULL;
2968b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell
2978b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell   if (node->current_size) {
2988b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell      /* If the malloc fails, we just pull the data out of the VBO
2998b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell       * later instead.
3008b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell       */
3018b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell      node->current_data = MALLOC( node->current_size * sizeof(GLfloat) );
3028b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell      if (node->current_data) {
3038b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell         const char *buffer = (const char *)save->vertex_store->buffer;
3048b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell         unsigned attr_offset = node->attrsz[0] * sizeof(GLfloat);
3058b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell         unsigned vertex_offset = 0;
3068b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell
3078b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell         if (node->count)
3088b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell            vertex_offset = (node->count-1) * node->vertex_size * sizeof(GLfloat);
3098b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell
3108b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell         memcpy( node->current_data,
3118b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell                 buffer + node->buffer_offset + vertex_offset + attr_offset,
3128b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell                 node->current_size * sizeof(GLfloat) );
3138b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell      }
3148b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell   }
3158b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell
3168b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell
3178b2ebd15310cbd5d905b08761b5e950f8e2580e5Keith Whitwell
318fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(node->attrsz[VBO_ATTRIB_POS] != 0 ||
319fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	  node->count == 0);
320fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
321fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->dangling_attr_ref)
322446abc2799a143c32c4c48472f3f964f9288a623Brian      ctx->ListState.CurrentList->Flags |= DLIST_DANGLING_REFS;
323fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
324fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vertex_store->used += save->vertex_size * node->count;
325fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_store->used += node->prim_count;
326fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
327fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
328fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Copy duplicated vertices
329fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
330fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->copied.nr = _save_copy_vertices( ctx, node, save->buffer );
331fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
332fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
333fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Deal with GL_COMPILE_AND_EXECUTE:
334fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
335fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->ExecuteFlag) {
336fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      struct _glapi_table *dispatch = GET_DISPATCH();
337fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
338fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _glapi_set_dispatch(ctx->Exec);
339fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
340fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      vbo_loopback_vertex_list( ctx,
341fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				(const GLfloat *)((const char *)save->vertex_store->buffer +
342fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell						  node->buffer_offset),
343fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				node->attrsz,
344fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				node->prim,
345fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				node->prim_count,
346fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				node->wrap_count,
347fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				node->vertex_size);
348fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
349fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _glapi_set_dispatch(dispatch);
350fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
351fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
352fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
353fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Decide whether the storage structs are full, or can be used for
354fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * the next vertex lists as well.
355fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
356fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->vertex_store->used >
357fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       VBO_SAVE_BUFFER_SIZE - 16 * (save->vertex_size + 4)) {
358fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
359fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Unmap old store:
360fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
361fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      unmap_vertex_store( ctx, save->vertex_store );
362fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
363fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Release old reference:
364fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
365fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vertex_store->refcount--;
366fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(save->vertex_store->refcount != 0);
367fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vertex_store = NULL;
368fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
369fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Allocate and map new store:
370fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
371fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vertex_store = alloc_vertex_store( ctx );
372c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell      save->buffer_ptr = map_vertex_store( ctx, save->vertex_store );
373fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
374fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
375fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->prim_store->used > VBO_SAVE_PRIM_SIZE - 6) {
376fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->prim_store->refcount--;
377fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(save->prim_store->refcount != 0);
378fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->prim_store = alloc_prim_store( ctx );
379fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
380fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
381fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Reset our structures for the next run of vertices:
382fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
383fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_counters( ctx );
384fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
385fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
386fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
387fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* TODO -- If no new vertices have been stored, don't bother saving
388fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * it.
389fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
390fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_wrap_buffers( GLcontext *ctx )
391fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
392fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
393fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i = save->prim_count - 1;
394fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLenum mode;
395fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLboolean weak;
396fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
397fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(i < (GLint) save->prim_max);
398fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(i >= 0);
399fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
400fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Close off in-progress primitive.
401fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
402fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].count = (save->vert_count -
403fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			  save->prim[i].start);
404fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   mode = save->prim[i].mode;
405fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   weak = save->prim[i].weak;
406fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
407fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* store the copied vertices, and allocate a new list.
408fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
409fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_compile_vertex_list( ctx );
410fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
411fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Restart interrupted primitive
412fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
413fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].mode = mode;
414fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].weak = weak;
415fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].begin = 0;
416fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].end = 0;
417fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].pad = 0;
418fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].start = 0;
419fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].count = 0;
420fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_count = 1;
421fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
422fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
423fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
424fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
425fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Called only when buffers are wrapped as the result of filling the
426fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * vertex_store struct.
427fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
428fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_wrap_filled_vertex( GLcontext *ctx )
429fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
430fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
431fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLfloat *data = save->copied.buffer;
432fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
433fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
434fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Emit a glEnd to close off the last vertex list.
435fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
436fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_wrap_buffers( ctx );
437fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
438fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    /* Copy stored stored vertices to start of new list.
439fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
440fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(save->max_vert - save->vert_count > save->copied.nr);
441fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
442fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0 ; i < save->copied.nr ; i++) {
443c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell      _mesa_memcpy( save->buffer_ptr, data, save->vertex_size * sizeof(GLfloat));
444fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      data += save->vertex_size;
445c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell      save->buffer_ptr += save->vertex_size;
446fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vert_count++;
447fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
448fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
449fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
450fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
451fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_copy_to_current( GLcontext *ctx )
452fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
453fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
454fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
455fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
4562421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell   for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
457fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (save->attrsz[i]) {
458fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->currentsz[i][0] = save->attrsz[i];
459fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 COPY_CLEAN_4V(save->current[i],
4602421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell		       save->attrsz[i],
4612421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell		       save->attrptr[i]);
462fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
463fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
464fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
465fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
466fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
467fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_copy_from_current( GLcontext *ctx )
468fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
469fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
470fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
471fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
4722421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell   for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
473fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      switch (save->attrsz[i]) {
474fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 4: save->attrptr[i][3] = save->current[i][3];
475fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 3: save->attrptr[i][2] = save->current[i][2];
476fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 2: save->attrptr[i][1] = save->current[i][1];
477fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 1: save->attrptr[i][0] = save->current[i][0];
478fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 0: break;
479fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
480fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
481fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
482fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
483fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
484fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
485fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
486fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Flush existing data, set new attrib size, replay copied vertices.
487fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
488fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_upgrade_vertex( GLcontext *ctx,
489fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				 GLuint attr,
490fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				 GLuint newsz )
491fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
492fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
493fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint oldsz;
494fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
495fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLfloat *tmp;
496fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
497fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Store the current run of vertices, and emit a GL_END.  Emit a
498fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * BEGIN in the new buffer.
499fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
500fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->vert_count)
501fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_wrap_buffers( ctx );
502fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   else
503fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert( save->copied.nr == 0 );
504fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
505fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
506fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * when the attribute already exists in the vertex and is having
507fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * its size increased.
508fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
509fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_copy_to_current( ctx );
510fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
511fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Fix up sizes:
512fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
513fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   oldsz = save->attrsz[attr];
514fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->attrsz[attr] = newsz;
515fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
516fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vertex_size += newsz - oldsz;
517fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) /
518fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		      save->vertex_size);
519fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vert_count = 0;
520fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
521fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Recalculate all the attrptr[] values:
522fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
523fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0, tmp = save->vertex ; i < VBO_ATTRIB_MAX ; i++) {
524fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (save->attrsz[i]) {
525fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->attrptr[i] = tmp;
526fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 tmp += save->attrsz[i];
527fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
528fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      else
529fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->attrptr[i] = NULL; /* will not be dereferenced. */
530fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
531fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
532fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Copy from current to repopulate the vertex with correct values.
533fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
534fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_copy_from_current( ctx );
535fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
536fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Replay stored vertices to translate them to new format here.
537fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    *
538fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * If there are copied vertices and the new (upgraded) attribute
539fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * has not been defined before, this list is somewhat degenerate,
540fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * and will need fixup at runtime.
541fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
542fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->copied.nr)
543fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   {
544fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLfloat *data = save->copied.buffer;
545fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLfloat *dest = save->buffer;
546fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLuint j;
547fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
548fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Need to note this and fix up at runtime (or loopback):
549fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
550dd60eaa6d9f61735141976db0e83d25176ac73c7Keith Whitwell      if (attr != VBO_ATTRIB_POS && save->currentsz[attr][0] == 0) {
551fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 assert(oldsz == 0);
552fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->dangling_attr_ref = GL_TRUE;
553fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
554fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
555fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < save->copied.nr ; i++) {
556fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) {
557fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	    if (save->attrsz[j]) {
558fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	       if (j == attr) {
559fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  if (oldsz) {
560fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		     COPY_CLEAN_4V( dest, oldsz, data );
561fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		     data += oldsz;
562fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		     dest += newsz;
563fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  }
564fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  else {
565fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		     COPY_SZ_4V( dest, newsz, save->current[attr] );
566fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		     dest += newsz;
567fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  }
568fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	       }
569fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	       else {
570fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  GLint sz = save->attrsz[j];
571fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  COPY_SZ_4V( dest, sz, data );
572fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  data += sz;
573fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  dest += sz;
574fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	       }
575fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	    }
576fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 }
577fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
578fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
579c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell      save->buffer_ptr = dest;
580fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vert_count += save->copied.nr;
581fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
582fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
583fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
584fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void save_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz )
585fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
586fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
587fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
588fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (sz > save->attrsz[attr]) {
589fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* New size is larger.  Need to flush existing vertices and get
590fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * an enlarged vertex format.
591fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
592fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_upgrade_vertex( ctx, attr, sz );
593fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
594fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   else if (sz < save->active_sz[attr]) {
595fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      static GLfloat id[4] = { 0, 0, 0, 1 };
596fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLuint i;
597fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
598fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* New size is equal or smaller - just need to fill in some
599fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * zeros.
600fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
601fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = sz ; i <= save->attrsz[attr] ; i++)
602fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->attrptr[attr][i-1] = id[i-1];
603fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
604fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
605fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->active_sz[attr] = sz;
606fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
607fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
608fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_reset_vertex( GLcontext *ctx )
609fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
610fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
611fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
612fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
613fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
614fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->attrsz[i] = 0;
615fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->active_sz[i] = 0;
616fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
617fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
618fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vertex_size = 0;
619fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
620fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
621fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
622fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
623fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#define ERROR()   _mesa_compile_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );
624fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
625fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
626fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Only one size for each attribute may be active at once.  Eg. if
627fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * Color3f is installed/active, then Color4f may not be, even if the
628fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * vertex actually contains 4 color coordinates.  This is because the
629fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * 3f version won't otherwise set color[3] to 1.0 -- this is the job
630fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * of the chooser function when switching between Color4f and Color3f.
631fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
632fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#define ATTR( A, N, V0, V1, V2, V3 )				\
633fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwelldo {								\
634fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;	\
635fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
636fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->active_sz[A] != N)				\
637fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save_fixup_vertex(ctx, A, N);				\
638fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
639fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   {								\
640fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLfloat *dest = save->attrptr[A];			\
641fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>0) dest[0] = V0;					\
642fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>1) dest[1] = V1;					\
643fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>2) dest[2] = V2;					\
644fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>3) dest[3] = V3;					\
645fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }								\
646fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
647fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if ((A) == 0) {						\
648fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLuint i;							\
649fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
650fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0; i < save->vertex_size; i++)			\
651c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell	 save->buffer_ptr[i] = save->vertex[i];			\
652fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
653c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell      save->buffer_ptr += save->vertex_size;				\
654fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
655fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (++save->vert_count >= save->max_vert)			\
656fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _save_wrap_filled_vertex( ctx );			\
657fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }								\
658fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell} while (0)
659fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
660fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#define TAG(x) _save_##x
661fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
662fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "vbo_attrib_tmp.h"
663fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
664fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
665fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
666fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
667fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Cope with EvalCoord/CallList called within a begin/end object:
668fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *     -- Flush current buffer
669fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *     -- Fallback to opcodes for the rest of the begin/end object.
670fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
6711fa4cde757cc94c0afa40d855309911247974e98Keith Whitwellstatic void DO_FALLBACK( GLcontext *ctx )
6721fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell{
6731fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
6741fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell
6751fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   if (save->vert_count || save->prim_count) {
6761fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell      GLint i = save->prim_count - 1;
6771fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell
6781fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell      /* Close off in-progress primitive.
6791fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell       */
6801fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell      save->prim[i].count = (save->vert_count -
6811fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell                             save->prim[i].start);
6821fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell
6831fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell      /* Need to replay this display list with loopback,
6841fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell       * unfortunately, otherwise this primitive won't be handled
6851fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell       * properly:
6861fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell       */
6871fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell      save->dangling_attr_ref = 1;
6881fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell
6891fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell      _save_compile_vertex_list( ctx );
6901fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   }
6911fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell
6921fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   _save_copy_to_current( ctx );
6931fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   _save_reset_vertex( ctx );
6941fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   _save_reset_counters( ctx );
6951fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
6961fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell   ctx->Driver.SaveNeedFlush = 0;
6971fa4cde757cc94c0afa40d855309911247974e98Keith Whitwell}
698fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
699fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalCoord1f( GLfloat u )
700fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
701fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
702fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
703fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->EvalCoord1f( u );
704fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
705fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
706fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalCoord1fv( const GLfloat *v )
707fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
708fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
709fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
710fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->EvalCoord1fv( v );
711fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
712fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
713fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalCoord2f( GLfloat u, GLfloat v )
714fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
715fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
716fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
717fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->EvalCoord2f( u, v );
718fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
719fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
720fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalCoord2fv( const GLfloat *v )
721fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
722fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
723fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
724fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->EvalCoord2fv( v );
725fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
726fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
727fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalPoint1( GLint i )
728fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
729fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
730fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
731fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->EvalPoint1( i );
732fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
733fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
734fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalPoint2( GLint i, GLint j )
735fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
736fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
737fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
738fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->EvalPoint2( i, j );
739fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
740fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
741fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_CallList( GLuint l )
742fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
743fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
744fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
745fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->CallList( l );
746fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
747fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
748fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_CallLists( GLsizei n, GLenum type, const GLvoid *v )
749fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
750fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
751fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
752fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->CallLists( n, type, v );
753fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
754fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
755fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
756fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
757fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
758fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* This begin is hooked into ...  Updating of
759fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * ctx->Driver.CurrentSavePrimitive is already taken care of.
760fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
761fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith WhitwellGLboolean vbo_save_NotifyBegin( GLcontext *ctx, GLenum mode )
762fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
763fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
764fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
765fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i = save->prim_count++;
766fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
767fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(i < save->prim_max);
768fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].mode = mode & ~VBO_SAVE_PRIM_WEAK;
769fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].begin = 1;
770fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].end = 0;
771fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0;
772fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].pad = 0;
773fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].start = save->vert_count;
774fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].count = 0;
775fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
776fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_install_save_vtxfmt( ctx, &save->vtxfmt );
777fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 1;
778fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return GL_TRUE;
779fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
780fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
781fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
782fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
783fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_End( void )
784fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
785fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT( ctx );
786fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
787fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i = save->prim_count - 1;
788fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
789fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
790fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].end = 1;
791fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].count = (save->vert_count -
792fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			  save->prim[i].start);
793fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
794fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (i == (GLint) save->prim_max - 1) {
795fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_compile_vertex_list( ctx );
796fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(save->copied.nr == 0);
797fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
798fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
799fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Swap out this vertex format while outside begin/end.  Any color,
800fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * etc. received between here and the next begin will be compiled
801fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * as opcodes.
802fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
803fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
804fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
805fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
806fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
807fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* These are all errors as this vtxfmt is only installed inside
808fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * begin/end pairs.
809fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
810fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_DrawElements(GLenum mode, GLsizei count, GLenum type,
811fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			       const GLvoid *indices)
812fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
813fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
814fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode; (void) count; (void) type; (void) indices;
815fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" );
816fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
817fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
818fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
819fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_DrawRangeElements(GLenum mode,
820fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				    GLuint start, GLuint end,
821fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				    GLsizei count, GLenum type,
822fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				    const GLvoid *indices)
823fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
824fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
825fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode; (void) start; (void) end; (void) count; (void) type; (void) indices;
826fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" );
827fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
828fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
82992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtstatic void GLAPIENTRY _save_DrawElementsBaseVertex(GLenum mode,
83092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt						    GLsizei count,
83192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt						    GLenum type,
83292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt						    const GLvoid *indices,
83392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt						    GLint basevertex)
83492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt{
83592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   GET_CURRENT_CONTEXT(ctx);
83692d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   (void) mode; (void) count; (void) type; (void) indices; (void)basevertex;
83792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
83892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" );
83992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
84092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
84192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholtstatic void GLAPIENTRY _save_DrawRangeElementsBaseVertex(GLenum mode,
84292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt							 GLuint start,
84392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt							 GLuint end,
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) start; (void) end; (void) count; (void) type;
85192d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   (void) indices; (void)basevertex;
85292d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
85392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" );
85492d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt}
85592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt
856fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count)
857fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
858fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
859fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode; (void) start; (void) count;
860fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" );
861fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
862fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
863fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
864fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
865fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
866fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) x1; (void) y1; (void) x2; (void) y2;
867fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glRectf" );
868fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
869fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
870fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
871fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
872fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
873fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode; (void) i1; (void) i2;
874fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh1" );
875fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
876fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
877fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalMesh2( GLenum mode, GLint i1, GLint i2,
878fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				  GLint j1, GLint j2 )
879fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
880fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
881fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode; (void) i1; (void) i2; (void) j1; (void) j2;
882fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh2" );
883fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
884fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
885fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_Begin( GLenum mode )
886fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
887fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT( ctx );
888fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode;
889fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "Recursive glBegin" );
890fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
891fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
892fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
893fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Unlike the functions above, these are to be hooked into the vtxfmt
894fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * maintained in ctx->ListState, active when the list is known or
895fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * suspected to be outside any begin/end primitive.
896fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
897fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
898fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
899fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
900fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vbo_save_NotifyBegin( ctx, GL_QUADS | VBO_SAVE_PRIM_WEAK );
901fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_Vertex2f(GET_DISPATCH(), ( x1, y1 ));
902fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_Vertex2f(GET_DISPATCH(), ( x2, y1 ));
903fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_Vertex2f(GET_DISPATCH(), ( x2, y2 ));
904fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_Vertex2f(GET_DISPATCH(), ( x1, y2 ));
905fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_End(GET_DISPATCH(), ());
906fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
907fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
908fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
909fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count)
910fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
911fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
912fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
913fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
914fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
915fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
916fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
917b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell   _ae_map_vbos( ctx );
918b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
919fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK );
9206a3fdc3a1ea6c306d9543791bf172dd1052d7382Keith Whitwell
921fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0; i < count; i++)
922fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       CALL_ArrayElement(GET_DISPATCH(), (start + i));
923fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_End(GET_DISPATCH(), ());
924b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
925b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell   _ae_unmap_vbos( ctx );
926fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
927fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
928fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Could do better by copying the arrays and element list intact and
929fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * then emitting an indexed prim at runtime.
930fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
931fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type,
932fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				   const GLvoid *indices)
933fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
934fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
935fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
936fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
93792d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))
938fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
939fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
940b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell   _ae_map_vbos( ctx );
941b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
942bd4c6a2e503db43e81ef41f77d876308badd93ebBrian Paul   if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj))
943982dcb74fd19b88208d127b8019e2a2af979cac2Xiang, Haihao      indices = ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Pointer, indices);
944982dcb74fd19b88208d127b8019e2a2af979cac2Xiang, Haihao
945fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK );
946fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
947fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   switch (type) {
948fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_BYTE:
949fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < count ; i++)
950fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	  CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] ));
951fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
952fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_SHORT:
953fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < count ; i++)
954fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	  CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] ));
955fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
956fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_INT:
957fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < count ; i++)
958fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	  CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] ));
959fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
960fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   default:
961fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
962fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
963fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
964fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
965fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_End(GET_DISPATCH(), ());
966b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
967b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell   _ae_unmap_vbos( ctx );
968fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
969fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
970fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode,
971fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell					GLuint start, GLuint end,
972fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell					GLsizei count, GLenum type,
973fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell					const GLvoid *indices)
974fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
975fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
976fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (_mesa_validate_DrawRangeElements( ctx, mode,
977fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell					 start, end,
97892d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt					 count, type, indices, 0 ))
979fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_OBE_DrawElements( mode, count, type, indices );
980fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
981fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
982fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
983fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
984fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
985fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
986fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_vtxfmt_init( GLcontext *ctx )
987fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
988fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
989fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLvertexformat *vfmt = &save->vtxfmt;
990fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
991fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->ArrayElement = _ae_loopback_array_elt;	        /* generic helper */
992fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Begin = _save_Begin;
993fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color3f = _save_Color3f;
994fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color3fv = _save_Color3fv;
995fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color4f = _save_Color4f;
996fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color4fv = _save_Color4fv;
997fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EdgeFlag = _save_EdgeFlag;
998fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->End = _save_End;
999fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->FogCoordfEXT = _save_FogCoordfEXT;
1000fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->FogCoordfvEXT = _save_FogCoordfvEXT;
1001fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Indexf = _save_Indexf;
1002fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Indexfv = _save_Indexfv;
1003fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Materialfv = _save_Materialfv;
1004fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f;
1005fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv;
1006fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f;
1007fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv;
1008fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f;
1009fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv;
1010fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f;
1011fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv;
1012fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Normal3f = _save_Normal3f;
1013fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Normal3fv = _save_Normal3fv;
1014fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT;
1015fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT;
1016fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord1f = _save_TexCoord1f;
1017fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord1fv = _save_TexCoord1fv;
1018fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord2f = _save_TexCoord2f;
1019fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord2fv = _save_TexCoord2fv;
1020fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord3f = _save_TexCoord3f;
1021fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord3fv = _save_TexCoord3fv;
1022fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord4f = _save_TexCoord4f;
1023fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord4fv = _save_TexCoord4fv;
1024fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex2f = _save_Vertex2f;
1025fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex2fv = _save_Vertex2fv;
1026fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex3f = _save_Vertex3f;
1027fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex3fv = _save_Vertex3fv;
1028fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex4f = _save_Vertex4f;
1029fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex4fv = _save_Vertex4fv;
1030fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB;
1031fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB;
1032fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB;
1033fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB;
1034fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB;
1035fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB;
1036fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB;
1037fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB;
1038fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1039fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV;
1040fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV;
1041fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV;
1042fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV;
1043fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV;
1044fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV;
1045fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV;
1046fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV;
1047fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1048fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* This will all require us to fallback to saving the list as opcodes:
1049fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
1050fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->CallList = _save_CallList; /* inside begin/end */
1051fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->CallLists = _save_CallLists; /* inside begin/end */
1052fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalCoord1f = _save_EvalCoord1f;
1053fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalCoord1fv = _save_EvalCoord1fv;
1054fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalCoord2f = _save_EvalCoord2f;
1055fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalCoord2fv = _save_EvalCoord2fv;
1056fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalPoint1 = _save_EvalPoint1;
1057fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalPoint2 = _save_EvalPoint2;
1058fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1059fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* These are all errors as we at least know we are in some sort of
1060fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * begin/end pair:
1061fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
1062fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalMesh1 = _save_EvalMesh1;
1063fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalMesh2 = _save_EvalMesh2;
1064fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Begin = _save_Begin;
1065fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Rectf = _save_Rectf;
1066fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->DrawArrays = _save_DrawArrays;
1067fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->DrawElements = _save_DrawElements;
1068fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->DrawRangeElements = _save_DrawRangeElements;
106992d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vfmt->DrawElementsBaseVertex = _save_DrawElementsBaseVertex;
107092d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vfmt->DrawRangeElementsBaseVertex = _save_DrawRangeElementsBaseVertex;
107160b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   /* Loops back into vfmt->DrawElements */
107260b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   vfmt->MultiDrawElementsEXT = _mesa_noop_MultiDrawElements;
107392d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   vfmt->MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;
1074fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1075fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1076fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1077fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellvoid vbo_save_SaveFlushVertices( GLcontext *ctx )
1078fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1079fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1080fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1081fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Noop when we are actually active:
1082fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
1083fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM ||
1084fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       ctx->Driver.CurrentSavePrimitive <= GL_POLYGON)
1085fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
1086fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1087fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->vert_count ||
1088fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       save->prim_count)
1089fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_compile_vertex_list( ctx );
1090fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1091fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_copy_to_current( ctx );
1092fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_vertex( ctx );
1093fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_counters( ctx );
1094fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 0;
1095fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1096fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1097fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellvoid vbo_save_NewList( GLcontext *ctx, GLuint list, GLenum mode )
1098fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1099fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1100fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1101fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) list; (void) mode;
1102fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1103fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!save->prim_store)
1104fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->prim_store = alloc_prim_store( ctx );
1105fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1106fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!save->vertex_store)
1107fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vertex_store = alloc_vertex_store( ctx );
1108fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1109c4d1f4607abf3dfbcfcffc5c67bb89d420d3381aKeith Whitwell   save->buffer_ptr = map_vertex_store( ctx, save->vertex_store );
1110fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1111fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_vertex( ctx );
1112fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_counters( ctx );
1113fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 0;
1114fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1115fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1116fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellvoid vbo_save_EndList( GLcontext *ctx )
1117fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1118fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1119bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1120bd953e872f22690bd232a758383883100d9347d0Keith Whitwell   /* EndList called inside a (saved) Begin/End pair?
1121bd953e872f22690bd232a758383883100d9347d0Keith Whitwell    */
1122bd953e872f22690bd232a758383883100d9347d0Keith Whitwell   if (ctx->Driver.CurrentSavePrimitive != PRIM_OUTSIDE_BEGIN_END) {
1123bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1124d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul      if (save->prim_count > 0) {
1125d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul         GLint i = save->prim_count - 1;
1126d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul         ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
1127d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul         save->prim[i].end = 0;
1128d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul         save->prim[i].count = (save->vert_count -
1129d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul                                save->prim[i].start);
1130d43951192baa7b76d3e035d689f73c1d2955cddbBrian Paul      }
1131bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1132bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      /* Make sure this vertex list gets replayed by the "loopback"
1133bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       * mechanism:
1134bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       */
1135bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      save->dangling_attr_ref = 1;
1136bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      vbo_save_SaveFlushVertices( ctx );
1137bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1138bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      /* Swap out this vertex format while outside begin/end.  Any color,
1139bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       * etc. received between here and the next begin will be compiled
1140bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       * as opcodes.
1141bd953e872f22690bd232a758383883100d9347d0Keith Whitwell       */
1142bd953e872f22690bd232a758383883100d9347d0Keith Whitwell      _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
1143bd953e872f22690bd232a758383883100d9347d0Keith Whitwell   }
1144bd953e872f22690bd232a758383883100d9347d0Keith Whitwell
1145fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   unmap_vertex_store( ctx, save->vertex_store );
1146fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1147fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(save->vertex_size == 0);
1148fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1149fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1150446abc2799a143c32c4c48472f3f964f9288a623Brianvoid vbo_save_BeginCallList( GLcontext *ctx, struct gl_display_list *dlist )
1151fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1152fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1153446abc2799a143c32c4c48472f3f964f9288a623Brian   save->replay_flags |= dlist->Flags;
1154fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1155fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1156fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellvoid vbo_save_EndCallList( GLcontext *ctx )
1157fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1158fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1159fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1160fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->ListState.CallDepth == 1) {
1161fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* This is correct: want to keep only the VBO_SAVE_FALLBACK
1162fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * flag, if it is set:
1163fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
1164fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->replay_flags &= VBO_SAVE_FALLBACK;
1165fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1166fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1167fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1168fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1169fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void vbo_destroy_vertex_list( GLcontext *ctx, void *data )
1170fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1171fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *)data;
1172fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) ctx;
1173fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1174fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if ( --node->vertex_store->refcount == 0 )
1175fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      free_vertex_store( ctx, node->vertex_store );
1176fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1177fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if ( --node->prim_store->refcount == 0 )
1178fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      FREE( node->prim_store );
1179ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul
1180ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul   if (node->current_data) {
1181ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul      FREE(node->current_data);
1182ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul      node->current_data = NULL;
1183ca1b71b78d9c31e9ea7ceed2542ec67f32e6e5c5Brian Paul   }
1184fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1185fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1186fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1187fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void vbo_print_vertex_list( GLcontext *ctx, void *data )
1188fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1189fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *)data;
1190fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
1191fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) ctx;
1192fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1193396b4043f085ec09a074447bbbb835c53aa82b7bEric Anholt   _mesa_printf("VBO-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n",
1194396b4043f085ec09a074447bbbb835c53aa82b7bEric Anholt		node->count,
1195396b4043f085ec09a074447bbbb835c53aa82b7bEric Anholt		node->prim_count,
1196396b4043f085ec09a074447bbbb835c53aa82b7bEric Anholt		node->vertex_size);
1197fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1198fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0 ; i < node->prim_count ; i++) {
1199fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      struct _mesa_prim *prim = &node->prim[i];
1200fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _mesa_debug(NULL, "   prim %d: %s%s %d..%d %s %s\n",
1201fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  i,
12020846c88ec3a63ac5e4096aedcdc107cbe71f306bKeith Whitwell		  _mesa_lookup_prim_by_nr(prim->mode),
1203fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  prim->weak ? " (weak)" : "",
1204fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  prim->start,
1205fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  prim->start + prim->count,
1206fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  (prim->begin) ? "BEGIN" : "(wrap)",
1207fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  (prim->end) ? "END" : "(wrap)");
1208fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1209fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1210fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1211fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1212fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_current_init( GLcontext *ctx )
1213fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1214fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1215fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
1216fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
12172421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell   for (i = VBO_ATTRIB_POS; i <= VBO_ATTRIB_GENERIC15; i++) {
12182421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      const GLuint j = i - VBO_ATTRIB_POS;
12192421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      ASSERT(j < VERT_ATTRIB_MAX);
12202421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      save->currentsz[i] = &ctx->ListState.ActiveAttribSize[j];
12212421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      save->current[i] = ctx->ListState.CurrentAttrib[j];
1222fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1223fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
12246a3fdc3a1ea6c306d9543791bf172dd1052d7382Keith Whitwell   for (i = VBO_ATTRIB_FIRST_MATERIAL; i <= VBO_ATTRIB_LAST_MATERIAL; i++) {
1225fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      const GLuint j = i - VBO_ATTRIB_FIRST_MATERIAL;
1226fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ASSERT(j < MAT_ATTRIB_MAX);
1227fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j];
1228fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->current[i] = ctx->ListState.CurrentMaterial[j];
1229fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1230fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1231fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1232fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/**
1233fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * Initialize the display list compiler
1234fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
1235fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellvoid vbo_save_api_init( struct vbo_save_context *save )
1236fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1237fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLcontext *ctx = save->ctx;
1238fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
1239fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1240fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->opcode_vertex_list =
1241fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _mesa_alloc_opcode( ctx,
1242fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			  sizeof(struct vbo_save_vertex_list),
1243fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			  vbo_save_playback_vertex_list,
1244fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			  vbo_destroy_vertex_list,
1245fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			  vbo_print_vertex_list );
1246fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1247fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.NotifySaveBegin = vbo_save_NotifyBegin;
1248fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1249fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_vtxfmt_init( ctx );
1250fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_current_init( ctx );
1251fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
125237c74af01ce52b603f565a6c8a9094500d5cb87aBrian Paul   /* These will actually get set again when binding/drawing */
1253fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0; i < VBO_ATTRIB_MAX; i++)
1254fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->inputs[i] = &save->arrays[i];
1255fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1256fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Hook our array functions into the outside-begin-end vtxfmt in
1257fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * ctx->ListState.
1258fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
1259fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf;
1260fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays;
1261fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements;
1262fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements;
126360b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   /* loops back into _save_OBE_DrawElements */
126460b08eb1fdf287d28ec66b9282513ab35a61aee0Eric Anholt   ctx->ListState.ListVtxfmt.MultiDrawElementsEXT = _mesa_noop_MultiDrawElements;
126592d7ed8a20d4a018ce5324e6537ae7b478b9e5bfEric Anholt   ctx->ListState.ListVtxfmt.MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;
1266fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
1267fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1268fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1269