vbo_save_api.c revision 2cb3594af9cd1434aa2c408cd6f8d51bcd12e8ea
1fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/**************************************************************************
2fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
3fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith WhitwellCopyright 2002 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
70fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "glheader.h"
71fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "context.h"
72fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "dlist.h"
73fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "enums.h"
74fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "macros.h"
75fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "api_validate.h"
76fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "api_arrayelt.h"
77fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "vtxfmt.h"
78fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "dispatch.h"
79fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
80fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "vbo_context.h"
81fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
82fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
83fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
84fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/*
85fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * NOTE: Old 'parity' issue is gone, but copying can still be
86fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * wrong-footed on replay.
87fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
88fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic GLuint _save_copy_vertices( GLcontext *ctx,
89fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				   const struct vbo_save_vertex_list *node,
90fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				   const GLfloat *src_buffer)
91fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
92fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context( ctx )->save;
93fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   const struct _mesa_prim *prim = &node->prim[node->prim_count-1];
94fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint nr = prim->count;
95fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint sz = save->vertex_size;
96fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   const GLfloat *src = src_buffer + prim->start * sz;
97fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLfloat *dst = save->copied.buffer;
98fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint ovf, i;
99fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
100fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (prim->end)
101fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return 0;
102fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
103fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   switch( prim->mode )
104fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   {
105fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_POINTS:
106fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return 0;
107fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_LINES:
108fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ovf = nr&1;
109fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < ovf ; i++)
110fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
111fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return i;
112fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_TRIANGLES:
113fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ovf = nr%3;
114fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < ovf ; i++)
115fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
116fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return i;
117fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_QUADS:
118fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ovf = nr&3;
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_LINE_STRIP:
123fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (nr == 0)
124fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 return 0;
125fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      else {
126fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _mesa_memcpy( dst, src+(nr-1)*sz, sz*sizeof(GLfloat) );
127fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 return 1;
128fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
129fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_LINE_LOOP:
130fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_TRIANGLE_FAN:
131fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_POLYGON:
132fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (nr == 0)
133fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 return 0;
134fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      else if (nr == 1) {
135fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) );
136fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 return 1;
137fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      } else {
138fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) );
139fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _mesa_memcpy( dst+sz, src+(nr-1)*sz, sz*sizeof(GLfloat) );
140fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 return 2;
141fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
142fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_TRIANGLE_STRIP:
143fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_QUAD_STRIP:
144fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      switch (nr) {
145fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 0: ovf = 0; break;
146fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 1: ovf = 1; break;
147fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      default: ovf = 2 + (nr&1); break;
148fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
149fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < ovf ; i++)
150fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
151fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return i;
152fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   default:
153fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(0);
154fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return 0;
155fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
156fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
157fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
158fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
159fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic struct vbo_save_vertex_store *alloc_vertex_store( GLcontext *ctx )
160fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
161fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_vertex_store *vertex_store = CALLOC_STRUCT(vbo_save_vertex_store);
162fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
163fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* obj->Name needs to be non-zero, but won't ever be examined more
164fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * closely than that.  In particular these buffers won't be entered
165fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * into the hash and can never be confused with ones visible to the
166fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * user.  Perhaps there could be a special number for internal
167fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * buffers:
168fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
169fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->bufferobj = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB);
170fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
171fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.BufferData( ctx,
172fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			   GL_ARRAY_BUFFER_ARB,
173fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			   VBO_SAVE_BUFFER_SIZE * sizeof(GLfloat),
174fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			   NULL,
175fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			   GL_STATIC_DRAW_ARB,
176fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			   vertex_store->bufferobj);
177fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
178fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->buffer = NULL;
179fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->used = 0;
180fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->refcount = 1;
181fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
182fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return vertex_store;
183fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
184fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
185fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void free_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store *vertex_store )
186fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
187fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(!vertex_store->buffer);
188fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
189fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (vertex_store->bufferobj)
190fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ctx->Driver.DeleteBuffer( ctx, vertex_store->bufferobj );
191fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
192fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   FREE( vertex_store );
193fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
194fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
195fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic GLfloat *map_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store *vertex_store )
196fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
197fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(vertex_store->bufferobj);
198fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(!vertex_store->buffer);
199fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->buffer = (GLfloat *)ctx->Driver.MapBuffer(ctx,
200fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell							   GL_ARRAY_BUFFER_ARB,	/* not used */
2012cb3594af9cd1434aa2c408cd6f8d51bcd12e8eaAapo Tahkola							   GL_WRITE_ONLY, /* not used */
202fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell							   vertex_store->bufferobj);
203fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
204fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(vertex_store->buffer);
205fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return vertex_store->buffer + vertex_store->used;
206fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
207fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
208fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void unmap_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store *vertex_store )
209fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
210fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.UnmapBuffer( ctx, GL_ARRAY_BUFFER_ARB, vertex_store->bufferobj );
211fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vertex_store->buffer = NULL;
212fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
213fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
214fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
215fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic struct vbo_save_primitive_store *alloc_prim_store( GLcontext *ctx )
216fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
217fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_primitive_store *store = CALLOC_STRUCT(vbo_save_primitive_store);
218fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) ctx;
219fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   store->used = 0;
220fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   store->refcount = 1;
221fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return store;
222fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
223fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
224fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_reset_counters( GLcontext *ctx )
225fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
226fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
227fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
228fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim = save->prim_store->buffer + save->prim_store->used;
229fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->buffer = (save->vertex_store->buffer +
230fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		   save->vertex_store->used);
231fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
232fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(save->buffer == save->vbptr);
233fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
234fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->vertex_size)
235fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) /
236fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			 save->vertex_size);
237fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   else
238fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->max_vert = 0;
239fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
240fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vert_count = 0;
241fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_count = 0;
242fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_max = VBO_SAVE_PRIM_SIZE - save->prim_store->used;
243fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->dangling_attr_ref = 0;
244fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
245fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
246fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
247fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Insert the active immediate struct onto the display list currently
248fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * being built.
249fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
250fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_compile_vertex_list( GLcontext *ctx )
251fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
252fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
253fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_vertex_list *node;
254fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
255fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Allocate space for this structure in the display list currently
256fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * being compiled.
257fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
258fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node = (struct vbo_save_vertex_list *)
259fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _mesa_alloc_instruction(ctx, save->opcode_vertex_list, sizeof(*node));
260fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
261fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!node)
262fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
263fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
264fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Duplicate our template, increment refcounts to the storage structs:
265fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
266fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz));
267fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->vertex_size = save->vertex_size;
268fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->buffer_offset = (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat);
269fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->count = save->vert_count;
270fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->wrap_count = save->copied.nr;
271fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->dangling_attr_ref = save->dangling_attr_ref;
272fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim = save->prim;
273fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim_count = save->prim_count;
274fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->vertex_store = save->vertex_store;
275fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim_store = save->prim_store;
276fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
277fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->vertex_store->refcount++;
278fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   node->prim_store->refcount++;
279fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
280fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(node->attrsz[VBO_ATTRIB_POS] != 0 ||
281fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	  node->count == 0);
282fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
283fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->dangling_attr_ref)
284fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ctx->ListState.CurrentList->flags |= MESA_DLIST_DANGLING_REFS;
285fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
286fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vertex_store->used += save->vertex_size * node->count;
287fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_store->used += node->prim_count;
288fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
289fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
290fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Copy duplicated vertices
291fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
292fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->copied.nr = _save_copy_vertices( ctx, node, save->buffer );
293fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
294fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
295fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Deal with GL_COMPILE_AND_EXECUTE:
296fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
297fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->ExecuteFlag) {
298fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      struct _glapi_table *dispatch = GET_DISPATCH();
299fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
300fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _glapi_set_dispatch(ctx->Exec);
301fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
302fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      vbo_loopback_vertex_list( ctx,
303fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				(const GLfloat *)((const char *)save->vertex_store->buffer +
304fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell						  node->buffer_offset),
305fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				node->attrsz,
306fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				node->prim,
307fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				node->prim_count,
308fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				node->wrap_count,
309fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				node->vertex_size);
310fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
311fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _glapi_set_dispatch(dispatch);
312fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
313fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
314fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
315fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Decide whether the storage structs are full, or can be used for
316fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * the next vertex lists as well.
317fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
318fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->vertex_store->used >
319fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       VBO_SAVE_BUFFER_SIZE - 16 * (save->vertex_size + 4)) {
320fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
321fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Unmap old store:
322fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
323fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      unmap_vertex_store( ctx, save->vertex_store );
324fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
325fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Release old reference:
326fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
327fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vertex_store->refcount--;
328fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(save->vertex_store->refcount != 0);
329fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vertex_store = NULL;
330fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
331fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Allocate and map new store:
332fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
333fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vertex_store = alloc_vertex_store( ctx );
334fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vbptr = map_vertex_store( ctx, save->vertex_store );
335fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
336fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
337fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->prim_store->used > VBO_SAVE_PRIM_SIZE - 6) {
338fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->prim_store->refcount--;
339fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(save->prim_store->refcount != 0);
340fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->prim_store = alloc_prim_store( ctx );
341fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
342fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
343fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Reset our structures for the next run of vertices:
344fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
345fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_counters( ctx );
346fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
347fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
348fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
349fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* TODO -- If no new vertices have been stored, don't bother saving
350fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * it.
351fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
352fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_wrap_buffers( GLcontext *ctx )
353fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
354fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
355fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i = save->prim_count - 1;
356fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLenum mode;
357fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLboolean weak;
358fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
359fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(i < (GLint) save->prim_max);
360fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(i >= 0);
361fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
362fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Close off in-progress primitive.
363fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
364fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].count = (save->vert_count -
365fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			  save->prim[i].start);
366fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   mode = save->prim[i].mode;
367fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   weak = save->prim[i].weak;
368fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
369fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* store the copied vertices, and allocate a new list.
370fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
371fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_compile_vertex_list( ctx );
372fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
373fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Restart interrupted primitive
374fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
375fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].mode = mode;
376fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].weak = weak;
377fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].begin = 0;
378fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].end = 0;
379fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].pad = 0;
380fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].start = 0;
381fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[0].count = 0;
382fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim_count = 1;
383fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
384fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
385fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
386fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
387fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Called only when buffers are wrapped as the result of filling the
388fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * vertex_store struct.
389fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
390fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_wrap_filled_vertex( GLcontext *ctx )
391fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
392fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
393fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLfloat *data = save->copied.buffer;
394fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
395fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
396fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Emit a glEnd to close off the last vertex list.
397fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
398fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_wrap_buffers( ctx );
399fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
400fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    /* Copy stored stored vertices to start of new list.
401fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
402fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(save->max_vert - save->vert_count > save->copied.nr);
403fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
404fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0 ; i < save->copied.nr ; i++) {
405fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _mesa_memcpy( save->vbptr, data, save->vertex_size * sizeof(GLfloat));
406fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      data += save->vertex_size;
407fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vbptr += save->vertex_size;
408fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vert_count++;
409fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
410fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
411fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
412fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
413fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_copy_to_current( GLcontext *ctx )
414fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
415fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
416fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
417fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
4182421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell   for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
419fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (save->attrsz[i]) {
420fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->currentsz[i][0] = save->attrsz[i];
421fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 COPY_CLEAN_4V(save->current[i],
4222421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell		       save->attrsz[i],
4232421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell		       save->attrptr[i]);
424fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
425fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
426fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
427fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
428fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
429fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_copy_from_current( GLcontext *ctx )
430fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
431fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
432fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
433fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
4342421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell   for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
435fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      switch (save->attrsz[i]) {
436fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 4: save->attrptr[i][3] = save->current[i][3];
437fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 3: save->attrptr[i][2] = save->current[i][2];
438fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 2: save->attrptr[i][1] = save->current[i][1];
439fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 1: save->attrptr[i][0] = save->current[i][0];
440fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      case 0: break;
441fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
442fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
443fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
444fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
445fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
446fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
447fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
448fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Flush existing data, set new attrib size, replay copied vertices.
449fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
450fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_upgrade_vertex( GLcontext *ctx,
451fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				 GLuint attr,
452fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				 GLuint newsz )
453fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
454fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
455fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint oldsz;
456fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
457fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLfloat *tmp;
458fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
459fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Store the current run of vertices, and emit a GL_END.  Emit a
460fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * BEGIN in the new buffer.
461fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
462fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->vert_count)
463fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_wrap_buffers( ctx );
464fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   else
465fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert( save->copied.nr == 0 );
466fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
467fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
468fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * when the attribute already exists in the vertex and is having
469fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * its size increased.
470fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
471fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_copy_to_current( ctx );
472fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
473fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Fix up sizes:
474fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
475fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   oldsz = save->attrsz[attr];
476fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->attrsz[attr] = newsz;
477fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
478fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vertex_size += newsz - oldsz;
479fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) /
480fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		      save->vertex_size);
481fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vert_count = 0;
482fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
483fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Recalculate all the attrptr[] values:
484fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
485fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0, tmp = save->vertex ; i < VBO_ATTRIB_MAX ; i++) {
486fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (save->attrsz[i]) {
487fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->attrptr[i] = tmp;
488fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 tmp += save->attrsz[i];
489fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
490fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      else
491fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->attrptr[i] = NULL; /* will not be dereferenced. */
492fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
493fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
494fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Copy from current to repopulate the vertex with correct values.
495fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
496fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_copy_from_current( ctx );
497fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
498fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Replay stored vertices to translate them to new format here.
499fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    *
500fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * If there are copied vertices and the new (upgraded) attribute
501fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * has not been defined before, this list is somewhat degenerate,
502fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * and will need fixup at runtime.
503fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
504fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->copied.nr)
505fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   {
506fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLfloat *data = save->copied.buffer;
507fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLfloat *dest = save->buffer;
508fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLuint j;
509fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
510fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* Need to note this and fix up at runtime (or loopback):
511fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
512dd60eaa6d9f61735141976db0e83d25176ac73c7Keith Whitwell      if (attr != VBO_ATTRIB_POS && save->currentsz[attr][0] == 0) {
513fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 assert(oldsz == 0);
514fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->dangling_attr_ref = GL_TRUE;
515fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
516fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
517fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < save->copied.nr ; i++) {
518fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) {
519fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	    if (save->attrsz[j]) {
520fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	       if (j == attr) {
521fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  if (oldsz) {
522fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		     COPY_CLEAN_4V( dest, oldsz, data );
523fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		     data += oldsz;
524fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		     dest += newsz;
525fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  }
526fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  else {
527fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		     COPY_SZ_4V( dest, newsz, save->current[attr] );
528fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		     dest += newsz;
529fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  }
530fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	       }
531fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	       else {
532fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  GLint sz = save->attrsz[j];
533fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  COPY_SZ_4V( dest, sz, data );
534fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  data += sz;
535fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  dest += sz;
536fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	       }
537fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	    }
538fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 }
539fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      }
540fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
541fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vbptr = dest;
542fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vert_count += save->copied.nr;
543fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
544fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
545fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
546fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void save_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz )
547fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
548fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
549fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
550fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (sz > save->attrsz[attr]) {
551fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* New size is larger.  Need to flush existing vertices and get
552fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * an enlarged vertex format.
553fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
554fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_upgrade_vertex( ctx, attr, sz );
555fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
556fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   else if (sz < save->active_sz[attr]) {
557fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      static GLfloat id[4] = { 0, 0, 0, 1 };
558fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLuint i;
559fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
560fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* New size is equal or smaller - just need to fill in some
561fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * zeros.
562fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
563fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = sz ; i <= save->attrsz[attr] ; i++)
564fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->attrptr[attr][i-1] = id[i-1];
565fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
566fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
567fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->active_sz[attr] = sz;
568fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
569fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
570fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_reset_vertex( GLcontext *ctx )
571fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
572fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
573fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
574fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
575fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
576fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->attrsz[i] = 0;
577fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->active_sz[i] = 0;
578fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
579fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
580fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vertex_size = 0;
581fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
582fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
583fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
584fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
585fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#define ERROR()   _mesa_compile_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );
586fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
587fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
588fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Only one size for each attribute may be active at once.  Eg. if
589fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * Color3f is installed/active, then Color4f may not be, even if the
590fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * vertex actually contains 4 color coordinates.  This is because the
591fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * 3f version won't otherwise set color[3] to 1.0 -- this is the job
592fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * of the chooser function when switching between Color4f and Color3f.
593fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
594fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#define ATTR( A, N, V0, V1, V2, V3 )				\
595fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwelldo {								\
596fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;	\
597fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
598fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->active_sz[A] != N)				\
599fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save_fixup_vertex(ctx, A, N);				\
600fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
601fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   {								\
602fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLfloat *dest = save->attrptr[A];			\
603fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>0) dest[0] = V0;					\
604fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>1) dest[1] = V1;					\
605fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>2) dest[2] = V2;					\
606fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (N>3) dest[3] = V3;					\
607fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }								\
608fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
609fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if ((A) == 0) {						\
610fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      GLuint i;							\
611fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
612fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0; i < save->vertex_size; i++)			\
613fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 save->vbptr[i] = save->vertex[i];			\
614fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
615fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vbptr += save->vertex_size;				\
616fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell								\
617fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      if (++save->vert_count >= save->max_vert)			\
618fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	 _save_wrap_filled_vertex( ctx );			\
619fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }								\
620fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell} while (0)
621fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
622fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#define TAG(x) _save_##x
623fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
624fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#include "vbo_attrib_tmp.h"
625fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
626fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
627fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
628fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
629fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Cope with EvalCoord/CallList called within a begin/end object:
630fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *     -- Flush current buffer
631fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell *     -- Fallback to opcodes for the rest of the begin/end object.
632fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
633fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell#define DO_FALLBACK(ctx) 							\
634fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwelldo {									\
635fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;					\
636fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell									\
637fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->vert_count || save->prim_count) 						\
638fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_compile_vertex_list( ctx );					\
639fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell									\
640fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_copy_to_current( ctx );					\
641fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_vertex( ctx );						\
642fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_counters( ctx );  \
643fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );	\
644fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 0;					\
645fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell} while (0)
646fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
647fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalCoord1f( GLfloat u )
648fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
649fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
650fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
651fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->EvalCoord1f( u );
652fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
653fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
654fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalCoord1fv( const GLfloat *v )
655fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
656fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
657fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
658fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->EvalCoord1fv( v );
659fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
660fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
661fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalCoord2f( GLfloat u, GLfloat v )
662fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
663fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
664fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
665fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->EvalCoord2f( u, v );
666fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
667fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
668fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalCoord2fv( const GLfloat *v )
669fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
670fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
671fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
672fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->EvalCoord2fv( v );
673fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
674fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
675fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalPoint1( GLint i )
676fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
677fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
678fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
679fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->EvalPoint1( i );
680fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
681fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
682fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalPoint2( GLint i, GLint j )
683fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
684fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
685fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
686fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->EvalPoint2( i, j );
687fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
688fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
689fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_CallList( GLuint l )
690fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
691fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
692fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
693fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->CallList( l );
694fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
695fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
696fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_CallLists( GLsizei n, GLenum type, const GLvoid *v )
697fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
698fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
699fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   DO_FALLBACK(ctx);
700fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Save->CallLists( n, type, v );
701fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
702fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
703fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
704fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
705fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
706fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* This begin is hooked into ...  Updating of
707fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * ctx->Driver.CurrentSavePrimitive is already taken care of.
708fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
709fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith WhitwellGLboolean vbo_save_NotifyBegin( GLcontext *ctx, GLenum mode )
710fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
711fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
712fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
713fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i = save->prim_count++;
714fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
715fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(i < save->prim_max);
716fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].mode = mode & ~VBO_SAVE_PRIM_WEAK;
717fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].begin = 1;
718fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].end = 0;
719fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0;
720fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].pad = 0;
721fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].start = save->vert_count;
722fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].count = 0;
723fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
724fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_install_save_vtxfmt( ctx, &save->vtxfmt );
725fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 1;
726fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   return GL_TRUE;
727fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
728fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
729fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
730fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
731fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_End( void )
732fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
733fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT( ctx );
734fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
735fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i = save->prim_count - 1;
736fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
737fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
738fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].end = 1;
739fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->prim[i].count = (save->vert_count -
740fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			  save->prim[i].start);
741fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
742fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (i == (GLint) save->prim_max - 1) {
743fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_compile_vertex_list( ctx );
744fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      assert(save->copied.nr == 0);
745fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
746fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
747fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Swap out this vertex format while outside begin/end.  Any color,
748fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * etc. received between here and the next begin will be compiled
749fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * as opcodes.
750fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
751fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
752fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
753fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
754fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
755fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* These are all errors as this vtxfmt is only installed inside
756fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * begin/end pairs.
757fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
758fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_DrawElements(GLenum mode, GLsizei count, GLenum type,
759fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			       const GLvoid *indices)
760fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
761fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
762fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode; (void) count; (void) type; (void) indices;
763fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" );
764fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
765fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
766fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
767fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_DrawRangeElements(GLenum mode,
768fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				    GLuint start, GLuint end,
769fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				    GLsizei count, GLenum type,
770fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				    const GLvoid *indices)
771fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
772fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
773fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode; (void) start; (void) end; (void) count; (void) type; (void) indices;
774fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" );
775fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
776fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
777fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count)
778fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
779fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
780fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode; (void) start; (void) count;
781fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" );
782fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
783fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
784fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
785fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
786fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
787fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) x1; (void) y1; (void) x2; (void) y2;
788fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glRectf" );
789fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
790fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
791fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
792fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
793fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
794fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode; (void) i1; (void) i2;
795fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh1" );
796fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
797fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
798fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_EvalMesh2( GLenum mode, GLint i1, GLint i2,
799fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				  GLint j1, GLint j2 )
800fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
801fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
802fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode; (void) i1; (void) i2; (void) j1; (void) j2;
803fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh2" );
804fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
805fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
806fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_Begin( GLenum mode )
807fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
808fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT( ctx );
809fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) mode;
810fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_compile_error( ctx, GL_INVALID_OPERATION, "Recursive glBegin" );
811fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
812fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
813fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
814fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Unlike the functions above, these are to be hooked into the vtxfmt
815fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * maintained in ctx->ListState, active when the list is known or
816fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * suspected to be outside any begin/end primitive.
817fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
818fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
819fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
820fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
821fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vbo_save_NotifyBegin( ctx, GL_QUADS | VBO_SAVE_PRIM_WEAK );
822fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_Vertex2f(GET_DISPATCH(), ( x1, y1 ));
823fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_Vertex2f(GET_DISPATCH(), ( x2, y1 ));
824fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_Vertex2f(GET_DISPATCH(), ( x2, y2 ));
825fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_Vertex2f(GET_DISPATCH(), ( x1, y2 ));
826fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_End(GET_DISPATCH(), ());
827fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
828fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
829fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
830fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count)
831fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
832fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
833fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
834fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
835fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
836fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
837fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
838b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell   _ae_map_vbos( ctx );
839b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
840fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK );
8416a3fdc3a1ea6c306d9543791bf172dd1052d7382Keith Whitwell
842fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0; i < count; i++)
843fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       CALL_ArrayElement(GET_DISPATCH(), (start + i));
844fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_End(GET_DISPATCH(), ());
845b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
846b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell   _ae_unmap_vbos( ctx );
847fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
848fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
849fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/* Could do better by copying the arrays and element list intact and
850fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * then emitting an indexed prim at runtime.
851fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
852fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type,
853fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell				   const GLvoid *indices)
854fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
855fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
856fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
857fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
858fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
859fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
860fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
861b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell   _ae_map_vbos( ctx );
862b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
863fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK );
864fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
865fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   switch (type) {
866fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_BYTE:
867fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < count ; i++)
868fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	  CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] ));
869fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
870fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_SHORT:
871fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < count ; i++)
872fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	  CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] ));
873fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
874fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   case GL_UNSIGNED_INT:
875fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      for (i = 0 ; i < count ; i++)
876fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	  CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] ));
877fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
878fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   default:
879fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
880fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      break;
881fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
882fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
883fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   CALL_End(GET_DISPATCH(), ());
884b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell
885b97947972193b6b004a0ee49da31146230d43dd8Keith Whitwell   _ae_unmap_vbos( ctx );
886fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
887fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
888fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode,
889fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell					GLuint start, GLuint end,
890fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell					GLsizei count, GLenum type,
891fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell					const GLvoid *indices)
892fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
893fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GET_CURRENT_CONTEXT(ctx);
894fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (_mesa_validate_DrawRangeElements( ctx, mode,
895fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell					 start, end,
896fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell					 count, type, indices ))
897fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_OBE_DrawElements( mode, count, type, indices );
898fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
899fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
900fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
901fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
902fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
903fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
904fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_vtxfmt_init( GLcontext *ctx )
905fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
906fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
907fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLvertexformat *vfmt = &save->vtxfmt;
908fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
909fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->ArrayElement = _ae_loopback_array_elt;	        /* generic helper */
910fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Begin = _save_Begin;
911fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color3f = _save_Color3f;
912fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color3fv = _save_Color3fv;
913fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color4f = _save_Color4f;
914fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Color4fv = _save_Color4fv;
915fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EdgeFlag = _save_EdgeFlag;
916fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->End = _save_End;
917fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->FogCoordfEXT = _save_FogCoordfEXT;
918fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->FogCoordfvEXT = _save_FogCoordfvEXT;
919fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Indexf = _save_Indexf;
920fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Indexfv = _save_Indexfv;
921fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Materialfv = _save_Materialfv;
922fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f;
923fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv;
924fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f;
925fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv;
926fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f;
927fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv;
928fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f;
929fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv;
930fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Normal3f = _save_Normal3f;
931fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Normal3fv = _save_Normal3fv;
932fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT;
933fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT;
934fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord1f = _save_TexCoord1f;
935fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord1fv = _save_TexCoord1fv;
936fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord2f = _save_TexCoord2f;
937fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord2fv = _save_TexCoord2fv;
938fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord3f = _save_TexCoord3f;
939fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord3fv = _save_TexCoord3fv;
940fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord4f = _save_TexCoord4f;
941fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->TexCoord4fv = _save_TexCoord4fv;
942fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex2f = _save_Vertex2f;
943fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex2fv = _save_Vertex2fv;
944fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex3f = _save_Vertex3f;
945fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex3fv = _save_Vertex3fv;
946fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex4f = _save_Vertex4f;
947fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Vertex4fv = _save_Vertex4fv;
948fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB;
949fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB;
950fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB;
951fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB;
952fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB;
953fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB;
954fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB;
955fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB;
956fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
957fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV;
958fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV;
959fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV;
960fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV;
961fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV;
962fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV;
963fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV;
964fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV;
965fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
966fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* This will all require us to fallback to saving the list as opcodes:
967fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
968fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->CallList = _save_CallList; /* inside begin/end */
969fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->CallLists = _save_CallLists; /* inside begin/end */
970fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalCoord1f = _save_EvalCoord1f;
971fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalCoord1fv = _save_EvalCoord1fv;
972fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalCoord2f = _save_EvalCoord2f;
973fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalCoord2fv = _save_EvalCoord2fv;
974fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalPoint1 = _save_EvalPoint1;
975fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalPoint2 = _save_EvalPoint2;
976fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
977fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* These are all errors as we at least know we are in some sort of
978fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * begin/end pair:
979fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
980fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalMesh1 = _save_EvalMesh1;
981fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->EvalMesh2 = _save_EvalMesh2;
982fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Begin = _save_Begin;
983fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->Rectf = _save_Rectf;
984fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->DrawArrays = _save_DrawArrays;
985fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->DrawElements = _save_DrawElements;
986fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   vfmt->DrawRangeElements = _save_DrawRangeElements;
987fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
988fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
989fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
990fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
991fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellvoid vbo_save_SaveFlushVertices( GLcontext *ctx )
992fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
993fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
994fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
995fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Noop when we are actually active:
996fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
997fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM ||
998fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       ctx->Driver.CurrentSavePrimitive <= GL_POLYGON)
999fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      return;
1000fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1001fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (save->vert_count ||
1002fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       save->prim_count)
1003fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _save_compile_vertex_list( ctx );
1004fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1005fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_copy_to_current( ctx );
1006fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_vertex( ctx );
1007fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_counters( ctx );
1008fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 0;
1009fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1010fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1011fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellvoid vbo_save_NewList( GLcontext *ctx, GLuint list, GLenum mode )
1012fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1013fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1014fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1015fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) list; (void) mode;
1016fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1017fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!save->prim_store)
1018fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->prim_store = alloc_prim_store( ctx );
1019fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1020fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (!save->vertex_store)
1021fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->vertex_store = alloc_vertex_store( ctx );
1022fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1023fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->vbptr = map_vertex_store( ctx, save->vertex_store );
1024fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1025fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_vertex( ctx );
1026fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_reset_counters( ctx );
1027fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.SaveNeedFlush = 0;
1028fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1029fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1030fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellvoid vbo_save_EndList( GLcontext *ctx )
1031fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1032fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1033fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   unmap_vertex_store( ctx, save->vertex_store );
1034fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1035fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   assert(save->vertex_size == 0);
1036fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1037fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1038fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellvoid vbo_save_BeginCallList( GLcontext *ctx, struct mesa_display_list *dlist )
1039fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1040fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1041fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->replay_flags |= dlist->flags;
1042fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1043fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1044fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellvoid vbo_save_EndCallList( GLcontext *ctx )
1045fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1046fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1047fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1048fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if (ctx->ListState.CallDepth == 1) {
1049fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      /* This is correct: want to keep only the VBO_SAVE_FALLBACK
1050fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       * flag, if it is set:
1051fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell       */
1052fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->replay_flags &= VBO_SAVE_FALLBACK;
1053fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1054fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1055fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1056fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1057fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void vbo_destroy_vertex_list( GLcontext *ctx, void *data )
1058fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1059fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *)data;
1060fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) ctx;
1061fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1062fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if ( --node->vertex_store->refcount == 0 )
1063fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      free_vertex_store( ctx, node->vertex_store );
1064fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1065fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   if ( --node->prim_store->refcount == 0 )
1066fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      FREE( node->prim_store );
1067fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1068fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1069fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1070fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void vbo_print_vertex_list( GLcontext *ctx, void *data )
1071fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1072fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *)data;
1073fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
1074fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   (void) ctx;
1075fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1076fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_debug(NULL, "VBO-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n",
1077fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell               node->count,
1078fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	       node->prim_count,
1079fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell	       node->vertex_size);
1080fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1081fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0 ; i < node->prim_count ; i++) {
1082fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      struct _mesa_prim *prim = &node->prim[i];
1083fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _mesa_debug(NULL, "   prim %d: %s%s %d..%d %s %s\n",
1084fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  i,
1085fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  _mesa_lookup_enum_by_nr(prim->mode),
1086fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  prim->weak ? " (weak)" : "",
1087fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  prim->start,
1088fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  prim->start + prim->count,
1089fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  (prim->begin) ? "BEGIN" : "(wrap)",
1090fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell		  (prim->end) ? "END" : "(wrap)");
1091fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1092fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1093fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1094fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1095fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellstatic void _save_current_init( GLcontext *ctx )
1096fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1097fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   struct vbo_save_context *save = &vbo_context(ctx)->save;
1098fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLint i;
1099fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
11002421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell   for (i = VBO_ATTRIB_POS; i <= VBO_ATTRIB_GENERIC15; i++) {
11012421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      const GLuint j = i - VBO_ATTRIB_POS;
11022421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      ASSERT(j < VERT_ATTRIB_MAX);
11032421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      save->currentsz[i] = &ctx->ListState.ActiveAttribSize[j];
11042421b25dd777ebfd614ae45907fd4af8c2713102Keith Whitwell      save->current[i] = ctx->ListState.CurrentAttrib[j];
1105fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1106fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
11076a3fdc3a1ea6c306d9543791bf172dd1052d7382Keith Whitwell   for (i = VBO_ATTRIB_FIRST_MATERIAL; i <= VBO_ATTRIB_LAST_MATERIAL; i++) {
1108fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      const GLuint j = i - VBO_ATTRIB_FIRST_MATERIAL;
1109fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      ASSERT(j < MAT_ATTRIB_MAX);
1110fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j];
1111fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->current[i] = ctx->ListState.CurrentMaterial[j];
1112fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   }
1113fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1114fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1115fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell/**
1116fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell * Initialize the display list compiler
1117fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell */
1118fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwellvoid vbo_save_api_init( struct vbo_save_context *save )
1119fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell{
1120fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLcontext *ctx = save->ctx;
1121fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   GLuint i;
1122fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1123fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   save->opcode_vertex_list =
1124fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      _mesa_alloc_opcode( ctx,
1125fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			  sizeof(struct vbo_save_vertex_list),
1126fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			  vbo_save_playback_vertex_list,
1127fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			  vbo_destroy_vertex_list,
1128fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell			  vbo_print_vertex_list );
1129fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1130fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->Driver.NotifySaveBegin = vbo_save_NotifyBegin;
1131fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1132fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_vtxfmt_init( ctx );
1133fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _save_current_init( ctx );
1134fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1135fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   for (i = 0; i < VBO_ATTRIB_MAX; i++)
1136fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell      save->inputs[i] = &save->arrays[i];
1137fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1138fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   /* Hook our array functions into the outside-begin-end vtxfmt in
1139fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    * ctx->ListState.
1140fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell    */
1141fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf;
1142fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays;
1143fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements;
1144fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements;
1145fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
1146fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell}
1147fd12b37dbada6f945a94b93ecf332d0b6a8eef06Keith Whitwell
1148