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