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