Initial work for bounds checking of vertex arrays and vertex buffer objects.
[mesa.git] / src / mesa / array_cache / ac_context.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 5.1
4 *
5 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Keith Whitwell <keith@tungstengraphics.com>
26 */
27
28 #include "glheader.h"
29 #include "macros.h"
30 #include "imports.h"
31 #include "mtypes.h"
32
33 #include "array_cache/ac_context.h"
34
35
36 /*
37 * Initialize the array fallbacks. That is, by default the fallback arrays
38 * point into the current vertex attribute values in ctx->Current.Attrib[]
39 */
40 static void _ac_fallbacks_init( GLcontext *ctx )
41 {
42 ACcontext *ac = AC_CONTEXT(ctx);
43 struct gl_client_array *cl;
44 GLuint i;
45
46 cl = &ac->Fallback.Normal;
47 cl->Size = 3;
48 cl->Type = GL_FLOAT;
49 cl->Stride = 0;
50 cl->StrideB = 0;
51 cl->Ptr = (GLubyte *) ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
52 cl->Enabled = 1;
53 cl->Flags = CA_CLIENT_DATA; /* hack */
54 #if FEATURE_ARB_vertex_buffer_object
55 cl->BufferObj = ctx->Array.NullBufferObj;
56 #endif
57
58 cl = &ac->Fallback.Color;
59 cl->Size = 4;
60 cl->Type = GL_FLOAT;
61 cl->Stride = 0;
62 cl->StrideB = 0;
63 cl->Ptr = (GLubyte *) ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
64 cl->Enabled = 1;
65 cl->Flags = CA_CLIENT_DATA; /* hack */
66 #if FEATURE_ARB_vertex_buffer_object
67 cl->BufferObj = ctx->Array.NullBufferObj;
68 #endif
69
70 cl = &ac->Fallback.SecondaryColor;
71 cl->Size = 3;
72 cl->Type = GL_FLOAT;
73 cl->Stride = 0;
74 cl->StrideB = 0;
75 cl->Ptr = (GLubyte *) ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
76 cl->Enabled = 1;
77 cl->Flags = CA_CLIENT_DATA; /* hack */
78 #if FEATURE_ARB_vertex_buffer_object
79 cl->BufferObj = ctx->Array.NullBufferObj;
80 #endif
81
82 cl = &ac->Fallback.FogCoord;
83 cl->Size = 1;
84 cl->Type = GL_FLOAT;
85 cl->Stride = 0;
86 cl->StrideB = 0;
87 cl->Ptr = (GLubyte *) &ctx->Current.Attrib[VERT_ATTRIB_FOG];
88 cl->Enabled = 1;
89 cl->Flags = CA_CLIENT_DATA; /* hack */
90 #if FEATURE_ARB_vertex_buffer_object
91 cl->BufferObj = ctx->Array.NullBufferObj;
92 #endif
93
94 cl = &ac->Fallback.Index;
95 cl->Size = 1;
96 cl->Type = GL_UNSIGNED_INT;
97 cl->Stride = 0;
98 cl->StrideB = 0;
99 cl->Ptr = (GLubyte *) &ctx->Current.Index;
100 cl->Enabled = 1;
101 cl->Flags = CA_CLIENT_DATA; /* hack */
102 #if FEATURE_ARB_vertex_buffer_object
103 cl->BufferObj = ctx->Array.NullBufferObj;
104 #endif
105
106 for (i = 0 ; i < MAX_TEXTURE_COORD_UNITS ; i++) {
107 cl = &ac->Fallback.TexCoord[i];
108 cl->Size = 4;
109 cl->Type = GL_FLOAT;
110 cl->Stride = 0;
111 cl->StrideB = 0;
112 cl->Ptr = (GLubyte *) ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i];
113 cl->Enabled = 1;
114 cl->Flags = CA_CLIENT_DATA; /* hack */
115 #if FEATURE_ARB_vertex_buffer_object
116 cl->BufferObj = ctx->Array.NullBufferObj;
117 #endif
118 }
119
120 cl = &ac->Fallback.EdgeFlag;
121 cl->Size = 1;
122 cl->Type = GL_UNSIGNED_BYTE;
123 cl->Stride = 0;
124 cl->StrideB = 0;
125 cl->Ptr = (GLubyte *) &ctx->Current.EdgeFlag;
126 cl->Enabled = 1;
127 cl->Flags = CA_CLIENT_DATA; /* hack */
128 #if FEATURE_ARB_vertex_buffer_object
129 cl->BufferObj = ctx->Array.NullBufferObj;
130 #endif
131
132 for (i = 0; i < VERT_ATTRIB_MAX; i++) {
133 cl = &ac->Fallback.Attrib[i];
134 cl->Size = 4;
135 cl->Type = GL_FLOAT;
136 cl->Stride = 0;
137 cl->StrideB = 0;
138 cl->Ptr = (GLubyte *) ctx->Current.Attrib[i];
139 cl->Enabled = 1;
140 cl->Flags = CA_CLIENT_DATA; /* hack */
141 #if FEATURE_ARB_vertex_buffer_object
142 cl->BufferObj = ctx->Array.NullBufferObj;
143 #endif
144 }
145 }
146
147
148 /*
149 * Initialize the array cache pointers, types, strides, etc.
150 */
151 static void _ac_cache_init( GLcontext *ctx )
152 {
153 ACcontext *ac = AC_CONTEXT(ctx);
154 struct gl_client_array *cl;
155 GLuint size = ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES;
156 GLuint i;
157
158 cl = &ac->Cache.Vertex;
159 cl->Size = 4;
160 cl->Type = GL_FLOAT;
161 cl->Stride = 0;
162 cl->StrideB = 4 * sizeof(GLfloat);
163 cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size );
164 cl->Enabled = 1;
165 cl->Flags = 0;
166 #if FEATURE_ARB_vertex_buffer_object
167 cl->BufferObj = ctx->Array.NullBufferObj;
168 #endif
169
170 cl = &ac->Cache.Normal;
171 cl->Size = 3;
172 cl->Type = GL_FLOAT;
173 cl->Stride = 0;
174 cl->StrideB = 3 * sizeof(GLfloat);
175 cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size );
176 cl->Enabled = 1;
177 cl->Flags = 0;
178 #if FEATURE_ARB_vertex_buffer_object
179 cl->BufferObj = ctx->Array.NullBufferObj;
180 #endif
181
182 cl = &ac->Cache.Color;
183 cl->Size = 4;
184 cl->Type = GL_FLOAT;
185 cl->Stride = 0;
186 cl->StrideB = 4 * sizeof(GLfloat);
187 cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size );
188 cl->Enabled = 1;
189 cl->Flags = 0;
190 #if FEATURE_ARB_vertex_buffer_object
191 cl->BufferObj = ctx->Array.NullBufferObj;
192 #endif
193
194 cl = &ac->Cache.SecondaryColor;
195 cl->Size = 3;
196 cl->Type = GL_FLOAT;
197 cl->Stride = 0;
198 cl->StrideB = 4 * sizeof(GLfloat);
199 cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size );
200 cl->Enabled = 1;
201 cl->Flags = 0;
202 #if FEATURE_ARB_vertex_buffer_object
203 cl->BufferObj = ctx->Array.NullBufferObj;
204 #endif
205
206 cl = &ac->Cache.FogCoord;
207 cl->Size = 1;
208 cl->Type = GL_FLOAT;
209 cl->Stride = 0;
210 cl->StrideB = sizeof(GLfloat);
211 cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size );
212 cl->Enabled = 1;
213 cl->Flags = 0;
214 #if FEATURE_ARB_vertex_buffer_object
215 cl->BufferObj = ctx->Array.NullBufferObj;
216 #endif
217
218 cl = &ac->Cache.Index;
219 cl->Size = 1;
220 cl->Type = GL_UNSIGNED_INT;
221 cl->Stride = 0;
222 cl->StrideB = sizeof(GLuint);
223 cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size );
224 cl->Enabled = 1;
225 cl->Flags = 0;
226 #if FEATURE_ARB_vertex_buffer_object
227 cl->BufferObj = ctx->Array.NullBufferObj;
228 #endif
229
230 for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
231 cl = &ac->Cache.TexCoord[i];
232 cl->Size = 4;
233 cl->Type = GL_FLOAT;
234 cl->Stride = 0;
235 cl->StrideB = 4 * sizeof(GLfloat);
236 cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size );
237 cl->Enabled = 1;
238 cl->Flags = 0;
239 #if FEATURE_ARB_vertex_buffer_object
240 cl->BufferObj = ctx->Array.NullBufferObj;
241 #endif
242 }
243
244 cl = &ac->Cache.EdgeFlag;
245 cl->Size = 1;
246 cl->Type = GL_UNSIGNED_BYTE;
247 cl->Stride = 0;
248 cl->StrideB = sizeof(GLubyte);
249 cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size );
250 cl->Enabled = 1;
251 cl->Flags = 0;
252 #if FEATURE_ARB_vertex_buffer_object
253 cl->BufferObj = ctx->Array.NullBufferObj;
254 #endif
255
256 for (i = 0 ; i < VERT_ATTRIB_MAX; i++) {
257 cl = &ac->Cache.Attrib[i];
258 cl->Size = 4;
259 cl->Type = GL_FLOAT;
260 cl->Stride = 0;
261 cl->StrideB = 4 * sizeof(GLfloat);
262 cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size );
263 cl->Enabled = 1;
264 cl->Flags = 0;
265 #if FEATURE_ARB_vertex_buffer_object
266 cl->BufferObj = ctx->Array.NullBufferObj;
267 #endif
268 }
269 }
270
271
272 /* This storage used to hold translated client data if type or stride
273 * need to be fixed.
274 */
275 static void _ac_elts_init( GLcontext *ctx )
276 {
277 ACcontext *ac = AC_CONTEXT(ctx);
278 GLuint size = 1000;
279
280 ac->Elts = (GLuint *)MALLOC( sizeof(GLuint) * size );
281 ac->elt_size = size;
282 }
283
284 static void _ac_raw_init( GLcontext *ctx )
285 {
286 ACcontext *ac = AC_CONTEXT(ctx);
287 GLuint i;
288
289 ac->Raw.Color = ac->Fallback.Color;
290 ac->Raw.EdgeFlag = ac->Fallback.EdgeFlag;
291 ac->Raw.FogCoord = ac->Fallback.FogCoord;
292 ac->Raw.Index = ac->Fallback.Index;
293 ac->Raw.Normal = ac->Fallback.Normal;
294 ac->Raw.SecondaryColor = ac->Fallback.SecondaryColor;
295 ac->Raw.Vertex = ctx->Array.Vertex;
296
297 ac->IsCached.Color = GL_FALSE;
298 ac->IsCached.EdgeFlag = GL_FALSE;
299 ac->IsCached.FogCoord = GL_FALSE;
300 ac->IsCached.Index = GL_FALSE;
301 ac->IsCached.Normal = GL_FALSE;
302 ac->IsCached.SecondaryColor = GL_FALSE;
303 ac->IsCached.Vertex = GL_FALSE;
304
305 for (i = 0 ; i < MAX_TEXTURE_COORD_UNITS ; i++) {
306 ac->Raw.TexCoord[i] = ac->Fallback.TexCoord[i];
307 ac->IsCached.TexCoord[i] = GL_FALSE;
308 }
309
310 for (i = 0 ; i < VERT_ATTRIB_MAX ; i++) {
311 ac->Raw.Attrib[i] = ac->Fallback.Attrib[i];
312 ac->IsCached.Attrib[i] = GL_FALSE;
313 }
314 }
315
316 GLboolean _ac_CreateContext( GLcontext *ctx )
317 {
318 ctx->acache_context = CALLOC(sizeof(ACcontext));
319 if (ctx->acache_context) {
320 _ac_cache_init( ctx );
321 _ac_fallbacks_init( ctx );
322 _ac_raw_init( ctx );
323 _ac_elts_init( ctx );
324 return GL_TRUE;
325 }
326 return GL_FALSE;
327 }
328
329 void _ac_DestroyContext( GLcontext *ctx )
330 {
331 struct gl_buffer_object *nullObj = ctx->Array.NullBufferObj;
332 ACcontext *ac = AC_CONTEXT(ctx);
333 GLint i;
334
335 /* only free vertex data if it's really a pointer to vertex data and
336 * not an offset into a buffer object.
337 */
338 if (ac->Cache.Vertex.Ptr && ac->Cache.Vertex.BufferObj == nullObj)
339 FREE( (void *) ac->Cache.Vertex.Ptr );
340 if (ac->Cache.Normal.Ptr && ac->Cache.Normal.BufferObj == nullObj)
341 FREE( (void *) ac->Cache.Normal.Ptr );
342 if (ac->Cache.Color.Ptr && ac->Cache.Color.BufferObj == nullObj)
343 FREE( (void *) ac->Cache.Color.Ptr );
344 if (ac->Cache.SecondaryColor.Ptr && ac->Cache.SecondaryColor.BufferObj == nullObj)
345 FREE( (void *) ac->Cache.SecondaryColor.Ptr );
346 if (ac->Cache.EdgeFlag.Ptr && ac->Cache.EdgeFlag.BufferObj == nullObj)
347 FREE( (void *) ac->Cache.EdgeFlag.Ptr );
348 if (ac->Cache.Index.Ptr && ac->Cache.Index.BufferObj == nullObj)
349 FREE( (void *) ac->Cache.Index.Ptr );
350 if (ac->Cache.FogCoord.Ptr && ac->Cache.FogCoord.BufferObj == nullObj)
351 FREE( (void *) ac->Cache.FogCoord.Ptr );
352
353 for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
354 if (ac->Cache.TexCoord[i].Ptr && ac->Cache.TexCoord[i].BufferObj == nullObj)
355 FREE( (void *) ac->Cache.TexCoord[i].Ptr );
356 }
357
358 for (i = 0; i < VERT_ATTRIB_MAX; i++) {
359 if (ac->Cache.Attrib[i].Ptr && ac->Cache.Attrib[i].BufferObj == nullObj)
360 FREE( (void *) ac->Cache.Attrib[i].Ptr );
361 }
362
363 if (ac->Elts)
364 FREE( ac->Elts );
365
366 /* Free the context structure itself */
367 FREE(ac);
368 ctx->acache_context = NULL;
369 }
370
371 void _ac_InvalidateState( GLcontext *ctx, GLuint new_state )
372 {
373 AC_CONTEXT(ctx)->NewState |= new_state;
374 AC_CONTEXT(ctx)->NewArrayState |= ctx->Array.NewState;
375 }