OSDN Git Service

1899975213f6be6f7f0a799ae46740ab767fe9ab
[android-x86/external-mesa.git] / src / mesa / main / api_arrayelt.c
1 /*
2  * Mesa 3-D graphics library
3  * Version:  6.5.1
4  *
5  * Copyright (C) 1999-2006  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
25 /* Author:
26  *    Keith Whitwell <keith@tungstengraphics.com>
27  */
28
29 #include "glheader.h"
30 #include "api_arrayelt.h"
31 #include "context.h"
32 #include "imports.h"
33 #include "macros.h"
34 #include "glapioffsets.h"
35 #include "dispatch.h"
36
37 typedef void (GLAPIENTRY *array_func)( const void * );
38
39 typedef struct {
40    const struct gl_client_array *array;
41    int offset;
42 } AEarray;
43
44 typedef void (GLAPIENTRY *attrib_func)( GLuint indx, const void *data );
45
46 typedef struct {
47    const struct gl_client_array *array;
48    attrib_func func;
49    GLuint index;
50 } AEattrib;
51
52 typedef struct {
53    AEarray arrays[32];
54    AEattrib attribs[VERT_ATTRIB_MAX + 1];
55    GLuint NewState;
56
57    struct gl_buffer_object *vbo[VERT_ATTRIB_MAX];
58    GLuint nr_vbos;
59    GLboolean mapped_vbos;
60
61 } AEcontext;
62
63 #define AE_CONTEXT(ctx) ((AEcontext *)(ctx)->aelt_context)
64
65
66 /*
67  * Convert GL_BYTE, GL_UNSIGNED_BYTE, .. GL_DOUBLE into an integer
68  * in the range [0, 7].  Luckily these type tokens are sequentially
69  * numbered in gl.h, except for GL_DOUBLE.
70  */
71 #define TYPE_IDX(t) ( (t) == GL_DOUBLE ? 7 : (t) & 7 )
72
73 static const int ColorFuncs[2][8] = {
74    {
75       _gloffset_Color3bv,
76       _gloffset_Color3ubv,
77       _gloffset_Color3sv,
78       _gloffset_Color3usv,
79       _gloffset_Color3iv,
80       _gloffset_Color3uiv,
81       _gloffset_Color3fv,
82       _gloffset_Color3dv,
83    },
84    {
85       _gloffset_Color4bv,
86       _gloffset_Color4ubv,
87       _gloffset_Color4sv,
88       _gloffset_Color4usv,
89       _gloffset_Color4iv,
90       _gloffset_Color4uiv,
91       _gloffset_Color4fv,
92       _gloffset_Color4dv,
93    },
94 };
95
96 static const int VertexFuncs[3][8] = {
97    {
98       -1,
99       -1,
100       _gloffset_Vertex2sv,
101       -1,
102       _gloffset_Vertex2iv,
103       -1,
104       _gloffset_Vertex2fv,
105       _gloffset_Vertex2dv,
106    },
107    {
108       -1,
109       -1,
110       _gloffset_Vertex3sv,
111       -1,
112       _gloffset_Vertex3iv,
113       -1,
114       _gloffset_Vertex3fv,
115       _gloffset_Vertex3dv,
116    },
117    {
118       -1,
119       -1,
120       _gloffset_Vertex4sv,
121       -1,
122       _gloffset_Vertex4iv,
123       -1,
124       _gloffset_Vertex4fv,
125       _gloffset_Vertex4dv,
126    },
127 };
128
129 static const int IndexFuncs[8] = {
130    -1,
131    _gloffset_Indexubv,
132    _gloffset_Indexsv,
133    -1,
134    _gloffset_Indexiv,
135    -1,
136    _gloffset_Indexfv,
137    _gloffset_Indexdv,
138 };
139
140 static const int NormalFuncs[8] = {
141    _gloffset_Normal3bv,
142    -1,
143    _gloffset_Normal3sv,
144    -1,
145    _gloffset_Normal3iv,
146    -1,
147    _gloffset_Normal3fv,
148    _gloffset_Normal3dv,
149 };
150
151 /* Note: _gloffset_* for these may not be a compile-time constant. */
152 static int SecondaryColorFuncs[8];
153 static int FogCoordFuncs[8];
154
155
156 /**
157  ** GL_NV_vertex_program
158  **/
159
160 /* GL_BYTE attributes */
161
162 static void GLAPIENTRY VertexAttrib1NbvNV(GLuint index, const GLbyte *v)
163 {
164    CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0])));
165 }
166
167 static void GLAPIENTRY VertexAttrib1bvNV(GLuint index, const GLbyte *v)
168 {
169    CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
170 }
171
172 static void GLAPIENTRY VertexAttrib2NbvNV(GLuint index, const GLbyte *v)
173 {
174    CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1])));
175 }
176
177 static void GLAPIENTRY VertexAttrib2bvNV(GLuint index, const GLbyte *v)
178 {
179    CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
180 }
181
182 static void GLAPIENTRY VertexAttrib3NbvNV(GLuint index, const GLbyte *v)
183 {
184    CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
185                                                BYTE_TO_FLOAT(v[1]),
186                                                BYTE_TO_FLOAT(v[2])));
187 }
188
189 static void GLAPIENTRY VertexAttrib3bvNV(GLuint index, const GLbyte *v)
190 {
191    CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
192 }
193
194 static void GLAPIENTRY VertexAttrib4NbvNV(GLuint index, const GLbyte *v)
195 {
196    CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
197                                                BYTE_TO_FLOAT(v[1]),
198                                                BYTE_TO_FLOAT(v[2]),
199                                                BYTE_TO_FLOAT(v[3])));
200 }
201
202 static void GLAPIENTRY VertexAttrib4bvNV(GLuint index, const GLbyte *v)
203 {
204    CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
205 }
206
207 /* GL_UNSIGNED_BYTE attributes */
208
209 static void GLAPIENTRY VertexAttrib1NubvNV(GLuint index, const GLubyte *v)
210 {
211    CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0])));
212 }
213
214 static void GLAPIENTRY VertexAttrib1ubvNV(GLuint index, const GLubyte *v)
215 {
216    CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
217 }
218
219 static void GLAPIENTRY VertexAttrib2NubvNV(GLuint index, const GLubyte *v)
220 {
221    CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
222                                                UBYTE_TO_FLOAT(v[1])));
223 }
224
225 static void GLAPIENTRY VertexAttrib2ubvNV(GLuint index, const GLubyte *v)
226 {
227    CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
228 }
229
230 static void GLAPIENTRY VertexAttrib3NubvNV(GLuint index, const GLubyte *v)
231 {
232    CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
233                                                UBYTE_TO_FLOAT(v[1]),
234                                                UBYTE_TO_FLOAT(v[2])));
235 }
236 static void GLAPIENTRY VertexAttrib3ubvNV(GLuint index, const GLubyte *v)
237 {
238    CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
239 }
240
241 static void GLAPIENTRY VertexAttrib4NubvNV(GLuint index, const GLubyte *v)
242 {
243    CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
244                                      UBYTE_TO_FLOAT(v[1]),
245                                      UBYTE_TO_FLOAT(v[2]),
246                                      UBYTE_TO_FLOAT(v[3])));
247 }
248
249 static void GLAPIENTRY VertexAttrib4ubvNV(GLuint index, const GLubyte *v)
250 {
251    CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
252 }
253
254 /* GL_SHORT attributes */
255
256 static void GLAPIENTRY VertexAttrib1NsvNV(GLuint index, const GLshort *v)
257 {
258    CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0])));
259 }
260
261 static void GLAPIENTRY VertexAttrib1svNV(GLuint index, const GLshort *v)
262 {
263    CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
264 }
265
266 static void GLAPIENTRY VertexAttrib2NsvNV(GLuint index, const GLshort *v)
267 {
268    CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
269                                                SHORT_TO_FLOAT(v[1])));
270 }
271
272 static void GLAPIENTRY VertexAttrib2svNV(GLuint index, const GLshort *v)
273 {
274    CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
275 }
276
277 static void GLAPIENTRY VertexAttrib3NsvNV(GLuint index, const GLshort *v)
278 {
279    CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
280                              SHORT_TO_FLOAT(v[1]),
281                              SHORT_TO_FLOAT(v[2])));
282 }
283
284 static void GLAPIENTRY VertexAttrib3svNV(GLuint index, const GLshort *v)
285 {
286    CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
287 }
288
289 static void GLAPIENTRY VertexAttrib4NsvNV(GLuint index, const GLshort *v)
290 {
291    CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
292                              SHORT_TO_FLOAT(v[1]),
293                              SHORT_TO_FLOAT(v[2]),
294                              SHORT_TO_FLOAT(v[3])));
295 }
296
297 static void GLAPIENTRY VertexAttrib4svNV(GLuint index, const GLshort *v)
298 {
299    CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
300 }
301
302 /* GL_UNSIGNED_SHORT attributes */
303
304 static void GLAPIENTRY VertexAttrib1NusvNV(GLuint index, const GLushort *v)
305 {
306    CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0])));
307 }
308
309 static void GLAPIENTRY VertexAttrib1usvNV(GLuint index, const GLushort *v)
310 {
311    CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
312 }
313
314 static void GLAPIENTRY VertexAttrib2NusvNV(GLuint index, const GLushort *v)
315 {
316    CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
317                              USHORT_TO_FLOAT(v[1])));
318 }
319
320 static void GLAPIENTRY VertexAttrib2usvNV(GLuint index, const GLushort *v)
321 {
322    CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
323 }
324
325 static void GLAPIENTRY VertexAttrib3NusvNV(GLuint index, const GLushort *v)
326 {
327    CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
328                                                USHORT_TO_FLOAT(v[1]),
329                                                USHORT_TO_FLOAT(v[2])));
330 }
331
332 static void GLAPIENTRY VertexAttrib3usvNV(GLuint index, const GLushort *v)
333 {
334    CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
335 }
336
337 static void GLAPIENTRY VertexAttrib4NusvNV(GLuint index, const GLushort *v)
338 {
339    CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
340                                                USHORT_TO_FLOAT(v[1]),
341                                                USHORT_TO_FLOAT(v[2]),
342                                                USHORT_TO_FLOAT(v[3])));
343 }
344
345 static void GLAPIENTRY VertexAttrib4usvNV(GLuint index, const GLushort *v)
346 {
347    CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
348 }
349
350 /* GL_INT attributes */
351
352 static void GLAPIENTRY VertexAttrib1NivNV(GLuint index, const GLint *v)
353 {
354    CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0])));
355 }
356
357 static void GLAPIENTRY VertexAttrib1ivNV(GLuint index, const GLint *v)
358 {
359    CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
360 }
361
362 static void GLAPIENTRY VertexAttrib2NivNV(GLuint index, const GLint *v)
363 {
364    CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
365                                                INT_TO_FLOAT(v[1])));
366 }
367
368 static void GLAPIENTRY VertexAttrib2ivNV(GLuint index, const GLint *v)
369 {
370    CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
371 }
372
373 static void GLAPIENTRY VertexAttrib3NivNV(GLuint index, const GLint *v)
374 {
375    CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
376                                                INT_TO_FLOAT(v[1]),
377                                                INT_TO_FLOAT(v[2])));
378 }
379
380 static void GLAPIENTRY VertexAttrib3ivNV(GLuint index, const GLint *v)
381 {
382    CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
383 }
384
385 static void GLAPIENTRY VertexAttrib4NivNV(GLuint index, const GLint *v)
386 {
387    CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
388                                                INT_TO_FLOAT(v[1]),
389                                                INT_TO_FLOAT(v[2]),
390                                                INT_TO_FLOAT(v[3])));
391 }
392
393 static void GLAPIENTRY VertexAttrib4ivNV(GLuint index, const GLint *v)
394 {
395    CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
396 }
397
398 /* GL_UNSIGNED_INT attributes */
399
400 static void GLAPIENTRY VertexAttrib1NuivNV(GLuint index, const GLuint *v)
401 {
402    CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0])));
403 }
404
405 static void GLAPIENTRY VertexAttrib1uivNV(GLuint index, const GLuint *v)
406 {
407    CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
408 }
409
410 static void GLAPIENTRY VertexAttrib2NuivNV(GLuint index, const GLuint *v)
411 {
412    CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
413                                                UINT_TO_FLOAT(v[1])));
414 }
415
416 static void GLAPIENTRY VertexAttrib2uivNV(GLuint index, const GLuint *v)
417 {
418    CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
419 }
420
421 static void GLAPIENTRY VertexAttrib3NuivNV(GLuint index, const GLuint *v)
422 {
423    CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
424                                                UINT_TO_FLOAT(v[1]),
425                                                UINT_TO_FLOAT(v[2])));
426 }
427
428 static void GLAPIENTRY VertexAttrib3uivNV(GLuint index, const GLuint *v)
429 {
430    CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
431 }
432
433 static void GLAPIENTRY VertexAttrib4NuivNV(GLuint index, const GLuint *v)
434 {
435    CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
436                                                UINT_TO_FLOAT(v[1]),
437                                                UINT_TO_FLOAT(v[2]),
438                                                UINT_TO_FLOAT(v[3])));
439 }
440
441 static void GLAPIENTRY VertexAttrib4uivNV(GLuint index, const GLuint *v)
442 {
443    CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
444 }
445
446 /* GL_FLOAT attributes */
447
448 static void GLAPIENTRY VertexAttrib1fvNV(GLuint index, const GLfloat *v)
449 {
450    CALL_VertexAttrib1fvNV(GET_DISPATCH(), (index, v));
451 }
452
453 static void GLAPIENTRY VertexAttrib2fvNV(GLuint index, const GLfloat *v)
454 {
455    CALL_VertexAttrib2fvNV(GET_DISPATCH(), (index, v));
456 }
457
458 static void GLAPIENTRY VertexAttrib3fvNV(GLuint index, const GLfloat *v)
459 {
460    CALL_VertexAttrib3fvNV(GET_DISPATCH(), (index, v));
461 }
462
463 static void GLAPIENTRY VertexAttrib4fvNV(GLuint index, const GLfloat *v)
464 {
465    CALL_VertexAttrib4fvNV(GET_DISPATCH(), (index, v));
466 }
467
468 /* GL_DOUBLE attributes */
469
470 static void GLAPIENTRY VertexAttrib1dvNV(GLuint index, const GLdouble *v)
471 {
472    CALL_VertexAttrib1dvNV(GET_DISPATCH(), (index, v));
473 }
474
475 static void GLAPIENTRY VertexAttrib2dvNV(GLuint index, const GLdouble *v)
476 {
477    CALL_VertexAttrib2dvNV(GET_DISPATCH(), (index, v));
478 }
479
480 static void GLAPIENTRY VertexAttrib3dvNV(GLuint index, const GLdouble *v)
481 {
482    CALL_VertexAttrib3dvNV(GET_DISPATCH(), (index, v));
483 }
484
485 static void GLAPIENTRY VertexAttrib4dvNV(GLuint index, const GLdouble *v)
486 {
487    CALL_VertexAttrib4dvNV(GET_DISPATCH(), (index, v));
488 }
489
490
491 /*
492  * Array [size][type] of VertexAttrib functions
493  */
494 static attrib_func AttribFuncsNV[2][4][8] = {
495    {
496       /* non-normalized */
497       {
498          /* size 1 */
499          (attrib_func) VertexAttrib1bvNV,
500          (attrib_func) VertexAttrib1ubvNV,
501          (attrib_func) VertexAttrib1svNV,
502          (attrib_func) VertexAttrib1usvNV,
503          (attrib_func) VertexAttrib1ivNV,
504          (attrib_func) VertexAttrib1uivNV,
505          (attrib_func) VertexAttrib1fvNV,
506          (attrib_func) VertexAttrib1dvNV
507       },
508       {
509          /* size 2 */
510          (attrib_func) VertexAttrib2bvNV,
511          (attrib_func) VertexAttrib2ubvNV,
512          (attrib_func) VertexAttrib2svNV,
513          (attrib_func) VertexAttrib2usvNV,
514          (attrib_func) VertexAttrib2ivNV,
515          (attrib_func) VertexAttrib2uivNV,
516          (attrib_func) VertexAttrib2fvNV,
517          (attrib_func) VertexAttrib2dvNV
518       },
519       {
520          /* size 3 */
521          (attrib_func) VertexAttrib3bvNV,
522          (attrib_func) VertexAttrib3ubvNV,
523          (attrib_func) VertexAttrib3svNV,
524          (attrib_func) VertexAttrib3usvNV,
525          (attrib_func) VertexAttrib3ivNV,
526          (attrib_func) VertexAttrib3uivNV,
527          (attrib_func) VertexAttrib3fvNV,
528          (attrib_func) VertexAttrib3dvNV
529       },
530       {
531          /* size 4 */
532          (attrib_func) VertexAttrib4bvNV,
533          (attrib_func) VertexAttrib4ubvNV,
534          (attrib_func) VertexAttrib4svNV,
535          (attrib_func) VertexAttrib4usvNV,
536          (attrib_func) VertexAttrib4ivNV,
537          (attrib_func) VertexAttrib4uivNV,
538          (attrib_func) VertexAttrib4fvNV,
539          (attrib_func) VertexAttrib4dvNV
540       }
541    },
542    {
543       /* normalized (except for float/double) */
544       {
545          /* size 1 */
546          (attrib_func) VertexAttrib1NbvNV,
547          (attrib_func) VertexAttrib1NubvNV,
548          (attrib_func) VertexAttrib1NsvNV,
549          (attrib_func) VertexAttrib1NusvNV,
550          (attrib_func) VertexAttrib1NivNV,
551          (attrib_func) VertexAttrib1NuivNV,
552          (attrib_func) VertexAttrib1fvNV,
553          (attrib_func) VertexAttrib1dvNV
554       },
555       {
556          /* size 2 */
557          (attrib_func) VertexAttrib2NbvNV,
558          (attrib_func) VertexAttrib2NubvNV,
559          (attrib_func) VertexAttrib2NsvNV,
560          (attrib_func) VertexAttrib2NusvNV,
561          (attrib_func) VertexAttrib2NivNV,
562          (attrib_func) VertexAttrib2NuivNV,
563          (attrib_func) VertexAttrib2fvNV,
564          (attrib_func) VertexAttrib2dvNV
565       },
566       {
567          /* size 3 */
568          (attrib_func) VertexAttrib3NbvNV,
569          (attrib_func) VertexAttrib3NubvNV,
570          (attrib_func) VertexAttrib3NsvNV,
571          (attrib_func) VertexAttrib3NusvNV,
572          (attrib_func) VertexAttrib3NivNV,
573          (attrib_func) VertexAttrib3NuivNV,
574          (attrib_func) VertexAttrib3fvNV,
575          (attrib_func) VertexAttrib3dvNV
576       },
577       {
578          /* size 4 */
579          (attrib_func) VertexAttrib4NbvNV,
580          (attrib_func) VertexAttrib4NubvNV,
581          (attrib_func) VertexAttrib4NsvNV,
582          (attrib_func) VertexAttrib4NusvNV,
583          (attrib_func) VertexAttrib4NivNV,
584          (attrib_func) VertexAttrib4NuivNV,
585          (attrib_func) VertexAttrib4fvNV,
586          (attrib_func) VertexAttrib4dvNV
587       }
588    }
589 };
590
591
592 /**
593  ** GL_ARB_vertex_program
594  **/
595
596 /* GL_BYTE attributes */
597
598 static void GLAPIENTRY VertexAttrib1NbvARB(GLuint index, const GLbyte *v)
599 {
600    CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0])));
601 }
602
603 static void GLAPIENTRY VertexAttrib1bvARB(GLuint index, const GLbyte *v)
604 {
605    CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
606 }
607
608 static void GLAPIENTRY VertexAttrib2NbvARB(GLuint index, const GLbyte *v)
609 {
610    CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1])));
611 }
612
613 static void GLAPIENTRY VertexAttrib2bvARB(GLuint index, const GLbyte *v)
614 {
615    CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
616 }
617
618 static void GLAPIENTRY VertexAttrib3NbvARB(GLuint index, const GLbyte *v)
619 {
620    CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
621                                                BYTE_TO_FLOAT(v[1]),
622                                                BYTE_TO_FLOAT(v[2])));
623 }
624
625 static void GLAPIENTRY VertexAttrib3bvARB(GLuint index, const GLbyte *v)
626 {
627    CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
628 }
629
630 static void GLAPIENTRY VertexAttrib4NbvARB(GLuint index, const GLbyte *v)
631 {
632    CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
633                                                BYTE_TO_FLOAT(v[1]),
634                                                BYTE_TO_FLOAT(v[2]),
635                                                BYTE_TO_FLOAT(v[3])));
636 }
637
638 static void GLAPIENTRY VertexAttrib4bvARB(GLuint index, const GLbyte *v)
639 {
640    CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
641 }
642
643 /* GL_UNSIGNED_BYTE attributes */
644
645 static void GLAPIENTRY VertexAttrib1NubvARB(GLuint index, const GLubyte *v)
646 {
647    CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0])));
648 }
649
650 static void GLAPIENTRY VertexAttrib1ubvARB(GLuint index, const GLubyte *v)
651 {
652    CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
653 }
654
655 static void GLAPIENTRY VertexAttrib2NubvARB(GLuint index, const GLubyte *v)
656 {
657    CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
658                                                UBYTE_TO_FLOAT(v[1])));
659 }
660
661 static void GLAPIENTRY VertexAttrib2ubvARB(GLuint index, const GLubyte *v)
662 {
663    CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
664 }
665
666 static void GLAPIENTRY VertexAttrib3NubvARB(GLuint index, const GLubyte *v)
667 {
668    CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
669                                                UBYTE_TO_FLOAT(v[1]),
670                                                UBYTE_TO_FLOAT(v[2])));
671 }
672 static void GLAPIENTRY VertexAttrib3ubvARB(GLuint index, const GLubyte *v)
673 {
674    CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
675 }
676
677 static void GLAPIENTRY VertexAttrib4NubvARB(GLuint index, const GLubyte *v)
678 {
679    CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
680                                      UBYTE_TO_FLOAT(v[1]),
681                                      UBYTE_TO_FLOAT(v[2]),
682                                      UBYTE_TO_FLOAT(v[3])));
683 }
684
685 static void GLAPIENTRY VertexAttrib4ubvARB(GLuint index, const GLubyte *v)
686 {
687    CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
688 }
689
690 /* GL_SHORT attributes */
691
692 static void GLAPIENTRY VertexAttrib1NsvARB(GLuint index, const GLshort *v)
693 {
694    CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0])));
695 }
696
697 static void GLAPIENTRY VertexAttrib1svARB(GLuint index, const GLshort *v)
698 {
699    CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
700 }
701
702 static void GLAPIENTRY VertexAttrib2NsvARB(GLuint index, const GLshort *v)
703 {
704    CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
705                                                SHORT_TO_FLOAT(v[1])));
706 }
707
708 static void GLAPIENTRY VertexAttrib2svARB(GLuint index, const GLshort *v)
709 {
710    CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
711 }
712
713 static void GLAPIENTRY VertexAttrib3NsvARB(GLuint index, const GLshort *v)
714 {
715    CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
716                              SHORT_TO_FLOAT(v[1]),
717                              SHORT_TO_FLOAT(v[2])));
718 }
719
720 static void GLAPIENTRY VertexAttrib3svARB(GLuint index, const GLshort *v)
721 {
722    CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
723 }
724
725 static void GLAPIENTRY VertexAttrib4NsvARB(GLuint index, const GLshort *v)
726 {
727    CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
728                              SHORT_TO_FLOAT(v[1]),
729                              SHORT_TO_FLOAT(v[2]),
730                              SHORT_TO_FLOAT(v[3])));
731 }
732
733 static void GLAPIENTRY VertexAttrib4svARB(GLuint index, const GLshort *v)
734 {
735    CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
736 }
737
738 /* GL_UNSIGNED_SHORT attributes */
739
740 static void GLAPIENTRY VertexAttrib1NusvARB(GLuint index, const GLushort *v)
741 {
742    CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0])));
743 }
744
745 static void GLAPIENTRY VertexAttrib1usvARB(GLuint index, const GLushort *v)
746 {
747    CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
748 }
749
750 static void GLAPIENTRY VertexAttrib2NusvARB(GLuint index, const GLushort *v)
751 {
752    CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
753                              USHORT_TO_FLOAT(v[1])));
754 }
755
756 static void GLAPIENTRY VertexAttrib2usvARB(GLuint index, const GLushort *v)
757 {
758    CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
759 }
760
761 static void GLAPIENTRY VertexAttrib3NusvARB(GLuint index, const GLushort *v)
762 {
763    CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
764                                                USHORT_TO_FLOAT(v[1]),
765                                                USHORT_TO_FLOAT(v[2])));
766 }
767
768 static void GLAPIENTRY VertexAttrib3usvARB(GLuint index, const GLushort *v)
769 {
770    CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
771 }
772
773 static void GLAPIENTRY VertexAttrib4NusvARB(GLuint index, const GLushort *v)
774 {
775    CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
776                                                USHORT_TO_FLOAT(v[1]),
777                                                USHORT_TO_FLOAT(v[2]),
778                                                USHORT_TO_FLOAT(v[3])));
779 }
780
781 static void GLAPIENTRY VertexAttrib4usvARB(GLuint index, const GLushort *v)
782 {
783    CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
784 }
785
786 /* GL_INT attributes */
787
788 static void GLAPIENTRY VertexAttrib1NivARB(GLuint index, const GLint *v)
789 {
790    CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0])));
791 }
792
793 static void GLAPIENTRY VertexAttrib1ivARB(GLuint index, const GLint *v)
794 {
795    CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
796 }
797
798 static void GLAPIENTRY VertexAttrib2NivARB(GLuint index, const GLint *v)
799 {
800    CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
801                                                INT_TO_FLOAT(v[1])));
802 }
803
804 static void GLAPIENTRY VertexAttrib2ivARB(GLuint index, const GLint *v)
805 {
806    CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
807 }
808
809 static void GLAPIENTRY VertexAttrib3NivARB(GLuint index, const GLint *v)
810 {
811    CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
812                                                INT_TO_FLOAT(v[1]),
813                                                INT_TO_FLOAT(v[2])));
814 }
815
816 static void GLAPIENTRY VertexAttrib3ivARB(GLuint index, const GLint *v)
817 {
818    CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
819 }
820
821 static void GLAPIENTRY VertexAttrib4NivARB(GLuint index, const GLint *v)
822 {
823    CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
824                                                INT_TO_FLOAT(v[1]),
825                                                INT_TO_FLOAT(v[2]),
826                                                INT_TO_FLOAT(v[3])));
827 }
828
829 static void GLAPIENTRY VertexAttrib4ivARB(GLuint index, const GLint *v)
830 {
831    CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
832 }
833
834 /* GL_UNSIGNED_INT attributes */
835
836 static void GLAPIENTRY VertexAttrib1NuivARB(GLuint index, const GLuint *v)
837 {
838    CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0])));
839 }
840
841 static void GLAPIENTRY VertexAttrib1uivARB(GLuint index, const GLuint *v)
842 {
843    CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
844 }
845
846 static void GLAPIENTRY VertexAttrib2NuivARB(GLuint index, const GLuint *v)
847 {
848    CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
849                                                UINT_TO_FLOAT(v[1])));
850 }
851
852 static void GLAPIENTRY VertexAttrib2uivARB(GLuint index, const GLuint *v)
853 {
854    CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
855 }
856
857 static void GLAPIENTRY VertexAttrib3NuivARB(GLuint index, const GLuint *v)
858 {
859    CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
860                                                UINT_TO_FLOAT(v[1]),
861                                                UINT_TO_FLOAT(v[2])));
862 }
863
864 static void GLAPIENTRY VertexAttrib3uivARB(GLuint index, const GLuint *v)
865 {
866    CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
867 }
868
869 static void GLAPIENTRY VertexAttrib4NuivARB(GLuint index, const GLuint *v)
870 {
871    CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
872                                                UINT_TO_FLOAT(v[1]),
873                                                UINT_TO_FLOAT(v[2]),
874                                                UINT_TO_FLOAT(v[3])));
875 }
876
877 static void GLAPIENTRY VertexAttrib4uivARB(GLuint index, const GLuint *v)
878 {
879    CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
880 }
881
882 /* GL_FLOAT attributes */
883
884 static void GLAPIENTRY VertexAttrib1fvARB(GLuint index, const GLfloat *v)
885 {
886    CALL_VertexAttrib1fvARB(GET_DISPATCH(), (index, v));
887 }
888
889 static void GLAPIENTRY VertexAttrib2fvARB(GLuint index, const GLfloat *v)
890 {
891    CALL_VertexAttrib2fvARB(GET_DISPATCH(), (index, v));
892 }
893
894 static void GLAPIENTRY VertexAttrib3fvARB(GLuint index, const GLfloat *v)
895 {
896    CALL_VertexAttrib3fvARB(GET_DISPATCH(), (index, v));
897 }
898
899 static void GLAPIENTRY VertexAttrib4fvARB(GLuint index, const GLfloat *v)
900 {
901    CALL_VertexAttrib4fvARB(GET_DISPATCH(), (index, v));
902 }
903
904 /* GL_DOUBLE attributes */
905
906 static void GLAPIENTRY VertexAttrib1dvARB(GLuint index, const GLdouble *v)
907 {
908    CALL_VertexAttrib1dvARB(GET_DISPATCH(), (index, v));
909 }
910
911 static void GLAPIENTRY VertexAttrib2dvARB(GLuint index, const GLdouble *v)
912 {
913    CALL_VertexAttrib2dvARB(GET_DISPATCH(), (index, v));
914 }
915
916 static void GLAPIENTRY VertexAttrib3dvARB(GLuint index, const GLdouble *v)
917 {
918    CALL_VertexAttrib3dvARB(GET_DISPATCH(), (index, v));
919 }
920
921 static void GLAPIENTRY VertexAttrib4dvARB(GLuint index, const GLdouble *v)
922 {
923    CALL_VertexAttrib4dvARB(GET_DISPATCH(), (index, v));
924 }
925
926
927 /*
928  * Array [size][type] of VertexAttrib functions
929  */
930 static attrib_func AttribFuncsARB[2][4][8] = {
931    {
932       /* non-normalized */
933       {
934          /* size 1 */
935          (attrib_func) VertexAttrib1bvARB,
936          (attrib_func) VertexAttrib1ubvARB,
937          (attrib_func) VertexAttrib1svARB,
938          (attrib_func) VertexAttrib1usvARB,
939          (attrib_func) VertexAttrib1ivARB,
940          (attrib_func) VertexAttrib1uivARB,
941          (attrib_func) VertexAttrib1fvARB,
942          (attrib_func) VertexAttrib1dvARB
943       },
944       {
945          /* size 2 */
946          (attrib_func) VertexAttrib2bvARB,
947          (attrib_func) VertexAttrib2ubvARB,
948          (attrib_func) VertexAttrib2svARB,
949          (attrib_func) VertexAttrib2usvARB,
950          (attrib_func) VertexAttrib2ivARB,
951          (attrib_func) VertexAttrib2uivARB,
952          (attrib_func) VertexAttrib2fvARB,
953          (attrib_func) VertexAttrib2dvARB
954       },
955       {
956          /* size 3 */
957          (attrib_func) VertexAttrib3bvARB,
958          (attrib_func) VertexAttrib3ubvARB,
959          (attrib_func) VertexAttrib3svARB,
960          (attrib_func) VertexAttrib3usvARB,
961          (attrib_func) VertexAttrib3ivARB,
962          (attrib_func) VertexAttrib3uivARB,
963          (attrib_func) VertexAttrib3fvARB,
964          (attrib_func) VertexAttrib3dvARB
965       },
966       {
967          /* size 4 */
968          (attrib_func) VertexAttrib4bvARB,
969          (attrib_func) VertexAttrib4ubvARB,
970          (attrib_func) VertexAttrib4svARB,
971          (attrib_func) VertexAttrib4usvARB,
972          (attrib_func) VertexAttrib4ivARB,
973          (attrib_func) VertexAttrib4uivARB,
974          (attrib_func) VertexAttrib4fvARB,
975          (attrib_func) VertexAttrib4dvARB
976       }
977    },
978    {
979       /* normalized (except for float/double) */
980       {
981          /* size 1 */
982          (attrib_func) VertexAttrib1NbvARB,
983          (attrib_func) VertexAttrib1NubvARB,
984          (attrib_func) VertexAttrib1NsvARB,
985          (attrib_func) VertexAttrib1NusvARB,
986          (attrib_func) VertexAttrib1NivARB,
987          (attrib_func) VertexAttrib1NuivARB,
988          (attrib_func) VertexAttrib1fvARB,
989          (attrib_func) VertexAttrib1dvARB
990       },
991       {
992          /* size 2 */
993          (attrib_func) VertexAttrib2NbvARB,
994          (attrib_func) VertexAttrib2NubvARB,
995          (attrib_func) VertexAttrib2NsvARB,
996          (attrib_func) VertexAttrib2NusvARB,
997          (attrib_func) VertexAttrib2NivARB,
998          (attrib_func) VertexAttrib2NuivARB,
999          (attrib_func) VertexAttrib2fvARB,
1000          (attrib_func) VertexAttrib2dvARB
1001       },
1002       {
1003          /* size 3 */
1004          (attrib_func) VertexAttrib3NbvARB,
1005          (attrib_func) VertexAttrib3NubvARB,
1006          (attrib_func) VertexAttrib3NsvARB,
1007          (attrib_func) VertexAttrib3NusvARB,
1008          (attrib_func) VertexAttrib3NivARB,
1009          (attrib_func) VertexAttrib3NuivARB,
1010          (attrib_func) VertexAttrib3fvARB,
1011          (attrib_func) VertexAttrib3dvARB
1012       },
1013       {
1014          /* size 4 */
1015          (attrib_func) VertexAttrib4NbvARB,
1016          (attrib_func) VertexAttrib4NubvARB,
1017          (attrib_func) VertexAttrib4NsvARB,
1018          (attrib_func) VertexAttrib4NusvARB,
1019          (attrib_func) VertexAttrib4NivARB,
1020          (attrib_func) VertexAttrib4NuivARB,
1021          (attrib_func) VertexAttrib4fvARB,
1022          (attrib_func) VertexAttrib4dvARB
1023       }
1024    }
1025 };
1026
1027 /**********************************************************************/
1028
1029
1030 GLboolean _ae_create_context( GLcontext *ctx )
1031 {
1032    if (ctx->aelt_context)
1033       return GL_TRUE;
1034
1035    /* These _gloffset_* values may not be compile-time constants */
1036    SecondaryColorFuncs[0] = _gloffset_SecondaryColor3bvEXT;
1037    SecondaryColorFuncs[1] = _gloffset_SecondaryColor3ubvEXT;
1038    SecondaryColorFuncs[2] = _gloffset_SecondaryColor3svEXT;
1039    SecondaryColorFuncs[3] = _gloffset_SecondaryColor3usvEXT;
1040    SecondaryColorFuncs[4] = _gloffset_SecondaryColor3ivEXT;
1041    SecondaryColorFuncs[5] = _gloffset_SecondaryColor3uivEXT;
1042    SecondaryColorFuncs[6] = _gloffset_SecondaryColor3fvEXT;
1043    SecondaryColorFuncs[7] = _gloffset_SecondaryColor3dvEXT;
1044
1045    FogCoordFuncs[0] = -1;
1046    FogCoordFuncs[1] = -1;
1047    FogCoordFuncs[2] = -1;
1048    FogCoordFuncs[3] = -1;
1049    FogCoordFuncs[4] = -1;
1050    FogCoordFuncs[5] = -1;
1051    FogCoordFuncs[6] = _gloffset_FogCoordfvEXT;
1052    FogCoordFuncs[7] = _gloffset_FogCoorddvEXT;
1053
1054    ctx->aelt_context = CALLOC( sizeof(AEcontext) );
1055    if (!ctx->aelt_context)
1056       return GL_FALSE;
1057
1058    AE_CONTEXT(ctx)->NewState = ~0;
1059    return GL_TRUE;
1060 }
1061
1062
1063 void _ae_destroy_context( GLcontext *ctx )
1064 {
1065    if ( AE_CONTEXT( ctx ) ) {
1066       FREE( ctx->aelt_context );
1067       ctx->aelt_context = NULL;
1068    }
1069 }
1070
1071 static void check_vbo( AEcontext *actx,
1072                        struct gl_buffer_object *vbo )
1073 {
1074    if (vbo->Name && !vbo->Pointer) {
1075       GLuint i;
1076       for (i = 0; i < actx->nr_vbos; i++)
1077          if (actx->vbo[i] == vbo)
1078             return;
1079       assert(actx->nr_vbos < VERT_ATTRIB_MAX);
1080       actx->vbo[actx->nr_vbos++] = vbo;
1081    }
1082 }
1083
1084
1085 /**
1086  * Make a list of per-vertex functions to call for each glArrayElement call.
1087  * These functions access the array data (i.e. glVertex, glColor, glNormal,
1088  * etc).
1089  * Note: this may be called during display list construction.
1090  */
1091 static void _ae_update_state( GLcontext *ctx )
1092 {
1093    AEcontext *actx = AE_CONTEXT(ctx);
1094    AEarray *aa = actx->arrays;
1095    AEattrib *at = actx->attribs;
1096    GLuint i;
1097
1098    actx->nr_vbos = 0;
1099
1100    /* conventional vertex arrays */
1101   if (ctx->Array.ArrayObj->Index.Enabled) {
1102       aa->array = &ctx->Array.ArrayObj->Index;
1103       aa->offset = IndexFuncs[TYPE_IDX(aa->array->Type)];
1104       check_vbo(actx, aa->array->BufferObj);
1105       aa++;
1106    }
1107    if (ctx->Array.ArrayObj->EdgeFlag.Enabled) {
1108       aa->array = &ctx->Array.ArrayObj->EdgeFlag;
1109       aa->offset = _gloffset_EdgeFlagv;
1110       check_vbo(actx, aa->array->BufferObj);
1111       aa++;
1112    }
1113    if (ctx->Array.ArrayObj->Normal.Enabled) {
1114       aa->array = &ctx->Array.ArrayObj->Normal;
1115       aa->offset = NormalFuncs[TYPE_IDX(aa->array->Type)];
1116       check_vbo(actx, aa->array->BufferObj);
1117       aa++;
1118    }
1119    if (ctx->Array.ArrayObj->Color.Enabled) {
1120       aa->array = &ctx->Array.ArrayObj->Color;
1121       aa->offset = ColorFuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)];
1122       check_vbo(actx, aa->array->BufferObj);
1123       aa++;
1124    }
1125    if (ctx->Array.ArrayObj->SecondaryColor.Enabled) {
1126       aa->array = &ctx->Array.ArrayObj->SecondaryColor;
1127       aa->offset = SecondaryColorFuncs[TYPE_IDX(aa->array->Type)];
1128       check_vbo(actx, aa->array->BufferObj);
1129       aa++;
1130    }
1131    if (ctx->Array.ArrayObj->FogCoord.Enabled) {
1132       aa->array = &ctx->Array.ArrayObj->FogCoord;
1133       aa->offset = FogCoordFuncs[TYPE_IDX(aa->array->Type)];
1134       check_vbo(actx, aa->array->BufferObj);
1135       aa++;
1136    }
1137    for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
1138       struct gl_client_array *attribArray = &ctx->Array.ArrayObj->TexCoord[i];
1139       if (attribArray->Enabled) {
1140          /* NOTE: we use generic glVertexAttribNV functions here.
1141           * If we ever remove GL_NV_vertex_program this will have to change.
1142           */
1143          at->array = attribArray;
1144          ASSERT(!at->array->Normalized);
1145          at->func = AttribFuncsNV[at->array->Normalized]
1146                                  [at->array->Size-1]
1147                                  [TYPE_IDX(at->array->Type)];
1148          at->index = VERT_ATTRIB_TEX0 + i;
1149          check_vbo(actx, at->array->BufferObj);
1150          at++;
1151       }
1152    }
1153
1154    /* generic vertex attribute arrays */   
1155    for (i = 1; i < VERT_ATTRIB_MAX; i++) {  /* skip zero! */
1156       struct gl_client_array *attribArray = &ctx->Array.ArrayObj->VertexAttrib[i];
1157       if (attribArray->Enabled) {
1158          at->array = attribArray;
1159          /* Note: we can't grab the _glapi_Dispatch->VertexAttrib1fvNV
1160           * function pointer here (for float arrays) since the pointer may
1161           * change from one execution of _ae_loopback_array_elt() to
1162           * the next.  Doing so caused UT to break.
1163           */
1164          if (ctx->VertexProgram._Enabled
1165              && ctx->VertexProgram.Current->IsNVProgram) {
1166             at->func = AttribFuncsNV[at->array->Normalized]
1167                                     [at->array->Size-1]
1168                                     [TYPE_IDX(at->array->Type)];
1169          }
1170          else {
1171             at->func = AttribFuncsARB[at->array->Normalized]
1172                                      [at->array->Size-1]
1173                                      [TYPE_IDX(at->array->Type)];
1174          }
1175          at->index = i;
1176          check_vbo(actx, at->array->BufferObj);
1177          at++;
1178       }
1179    }
1180
1181    /* finally, vertex position */
1182    if (ctx->Array.ArrayObj->VertexAttrib[0].Enabled) {
1183       /* Use glVertex(v) instead of glVertexAttrib(0, v) to be sure it's
1184        * issued as the last (provoking) attribute).
1185        */
1186       aa->array = &ctx->Array.ArrayObj->VertexAttrib[0];
1187       assert(aa->array->Size >= 2); /* XXX fix someday? */
1188       aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
1189       check_vbo(actx, aa->array->BufferObj);
1190       aa++;
1191    }
1192    else if (ctx->Array.ArrayObj->Vertex.Enabled) {
1193       aa->array = &ctx->Array.ArrayObj->Vertex;
1194       aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
1195       check_vbo(actx, aa->array->BufferObj);
1196       aa++;
1197    }
1198
1199    check_vbo(actx, ctx->Array.ElementArrayBufferObj);
1200
1201    ASSERT(at - actx->attribs <= VERT_ATTRIB_MAX);
1202    ASSERT(aa - actx->arrays < 32);
1203    at->func = NULL;  /* terminate the list */
1204    aa->offset = -1;  /* terminate the list */
1205
1206    actx->NewState = 0;
1207 }
1208
1209 void _ae_map_vbos( GLcontext *ctx )
1210 {
1211    AEcontext *actx = AE_CONTEXT(ctx);
1212    GLuint i;
1213    
1214    if (actx->mapped_vbos)
1215       return;
1216
1217    if (actx->NewState)
1218       _ae_update_state(ctx);
1219
1220    for (i = 0; i < actx->nr_vbos; i++)
1221       ctx->Driver.MapBuffer(ctx,
1222                             GL_ARRAY_BUFFER_ARB,
1223                             GL_DYNAMIC_DRAW_ARB,
1224                             actx->vbo[i]);
1225
1226    if (actx->nr_vbos)
1227       actx->mapped_vbos = GL_TRUE;
1228 }
1229
1230 void _ae_unmap_vbos( GLcontext *ctx )
1231 {
1232    AEcontext *actx = AE_CONTEXT(ctx);
1233    GLuint i;
1234
1235    if (!actx->mapped_vbos)
1236       return;
1237
1238    assert (!actx->NewState);
1239
1240    for (i = 0; i < actx->nr_vbos; i++)
1241       ctx->Driver.UnmapBuffer(ctx,
1242                               GL_ARRAY_BUFFER_ARB,
1243                               actx->vbo[i]);
1244
1245    actx->mapped_vbos = GL_FALSE;
1246 }
1247
1248
1249 /**
1250  * Called via glArrayElement() and glDrawArrays().
1251  * Issue the glNormal, glVertex, glColor, glVertexAttrib, etc functions
1252  * for all enabled vertex arrays (for elt-th element).
1253  * Note: this may be called during display list construction.
1254  */
1255 void GLAPIENTRY _ae_loopback_array_elt( GLint elt )
1256 {
1257    GET_CURRENT_CONTEXT(ctx);
1258    const AEcontext *actx = AE_CONTEXT(ctx);
1259    const AEarray *aa;
1260    const AEattrib *at;
1261    const struct _glapi_table * const disp = GET_DISPATCH();
1262    GLboolean do_map;
1263
1264    if (actx->NewState) {
1265       assert(!actx->mapped_vbos);
1266       _ae_update_state( ctx );
1267    }
1268
1269    do_map = actx->nr_vbos && !actx->mapped_vbos;
1270
1271    /* 
1272     */
1273    if (do_map)
1274       _ae_map_vbos(ctx);
1275    
1276    /* generic attributes */
1277    for (at = actx->attribs; at->func; at++) {
1278       const GLubyte *src
1279          = ADD_POINTERS(at->array->BufferObj->Pointer, at->array->Ptr)
1280          + elt * at->array->StrideB;
1281       at->func( at->index, src );
1282    }
1283
1284    /* conventional arrays */
1285    for (aa = actx->arrays; aa->offset != -1 ; aa++) {
1286       const GLubyte *src
1287          = ADD_POINTERS(aa->array->BufferObj->Pointer, aa->array->Ptr)
1288          + elt * aa->array->StrideB;
1289       CALL_by_offset( disp, (array_func), aa->offset, 
1290                       ((const void *) src) );
1291    }
1292
1293    if (do_map)
1294       _ae_unmap_vbos(ctx);
1295 }
1296
1297
1298 void _ae_invalidate_state( GLcontext *ctx, GLuint new_state )
1299 {
1300    AEcontext *actx = AE_CONTEXT(ctx);
1301
1302    
1303    /* Only interested in this subset of mesa state.  Need to prune
1304     * this down as both tnl/ and the drivers can raise statechanges
1305     * for arcane reasons in the middle of seemingly atomic operations
1306     * like DrawElements, over which we'd like to keep a known set of
1307     * arrays and vbo's mapped.  
1308     *
1309     * Luckily, neither the drivers nor tnl muck with the state that
1310     * concerns us here:
1311     */
1312    new_state &= _NEW_ARRAY | _NEW_PROGRAM;
1313    if (new_state) {
1314       assert(!actx->mapped_vbos);
1315       actx->NewState |= new_state;
1316    }
1317 }