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