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 *attrib_func)( GLuint indx, const void *data );
49
50/*
51 * Convert GL_BYTE, GL_UNSIGNED_BYTE, .. GL_DOUBLE into an integer
52 * in the range [0, 7].  Luckily these type tokens are sequentially
53 * numbered in gl.h, except for GL_DOUBLE.
54 */
55static inline int
56TYPE_IDX(GLenum t)
57{
58   return t == GL_DOUBLE ? 7 : t & 7;
59}
60
61
62/*
63 * Convert normalized/integer/double to the range [0, 3].
64 */
65static inline int
66vertex_format_to_index(const struct gl_vertex_format *vformat)
67{
68   if (vformat->Doubles)
69      return 3;
70   else if (vformat->Integer)
71      return 2;
72   else if (vformat->Normalized)
73      return 1;
74   else
75      return 0;
76}
77
78
79#define NUM_TYPES 8
80
81
82/**
83 ** GL_NV_vertex_program
84 **/
85
86/* GL_BYTE attributes */
87
88static void GLAPIENTRY
89VertexAttrib1NbvNV(GLuint index, const GLbyte *v)
90{
91   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0])));
92}
93
94static void GLAPIENTRY
95VertexAttrib1bvNV(GLuint index, const GLbyte *v)
96{
97   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
98}
99
100static void GLAPIENTRY
101VertexAttrib2NbvNV(GLuint index, const GLbyte *v)
102{
103   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1])));
104}
105
106static void GLAPIENTRY
107VertexAttrib2bvNV(GLuint index, const GLbyte *v)
108{
109   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
110}
111
112static void GLAPIENTRY
113VertexAttrib3NbvNV(GLuint index, const GLbyte *v)
114{
115   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
116					       BYTE_TO_FLOAT(v[1]),
117					       BYTE_TO_FLOAT(v[2])));
118}
119
120static void GLAPIENTRY
121VertexAttrib3bvNV(GLuint index, const GLbyte *v)
122{
123   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
124}
125
126static void GLAPIENTRY
127VertexAttrib4NbvNV(GLuint index, const GLbyte *v)
128{
129   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
130					       BYTE_TO_FLOAT(v[1]),
131					       BYTE_TO_FLOAT(v[2]),
132					       BYTE_TO_FLOAT(v[3])));
133}
134
135static void GLAPIENTRY
136VertexAttrib4bvNV(GLuint index, const GLbyte *v)
137{
138   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
139}
140
141/* GL_UNSIGNED_BYTE attributes */
142
143static void GLAPIENTRY
144VertexAttrib1NubvNV(GLuint index, const GLubyte *v)
145{
146   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0])));
147}
148
149static void GLAPIENTRY
150VertexAttrib1ubvNV(GLuint index, const GLubyte *v)
151{
152   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
153}
154
155static void GLAPIENTRY
156VertexAttrib2NubvNV(GLuint index, const GLubyte *v)
157{
158   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
159                                          UBYTE_TO_FLOAT(v[1])));
160}
161
162static void GLAPIENTRY
163VertexAttrib2ubvNV(GLuint index, const GLubyte *v)
164{
165   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
166}
167
168static void GLAPIENTRY
169VertexAttrib3NubvNV(GLuint index, const GLubyte *v)
170{
171   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
172					       UBYTE_TO_FLOAT(v[1]),
173					       UBYTE_TO_FLOAT(v[2])));
174}
175static void GLAPIENTRY
176VertexAttrib3ubvNV(GLuint index, const GLubyte *v)
177{
178   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0],
179                                          (GLfloat)v[1], (GLfloat)v[2]));
180}
181
182static void GLAPIENTRY
183VertexAttrib4NubvNV(GLuint index, const GLubyte *v)
184{
185   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
186                                          UBYTE_TO_FLOAT(v[1]),
187                                          UBYTE_TO_FLOAT(v[2]),
188                                          UBYTE_TO_FLOAT(v[3])));
189}
190
191static void GLAPIENTRY
192VertexAttrib4ubvNV(GLuint index, const GLubyte *v)
193{
194   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0],
195                                          (GLfloat)v[1], (GLfloat)v[2],
196                                          (GLfloat)v[3]));
197}
198
199/* GL_SHORT attributes */
200
201static void GLAPIENTRY
202VertexAttrib1NsvNV(GLuint index, const GLshort *v)
203{
204   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0])));
205}
206
207static void GLAPIENTRY
208VertexAttrib1svNV(GLuint index, const GLshort *v)
209{
210   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
211}
212
213static void GLAPIENTRY
214VertexAttrib2NsvNV(GLuint index, const GLshort *v)
215{
216   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
217                                          SHORT_TO_FLOAT(v[1])));
218}
219
220static void GLAPIENTRY
221VertexAttrib2svNV(GLuint index, const GLshort *v)
222{
223   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
224}
225
226static void GLAPIENTRY
227VertexAttrib3NsvNV(GLuint index, const GLshort *v)
228{
229   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
230			     SHORT_TO_FLOAT(v[1]),
231			     SHORT_TO_FLOAT(v[2])));
232}
233
234static void GLAPIENTRY
235VertexAttrib3svNV(GLuint index, const GLshort *v)
236{
237   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
238                                          (GLfloat)v[2]));
239}
240
241static void GLAPIENTRY
242VertexAttrib4NsvNV(GLuint index, const GLshort *v)
243{
244   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
245			     SHORT_TO_FLOAT(v[1]),
246			     SHORT_TO_FLOAT(v[2]),
247			     SHORT_TO_FLOAT(v[3])));
248}
249
250static void GLAPIENTRY
251VertexAttrib4svNV(GLuint index, const GLshort *v)
252{
253   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
254                                          (GLfloat)v[2], (GLfloat)v[3]));
255}
256
257/* GL_UNSIGNED_SHORT attributes */
258
259static void GLAPIENTRY
260VertexAttrib1NusvNV(GLuint index, const GLushort *v)
261{
262   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0])));
263}
264
265static void GLAPIENTRY
266VertexAttrib1usvNV(GLuint index, const GLushort *v)
267{
268   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
269}
270
271static void GLAPIENTRY
272VertexAttrib2NusvNV(GLuint index, const GLushort *v)
273{
274   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
275			     USHORT_TO_FLOAT(v[1])));
276}
277
278static void GLAPIENTRY
279VertexAttrib2usvNV(GLuint index, const GLushort *v)
280{
281   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0],
282                                          (GLfloat)v[1]));
283}
284
285static void GLAPIENTRY
286VertexAttrib3NusvNV(GLuint index, const GLushort *v)
287{
288   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
289					       USHORT_TO_FLOAT(v[1]),
290					       USHORT_TO_FLOAT(v[2])));
291}
292
293static void GLAPIENTRY
294VertexAttrib3usvNV(GLuint index, const GLushort *v)
295{
296   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
297                                          (GLfloat)v[2]));
298}
299
300static void GLAPIENTRY
301VertexAttrib4NusvNV(GLuint index, const GLushort *v)
302{
303   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
304					       USHORT_TO_FLOAT(v[1]),
305					       USHORT_TO_FLOAT(v[2]),
306					       USHORT_TO_FLOAT(v[3])));
307}
308
309static void GLAPIENTRY
310VertexAttrib4usvNV(GLuint index, const GLushort *v)
311{
312   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
313                                          (GLfloat)v[2], (GLfloat)v[3]));
314}
315
316/* GL_INT attributes */
317
318static void GLAPIENTRY
319VertexAttrib1NivNV(GLuint index, const GLint *v)
320{
321   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0])));
322}
323
324static void GLAPIENTRY
325VertexAttrib1ivNV(GLuint index, const GLint *v)
326{
327   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
328}
329
330static void GLAPIENTRY
331VertexAttrib2NivNV(GLuint index, const GLint *v)
332{
333   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
334					       INT_TO_FLOAT(v[1])));
335}
336
337static void GLAPIENTRY
338VertexAttrib2ivNV(GLuint index, const GLint *v)
339{
340   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
341}
342
343static void GLAPIENTRY
344VertexAttrib3NivNV(GLuint index, const GLint *v)
345{
346   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
347					       INT_TO_FLOAT(v[1]),
348					       INT_TO_FLOAT(v[2])));
349}
350
351static void GLAPIENTRY
352VertexAttrib3ivNV(GLuint index, const GLint *v)
353{
354   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
355                                          (GLfloat)v[2]));
356}
357
358static void GLAPIENTRY
359VertexAttrib4NivNV(GLuint index, const GLint *v)
360{
361   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
362                                          INT_TO_FLOAT(v[1]),
363                                          INT_TO_FLOAT(v[2]),
364                                          INT_TO_FLOAT(v[3])));
365}
366
367static void GLAPIENTRY
368VertexAttrib4ivNV(GLuint index, const GLint *v)
369{
370   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
371                                          (GLfloat)v[2], (GLfloat)v[3]));
372}
373
374/* GL_UNSIGNED_INT attributes */
375
376static void GLAPIENTRY
377VertexAttrib1NuivNV(GLuint index, const GLuint *v)
378{
379   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0])));
380}
381
382static void GLAPIENTRY
383VertexAttrib1uivNV(GLuint index, const GLuint *v)
384{
385   CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
386}
387
388static void GLAPIENTRY
389VertexAttrib2NuivNV(GLuint index, const GLuint *v)
390{
391   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
392                                          UINT_TO_FLOAT(v[1])));
393}
394
395static void GLAPIENTRY
396VertexAttrib2uivNV(GLuint index, const GLuint *v)
397{
398   CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0],
399                                          (GLfloat)v[1]));
400}
401
402static void GLAPIENTRY
403VertexAttrib3NuivNV(GLuint index, const GLuint *v)
404{
405   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
406					       UINT_TO_FLOAT(v[1]),
407					       UINT_TO_FLOAT(v[2])));
408}
409
410static void GLAPIENTRY
411VertexAttrib3uivNV(GLuint index, const GLuint *v)
412{
413   CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
414                                          (GLfloat)v[2]));
415}
416
417static void GLAPIENTRY
418VertexAttrib4NuivNV(GLuint index, const GLuint *v)
419{
420   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
421					       UINT_TO_FLOAT(v[1]),
422					       UINT_TO_FLOAT(v[2]),
423					       UINT_TO_FLOAT(v[3])));
424}
425
426static void GLAPIENTRY
427VertexAttrib4uivNV(GLuint index, const GLuint *v)
428{
429   CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
430                                          (GLfloat)v[2], (GLfloat)v[3]));
431}
432
433/* GL_FLOAT attributes */
434
435static void GLAPIENTRY
436VertexAttrib1fvNV(GLuint index, const GLfloat *v)
437{
438   CALL_VertexAttrib1fvNV(GET_DISPATCH(), (index, v));
439}
440
441static void GLAPIENTRY
442VertexAttrib2fvNV(GLuint index, const GLfloat *v)
443{
444   CALL_VertexAttrib2fvNV(GET_DISPATCH(), (index, v));
445}
446
447static void GLAPIENTRY
448VertexAttrib3fvNV(GLuint index, const GLfloat *v)
449{
450   CALL_VertexAttrib3fvNV(GET_DISPATCH(), (index, v));
451}
452
453static void GLAPIENTRY
454VertexAttrib4fvNV(GLuint index, const GLfloat *v)
455{
456   CALL_VertexAttrib4fvNV(GET_DISPATCH(), (index, v));
457}
458
459/* GL_DOUBLE attributes */
460
461static void GLAPIENTRY
462VertexAttrib1dvNV(GLuint index, const GLdouble *v)
463{
464   CALL_VertexAttrib1dvNV(GET_DISPATCH(), (index, v));
465}
466
467static void GLAPIENTRY
468VertexAttrib2dvNV(GLuint index, const GLdouble *v)
469{
470   CALL_VertexAttrib2dvNV(GET_DISPATCH(), (index, v));
471}
472
473static void GLAPIENTRY
474VertexAttrib3dvNV(GLuint index, const GLdouble *v)
475{
476   CALL_VertexAttrib3dvNV(GET_DISPATCH(), (index, v));
477}
478
479static void GLAPIENTRY
480VertexAttrib4dvNV(GLuint index, const GLdouble *v)
481{
482   CALL_VertexAttrib4dvNV(GET_DISPATCH(), (index, v));
483}
484
485
486/*
487 * Array [size][type] of VertexAttrib functions
488 */
489static const attrib_func AttribFuncsNV[2][4][NUM_TYPES] = {
490   {
491      /* non-normalized */
492      {
493         /* size 1 */
494         (attrib_func) VertexAttrib1bvNV,
495         (attrib_func) VertexAttrib1ubvNV,
496         (attrib_func) VertexAttrib1svNV,
497         (attrib_func) VertexAttrib1usvNV,
498         (attrib_func) VertexAttrib1ivNV,
499         (attrib_func) VertexAttrib1uivNV,
500         (attrib_func) VertexAttrib1fvNV,
501         (attrib_func) VertexAttrib1dvNV
502      },
503      {
504         /* size 2 */
505         (attrib_func) VertexAttrib2bvNV,
506         (attrib_func) VertexAttrib2ubvNV,
507         (attrib_func) VertexAttrib2svNV,
508         (attrib_func) VertexAttrib2usvNV,
509         (attrib_func) VertexAttrib2ivNV,
510         (attrib_func) VertexAttrib2uivNV,
511         (attrib_func) VertexAttrib2fvNV,
512         (attrib_func) VertexAttrib2dvNV
513      },
514      {
515         /* size 3 */
516         (attrib_func) VertexAttrib3bvNV,
517         (attrib_func) VertexAttrib3ubvNV,
518         (attrib_func) VertexAttrib3svNV,
519         (attrib_func) VertexAttrib3usvNV,
520         (attrib_func) VertexAttrib3ivNV,
521         (attrib_func) VertexAttrib3uivNV,
522         (attrib_func) VertexAttrib3fvNV,
523         (attrib_func) VertexAttrib3dvNV
524      },
525      {
526         /* size 4 */
527         (attrib_func) VertexAttrib4bvNV,
528         (attrib_func) VertexAttrib4ubvNV,
529         (attrib_func) VertexAttrib4svNV,
530         (attrib_func) VertexAttrib4usvNV,
531         (attrib_func) VertexAttrib4ivNV,
532         (attrib_func) VertexAttrib4uivNV,
533         (attrib_func) VertexAttrib4fvNV,
534         (attrib_func) VertexAttrib4dvNV
535      }
536   },
537   {
538      /* normalized (except for float/double) */
539      {
540         /* size 1 */
541         (attrib_func) VertexAttrib1NbvNV,
542         (attrib_func) VertexAttrib1NubvNV,
543         (attrib_func) VertexAttrib1NsvNV,
544         (attrib_func) VertexAttrib1NusvNV,
545         (attrib_func) VertexAttrib1NivNV,
546         (attrib_func) VertexAttrib1NuivNV,
547         (attrib_func) VertexAttrib1fvNV,
548         (attrib_func) VertexAttrib1dvNV
549      },
550      {
551         /* size 2 */
552         (attrib_func) VertexAttrib2NbvNV,
553         (attrib_func) VertexAttrib2NubvNV,
554         (attrib_func) VertexAttrib2NsvNV,
555         (attrib_func) VertexAttrib2NusvNV,
556         (attrib_func) VertexAttrib2NivNV,
557         (attrib_func) VertexAttrib2NuivNV,
558         (attrib_func) VertexAttrib2fvNV,
559         (attrib_func) VertexAttrib2dvNV
560      },
561      {
562         /* size 3 */
563         (attrib_func) VertexAttrib3NbvNV,
564         (attrib_func) VertexAttrib3NubvNV,
565         (attrib_func) VertexAttrib3NsvNV,
566         (attrib_func) VertexAttrib3NusvNV,
567         (attrib_func) VertexAttrib3NivNV,
568         (attrib_func) VertexAttrib3NuivNV,
569         (attrib_func) VertexAttrib3fvNV,
570         (attrib_func) VertexAttrib3dvNV
571      },
572      {
573         /* size 4 */
574         (attrib_func) VertexAttrib4NbvNV,
575         (attrib_func) VertexAttrib4NubvNV,
576         (attrib_func) VertexAttrib4NsvNV,
577         (attrib_func) VertexAttrib4NusvNV,
578         (attrib_func) VertexAttrib4NivNV,
579         (attrib_func) VertexAttrib4NuivNV,
580         (attrib_func) VertexAttrib4fvNV,
581         (attrib_func) VertexAttrib4dvNV
582      }
583   }
584};
585
586
587/**
588 ** GL_ARB_vertex_program
589 **/
590
591/* GL_BYTE attributes */
592
593static void GLAPIENTRY
594VertexAttrib1NbvARB(GLuint index, const GLbyte *v)
595{
596   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0])));
597}
598
599static void GLAPIENTRY
600VertexAttrib1bvARB(GLuint index, const GLbyte *v)
601{
602   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
603}
604
605static void GLAPIENTRY
606VertexAttrib2NbvARB(GLuint index, const GLbyte *v)
607{
608   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1])));
609}
610
611static void GLAPIENTRY
612VertexAttrib2bvARB(GLuint index, const GLbyte *v)
613{
614   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
615}
616
617static void GLAPIENTRY
618VertexAttrib3NbvARB(GLuint index, const GLbyte *v)
619{
620   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
621					       BYTE_TO_FLOAT(v[1]),
622					       BYTE_TO_FLOAT(v[2])));
623}
624
625static void GLAPIENTRY
626VertexAttrib3bvARB(GLuint index, const GLbyte *v)
627{
628   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
629}
630
631static void GLAPIENTRY
632VertexAttrib4NbvARB(GLuint index, const GLbyte *v)
633{
634   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
635					       BYTE_TO_FLOAT(v[1]),
636					       BYTE_TO_FLOAT(v[2]),
637					       BYTE_TO_FLOAT(v[3])));
638}
639
640static void GLAPIENTRY
641VertexAttrib4bvARB(GLuint index, const GLbyte *v)
642{
643   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
644}
645
646/* GL_UNSIGNED_BYTE attributes */
647
648static void GLAPIENTRY
649VertexAttrib1NubvARB(GLuint index, const GLubyte *v)
650{
651   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0])));
652}
653
654static void GLAPIENTRY
655VertexAttrib1ubvARB(GLuint index, const GLubyte *v)
656{
657   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
658}
659
660static void GLAPIENTRY
661VertexAttrib2NubvARB(GLuint index, const GLubyte *v)
662{
663   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index,
664                                           UBYTE_TO_FLOAT(v[0]),
665                                           UBYTE_TO_FLOAT(v[1])));
666}
667
668static void GLAPIENTRY
669VertexAttrib2ubvARB(GLuint index, const GLubyte *v)
670{
671   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index,
672                                           (GLfloat)v[0], (GLfloat)v[1]));
673}
674
675static void GLAPIENTRY
676VertexAttrib3NubvARB(GLuint index, const GLubyte *v)
677{
678   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index,
679                                           UBYTE_TO_FLOAT(v[0]),
680                                           UBYTE_TO_FLOAT(v[1]),
681                                           UBYTE_TO_FLOAT(v[2])));
682}
683static void GLAPIENTRY
684VertexAttrib3ubvARB(GLuint index, const GLubyte *v)
685{
686   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index,
687                                           (GLfloat)v[0],
688                                           (GLfloat)v[1],
689                                           (GLfloat)v[2]));
690}
691
692static void GLAPIENTRY
693VertexAttrib4NubvARB(GLuint index, const GLubyte *v)
694{
695   CALL_VertexAttrib4fARB(GET_DISPATCH(),
696                          (index,
697                           UBYTE_TO_FLOAT(v[0]),
698                           UBYTE_TO_FLOAT(v[1]),
699                           UBYTE_TO_FLOAT(v[2]),
700                           UBYTE_TO_FLOAT(v[3])));
701}
702
703static void GLAPIENTRY
704VertexAttrib4ubvARB(GLuint index, const GLubyte *v)
705{
706   CALL_VertexAttrib4fARB(GET_DISPATCH(),
707                          (index,
708                           (GLfloat)v[0], (GLfloat)v[1],
709                           (GLfloat)v[2], (GLfloat)v[3]));
710}
711
712/* GL_SHORT attributes */
713
714static void GLAPIENTRY
715VertexAttrib1NsvARB(GLuint index, const GLshort *v)
716{
717   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0])));
718}
719
720static void GLAPIENTRY
721VertexAttrib1svARB(GLuint index, const GLshort *v)
722{
723   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
724}
725
726static void GLAPIENTRY
727VertexAttrib2NsvARB(GLuint index, const GLshort *v)
728{
729   CALL_VertexAttrib2fARB(GET_DISPATCH(),
730                          (index, SHORT_TO_FLOAT(v[0]),
731                           SHORT_TO_FLOAT(v[1])));
732}
733
734static void GLAPIENTRY
735VertexAttrib2svARB(GLuint index, const GLshort *v)
736{
737   CALL_VertexAttrib2fARB(GET_DISPATCH(),
738                          (index, (GLfloat)v[0], (GLfloat)v[1]));
739}
740
741static void GLAPIENTRY
742VertexAttrib3NsvARB(GLuint index, const GLshort *v)
743{
744   CALL_VertexAttrib3fARB(GET_DISPATCH(),
745                          (index,
746                           SHORT_TO_FLOAT(v[0]),
747                           SHORT_TO_FLOAT(v[1]),
748                           SHORT_TO_FLOAT(v[2])));
749}
750
751static void GLAPIENTRY
752VertexAttrib3svARB(GLuint index, const GLshort *v)
753{
754   CALL_VertexAttrib3fARB(GET_DISPATCH(),
755                          (index,
756                           (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
757}
758
759static void GLAPIENTRY
760VertexAttrib4NsvARB(GLuint index, const GLshort *v)
761{
762   CALL_VertexAttrib4fARB(GET_DISPATCH(),
763                          (index,
764                           SHORT_TO_FLOAT(v[0]),
765                           SHORT_TO_FLOAT(v[1]),
766                           SHORT_TO_FLOAT(v[2]),
767                           SHORT_TO_FLOAT(v[3])));
768}
769
770static void GLAPIENTRY
771VertexAttrib4svARB(GLuint index, const GLshort *v)
772{
773   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
774                                           (GLfloat)v[2], (GLfloat)v[3]));
775}
776
777/* GL_UNSIGNED_SHORT attributes */
778
779static void GLAPIENTRY
780VertexAttrib1NusvARB(GLuint index, const GLushort *v)
781{
782   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0])));
783}
784
785static void GLAPIENTRY
786VertexAttrib1usvARB(GLuint index, const GLushort *v)
787{
788   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
789}
790
791static void GLAPIENTRY
792VertexAttrib2NusvARB(GLuint index, const GLushort *v)
793{
794   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
795			     USHORT_TO_FLOAT(v[1])));
796}
797
798static void GLAPIENTRY
799VertexAttrib2usvARB(GLuint index, const GLushort *v)
800{
801   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, (GLfloat)v[0],
802                                           (GLfloat)v[1]));
803}
804
805static void GLAPIENTRY
806VertexAttrib3NusvARB(GLuint index, const GLushort *v)
807{
808   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
809					       USHORT_TO_FLOAT(v[1]),
810					       USHORT_TO_FLOAT(v[2])));
811}
812
813static void GLAPIENTRY
814VertexAttrib3usvARB(GLuint index, const GLushort *v)
815{
816   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, (GLfloat)v[0],
817                                           (GLfloat)v[1], (GLfloat)v[2]));
818}
819
820static void GLAPIENTRY
821VertexAttrib4NusvARB(GLuint index, const GLushort *v)
822{
823   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
824					       USHORT_TO_FLOAT(v[1]),
825					       USHORT_TO_FLOAT(v[2]),
826					       USHORT_TO_FLOAT(v[3])));
827}
828
829static void GLAPIENTRY
830VertexAttrib4usvARB(GLuint index, const GLushort *v)
831{
832   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
833}
834
835/* GL_INT attributes */
836
837static void GLAPIENTRY
838VertexAttrib1NivARB(GLuint index, const GLint *v)
839{
840   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0])));
841}
842
843static void GLAPIENTRY
844VertexAttrib1ivARB(GLuint index, const GLint *v)
845{
846   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
847}
848
849static void GLAPIENTRY
850VertexAttrib2NivARB(GLuint index, const GLint *v)
851{
852   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
853					       INT_TO_FLOAT(v[1])));
854}
855
856static void GLAPIENTRY
857VertexAttrib2ivARB(GLuint index, const GLint *v)
858{
859   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, (GLfloat)v[0],
860                                           (GLfloat)v[1]));
861}
862
863static void GLAPIENTRY
864VertexAttrib3NivARB(GLuint index, const GLint *v)
865{
866   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
867					       INT_TO_FLOAT(v[1]),
868					       INT_TO_FLOAT(v[2])));
869}
870
871static void GLAPIENTRY
872VertexAttrib3ivARB(GLuint index, const GLint *v)
873{
874   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, (GLfloat)v[0],
875                                           (GLfloat)v[1], (GLfloat)v[2]));
876}
877
878static void GLAPIENTRY
879VertexAttrib4NivARB(GLuint index, const GLint *v)
880{
881   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
882					       INT_TO_FLOAT(v[1]),
883					       INT_TO_FLOAT(v[2]),
884					       INT_TO_FLOAT(v[3])));
885}
886
887static void GLAPIENTRY
888VertexAttrib4ivARB(GLuint index, const GLint *v)
889{
890   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
891                                           (GLfloat)v[2], (GLfloat)v[3]));
892}
893
894/* GL_UNSIGNED_INT attributes */
895
896static void GLAPIENTRY
897VertexAttrib1NuivARB(GLuint index, const GLuint *v)
898{
899   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0])));
900}
901
902static void GLAPIENTRY
903VertexAttrib1uivARB(GLuint index, const GLuint *v)
904{
905   CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
906}
907
908static void GLAPIENTRY
909VertexAttrib2NuivARB(GLuint index, const GLuint *v)
910{
911   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
912                                           UINT_TO_FLOAT(v[1])));
913}
914
915static void GLAPIENTRY
916VertexAttrib2uivARB(GLuint index, const GLuint *v)
917{
918   CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, (GLfloat)v[0],
919                                           (GLfloat)v[1]));
920}
921
922static void GLAPIENTRY
923VertexAttrib3NuivARB(GLuint index, const GLuint *v)
924{
925   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
926                                           UINT_TO_FLOAT(v[1]),
927                                           UINT_TO_FLOAT(v[2])));
928}
929
930static void GLAPIENTRY
931VertexAttrib3uivARB(GLuint index, const GLuint *v)
932{
933   CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, (GLfloat)v[0],
934                                           (GLfloat)v[1], (GLfloat)v[2]));
935}
936
937static void GLAPIENTRY
938VertexAttrib4NuivARB(GLuint index, const GLuint *v)
939{
940   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
941                                           UINT_TO_FLOAT(v[1]),
942                                           UINT_TO_FLOAT(v[2]),
943                                           UINT_TO_FLOAT(v[3])));
944}
945
946static void GLAPIENTRY
947VertexAttrib4uivARB(GLuint index, const GLuint *v)
948{
949   CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
950                                           (GLfloat)v[2], (GLfloat)v[3]));
951}
952
953/* GL_FLOAT attributes */
954
955static void GLAPIENTRY
956VertexAttrib1fvARB(GLuint index, const GLfloat *v)
957{
958   CALL_VertexAttrib1fvARB(GET_DISPATCH(), (index, v));
959}
960
961static void GLAPIENTRY
962VertexAttrib2fvARB(GLuint index, const GLfloat *v)
963{
964   CALL_VertexAttrib2fvARB(GET_DISPATCH(), (index, v));
965}
966
967static void GLAPIENTRY
968VertexAttrib3fvARB(GLuint index, const GLfloat *v)
969{
970   CALL_VertexAttrib3fvARB(GET_DISPATCH(), (index, v));
971}
972
973static void GLAPIENTRY
974VertexAttrib4fvARB(GLuint index, const GLfloat *v)
975{
976   CALL_VertexAttrib4fvARB(GET_DISPATCH(), (index, v));
977}
978
979/* GL_DOUBLE attributes */
980
981static void GLAPIENTRY
982VertexAttrib1dvARB(GLuint index, const GLdouble *v)
983{
984   CALL_VertexAttrib1dv(GET_DISPATCH(), (index, v));
985}
986
987static void GLAPIENTRY
988VertexAttrib2dvARB(GLuint index, const GLdouble *v)
989{
990   CALL_VertexAttrib2dv(GET_DISPATCH(), (index, v));
991}
992
993static void GLAPIENTRY
994VertexAttrib3dvARB(GLuint index, const GLdouble *v)
995{
996   CALL_VertexAttrib3dv(GET_DISPATCH(), (index, v));
997}
998
999static void GLAPIENTRY
1000VertexAttrib4dvARB(GLuint index, const GLdouble *v)
1001{
1002   CALL_VertexAttrib4dv(GET_DISPATCH(), (index, v));
1003}
1004
1005
1006/**
1007 * Integer-valued attributes
1008 */
1009static void GLAPIENTRY
1010VertexAttribI1bv(GLuint index, const GLbyte *v)
1011{
1012   CALL_VertexAttribI1iEXT(GET_DISPATCH(), (index, v[0]));
1013}
1014
1015static void GLAPIENTRY
1016VertexAttribI2bv(GLuint index, const GLbyte *v)
1017{
1018   CALL_VertexAttribI2iEXT(GET_DISPATCH(), (index, v[0], v[1]));
1019}
1020
1021static void GLAPIENTRY
1022VertexAttribI3bv(GLuint index, const GLbyte *v)
1023{
1024   CALL_VertexAttribI3iEXT(GET_DISPATCH(), (index, v[0], v[1], v[2]));
1025}
1026
1027static void GLAPIENTRY
1028VertexAttribI4bv(GLuint index, const GLbyte *v)
1029{
1030   CALL_VertexAttribI4bv(GET_DISPATCH(), (index, v));
1031}
1032
1033
1034static void GLAPIENTRY
1035VertexAttribI1ubv(GLuint index, const GLubyte *v)
1036{
1037   CALL_VertexAttribI1uiEXT(GET_DISPATCH(), (index, v[0]));
1038}
1039
1040static void GLAPIENTRY
1041VertexAttribI2ubv(GLuint index, const GLubyte *v)
1042{
1043   CALL_VertexAttribI2uiEXT(GET_DISPATCH(), (index, v[0], v[1]));
1044}
1045
1046static void GLAPIENTRY
1047VertexAttribI3ubv(GLuint index, const GLubyte *v)
1048{
1049   CALL_VertexAttribI3uiEXT(GET_DISPATCH(), (index, v[0], v[1], v[2]));
1050}
1051
1052static void GLAPIENTRY
1053VertexAttribI4ubv(GLuint index, const GLubyte *v)
1054{
1055   CALL_VertexAttribI4ubv(GET_DISPATCH(), (index, v));
1056}
1057
1058
1059
1060static void GLAPIENTRY
1061VertexAttribI1sv(GLuint index, const GLshort *v)
1062{
1063   CALL_VertexAttribI1iEXT(GET_DISPATCH(), (index, v[0]));
1064}
1065
1066static void GLAPIENTRY
1067VertexAttribI2sv(GLuint index, const GLshort *v)
1068{
1069   CALL_VertexAttribI2iEXT(GET_DISPATCH(), (index, v[0], v[1]));
1070}
1071
1072static void GLAPIENTRY
1073VertexAttribI3sv(GLuint index, const GLshort *v)
1074{
1075   CALL_VertexAttribI3iEXT(GET_DISPATCH(), (index, v[0], v[1], v[2]));
1076}
1077
1078static void GLAPIENTRY
1079VertexAttribI4sv(GLuint index, const GLshort *v)
1080{
1081   CALL_VertexAttribI4sv(GET_DISPATCH(), (index, v));
1082}
1083
1084
1085static void GLAPIENTRY
1086VertexAttribI1usv(GLuint index, const GLushort *v)
1087{
1088   CALL_VertexAttribI1uiEXT(GET_DISPATCH(), (index, v[0]));
1089}
1090
1091static void GLAPIENTRY
1092VertexAttribI2usv(GLuint index, const GLushort *v)
1093{
1094   CALL_VertexAttribI2uiEXT(GET_DISPATCH(), (index, v[0], v[1]));
1095}
1096
1097static void GLAPIENTRY
1098VertexAttribI3usv(GLuint index, const GLushort *v)
1099{
1100   CALL_VertexAttribI3uiEXT(GET_DISPATCH(), (index, v[0], v[1], v[2]));
1101}
1102
1103static void GLAPIENTRY
1104VertexAttribI4usv(GLuint index, const GLushort *v)
1105{
1106   CALL_VertexAttribI4usv(GET_DISPATCH(), (index, v));
1107}
1108
1109
1110
1111static void GLAPIENTRY
1112VertexAttribI1iv(GLuint index, const GLint *v)
1113{
1114   CALL_VertexAttribI1iEXT(GET_DISPATCH(), (index, v[0]));
1115}
1116
1117static void GLAPIENTRY
1118VertexAttribI2iv(GLuint index, const GLint *v)
1119{
1120   CALL_VertexAttribI2iEXT(GET_DISPATCH(), (index, v[0], v[1]));
1121}
1122
1123static void GLAPIENTRY
1124VertexAttribI3iv(GLuint index, const GLint *v)
1125{
1126   CALL_VertexAttribI3iEXT(GET_DISPATCH(), (index, v[0], v[1], v[2]));
1127}
1128
1129static void GLAPIENTRY
1130VertexAttribI4iv(GLuint index, const GLint *v)
1131{
1132   CALL_VertexAttribI4ivEXT(GET_DISPATCH(), (index, v));
1133}
1134
1135
1136static void GLAPIENTRY
1137VertexAttribI1uiv(GLuint index, const GLuint *v)
1138{
1139   CALL_VertexAttribI1uiEXT(GET_DISPATCH(), (index, v[0]));
1140}
1141
1142static void GLAPIENTRY
1143VertexAttribI2uiv(GLuint index, const GLuint *v)
1144{
1145   CALL_VertexAttribI2uiEXT(GET_DISPATCH(), (index, v[0], v[1]));
1146}
1147
1148static void GLAPIENTRY
1149VertexAttribI3uiv(GLuint index, const GLuint *v)
1150{
1151   CALL_VertexAttribI3uiEXT(GET_DISPATCH(), (index, v[0], v[1], v[2]));
1152}
1153
1154static void GLAPIENTRY
1155VertexAttribI4uiv(GLuint index, const GLuint *v)
1156{
1157   CALL_VertexAttribI4uivEXT(GET_DISPATCH(), (index, v));
1158}
1159
1160/* GL_DOUBLE unconverted attributes */
1161
1162static void GLAPIENTRY
1163VertexAttribL1dv(GLuint index, const GLdouble *v)
1164{
1165   CALL_VertexAttribL1dv(GET_DISPATCH(), (index, v));
1166}
1167
1168static void GLAPIENTRY
1169VertexAttribL2dv(GLuint index, const GLdouble *v)
1170{
1171   CALL_VertexAttribL2dv(GET_DISPATCH(), (index, v));
1172}
1173
1174static void GLAPIENTRY
1175VertexAttribL3dv(GLuint index, const GLdouble *v)
1176{
1177   CALL_VertexAttribL3dv(GET_DISPATCH(), (index, v));
1178}
1179
1180static void GLAPIENTRY
1181VertexAttribL4dv(GLuint index, const GLdouble *v)
1182{
1183   CALL_VertexAttribL4dv(GET_DISPATCH(), (index, v));
1184}
1185
1186/*
1187 * Array [unnormalized/normalized/integer][size][type] of VertexAttrib
1188 * functions
1189 */
1190static const attrib_func AttribFuncsARB[4][4][NUM_TYPES] = {
1191   {
1192      /* non-normalized */
1193      {
1194         /* size 1 */
1195         (attrib_func) VertexAttrib1bvARB,
1196         (attrib_func) VertexAttrib1ubvARB,
1197         (attrib_func) VertexAttrib1svARB,
1198         (attrib_func) VertexAttrib1usvARB,
1199         (attrib_func) VertexAttrib1ivARB,
1200         (attrib_func) VertexAttrib1uivARB,
1201         (attrib_func) VertexAttrib1fvARB,
1202         (attrib_func) VertexAttrib1dvARB
1203      },
1204      {
1205         /* size 2 */
1206         (attrib_func) VertexAttrib2bvARB,
1207         (attrib_func) VertexAttrib2ubvARB,
1208         (attrib_func) VertexAttrib2svARB,
1209         (attrib_func) VertexAttrib2usvARB,
1210         (attrib_func) VertexAttrib2ivARB,
1211         (attrib_func) VertexAttrib2uivARB,
1212         (attrib_func) VertexAttrib2fvARB,
1213         (attrib_func) VertexAttrib2dvARB
1214      },
1215      {
1216         /* size 3 */
1217         (attrib_func) VertexAttrib3bvARB,
1218         (attrib_func) VertexAttrib3ubvARB,
1219         (attrib_func) VertexAttrib3svARB,
1220         (attrib_func) VertexAttrib3usvARB,
1221         (attrib_func) VertexAttrib3ivARB,
1222         (attrib_func) VertexAttrib3uivARB,
1223         (attrib_func) VertexAttrib3fvARB,
1224         (attrib_func) VertexAttrib3dvARB
1225      },
1226      {
1227         /* size 4 */
1228         (attrib_func) VertexAttrib4bvARB,
1229         (attrib_func) VertexAttrib4ubvARB,
1230         (attrib_func) VertexAttrib4svARB,
1231         (attrib_func) VertexAttrib4usvARB,
1232         (attrib_func) VertexAttrib4ivARB,
1233         (attrib_func) VertexAttrib4uivARB,
1234         (attrib_func) VertexAttrib4fvARB,
1235         (attrib_func) VertexAttrib4dvARB
1236      }
1237   },
1238   {
1239      /* normalized (except for float/double) */
1240      {
1241         /* size 1 */
1242         (attrib_func) VertexAttrib1NbvARB,
1243         (attrib_func) VertexAttrib1NubvARB,
1244         (attrib_func) VertexAttrib1NsvARB,
1245         (attrib_func) VertexAttrib1NusvARB,
1246         (attrib_func) VertexAttrib1NivARB,
1247         (attrib_func) VertexAttrib1NuivARB,
1248         (attrib_func) VertexAttrib1fvARB,
1249         (attrib_func) VertexAttrib1dvARB
1250      },
1251      {
1252         /* size 2 */
1253         (attrib_func) VertexAttrib2NbvARB,
1254         (attrib_func) VertexAttrib2NubvARB,
1255         (attrib_func) VertexAttrib2NsvARB,
1256         (attrib_func) VertexAttrib2NusvARB,
1257         (attrib_func) VertexAttrib2NivARB,
1258         (attrib_func) VertexAttrib2NuivARB,
1259         (attrib_func) VertexAttrib2fvARB,
1260         (attrib_func) VertexAttrib2dvARB
1261      },
1262      {
1263         /* size 3 */
1264         (attrib_func) VertexAttrib3NbvARB,
1265         (attrib_func) VertexAttrib3NubvARB,
1266         (attrib_func) VertexAttrib3NsvARB,
1267         (attrib_func) VertexAttrib3NusvARB,
1268         (attrib_func) VertexAttrib3NivARB,
1269         (attrib_func) VertexAttrib3NuivARB,
1270         (attrib_func) VertexAttrib3fvARB,
1271         (attrib_func) VertexAttrib3dvARB
1272      },
1273      {
1274         /* size 4 */
1275         (attrib_func) VertexAttrib4NbvARB,
1276         (attrib_func) VertexAttrib4NubvARB,
1277         (attrib_func) VertexAttrib4NsvARB,
1278         (attrib_func) VertexAttrib4NusvARB,
1279         (attrib_func) VertexAttrib4NivARB,
1280         (attrib_func) VertexAttrib4NuivARB,
1281         (attrib_func) VertexAttrib4fvARB,
1282         (attrib_func) VertexAttrib4dvARB
1283      }
1284   },
1285
1286   {
1287      /* integer-valued */
1288      {
1289         /* size 1 */
1290         (attrib_func) VertexAttribI1bv,
1291         (attrib_func) VertexAttribI1ubv,
1292         (attrib_func) VertexAttribI1sv,
1293         (attrib_func) VertexAttribI1usv,
1294         (attrib_func) VertexAttribI1iv,
1295         (attrib_func) VertexAttribI1uiv,
1296         NULL, /* GL_FLOAT */
1297         NULL  /* GL_DOUBLE */
1298      },
1299      {
1300         /* size 2 */
1301         (attrib_func) VertexAttribI2bv,
1302         (attrib_func) VertexAttribI2ubv,
1303         (attrib_func) VertexAttribI2sv,
1304         (attrib_func) VertexAttribI2usv,
1305         (attrib_func) VertexAttribI2iv,
1306         (attrib_func) VertexAttribI2uiv,
1307         NULL, /* GL_FLOAT */
1308         NULL  /* GL_DOUBLE */
1309      },
1310      {
1311         /* size 3 */
1312         (attrib_func) VertexAttribI3bv,
1313         (attrib_func) VertexAttribI3ubv,
1314         (attrib_func) VertexAttribI3sv,
1315         (attrib_func) VertexAttribI3usv,
1316         (attrib_func) VertexAttribI3iv,
1317         (attrib_func) VertexAttribI3uiv,
1318         NULL, /* GL_FLOAT */
1319         NULL  /* GL_DOUBLE */
1320      },
1321      {
1322         /* size 4 */
1323         (attrib_func) VertexAttribI4bv,
1324         (attrib_func) VertexAttribI4ubv,
1325         (attrib_func) VertexAttribI4sv,
1326         (attrib_func) VertexAttribI4usv,
1327         (attrib_func) VertexAttribI4iv,
1328         (attrib_func) VertexAttribI4uiv,
1329         NULL, /* GL_FLOAT */
1330         NULL  /* GL_DOUBLE */
1331      }
1332   },
1333   {
1334      /* double-valued */
1335      {
1336         /* size 1 */
1337         NULL,
1338         NULL,
1339         NULL,
1340         NULL,
1341         NULL,
1342         NULL,
1343         NULL,
1344         (attrib_func) VertexAttribL1dv,
1345      },
1346      {
1347         /* size 2 */
1348         NULL,
1349         NULL,
1350         NULL,
1351         NULL,
1352         NULL,
1353         NULL,
1354         NULL,
1355         (attrib_func) VertexAttribL2dv,
1356      },
1357      {
1358         /* size 3 */
1359         NULL,
1360         NULL,
1361         NULL,
1362         NULL,
1363         NULL,
1364         NULL,
1365         NULL,
1366         (attrib_func) VertexAttribL3dv,
1367      },
1368      {
1369         /* size 4 */
1370         NULL,
1371         NULL,
1372         NULL,
1373         NULL,
1374         NULL,
1375         NULL,
1376         NULL,
1377         (attrib_func) VertexAttribL4dv,
1378      }
1379   }
1380
1381};
1382
1383
1384/*
1385 * Return VertexAttrib*NV function pointer matching the provided vertex format.
1386 */
1387static inline attrib_func
1388func_nv(const struct gl_vertex_format *vformat)
1389{
1390   return AttribFuncsNV[vformat->Normalized][vformat->Size-1]
1391      [TYPE_IDX(vformat->Type)];
1392}
1393
1394
1395/*
1396 * Return VertexAttrib*ARB function pointer matching the provided vertex format.
1397 */
1398static inline attrib_func
1399func_arb(const struct gl_vertex_format *vformat)
1400{
1401   return AttribFuncsARB[vertex_format_to_index(vformat)][vformat->Size-1]
1402      [TYPE_IDX(vformat->Type)];
1403}
1404
1405
1406/*
1407 * Return the address of the array attribute array at elt in the
1408 * vertex array object vao.
1409 */
1410static inline const void *
1411attrib_src(const struct gl_vertex_array_object *vao,
1412           const struct gl_array_attributes *array, GLint elt)
1413{
1414   const struct gl_vertex_buffer_binding *binding =
1415      &vao->BufferBinding[array->BufferBindingIndex];
1416   const GLubyte *src
1417      = ADD_POINTERS(binding->BufferObj->Mappings[MAP_INTERNAL].Pointer,
1418                     _mesa_vertex_attrib_address(array, binding))
1419      + elt * binding->Stride;
1420   return src;
1421}
1422
1423
1424void
1425_mesa_array_element(struct gl_context *ctx, GLint elt)
1426{
1427   const struct gl_vertex_array_object *vao = ctx->Array.VAO;
1428   GLbitfield mask;
1429
1430   /* emit conventional arrays elements */
1431   mask = (VERT_BIT_FF_ALL & ~VERT_BIT_POS) & vao->Enabled;
1432   while (mask) {
1433      const gl_vert_attrib attrib = u_bit_scan(&mask);
1434      const struct gl_array_attributes *array = &vao->VertexAttrib[attrib];
1435      const void *src = attrib_src(vao, array, elt);
1436      func_nv(&array->Format)(attrib, src);
1437   }
1438
1439   /* emit generic attribute elements */
1440   mask = (VERT_BIT_GENERIC_ALL & ~VERT_BIT_GENERIC0) & vao->Enabled;
1441   while (mask) {
1442      const gl_vert_attrib attrib = u_bit_scan(&mask);
1443      const struct gl_array_attributes *array = &vao->VertexAttrib[attrib];
1444      const void *src = attrib_src(vao, array, elt);
1445      func_arb(&array->Format)(attrib - VERT_ATTRIB_GENERIC0, src);
1446   }
1447
1448   /* finally, vertex position */
1449   if (vao->Enabled & VERT_BIT_GENERIC0) {
1450      const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC0;
1451      const struct gl_array_attributes *array = &vao->VertexAttrib[attrib];
1452      const void *src = attrib_src(vao, array, elt);
1453      func_arb(&array->Format)(0, src);
1454   } else if (vao->Enabled & VERT_BIT_POS) {
1455      const gl_vert_attrib attrib = VERT_ATTRIB_POS;
1456      const struct gl_array_attributes *array = &vao->VertexAttrib[attrib];
1457      const void *src = attrib_src(vao, array, elt);
1458      func_nv(&array->Format)(0, src);
1459    }
1460}
1461
1462
1463/**
1464 * Called via glArrayElement() and glDrawArrays().
1465 * Issue the glNormal, glVertex, glColor, glVertexAttrib, etc functions
1466 * for all enabled vertex arrays (for elt-th element).
1467 * Note: this may be called during display list construction.
1468 */
1469void GLAPIENTRY
1470_ae_ArrayElement(GLint elt)
1471{
1472   GET_CURRENT_CONTEXT(ctx);
1473   struct gl_vertex_array_object *vao;
1474
1475   /* If PrimitiveRestart is enabled and the index is the RestartIndex
1476    * then we call PrimitiveRestartNV and return.
1477    */
1478   if (ctx->Array.PrimitiveRestart && (elt == ctx->Array.RestartIndex)) {
1479      CALL_PrimitiveRestartNV(GET_DISPATCH(), ());
1480      return;
1481   }
1482
1483   vao = ctx->Array.VAO;
1484   _mesa_vao_map_arrays(ctx, vao, GL_MAP_READ_BIT);
1485
1486   _mesa_array_element(ctx, elt);
1487
1488   _mesa_vao_unmap_arrays(ctx, vao);
1489}
1490
1491
1492void
1493_mesa_install_arrayelt_vtxfmt(struct _glapi_table *disp,
1494                              const GLvertexformat *vfmt)
1495{
1496   SET_ArrayElement(disp, vfmt->ArrayElement);
1497}
1498