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/**
26 * This file implements the glArrayElement() function.
27 * It involves looking at the format/type of all the enabled vertex arrays
28 * and emitting a list of pointers to functions which set the per-vertex
29 * state for the element/index.
30 */
31
32
33/* Author:
34 *    Keith Whitwell <keith@tungstengraphics.com>
35 */
36
37#include "glheader.h"
38#include "api_arrayelt.h"
39#include "bufferobj.h"
40#include "context.h"
41#include "imports.h"
42#include "macros.h"
43#include "mfeatures.h"
44#include "mtypes.h"
45#include "main/dispatch.h"
46
47typedef void (GLAPIENTRY *array_func)( const void * );
48
49typedef struct {
50   const struct gl_client_array *array;
51   int offset;
52} AEarray;
53
54typedef void (GLAPIENTRY *attrib_func)( GLuint indx, const void *data );
55
56typedef struct {
57   const struct gl_client_array *array;
58   attrib_func func;
59   GLuint index;
60} AEattrib;
61
62typedef struct {
63   AEarray arrays[32];
64   AEattrib attribs[VERT_ATTRIB_MAX + 1];
65   GLuint NewState;
66
67   struct gl_buffer_object *vbo[VERT_ATTRIB_MAX];
68   GLuint nr_vbos;
69   GLboolean mapped_vbos;
70
71} AEcontext;
72
73#define AE_CONTEXT(ctx) ((AEcontext *)(ctx)->aelt_context)
74
75
76/*
77 * Convert GL_BYTE, GL_UNSIGNED_BYTE, .. GL_DOUBLE into an integer
78 * in the range [0, 7].  Luckily these type tokens are sequentially
79 * numbered in gl.h, except for GL_DOUBLE.
80 */
81#define TYPE_IDX(t) ( (t) == GL_DOUBLE ? 7 : (t) & 7 )
82
83#define NUM_TYPES 8
84
85
86#if FEATURE_arrayelt
87
88
89static const int ColorFuncs[2][NUM_TYPES] = {
90   {
91      _gloffset_Color3bv,
92      _gloffset_Color3ubv,
93      _gloffset_Color3sv,
94      _gloffset_Color3usv,
95      _gloffset_Color3iv,
96      _gloffset_Color3uiv,
97      _gloffset_Color3fv,
98      _gloffset_Color3dv,
99   },
100   {
101      _gloffset_Color4bv,
102      _gloffset_Color4ubv,
103      _gloffset_Color4sv,
104      _gloffset_Color4usv,
105      _gloffset_Color4iv,
106      _gloffset_Color4uiv,
107      _gloffset_Color4fv,
108      _gloffset_Color4dv,
109   },
110};
111
112static const int VertexFuncs[3][NUM_TYPES] = {
113   {
114      -1,
115      -1,
116      _gloffset_Vertex2sv,
117      -1,
118      _gloffset_Vertex2iv,
119      -1,
120      _gloffset_Vertex2fv,
121      _gloffset_Vertex2dv,
122   },
123   {
124      -1,
125      -1,
126      _gloffset_Vertex3sv,
127      -1,
128      _gloffset_Vertex3iv,
129      -1,
130      _gloffset_Vertex3fv,
131      _gloffset_Vertex3dv,
132   },
133   {
134      -1,
135      -1,
136      _gloffset_Vertex4sv,
137      -1,
138      _gloffset_Vertex4iv,
139      -1,
140      _gloffset_Vertex4fv,
141      _gloffset_Vertex4dv,
142   },
143};
144
145static const int IndexFuncs[NUM_TYPES] = {
146   -1,
147   _gloffset_Indexubv,
148   _gloffset_Indexsv,
149   -1,
150   _gloffset_Indexiv,
151   -1,
152   _gloffset_Indexfv,
153   _gloffset_Indexdv,
154};
155
156static const int NormalFuncs[NUM_TYPES] = {
157   _gloffset_Normal3bv,
158   -1,
159   _gloffset_Normal3sv,
160   -1,
161   _gloffset_Normal3iv,
162   -1,
163   _gloffset_Normal3fv,
164   _gloffset_Normal3dv,
165};
166
167/* Note: _gloffset_* for these may not be a compile-time constant. */
168static int SecondaryColorFuncs[NUM_TYPES];
169static int FogCoordFuncs[NUM_TYPES];
170
171
172/**
173 ** GL_NV_vertex_program
174 **/
175
176/* GL_BYTE attributes */
177
178static void GLAPIENTRY
179VertexAttrib1NbvNV(GLuint index, const GLbyte *v)
180{
181   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0])));
182}
183
184static void GLAPIENTRY
185VertexAttrib1bvNV(GLuint index, const GLbyte *v)
186{
187   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
188}
189
190static void GLAPIENTRY
191VertexAttrib2NbvNV(GLuint index, const GLbyte *v)
192{
193   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1])));
194}
195
196static void GLAPIENTRY
197VertexAttrib2bvNV(GLuint index, const GLbyte *v)
198{
199   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
200}
201
202static void GLAPIENTRY
203VertexAttrib3NbvNV(GLuint index, const GLbyte *v)
204{
205   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
206					       BYTE_TO_FLOAT(v[1]),
207					       BYTE_TO_FLOAT(v[2])));
208}
209
210static void GLAPIENTRY
211VertexAttrib3bvNV(GLuint index, const GLbyte *v)
212{
213   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
214}
215
216static void GLAPIENTRY
217VertexAttrib4NbvNV(GLuint index, const GLbyte *v)
218{
219   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
220					       BYTE_TO_FLOAT(v[1]),
221					       BYTE_TO_FLOAT(v[2]),
222					       BYTE_TO_FLOAT(v[3])));
223}
224
225static void GLAPIENTRY
226VertexAttrib4bvNV(GLuint index, const GLbyte *v)
227{
228   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
229}
230
231/* GL_UNSIGNED_BYTE attributes */
232
233static void GLAPIENTRY
234VertexAttrib1NubvNV(GLuint index, const GLubyte *v)
235{
236   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0])));
237}
238
239static void GLAPIENTRY
240VertexAttrib1ubvNV(GLuint index, const GLubyte *v)
241{
242   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
243}
244
245static void GLAPIENTRY
246VertexAttrib2NubvNV(GLuint index, const GLubyte *v)
247{
248   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
249                                          UBYTE_TO_FLOAT(v[1])));
250}
251
252static void GLAPIENTRY
253VertexAttrib2ubvNV(GLuint index, const GLubyte *v)
254{
255   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
256}
257
258static void GLAPIENTRY
259VertexAttrib3NubvNV(GLuint index, const GLubyte *v)
260{
261   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
262					       UBYTE_TO_FLOAT(v[1]),
263					       UBYTE_TO_FLOAT(v[2])));
264}
265static void GLAPIENTRY
266VertexAttrib3ubvNV(GLuint index, const GLubyte *v)
267{
268   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0],
269                                          (GLfloat)v[1], (GLfloat)v[2]));
270}
271
272static void GLAPIENTRY
273VertexAttrib4NubvNV(GLuint index, const GLubyte *v)
274{
275   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
276                                          UBYTE_TO_FLOAT(v[1]),
277                                          UBYTE_TO_FLOAT(v[2]),
278                                          UBYTE_TO_FLOAT(v[3])));
279}
280
281static void GLAPIENTRY
282VertexAttrib4ubvNV(GLuint index, const GLubyte *v)
283{
284   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0],
285                                          (GLfloat)v[1], (GLfloat)v[2],
286                                          (GLfloat)v[3]));
287}
288
289/* GL_SHORT attributes */
290
291static void GLAPIENTRY
292VertexAttrib1NsvNV(GLuint index, const GLshort *v)
293{
294   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0])));
295}
296
297static void GLAPIENTRY
298VertexAttrib1svNV(GLuint index, const GLshort *v)
299{
300   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
301}
302
303static void GLAPIENTRY
304VertexAttrib2NsvNV(GLuint index, const GLshort *v)
305{
306   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
307                                          SHORT_TO_FLOAT(v[1])));
308}
309
310static void GLAPIENTRY
311VertexAttrib2svNV(GLuint index, const GLshort *v)
312{
313   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
314}
315
316static void GLAPIENTRY
317VertexAttrib3NsvNV(GLuint index, const GLshort *v)
318{
319   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
320			     SHORT_TO_FLOAT(v[1]),
321			     SHORT_TO_FLOAT(v[2])));
322}
323
324static void GLAPIENTRY
325VertexAttrib3svNV(GLuint index, const GLshort *v)
326{
327   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
328                                          (GLfloat)v[2]));
329}
330
331static void GLAPIENTRY
332VertexAttrib4NsvNV(GLuint index, const GLshort *v)
333{
334   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
335			     SHORT_TO_FLOAT(v[1]),
336			     SHORT_TO_FLOAT(v[2]),
337			     SHORT_TO_FLOAT(v[3])));
338}
339
340static void GLAPIENTRY
341VertexAttrib4svNV(GLuint index, const GLshort *v)
342{
343   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
344                                          (GLfloat)v[2], (GLfloat)v[3]));
345}
346
347/* GL_UNSIGNED_SHORT attributes */
348
349static void GLAPIENTRY
350VertexAttrib1NusvNV(GLuint index, const GLushort *v)
351{
352   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0])));
353}
354
355static void GLAPIENTRY
356VertexAttrib1usvNV(GLuint index, const GLushort *v)
357{
358   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
359}
360
361static void GLAPIENTRY
362VertexAttrib2NusvNV(GLuint index, const GLushort *v)
363{
364   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
365			     USHORT_TO_FLOAT(v[1])));
366}
367
368static void GLAPIENTRY
369VertexAttrib2usvNV(GLuint index, const GLushort *v)
370{
371   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0],
372                                          (GLfloat)v[1]));
373}
374
375static void GLAPIENTRY
376VertexAttrib3NusvNV(GLuint index, const GLushort *v)
377{
378   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
379					       USHORT_TO_FLOAT(v[1]),
380					       USHORT_TO_FLOAT(v[2])));
381}
382
383static void GLAPIENTRY
384VertexAttrib3usvNV(GLuint index, const GLushort *v)
385{
386   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
387                                          (GLfloat)v[2]));
388}
389
390static void GLAPIENTRY
391VertexAttrib4NusvNV(GLuint index, const GLushort *v)
392{
393   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
394					       USHORT_TO_FLOAT(v[1]),
395					       USHORT_TO_FLOAT(v[2]),
396					       USHORT_TO_FLOAT(v[3])));
397}
398
399static void GLAPIENTRY
400VertexAttrib4usvNV(GLuint index, const GLushort *v)
401{
402   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
403                                          (GLfloat)v[2], (GLfloat)v[3]));
404}
405
406/* GL_INT attributes */
407
408static void GLAPIENTRY
409VertexAttrib1NivNV(GLuint index, const GLint *v)
410{
411   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0])));
412}
413
414static void GLAPIENTRY
415VertexAttrib1ivNV(GLuint index, const GLint *v)
416{
417   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
418}
419
420static void GLAPIENTRY
421VertexAttrib2NivNV(GLuint index, const GLint *v)
422{
423   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
424					       INT_TO_FLOAT(v[1])));
425}
426
427static void GLAPIENTRY
428VertexAttrib2ivNV(GLuint index, const GLint *v)
429{
430   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
431}
432
433static void GLAPIENTRY
434VertexAttrib3NivNV(GLuint index, const GLint *v)
435{
436   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
437					       INT_TO_FLOAT(v[1]),
438					       INT_TO_FLOAT(v[2])));
439}
440
441static void GLAPIENTRY
442VertexAttrib3ivNV(GLuint index, const GLint *v)
443{
444   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
445                                          (GLfloat)v[2]));
446}
447
448static void GLAPIENTRY
449VertexAttrib4NivNV(GLuint index, const GLint *v)
450{
451   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
452                                          INT_TO_FLOAT(v[1]),
453                                          INT_TO_FLOAT(v[2]),
454                                          INT_TO_FLOAT(v[3])));
455}
456
457static void GLAPIENTRY
458VertexAttrib4ivNV(GLuint index, const GLint *v)
459{
460   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
461                                          (GLfloat)v[2], (GLfloat)v[3]));
462}
463
464/* GL_UNSIGNED_INT attributes */
465
466static void GLAPIENTRY
467VertexAttrib1NuivNV(GLuint index, const GLuint *v)
468{
469   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0])));
470}
471
472static void GLAPIENTRY
473VertexAttrib1uivNV(GLuint index, const GLuint *v)
474{
475   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
476}
477
478static void GLAPIENTRY
479VertexAttrib2NuivNV(GLuint index, const GLuint *v)
480{
481   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
482                                          UINT_TO_FLOAT(v[1])));
483}
484
485static void GLAPIENTRY
486VertexAttrib2uivNV(GLuint index, const GLuint *v)
487{
488   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0],
489                                          (GLfloat)v[1]));
490}
491
492static void GLAPIENTRY
493VertexAttrib3NuivNV(GLuint index, const GLuint *v)
494{
495   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
496					       UINT_TO_FLOAT(v[1]),
497					       UINT_TO_FLOAT(v[2])));
498}
499
500static void GLAPIENTRY
501VertexAttrib3uivNV(GLuint index, const GLuint *v)
502{
503   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
504                                          (GLfloat)v[2]));
505}
506
507static void GLAPIENTRY
508VertexAttrib4NuivNV(GLuint index, const GLuint *v)
509{
510   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
511					       UINT_TO_FLOAT(v[1]),
512					       UINT_TO_FLOAT(v[2]),
513					       UINT_TO_FLOAT(v[3])));
514}
515
516static void GLAPIENTRY
517VertexAttrib4uivNV(GLuint index, const GLuint *v)
518{
519   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
520                                          (GLfloat)v[2], (GLfloat)v[3]));
521}
522
523/* GL_FLOAT attributes */
524
525static void GLAPIENTRY
526VertexAttrib1fvNV(GLuint index, const GLfloat *v)
527{
528   CALL_VertexAttrib1fvNV(GET_DISPATCH(), (index, v));
529}
530
531static void GLAPIENTRY
532VertexAttrib2fvNV(GLuint index, const GLfloat *v)
533{
534   CALL_VertexAttrib2fvNV(GET_DISPATCH(), (index, v));
535}
536
537static void GLAPIENTRY
538VertexAttrib3fvNV(GLuint index, const GLfloat *v)
539{
540   CALL_VertexAttrib3fvNV(GET_DISPATCH(), (index, v));
541}
542
543static void GLAPIENTRY
544VertexAttrib4fvNV(GLuint index, const GLfloat *v)
545{
546   CALL_VertexAttrib4fvNV(GET_DISPATCH(), (index, v));
547}
548
549/* GL_DOUBLE attributes */
550
551static void GLAPIENTRY
552VertexAttrib1dvNV(GLuint index, const GLdouble *v)
553{
554   CALL_VertexAttrib1dvNV(GET_DISPATCH(), (index, v));
555}
556
557static void GLAPIENTRY
558VertexAttrib2dvNV(GLuint index, const GLdouble *v)
559{
560   CALL_VertexAttrib2dvNV(GET_DISPATCH(), (index, v));
561}
562
563static void GLAPIENTRY
564VertexAttrib3dvNV(GLuint index, const GLdouble *v)
565{
566   CALL_VertexAttrib3dvNV(GET_DISPATCH(), (index, v));
567}
568
569static void GLAPIENTRY
570VertexAttrib4dvNV(GLuint index, const GLdouble *v)
571{
572   CALL_VertexAttrib4dvNV(GET_DISPATCH(), (index, v));
573}
574
575
576/*
577 * Array [size][type] of VertexAttrib functions
578 */
579static attrib_func AttribFuncsNV[2][4][NUM_TYPES] = {
580   {
581      /* non-normalized */
582      {
583         /* size 1 */
584         (attrib_func) VertexAttrib1bvNV,
585         (attrib_func) VertexAttrib1ubvNV,
586         (attrib_func) VertexAttrib1svNV,
587         (attrib_func) VertexAttrib1usvNV,
588         (attrib_func) VertexAttrib1ivNV,
589         (attrib_func) VertexAttrib1uivNV,
590         (attrib_func) VertexAttrib1fvNV,
591         (attrib_func) VertexAttrib1dvNV
592      },
593      {
594         /* size 2 */
595         (attrib_func) VertexAttrib2bvNV,
596         (attrib_func) VertexAttrib2ubvNV,
597         (attrib_func) VertexAttrib2svNV,
598         (attrib_func) VertexAttrib2usvNV,
599         (attrib_func) VertexAttrib2ivNV,
600         (attrib_func) VertexAttrib2uivNV,
601         (attrib_func) VertexAttrib2fvNV,
602         (attrib_func) VertexAttrib2dvNV
603      },
604      {
605         /* size 3 */
606         (attrib_func) VertexAttrib3bvNV,
607         (attrib_func) VertexAttrib3ubvNV,
608         (attrib_func) VertexAttrib3svNV,
609         (attrib_func) VertexAttrib3usvNV,
610         (attrib_func) VertexAttrib3ivNV,
611         (attrib_func) VertexAttrib3uivNV,
612         (attrib_func) VertexAttrib3fvNV,
613         (attrib_func) VertexAttrib3dvNV
614      },
615      {
616         /* size 4 */
617         (attrib_func) VertexAttrib4bvNV,
618         (attrib_func) VertexAttrib4ubvNV,
619         (attrib_func) VertexAttrib4svNV,
620         (attrib_func) VertexAttrib4usvNV,
621         (attrib_func) VertexAttrib4ivNV,
622         (attrib_func) VertexAttrib4uivNV,
623         (attrib_func) VertexAttrib4fvNV,
624         (attrib_func) VertexAttrib4dvNV
625      }
626   },
627   {
628      /* normalized (except for float/double) */
629      {
630         /* size 1 */
631         (attrib_func) VertexAttrib1NbvNV,
632         (attrib_func) VertexAttrib1NubvNV,
633         (attrib_func) VertexAttrib1NsvNV,
634         (attrib_func) VertexAttrib1NusvNV,
635         (attrib_func) VertexAttrib1NivNV,
636         (attrib_func) VertexAttrib1NuivNV,
637         (attrib_func) VertexAttrib1fvNV,
638         (attrib_func) VertexAttrib1dvNV
639      },
640      {
641         /* size 2 */
642         (attrib_func) VertexAttrib2NbvNV,
643         (attrib_func) VertexAttrib2NubvNV,
644         (attrib_func) VertexAttrib2NsvNV,
645         (attrib_func) VertexAttrib2NusvNV,
646         (attrib_func) VertexAttrib2NivNV,
647         (attrib_func) VertexAttrib2NuivNV,
648         (attrib_func) VertexAttrib2fvNV,
649         (attrib_func) VertexAttrib2dvNV
650      },
651      {
652         /* size 3 */
653         (attrib_func) VertexAttrib3NbvNV,
654         (attrib_func) VertexAttrib3NubvNV,
655         (attrib_func) VertexAttrib3NsvNV,
656         (attrib_func) VertexAttrib3NusvNV,
657         (attrib_func) VertexAttrib3NivNV,
658         (attrib_func) VertexAttrib3NuivNV,
659         (attrib_func) VertexAttrib3fvNV,
660         (attrib_func) VertexAttrib3dvNV
661      },
662      {
663         /* size 4 */
664         (attrib_func) VertexAttrib4NbvNV,
665         (attrib_func) VertexAttrib4NubvNV,
666         (attrib_func) VertexAttrib4NsvNV,
667         (attrib_func) VertexAttrib4NusvNV,
668         (attrib_func) VertexAttrib4NivNV,
669         (attrib_func) VertexAttrib4NuivNV,
670         (attrib_func) VertexAttrib4fvNV,
671         (attrib_func) VertexAttrib4dvNV
672      }
673   }
674};
675
676
677/**
678 ** GL_ARB_vertex_program
679 **/
680
681/* GL_BYTE attributes */
682
683static void GLAPIENTRY
684VertexAttrib1NbvARB(GLuint index, const GLbyte *v)
685{
686   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0])));
687}
688
689static void GLAPIENTRY
690VertexAttrib1bvARB(GLuint index, const GLbyte *v)
691{
692   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
693}
694
695static void GLAPIENTRY
696VertexAttrib2NbvARB(GLuint index, const GLbyte *v)
697{
698   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1])));
699}
700
701static void GLAPIENTRY
702VertexAttrib2bvARB(GLuint index, const GLbyte *v)
703{
704   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
705}
706
707static void GLAPIENTRY
708VertexAttrib3NbvARB(GLuint index, const GLbyte *v)
709{
710   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
711					       BYTE_TO_FLOAT(v[1]),
712					       BYTE_TO_FLOAT(v[2])));
713}
714
715static void GLAPIENTRY
716VertexAttrib3bvARB(GLuint index, const GLbyte *v)
717{
718   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
719}
720
721static void GLAPIENTRY
722VertexAttrib4NbvARB(GLuint index, const GLbyte *v)
723{
724   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
725					       BYTE_TO_FLOAT(v[1]),
726					       BYTE_TO_FLOAT(v[2]),
727					       BYTE_TO_FLOAT(v[3])));
728}
729
730static void GLAPIENTRY
731VertexAttrib4bvARB(GLuint index, const GLbyte *v)
732{
733   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
734}
735
736/* GL_UNSIGNED_BYTE attributes */
737
738static void GLAPIENTRY
739VertexAttrib1NubvARB(GLuint index, const GLubyte *v)
740{
741   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0])));
742}
743
744static void GLAPIENTRY
745VertexAttrib1ubvARB(GLuint index, const GLubyte *v)
746{
747   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
748}
749
750static void GLAPIENTRY
751VertexAttrib2NubvARB(GLuint index, const GLubyte *v)
752{
753   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index,
754                                           UBYTE_TO_FLOAT(v[0]),
755                                           UBYTE_TO_FLOAT(v[1])));
756}
757
758static void GLAPIENTRY
759VertexAttrib2ubvARB(GLuint index, const GLubyte *v)
760{
761   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index,
762                                           (GLfloat)v[0], (GLfloat)v[1]));
763}
764
765static void GLAPIENTRY
766VertexAttrib3NubvARB(GLuint index, const GLubyte *v)
767{
768   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index,
769                                           UBYTE_TO_FLOAT(v[0]),
770                                           UBYTE_TO_FLOAT(v[1]),
771                                           UBYTE_TO_FLOAT(v[2])));
772}
773static void GLAPIENTRY
774VertexAttrib3ubvARB(GLuint index, const GLubyte *v)
775{
776   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index,
777                                           (GLfloat)v[0],
778                                           (GLfloat)v[1],
779                                           (GLfloat)v[2]));
780}
781
782static void GLAPIENTRY
783VertexAttrib4NubvARB(GLuint index, const GLubyte *v)
784{
785   CALL_VertexAttrib4fARB(GET_DISPATCH(),
786                          (index,
787                           UBYTE_TO_FLOAT(v[0]),
788                           UBYTE_TO_FLOAT(v[1]),
789                           UBYTE_TO_FLOAT(v[2]),
790                           UBYTE_TO_FLOAT(v[3])));
791}
792
793static void GLAPIENTRY
794VertexAttrib4ubvARB(GLuint index, const GLubyte *v)
795{
796   CALL_VertexAttrib4fARB(GET_DISPATCH(),
797                          (index,
798                           (GLfloat)v[0], (GLfloat)v[1],
799                           (GLfloat)v[2], (GLfloat)v[3]));
800}
801
802/* GL_SHORT attributes */
803
804static void GLAPIENTRY
805VertexAttrib1NsvARB(GLuint index, const GLshort *v)
806{
807   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0])));
808}
809
810static void GLAPIENTRY
811VertexAttrib1svARB(GLuint index, const GLshort *v)
812{
813   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
814}
815
816static void GLAPIENTRY
817VertexAttrib2NsvARB(GLuint index, const GLshort *v)
818{
819   CALL_VertexAttrib2fARB(GET_DISPATCH(),
820                          (index, SHORT_TO_FLOAT(v[0]),
821                           SHORT_TO_FLOAT(v[1])));
822}
823
824static void GLAPIENTRY
825VertexAttrib2svARB(GLuint index, const GLshort *v)
826{
827   CALL_VertexAttrib2fARB(GET_DISPATCH(),
828                          (index, (GLfloat)v[0], (GLfloat)v[1]));
829}
830
831static void GLAPIENTRY
832VertexAttrib3NsvARB(GLuint index, const GLshort *v)
833{
834   CALL_VertexAttrib3fARB(GET_DISPATCH(),
835                          (index,
836                           SHORT_TO_FLOAT(v[0]),
837                           SHORT_TO_FLOAT(v[1]),
838                           SHORT_TO_FLOAT(v[2])));
839}
840
841static void GLAPIENTRY
842VertexAttrib3svARB(GLuint index, const GLshort *v)
843{
844   CALL_VertexAttrib3fARB(GET_DISPATCH(),
845                          (index,
846                           (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
847}
848
849static void GLAPIENTRY
850VertexAttrib4NsvARB(GLuint index, const GLshort *v)
851{
852   CALL_VertexAttrib4fARB(GET_DISPATCH(),
853                          (index,
854                           SHORT_TO_FLOAT(v[0]),
855                           SHORT_TO_FLOAT(v[1]),
856                           SHORT_TO_FLOAT(v[2]),
857                           SHORT_TO_FLOAT(v[3])));
858}
859
860static void GLAPIENTRY
861VertexAttrib4svARB(GLuint index, const GLshort *v)
862{
863   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
864                                           (GLfloat)v[2], (GLfloat)v[3]));
865}
866
867/* GL_UNSIGNED_SHORT attributes */
868
869static void GLAPIENTRY
870VertexAttrib1NusvARB(GLuint index, const GLushort *v)
871{
872   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0])));
873}
874
875static void GLAPIENTRY
876VertexAttrib1usvARB(GLuint index, const GLushort *v)
877{
878   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
879}
880
881static void GLAPIENTRY
882VertexAttrib2NusvARB(GLuint index, const GLushort *v)
883{
884   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
885			     USHORT_TO_FLOAT(v[1])));
886}
887
888static void GLAPIENTRY
889VertexAttrib2usvARB(GLuint index, const GLushort *v)
890{
891   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, (GLfloat)v[0],
892                                           (GLfloat)v[1]));
893}
894
895static void GLAPIENTRY
896VertexAttrib3NusvARB(GLuint index, const GLushort *v)
897{
898   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
899					       USHORT_TO_FLOAT(v[1]),
900					       USHORT_TO_FLOAT(v[2])));
901}
902
903static void GLAPIENTRY
904VertexAttrib3usvARB(GLuint index, const GLushort *v)
905{
906   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, (GLfloat)v[0],
907                                           (GLfloat)v[1], (GLfloat)v[2]));
908}
909
910static void GLAPIENTRY
911VertexAttrib4NusvARB(GLuint index, const GLushort *v)
912{
913   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
914					       USHORT_TO_FLOAT(v[1]),
915					       USHORT_TO_FLOAT(v[2]),
916					       USHORT_TO_FLOAT(v[3])));
917}
918
919static void GLAPIENTRY
920VertexAttrib4usvARB(GLuint index, const GLushort *v)
921{
922   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
923}
924
925/* GL_INT attributes */
926
927static void GLAPIENTRY
928VertexAttrib1NivARB(GLuint index, const GLint *v)
929{
930   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0])));
931}
932
933static void GLAPIENTRY
934VertexAttrib1ivARB(GLuint index, const GLint *v)
935{
936   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
937}
938
939static void GLAPIENTRY
940VertexAttrib2NivARB(GLuint index, const GLint *v)
941{
942   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
943					       INT_TO_FLOAT(v[1])));
944}
945
946static void GLAPIENTRY
947VertexAttrib2ivARB(GLuint index, const GLint *v)
948{
949   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, (GLfloat)v[0],
950                                           (GLfloat)v[1]));
951}
952
953static void GLAPIENTRY
954VertexAttrib3NivARB(GLuint index, const GLint *v)
955{
956   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
957					       INT_TO_FLOAT(v[1]),
958					       INT_TO_FLOAT(v[2])));
959}
960
961static void GLAPIENTRY
962VertexAttrib3ivARB(GLuint index, const GLint *v)
963{
964   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, (GLfloat)v[0],
965                                           (GLfloat)v[1], (GLfloat)v[2]));
966}
967
968static void GLAPIENTRY
969VertexAttrib4NivARB(GLuint index, const GLint *v)
970{
971   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
972					       INT_TO_FLOAT(v[1]),
973					       INT_TO_FLOAT(v[2]),
974					       INT_TO_FLOAT(v[3])));
975}
976
977static void GLAPIENTRY
978VertexAttrib4ivARB(GLuint index, const GLint *v)
979{
980   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
981                                           (GLfloat)v[2], (GLfloat)v[3]));
982}
983
984/* GL_UNSIGNED_INT attributes */
985
986static void GLAPIENTRY
987VertexAttrib1NuivARB(GLuint index, const GLuint *v)
988{
989   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0])));
990}
991
992static void GLAPIENTRY
993VertexAttrib1uivARB(GLuint index, const GLuint *v)
994{
995   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
996}
997
998static void GLAPIENTRY
999VertexAttrib2NuivARB(GLuint index, const GLuint *v)
1000{
1001   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
1002                                           UINT_TO_FLOAT(v[1])));
1003}
1004
1005static void GLAPIENTRY
1006VertexAttrib2uivARB(GLuint index, const GLuint *v)
1007{
1008   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, (GLfloat)v[0],
1009                                           (GLfloat)v[1]));
1010}
1011
1012static void GLAPIENTRY
1013VertexAttrib3NuivARB(GLuint index, const GLuint *v)
1014{
1015   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
1016                                           UINT_TO_FLOAT(v[1]),
1017                                           UINT_TO_FLOAT(v[2])));
1018}
1019
1020static void GLAPIENTRY
1021VertexAttrib3uivARB(GLuint index, const GLuint *v)
1022{
1023   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, (GLfloat)v[0],
1024                                           (GLfloat)v[1], (GLfloat)v[2]));
1025}
1026
1027static void GLAPIENTRY
1028VertexAttrib4NuivARB(GLuint index, const GLuint *v)
1029{
1030   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
1031                                           UINT_TO_FLOAT(v[1]),
1032                                           UINT_TO_FLOAT(v[2]),
1033                                           UINT_TO_FLOAT(v[3])));
1034}
1035
1036static void GLAPIENTRY
1037VertexAttrib4uivARB(GLuint index, const GLuint *v)
1038{
1039   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
1040                                           (GLfloat)v[2], (GLfloat)v[3]));
1041}
1042
1043/* GL_FLOAT attributes */
1044
1045static void GLAPIENTRY
1046VertexAttrib1fvARB(GLuint index, const GLfloat *v)
1047{
1048   CALL_VertexAttrib1fvARB(GET_DISPATCH(), (index, v));
1049}
1050
1051static void GLAPIENTRY
1052VertexAttrib2fvARB(GLuint index, const GLfloat *v)
1053{
1054   CALL_VertexAttrib2fvARB(GET_DISPATCH(), (index, v));
1055}
1056
1057static void GLAPIENTRY
1058VertexAttrib3fvARB(GLuint index, const GLfloat *v)
1059{
1060   CALL_VertexAttrib3fvARB(GET_DISPATCH(), (index, v));
1061}
1062
1063static void GLAPIENTRY
1064VertexAttrib4fvARB(GLuint index, const GLfloat *v)
1065{
1066   CALL_VertexAttrib4fvARB(GET_DISPATCH(), (index, v));
1067}
1068
1069/* GL_DOUBLE attributes */
1070
1071static void GLAPIENTRY
1072VertexAttrib1dvARB(GLuint index, const GLdouble *v)
1073{
1074   CALL_VertexAttrib1dvARB(GET_DISPATCH(), (index, v));
1075}
1076
1077static void GLAPIENTRY
1078VertexAttrib2dvARB(GLuint index, const GLdouble *v)
1079{
1080   CALL_VertexAttrib2dvARB(GET_DISPATCH(), (index, v));
1081}
1082
1083static void GLAPIENTRY
1084VertexAttrib3dvARB(GLuint index, const GLdouble *v)
1085{
1086   CALL_VertexAttrib3dvARB(GET_DISPATCH(), (index, v));
1087}
1088
1089static void GLAPIENTRY
1090VertexAttrib4dvARB(GLuint index, const GLdouble *v)
1091{
1092   CALL_VertexAttrib4dvARB(GET_DISPATCH(), (index, v));
1093}
1094
1095
1096/**
1097 * Integer-valued attributes
1098 */
1099static void GLAPIENTRY
1100VertexAttribI1bv(GLuint index, const GLbyte *v)
1101{
1102   CALL_VertexAttribI1iEXT(GET_DISPATCH(), (index, v[0]));
1103}
1104
1105static void GLAPIENTRY
1106VertexAttribI2bv(GLuint index, const GLbyte *v)
1107{
1108   CALL_VertexAttribI2iEXT(GET_DISPATCH(), (index, v[0], v[1]));
1109}
1110
1111static void GLAPIENTRY
1112VertexAttribI3bv(GLuint index, const GLbyte *v)
1113{
1114   CALL_VertexAttribI3iEXT(GET_DISPATCH(), (index, v[0], v[1], v[2]));
1115}
1116
1117static void GLAPIENTRY
1118VertexAttribI4bv(GLuint index, const GLbyte *v)
1119{
1120   CALL_VertexAttribI4bvEXT(GET_DISPATCH(), (index, v));
1121}
1122
1123
1124static void GLAPIENTRY
1125VertexAttribI1ubv(GLuint index, const GLubyte *v)
1126{
1127   CALL_VertexAttribI1uiEXT(GET_DISPATCH(), (index, v[0]));
1128}
1129
1130static void GLAPIENTRY
1131VertexAttribI2ubv(GLuint index, const GLubyte *v)
1132{
1133   CALL_VertexAttribI2uiEXT(GET_DISPATCH(), (index, v[0], v[1]));
1134}
1135
1136static void GLAPIENTRY
1137VertexAttribI3ubv(GLuint index, const GLubyte *v)
1138{
1139   CALL_VertexAttribI3uiEXT(GET_DISPATCH(), (index, v[0], v[1], v[2]));
1140}
1141
1142static void GLAPIENTRY
1143VertexAttribI4ubv(GLuint index, const GLubyte *v)
1144{
1145   CALL_VertexAttribI4ubvEXT(GET_DISPATCH(), (index, v));
1146}
1147
1148
1149
1150static void GLAPIENTRY
1151VertexAttribI1sv(GLuint index, const GLshort *v)
1152{
1153   CALL_VertexAttribI1iEXT(GET_DISPATCH(), (index, v[0]));
1154}
1155
1156static void GLAPIENTRY
1157VertexAttribI2sv(GLuint index, const GLshort *v)
1158{
1159   CALL_VertexAttribI2iEXT(GET_DISPATCH(), (index, v[0], v[1]));
1160}
1161
1162static void GLAPIENTRY
1163VertexAttribI3sv(GLuint index, const GLshort *v)
1164{
1165   CALL_VertexAttribI3iEXT(GET_DISPATCH(), (index, v[0], v[1], v[2]));
1166}
1167
1168static void GLAPIENTRY
1169VertexAttribI4sv(GLuint index, const GLshort *v)
1170{
1171   CALL_VertexAttribI4svEXT(GET_DISPATCH(), (index, v));
1172}
1173
1174
1175static void GLAPIENTRY
1176VertexAttribI1usv(GLuint index, const GLushort *v)
1177{
1178   CALL_VertexAttribI1uiEXT(GET_DISPATCH(), (index, v[0]));
1179}
1180
1181static void GLAPIENTRY
1182VertexAttribI2usv(GLuint index, const GLushort *v)
1183{
1184   CALL_VertexAttribI2uiEXT(GET_DISPATCH(), (index, v[0], v[1]));
1185}
1186
1187static void GLAPIENTRY
1188VertexAttribI3usv(GLuint index, const GLushort *v)
1189{
1190   CALL_VertexAttribI3uiEXT(GET_DISPATCH(), (index, v[0], v[1], v[2]));
1191}
1192
1193static void GLAPIENTRY
1194VertexAttribI4usv(GLuint index, const GLushort *v)
1195{
1196   CALL_VertexAttribI4usvEXT(GET_DISPATCH(), (index, v));
1197}
1198
1199
1200
1201static void GLAPIENTRY
1202VertexAttribI1iv(GLuint index, const GLint *v)
1203{
1204   CALL_VertexAttribI1iEXT(GET_DISPATCH(), (index, v[0]));
1205}
1206
1207static void GLAPIENTRY
1208VertexAttribI2iv(GLuint index, const GLint *v)
1209{
1210   CALL_VertexAttribI2iEXT(GET_DISPATCH(), (index, v[0], v[1]));
1211}
1212
1213static void GLAPIENTRY
1214VertexAttribI3iv(GLuint index, const GLint *v)
1215{
1216   CALL_VertexAttribI3iEXT(GET_DISPATCH(), (index, v[0], v[1], v[2]));
1217}
1218
1219static void GLAPIENTRY
1220VertexAttribI4iv(GLuint index, const GLint *v)
1221{
1222   CALL_VertexAttribI4ivEXT(GET_DISPATCH(), (index, v));
1223}
1224
1225
1226static void GLAPIENTRY
1227VertexAttribI1uiv(GLuint index, const GLuint *v)
1228{
1229   CALL_VertexAttribI1uiEXT(GET_DISPATCH(), (index, v[0]));
1230}
1231
1232static void GLAPIENTRY
1233VertexAttribI2uiv(GLuint index, const GLuint *v)
1234{
1235   CALL_VertexAttribI2uiEXT(GET_DISPATCH(), (index, v[0], v[1]));
1236}
1237
1238static void GLAPIENTRY
1239VertexAttribI3uiv(GLuint index, const GLuint *v)
1240{
1241   CALL_VertexAttribI3uiEXT(GET_DISPATCH(), (index, v[0], v[1], v[2]));
1242}
1243
1244static void GLAPIENTRY
1245VertexAttribI4uiv(GLuint index, const GLuint *v)
1246{
1247   CALL_VertexAttribI4uivEXT(GET_DISPATCH(), (index, v));
1248}
1249
1250
1251
1252
1253/*
1254 * Array [unnormalized/normalized/integer][size][type] of VertexAttrib
1255 * functions
1256 */
1257static attrib_func AttribFuncsARB[3][4][NUM_TYPES] = {
1258   {
1259      /* non-normalized */
1260      {
1261         /* size 1 */
1262         (attrib_func) VertexAttrib1bvARB,
1263         (attrib_func) VertexAttrib1ubvARB,
1264         (attrib_func) VertexAttrib1svARB,
1265         (attrib_func) VertexAttrib1usvARB,
1266         (attrib_func) VertexAttrib1ivARB,
1267         (attrib_func) VertexAttrib1uivARB,
1268         (attrib_func) VertexAttrib1fvARB,
1269         (attrib_func) VertexAttrib1dvARB
1270      },
1271      {
1272         /* size 2 */
1273         (attrib_func) VertexAttrib2bvARB,
1274         (attrib_func) VertexAttrib2ubvARB,
1275         (attrib_func) VertexAttrib2svARB,
1276         (attrib_func) VertexAttrib2usvARB,
1277         (attrib_func) VertexAttrib2ivARB,
1278         (attrib_func) VertexAttrib2uivARB,
1279         (attrib_func) VertexAttrib2fvARB,
1280         (attrib_func) VertexAttrib2dvARB
1281      },
1282      {
1283         /* size 3 */
1284         (attrib_func) VertexAttrib3bvARB,
1285         (attrib_func) VertexAttrib3ubvARB,
1286         (attrib_func) VertexAttrib3svARB,
1287         (attrib_func) VertexAttrib3usvARB,
1288         (attrib_func) VertexAttrib3ivARB,
1289         (attrib_func) VertexAttrib3uivARB,
1290         (attrib_func) VertexAttrib3fvARB,
1291         (attrib_func) VertexAttrib3dvARB
1292      },
1293      {
1294         /* size 4 */
1295         (attrib_func) VertexAttrib4bvARB,
1296         (attrib_func) VertexAttrib4ubvARB,
1297         (attrib_func) VertexAttrib4svARB,
1298         (attrib_func) VertexAttrib4usvARB,
1299         (attrib_func) VertexAttrib4ivARB,
1300         (attrib_func) VertexAttrib4uivARB,
1301         (attrib_func) VertexAttrib4fvARB,
1302         (attrib_func) VertexAttrib4dvARB
1303      }
1304   },
1305   {
1306      /* normalized (except for float/double) */
1307      {
1308         /* size 1 */
1309         (attrib_func) VertexAttrib1NbvARB,
1310         (attrib_func) VertexAttrib1NubvARB,
1311         (attrib_func) VertexAttrib1NsvARB,
1312         (attrib_func) VertexAttrib1NusvARB,
1313         (attrib_func) VertexAttrib1NivARB,
1314         (attrib_func) VertexAttrib1NuivARB,
1315         (attrib_func) VertexAttrib1fvARB,
1316         (attrib_func) VertexAttrib1dvARB
1317      },
1318      {
1319         /* size 2 */
1320         (attrib_func) VertexAttrib2NbvARB,
1321         (attrib_func) VertexAttrib2NubvARB,
1322         (attrib_func) VertexAttrib2NsvARB,
1323         (attrib_func) VertexAttrib2NusvARB,
1324         (attrib_func) VertexAttrib2NivARB,
1325         (attrib_func) VertexAttrib2NuivARB,
1326         (attrib_func) VertexAttrib2fvARB,
1327         (attrib_func) VertexAttrib2dvARB
1328      },
1329      {
1330         /* size 3 */
1331         (attrib_func) VertexAttrib3NbvARB,
1332         (attrib_func) VertexAttrib3NubvARB,
1333         (attrib_func) VertexAttrib3NsvARB,
1334         (attrib_func) VertexAttrib3NusvARB,
1335         (attrib_func) VertexAttrib3NivARB,
1336         (attrib_func) VertexAttrib3NuivARB,
1337         (attrib_func) VertexAttrib3fvARB,
1338         (attrib_func) VertexAttrib3dvARB
1339      },
1340      {
1341         /* size 4 */
1342         (attrib_func) VertexAttrib4NbvARB,
1343         (attrib_func) VertexAttrib4NubvARB,
1344         (attrib_func) VertexAttrib4NsvARB,
1345         (attrib_func) VertexAttrib4NusvARB,
1346         (attrib_func) VertexAttrib4NivARB,
1347         (attrib_func) VertexAttrib4NuivARB,
1348         (attrib_func) VertexAttrib4fvARB,
1349         (attrib_func) VertexAttrib4dvARB
1350      }
1351   },
1352
1353   {
1354      /* integer-valued */
1355      {
1356         /* size 1 */
1357         (attrib_func) VertexAttribI1bv,
1358         (attrib_func) VertexAttribI1ubv,
1359         (attrib_func) VertexAttribI1sv,
1360         (attrib_func) VertexAttribI1usv,
1361         (attrib_func) VertexAttribI1iv,
1362         (attrib_func) VertexAttribI1uiv,
1363         NULL, /* GL_FLOAT */
1364         NULL  /* GL_DOUBLE */
1365      },
1366      {
1367         /* size 2 */
1368         (attrib_func) VertexAttribI2bv,
1369         (attrib_func) VertexAttribI2ubv,
1370         (attrib_func) VertexAttribI2sv,
1371         (attrib_func) VertexAttribI2usv,
1372         (attrib_func) VertexAttribI2iv,
1373         (attrib_func) VertexAttribI2uiv,
1374         NULL, /* GL_FLOAT */
1375         NULL  /* GL_DOUBLE */
1376      },
1377      {
1378         /* size 3 */
1379         (attrib_func) VertexAttribI3bv,
1380         (attrib_func) VertexAttribI3ubv,
1381         (attrib_func) VertexAttribI3sv,
1382         (attrib_func) VertexAttribI3usv,
1383         (attrib_func) VertexAttribI3iv,
1384         (attrib_func) VertexAttribI3uiv,
1385         NULL, /* GL_FLOAT */
1386         NULL  /* GL_DOUBLE */
1387      },
1388      {
1389         /* size 4 */
1390         (attrib_func) VertexAttribI4bv,
1391         (attrib_func) VertexAttribI4ubv,
1392         (attrib_func) VertexAttribI4sv,
1393         (attrib_func) VertexAttribI4usv,
1394         (attrib_func) VertexAttribI4iv,
1395         (attrib_func) VertexAttribI4uiv,
1396         NULL, /* GL_FLOAT */
1397         NULL  /* GL_DOUBLE */
1398      }
1399   }
1400};
1401
1402/**********************************************************************/
1403
1404
1405GLboolean _ae_create_context( struct gl_context *ctx )
1406{
1407   if (ctx->aelt_context)
1408      return GL_TRUE;
1409
1410   /* These _gloffset_* values may not be compile-time constants */
1411   SecondaryColorFuncs[0] = _gloffset_SecondaryColor3bvEXT;
1412   SecondaryColorFuncs[1] = _gloffset_SecondaryColor3ubvEXT;
1413   SecondaryColorFuncs[2] = _gloffset_SecondaryColor3svEXT;
1414   SecondaryColorFuncs[3] = _gloffset_SecondaryColor3usvEXT;
1415   SecondaryColorFuncs[4] = _gloffset_SecondaryColor3ivEXT;
1416   SecondaryColorFuncs[5] = _gloffset_SecondaryColor3uivEXT;
1417   SecondaryColorFuncs[6] = _gloffset_SecondaryColor3fvEXT;
1418   SecondaryColorFuncs[7] = _gloffset_SecondaryColor3dvEXT;
1419
1420   FogCoordFuncs[0] = -1;
1421   FogCoordFuncs[1] = -1;
1422   FogCoordFuncs[2] = -1;
1423   FogCoordFuncs[3] = -1;
1424   FogCoordFuncs[4] = -1;
1425   FogCoordFuncs[5] = -1;
1426   FogCoordFuncs[6] = _gloffset_FogCoordfvEXT;
1427   FogCoordFuncs[7] = _gloffset_FogCoorddvEXT;
1428
1429   ctx->aelt_context = CALLOC( sizeof(AEcontext) );
1430   if (!ctx->aelt_context)
1431      return GL_FALSE;
1432
1433   AE_CONTEXT(ctx)->NewState = ~0;
1434   return GL_TRUE;
1435}
1436
1437
1438void _ae_destroy_context( struct gl_context *ctx )
1439{
1440   if ( AE_CONTEXT( ctx ) ) {
1441      FREE( ctx->aelt_context );
1442      ctx->aelt_context = NULL;
1443   }
1444}
1445
1446static void check_vbo( AEcontext *actx,
1447		       struct gl_buffer_object *vbo )
1448{
1449   if (_mesa_is_bufferobj(vbo) && !_mesa_bufferobj_mapped(vbo)) {
1450      GLuint i;
1451      for (i = 0; i < actx->nr_vbos; i++)
1452	 if (actx->vbo[i] == vbo)
1453	    return;
1454      assert(actx->nr_vbos < VERT_ATTRIB_MAX);
1455      actx->vbo[actx->nr_vbos++] = vbo;
1456   }
1457}
1458
1459
1460/**
1461 * Make a list of per-vertex functions to call for each glArrayElement call.
1462 * These functions access the array data (i.e. glVertex, glColor, glNormal,
1463 * etc).
1464 * Note: this may be called during display list construction.
1465 */
1466static void _ae_update_state( struct gl_context *ctx )
1467{
1468   AEcontext *actx = AE_CONTEXT(ctx);
1469   AEarray *aa = actx->arrays;
1470   AEattrib *at = actx->attribs;
1471   GLuint i;
1472   struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
1473
1474   actx->nr_vbos = 0;
1475
1476   /* conventional vertex arrays */
1477   if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) {
1478      aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX];
1479      aa->offset = IndexFuncs[TYPE_IDX(aa->array->Type)];
1480      check_vbo(actx, aa->array->BufferObj);
1481      aa++;
1482   }
1483   if (arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) {
1484      aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG];
1485      aa->offset = _gloffset_EdgeFlagv;
1486      check_vbo(actx, aa->array->BufferObj);
1487      aa++;
1488   }
1489   if (arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) {
1490      aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL];
1491      aa->offset = NormalFuncs[TYPE_IDX(aa->array->Type)];
1492      check_vbo(actx, aa->array->BufferObj);
1493      aa++;
1494   }
1495   if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) {
1496      aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0];
1497      aa->offset = ColorFuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)];
1498      check_vbo(actx, aa->array->BufferObj);
1499      aa++;
1500   }
1501   if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) {
1502      aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1];
1503      aa->offset = SecondaryColorFuncs[TYPE_IDX(aa->array->Type)];
1504      check_vbo(actx, aa->array->BufferObj);
1505      aa++;
1506   }
1507   if (arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) {
1508      aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_FOG];
1509      aa->offset = FogCoordFuncs[TYPE_IDX(aa->array->Type)];
1510      check_vbo(actx, aa->array->BufferObj);
1511      aa++;
1512   }
1513   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
1514      struct gl_client_array *attribArray = &arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)];
1515      if (attribArray->Enabled) {
1516         /* NOTE: we use generic glVertexAttribNV functions here.
1517          * If we ever remove GL_NV_vertex_program this will have to change.
1518          */
1519         at->array = attribArray;
1520         ASSERT(!at->array->Normalized);
1521         at->func = AttribFuncsNV[at->array->Normalized]
1522                                 [at->array->Size-1]
1523                                 [TYPE_IDX(at->array->Type)];
1524         at->index = VERT_ATTRIB_TEX0 + i;
1525	 check_vbo(actx, at->array->BufferObj);
1526         at++;
1527      }
1528   }
1529
1530   /* generic vertex attribute arrays */
1531   for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) {  /* skip zero! */
1532      struct gl_client_array *attribArray = &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)];
1533      if (attribArray->Enabled) {
1534         at->array = attribArray;
1535         /* Note: we can't grab the _glapi_Dispatch->VertexAttrib1fvNV
1536          * function pointer here (for float arrays) since the pointer may
1537          * change from one execution of _ae_ArrayElement() to
1538          * the next.  Doing so caused UT to break.
1539          */
1540         if (ctx->VertexProgram._Enabled
1541             && ctx->VertexProgram.Current->IsNVProgram) {
1542            at->func = AttribFuncsNV[at->array->Normalized]
1543                                    [at->array->Size-1]
1544                                    [TYPE_IDX(at->array->Type)];
1545         }
1546         else {
1547            GLint intOrNorm;
1548            if (at->array->Integer)
1549               intOrNorm = 2;
1550            else if (at->array->Normalized)
1551               intOrNorm = 1;
1552            else
1553               intOrNorm = 0;
1554
1555            at->func = AttribFuncsARB[intOrNorm]
1556                                     [at->array->Size-1]
1557                                     [TYPE_IDX(at->array->Type)];
1558         }
1559         at->index = i;
1560	 check_vbo(actx, at->array->BufferObj);
1561         at++;
1562      }
1563   }
1564
1565   /* finally, vertex position */
1566   if (arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) {
1567      /* Use glVertex(v) instead of glVertexAttrib(0, v) to be sure it's
1568       * issued as the last (provoking) attribute).
1569       */
1570      aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0];
1571      assert(aa->array->Size >= 2); /* XXX fix someday? */
1572      aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
1573      check_vbo(actx, aa->array->BufferObj);
1574      aa++;
1575   }
1576   else if (arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) {
1577      aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_POS];
1578      aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
1579      check_vbo(actx, aa->array->BufferObj);
1580      aa++;
1581   }
1582
1583   check_vbo(actx, arrayObj->ElementArrayBufferObj);
1584
1585   ASSERT(at - actx->attribs <= VERT_ATTRIB_MAX);
1586   ASSERT(aa - actx->arrays < 32);
1587   at->func = NULL;  /* terminate the list */
1588   aa->offset = -1;  /* terminate the list */
1589
1590   actx->NewState = 0;
1591}
1592
1593void _ae_map_vbos( struct gl_context *ctx )
1594{
1595   AEcontext *actx = AE_CONTEXT(ctx);
1596   GLuint i;
1597
1598   if (actx->mapped_vbos)
1599      return;
1600
1601   if (actx->NewState)
1602      _ae_update_state(ctx);
1603
1604   for (i = 0; i < actx->nr_vbos; i++)
1605      ctx->Driver.MapBufferRange(ctx, 0,
1606				 actx->vbo[i]->Size,
1607				 GL_MAP_READ_BIT,
1608				 actx->vbo[i]);
1609
1610   if (actx->nr_vbos)
1611      actx->mapped_vbos = GL_TRUE;
1612}
1613
1614void _ae_unmap_vbos( struct gl_context *ctx )
1615{
1616   AEcontext *actx = AE_CONTEXT(ctx);
1617   GLuint i;
1618
1619   if (!actx->mapped_vbos)
1620      return;
1621
1622   assert (!actx->NewState);
1623
1624   for (i = 0; i < actx->nr_vbos; i++)
1625      ctx->Driver.UnmapBuffer(ctx, actx->vbo[i]);
1626
1627   actx->mapped_vbos = GL_FALSE;
1628}
1629
1630
1631/**
1632 * Called via glArrayElement() and glDrawArrays().
1633 * Issue the glNormal, glVertex, glColor, glVertexAttrib, etc functions
1634 * for all enabled vertex arrays (for elt-th element).
1635 * Note: this may be called during display list construction.
1636 */
1637void GLAPIENTRY _ae_ArrayElement( GLint elt )
1638{
1639   GET_CURRENT_CONTEXT(ctx);
1640   const AEcontext *actx = AE_CONTEXT(ctx);
1641   const AEarray *aa;
1642   const AEattrib *at;
1643   const struct _glapi_table * const disp = GET_DISPATCH();
1644   GLboolean do_map;
1645
1646   /* If PrimitiveRestart is enabled and the index is the RestartIndex
1647    * then we call PrimitiveRestartNV and return.
1648    */
1649   if (ctx->Array.PrimitiveRestart && (elt == ctx->Array.RestartIndex)) {
1650      CALL_PrimitiveRestartNV((struct _glapi_table *)disp, ());
1651      return;
1652   }
1653
1654   if (actx->NewState) {
1655      assert(!actx->mapped_vbos);
1656      _ae_update_state( ctx );
1657   }
1658
1659   /* Determine if we need to map/unmap VBOs */
1660   do_map = actx->nr_vbos && !actx->mapped_vbos;
1661
1662   if (do_map)
1663      _ae_map_vbos(ctx);
1664
1665   /* emit generic attribute elements */
1666   for (at = actx->attribs; at->func; at++) {
1667      const GLubyte *src
1668         = ADD_POINTERS(at->array->BufferObj->Pointer, at->array->Ptr)
1669         + elt * at->array->StrideB;
1670      at->func( at->index, src );
1671   }
1672
1673   /* emit conventional arrays elements */
1674   for (aa = actx->arrays; aa->offset != -1 ; aa++) {
1675      const GLubyte *src
1676         = ADD_POINTERS(aa->array->BufferObj->Pointer, aa->array->Ptr)
1677         + elt * aa->array->StrideB;
1678      CALL_by_offset( disp, (array_func), aa->offset,
1679		      ((const void *) src) );
1680   }
1681
1682   if (do_map)
1683      _ae_unmap_vbos(ctx);
1684}
1685
1686
1687void _ae_invalidate_state( struct gl_context *ctx, GLuint new_state )
1688{
1689   AEcontext *actx = AE_CONTEXT(ctx);
1690
1691
1692   /* Only interested in this subset of mesa state.  Need to prune
1693    * this down as both tnl/ and the drivers can raise statechanges
1694    * for arcane reasons in the middle of seemingly atomic operations
1695    * like DrawElements, over which we'd like to keep a known set of
1696    * arrays and vbo's mapped.
1697    *
1698    * Luckily, neither the drivers nor tnl muck with the state that
1699    * concerns us here:
1700    */
1701   new_state &= _NEW_ARRAY | _NEW_PROGRAM;
1702   if (new_state) {
1703      assert(!actx->mapped_vbos);
1704      actx->NewState |= new_state;
1705   }
1706}
1707
1708
1709void _mesa_install_arrayelt_vtxfmt(struct _glapi_table *disp,
1710                                   const GLvertexformat *vfmt)
1711{
1712   SET_ArrayElement(disp, vfmt->ArrayElement);
1713}
1714
1715
1716#endif /* FEATURE_arrayelt */
1717