api_arrayelt.c revision 7117f1b4
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
37typedef void (GLAPIENTRY *array_func)( const void * );
38
39typedef struct {
40   const struct gl_client_array *array;
41   int offset;
42} AEarray;
43
44typedef void (GLAPIENTRY *attrib_func)( GLuint indx, const void *data );
45
46typedef struct {
47   const struct gl_client_array *array;
48   attrib_func func;
49   GLuint index;
50} AEattrib;
51
52typedef 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
73static 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
96static 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
129static 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
140static 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. */
152static int SecondaryColorFuncs[8];
153static int FogCoordFuncs[8];
154
155
156/**
157 ** GL_NV_vertex_program
158 **/
159
160/* GL_BYTE attributes */
161
162static void GLAPIENTRY VertexAttrib1NbvNV(GLuint index, const GLbyte *v)
163{
164   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0])));
165}
166
167static void GLAPIENTRY VertexAttrib1bvNV(GLuint index, const GLbyte *v)
168{
169   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
170}
171
172static 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
177static void GLAPIENTRY VertexAttrib2bvNV(GLuint index, const GLbyte *v)
178{
179   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
180}
181
182static 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
189static void GLAPIENTRY VertexAttrib3bvNV(GLuint index, const GLbyte *v)
190{
191   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
192}
193
194static 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
202static 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
209static void GLAPIENTRY VertexAttrib1NubvNV(GLuint index, const GLubyte *v)
210{
211   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0])));
212}
213
214static void GLAPIENTRY VertexAttrib1ubvNV(GLuint index, const GLubyte *v)
215{
216   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
217}
218
219static 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
225static void GLAPIENTRY VertexAttrib2ubvNV(GLuint index, const GLubyte *v)
226{
227   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
228}
229
230static 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}
236static void GLAPIENTRY VertexAttrib3ubvNV(GLuint index, const GLubyte *v)
237{
238   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
239}
240
241static 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
249static 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
256static void GLAPIENTRY VertexAttrib1NsvNV(GLuint index, const GLshort *v)
257{
258   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0])));
259}
260
261static void GLAPIENTRY VertexAttrib1svNV(GLuint index, const GLshort *v)
262{
263   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
264}
265
266static 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
272static void GLAPIENTRY VertexAttrib2svNV(GLuint index, const GLshort *v)
273{
274   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
275}
276
277static 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
284static void GLAPIENTRY VertexAttrib3svNV(GLuint index, const GLshort *v)
285{
286   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
287}
288
289static 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
297static 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
304static void GLAPIENTRY VertexAttrib1NusvNV(GLuint index, const GLushort *v)
305{
306   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0])));
307}
308
309static void GLAPIENTRY VertexAttrib1usvNV(GLuint index, const GLushort *v)
310{
311   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
312}
313
314static 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
320static void GLAPIENTRY VertexAttrib2usvNV(GLuint index, const GLushort *v)
321{
322   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
323}
324
325static 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
332static void GLAPIENTRY VertexAttrib3usvNV(GLuint index, const GLushort *v)
333{
334   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
335}
336
337static 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
345static 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
352static void GLAPIENTRY VertexAttrib1NivNV(GLuint index, const GLint *v)
353{
354   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0])));
355}
356
357static void GLAPIENTRY VertexAttrib1ivNV(GLuint index, const GLint *v)
358{
359   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
360}
361
362static 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
368static void GLAPIENTRY VertexAttrib2ivNV(GLuint index, const GLint *v)
369{
370   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
371}
372
373static 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
380static void GLAPIENTRY VertexAttrib3ivNV(GLuint index, const GLint *v)
381{
382   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
383}
384
385static 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
393static 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
400static void GLAPIENTRY VertexAttrib1NuivNV(GLuint index, const GLuint *v)
401{
402   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0])));
403}
404
405static void GLAPIENTRY VertexAttrib1uivNV(GLuint index, const GLuint *v)
406{
407   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
408}
409
410static 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
416static void GLAPIENTRY VertexAttrib2uivNV(GLuint index, const GLuint *v)
417{
418   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
419}
420
421static 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
428static void GLAPIENTRY VertexAttrib3uivNV(GLuint index, const GLuint *v)
429{
430   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
431}
432
433static 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
441static 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
448static void GLAPIENTRY VertexAttrib1fvNV(GLuint index, const GLfloat *v)
449{
450   CALL_VertexAttrib1fvNV(GET_DISPATCH(), (index, v));
451}
452
453static void GLAPIENTRY VertexAttrib2fvNV(GLuint index, const GLfloat *v)
454{
455   CALL_VertexAttrib2fvNV(GET_DISPATCH(), (index, v));
456}
457
458static void GLAPIENTRY VertexAttrib3fvNV(GLuint index, const GLfloat *v)
459{
460   CALL_VertexAttrib3fvNV(GET_DISPATCH(), (index, v));
461}
462
463static void GLAPIENTRY VertexAttrib4fvNV(GLuint index, const GLfloat *v)
464{
465   CALL_VertexAttrib4fvNV(GET_DISPATCH(), (index, v));
466}
467
468/* GL_DOUBLE attributes */
469
470static void GLAPIENTRY VertexAttrib1dvNV(GLuint index, const GLdouble *v)
471{
472   CALL_VertexAttrib1dvNV(GET_DISPATCH(), (index, v));
473}
474
475static void GLAPIENTRY VertexAttrib2dvNV(GLuint index, const GLdouble *v)
476{
477   CALL_VertexAttrib2dvNV(GET_DISPATCH(), (index, v));
478}
479
480static void GLAPIENTRY VertexAttrib3dvNV(GLuint index, const GLdouble *v)
481{
482   CALL_VertexAttrib3dvNV(GET_DISPATCH(), (index, v));
483}
484
485static 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 */
494static 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
598static void GLAPIENTRY VertexAttrib1NbvARB(GLuint index, const GLbyte *v)
599{
600   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0])));
601}
602
603static void GLAPIENTRY VertexAttrib1bvARB(GLuint index, const GLbyte *v)
604{
605   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
606}
607
608static 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
613static void GLAPIENTRY VertexAttrib2bvARB(GLuint index, const GLbyte *v)
614{
615   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
616}
617
618static 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
625static void GLAPIENTRY VertexAttrib3bvARB(GLuint index, const GLbyte *v)
626{
627   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
628}
629
630static 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
638static 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
645static void GLAPIENTRY VertexAttrib1NubvARB(GLuint index, const GLubyte *v)
646{
647   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0])));
648}
649
650static void GLAPIENTRY VertexAttrib1ubvARB(GLuint index, const GLubyte *v)
651{
652   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
653}
654
655static 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
661static void GLAPIENTRY VertexAttrib2ubvARB(GLuint index, const GLubyte *v)
662{
663   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
664}
665
666static 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}
672static void GLAPIENTRY VertexAttrib3ubvARB(GLuint index, const GLubyte *v)
673{
674   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
675}
676
677static 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
685static 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
692static void GLAPIENTRY VertexAttrib1NsvARB(GLuint index, const GLshort *v)
693{
694   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0])));
695}
696
697static void GLAPIENTRY VertexAttrib1svARB(GLuint index, const GLshort *v)
698{
699   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
700}
701
702static 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
708static void GLAPIENTRY VertexAttrib2svARB(GLuint index, const GLshort *v)
709{
710   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
711}
712
713static 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
720static void GLAPIENTRY VertexAttrib3svARB(GLuint index, const GLshort *v)
721{
722   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
723}
724
725static 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
733static 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
740static void GLAPIENTRY VertexAttrib1NusvARB(GLuint index, const GLushort *v)
741{
742   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0])));
743}
744
745static void GLAPIENTRY VertexAttrib1usvARB(GLuint index, const GLushort *v)
746{
747   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
748}
749
750static 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
756static void GLAPIENTRY VertexAttrib2usvARB(GLuint index, const GLushort *v)
757{
758   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
759}
760
761static 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
768static void GLAPIENTRY VertexAttrib3usvARB(GLuint index, const GLushort *v)
769{
770   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
771}
772
773static 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
781static 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
788static void GLAPIENTRY VertexAttrib1NivARB(GLuint index, const GLint *v)
789{
790   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0])));
791}
792
793static void GLAPIENTRY VertexAttrib1ivARB(GLuint index, const GLint *v)
794{
795   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
796}
797
798static 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
804static void GLAPIENTRY VertexAttrib2ivARB(GLuint index, const GLint *v)
805{
806   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
807}
808
809static 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
816static void GLAPIENTRY VertexAttrib3ivARB(GLuint index, const GLint *v)
817{
818   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
819}
820
821static 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
829static 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
836static void GLAPIENTRY VertexAttrib1NuivARB(GLuint index, const GLuint *v)
837{
838   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0])));
839}
840
841static void GLAPIENTRY VertexAttrib1uivARB(GLuint index, const GLuint *v)
842{
843   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
844}
845
846static 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
852static void GLAPIENTRY VertexAttrib2uivARB(GLuint index, const GLuint *v)
853{
854   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
855}
856
857static 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
864static void GLAPIENTRY VertexAttrib3uivARB(GLuint index, const GLuint *v)
865{
866   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
867}
868
869static 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
877static 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
884static void GLAPIENTRY VertexAttrib1fvARB(GLuint index, const GLfloat *v)
885{
886   CALL_VertexAttrib1fvARB(GET_DISPATCH(), (index, v));
887}
888
889static void GLAPIENTRY VertexAttrib2fvARB(GLuint index, const GLfloat *v)
890{
891   CALL_VertexAttrib2fvARB(GET_DISPATCH(), (index, v));
892}
893
894static void GLAPIENTRY VertexAttrib3fvARB(GLuint index, const GLfloat *v)
895{
896   CALL_VertexAttrib3fvARB(GET_DISPATCH(), (index, v));
897}
898
899static void GLAPIENTRY VertexAttrib4fvARB(GLuint index, const GLfloat *v)
900{
901   CALL_VertexAttrib4fvARB(GET_DISPATCH(), (index, v));
902}
903
904/* GL_DOUBLE attributes */
905
906static void GLAPIENTRY VertexAttrib1dvARB(GLuint index, const GLdouble *v)
907{
908   CALL_VertexAttrib1dvARB(GET_DISPATCH(), (index, v));
909}
910
911static void GLAPIENTRY VertexAttrib2dvARB(GLuint index, const GLdouble *v)
912{
913   CALL_VertexAttrib2dvARB(GET_DISPATCH(), (index, v));
914}
915
916static void GLAPIENTRY VertexAttrib3dvARB(GLuint index, const GLdouble *v)
917{
918   CALL_VertexAttrib3dvARB(GET_DISPATCH(), (index, v));
919}
920
921static 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 */
930static 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
1030GLboolean _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
1063void _ae_destroy_context( GLcontext *ctx )
1064{
1065   if ( AE_CONTEXT( ctx ) ) {
1066      FREE( ctx->aelt_context );
1067      ctx->aelt_context = NULL;
1068   }
1069}
1070
1071static 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 */
1091static 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
1209void _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
1230void _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 */
1255void 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
1298void _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}
1318