Better driver notification on changes.
[mesa.git] / src / mesa / main / api_arrayelt.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.3
4 *
5 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /* Author:
26 * Keith Whitwell <keith@tungstengraphics.com>
27 */
28
29 #include "glheader.h"
30 #include "api_arrayelt.h"
31 #include "context.h"
32 #include "glapi.h"
33 #include "imports.h"
34 #include "macros.h"
35 #include "mtypes.h"
36
37 typedef void (GLAPIENTRY *array_func)( const void * );
38
39 typedef struct {
40 const struct gl_client_array *array;
41 array_func func;
42 } AEarray;
43
44 typedef void (GLAPIENTRY *attrib_func)( GLuint indx, const void *data );
45
46 typedef struct {
47 const struct gl_client_array *array;
48 attrib_func func;
49 GLuint index;
50 } AEattrib;
51
52 typedef struct {
53 AEarray arrays[32];
54 AEattrib attribs[VERT_ATTRIB_MAX + 1];
55 GLuint NewState;
56 } AEcontext;
57
58 #define AE_CONTEXT(ctx) ((AEcontext *)(ctx)->aelt_context)
59
60 /*
61 * Convert GL_BYTE, GL_UNSIGNED_BYTE, .. GL_DOUBLE into an integer
62 * in the range [0, 7]. Luckily these type tokens are sequentially
63 * numbered in gl.h, except for GL_DOUBLE.
64 */
65 #define TYPE_IDX(t) ( (t) == GL_DOUBLE ? 7 : (t) & 7 )
66
67 static void GLAPIENTRY Color3bv(const GLbyte *v)
68 {
69 GL_CALL(Color3bv)(v);
70 }
71
72 static void GLAPIENTRY Color3ubv(const GLubyte *v)
73 {
74 GL_CALL(Color3ubv)(v);
75 }
76
77 static void GLAPIENTRY Color3sv(const GLshort *v)
78 {
79 GL_CALL(Color3sv)(v);
80 }
81
82 static void GLAPIENTRY Color3usv(const GLushort *v)
83 {
84 GL_CALL(Color3usv)(v);
85 }
86
87 static void GLAPIENTRY Color3iv(const GLint *v)
88 {
89 GL_CALL(Color3iv)(v);
90 }
91
92 static void GLAPIENTRY Color3uiv(const GLuint *v)
93 {
94 GL_CALL(Color3uiv)(v);
95 }
96
97 static void GLAPIENTRY Color3fv(const GLfloat *v)
98 {
99 GL_CALL(Color3fv)(v);
100 }
101
102 static void GLAPIENTRY Color3dv(const GLdouble *v)
103 {
104 GL_CALL(Color3dv)(v);
105 }
106
107 static void GLAPIENTRY Color4bv(const GLbyte *v)
108 {
109 GL_CALL(Color4bv)(v);
110 }
111
112 static void GLAPIENTRY Color4ubv(const GLubyte *v)
113 {
114 GL_CALL(Color4ubv)(v);
115 }
116
117 static void GLAPIENTRY Color4sv(const GLshort *v)
118 {
119 GL_CALL(Color4sv)(v);
120 }
121
122 static void GLAPIENTRY Color4usv(const GLushort *v)
123 {
124 GL_CALL(Color4usv)(v);
125 }
126
127 static void GLAPIENTRY Color4iv(const GLint *v)
128 {
129 GL_CALL(Color4iv)(v);
130 }
131
132 static void GLAPIENTRY Color4uiv(const GLuint *v)
133 {
134 GL_CALL(Color4uiv)(v);
135 }
136
137 static void GLAPIENTRY Color4fv(const GLfloat *v)
138 {
139 GL_CALL(Color4fv)(v);
140 }
141
142 static void GLAPIENTRY Color4dv(const GLdouble *v)
143 {
144 GL_CALL(Color4dv)(v);
145 }
146
147 static const array_func ColorFuncs[2][8] = {
148 {
149 (array_func) Color3bv,
150 (array_func) Color3ubv,
151 (array_func) Color3sv,
152 (array_func) Color3usv,
153 (array_func) Color3iv,
154 (array_func) Color3uiv,
155 (array_func) Color3fv,
156 (array_func) Color3dv,
157 },
158 {
159 (array_func) Color4bv,
160 (array_func) Color4ubv,
161 (array_func) Color4sv,
162 (array_func) Color4usv,
163 (array_func) Color4iv,
164 (array_func) Color4uiv,
165 (array_func) Color4fv,
166 (array_func) Color4dv,
167 },
168 };
169
170 static void GLAPIENTRY Vertex2sv(const GLshort *v)
171 {
172 GL_CALL(Vertex2sv)(v);
173 }
174
175 static void GLAPIENTRY Vertex2iv(const GLint *v)
176 {
177 GL_CALL(Vertex2iv)(v);
178 }
179
180 static void GLAPIENTRY Vertex2fv(const GLfloat *v)
181 {
182 GL_CALL(Vertex2fv)(v);
183 }
184
185 static void GLAPIENTRY Vertex2dv(const GLdouble *v)
186 {
187 GL_CALL(Vertex2dv)(v);
188 }
189
190 static void GLAPIENTRY Vertex3sv(const GLshort *v)
191 {
192 GL_CALL(Vertex3sv)(v);
193 }
194
195 static void GLAPIENTRY Vertex3iv(const GLint *v)
196 {
197 GL_CALL(Vertex3iv)(v);
198 }
199
200 static void GLAPIENTRY Vertex3fv(const GLfloat *v)
201 {
202 GL_CALL(Vertex3fv)(v);
203 }
204
205 static void GLAPIENTRY Vertex3dv(const GLdouble *v)
206 {
207 GL_CALL(Vertex3dv)(v);
208 }
209
210 static void GLAPIENTRY Vertex4sv(const GLshort *v)
211 {
212 GL_CALL(Vertex4sv)(v);
213 }
214
215 static void GLAPIENTRY Vertex4iv(const GLint *v)
216 {
217 GL_CALL(Vertex4iv)(v);
218 }
219
220 static void GLAPIENTRY Vertex4fv(const GLfloat *v)
221 {
222 GL_CALL(Vertex4fv)(v);
223 }
224
225 static void GLAPIENTRY Vertex4dv(const GLdouble *v)
226 {
227 GL_CALL(Vertex4dv)(v);
228 }
229
230 static const array_func VertexFuncs[3][8] = {
231 {
232 NULL,
233 NULL,
234 (array_func) Vertex2sv,
235 NULL,
236 (array_func) Vertex2iv,
237 NULL,
238 (array_func) Vertex2fv,
239 (array_func) Vertex2dv,
240 },
241 {
242 NULL,
243 NULL,
244 (array_func) Vertex3sv,
245 NULL,
246 (array_func) Vertex3iv,
247 NULL,
248 (array_func) Vertex3fv,
249 (array_func) Vertex3dv,
250 },
251 {
252 NULL,
253 NULL,
254 (array_func) Vertex4sv,
255 NULL,
256 (array_func) Vertex4iv,
257 NULL,
258 (array_func) Vertex4fv,
259 (array_func) Vertex4dv,
260 },
261 };
262
263 static void GLAPIENTRY Indexubv(const GLubyte *c)
264 {
265 GL_CALL(Indexubv)(c);
266 }
267
268 static void GLAPIENTRY Indexsv(const GLshort *c)
269 {
270 GL_CALL(Indexsv)(c);
271 }
272
273 static void GLAPIENTRY Indexiv(const GLint *c)
274 {
275 GL_CALL(Indexiv)(c);
276 }
277
278 static void GLAPIENTRY Indexfv(const GLfloat *c)
279 {
280 GL_CALL(Indexfv)(c);
281 }
282
283 static void GLAPIENTRY Indexdv(const GLdouble *c)
284 {
285 GL_CALL(Indexdv)(c);
286 }
287
288 static const array_func IndexFuncs[8] = {
289 NULL,
290 (array_func) Indexubv,
291 (array_func) Indexsv,
292 NULL,
293 (array_func) Indexiv,
294 NULL,
295 (array_func) Indexfv,
296 (array_func) Indexdv,
297 };
298
299 static void GLAPIENTRY Normal3bv(const GLbyte *v)
300 {
301 GL_CALL(Normal3bv)(v);
302 }
303
304 static void GLAPIENTRY Normal3sv(const GLshort *v)
305 {
306 GL_CALL(Normal3sv)(v);
307 }
308
309 static void GLAPIENTRY Normal3iv(const GLint *v)
310 {
311 GL_CALL(Normal3iv)(v);
312 }
313
314 static void GLAPIENTRY Normal3fv(const GLfloat *v)
315 {
316 GL_CALL(Normal3fv)(v);
317 }
318
319 static void GLAPIENTRY Normal3dv(const GLdouble *v)
320 {
321 GL_CALL(Normal3dv)(v);
322 }
323
324 static const array_func NormalFuncs[8] = {
325 (array_func) Normal3bv,
326 NULL,
327 (array_func) Normal3sv,
328 NULL,
329 (array_func) Normal3iv,
330 NULL,
331 (array_func) Normal3fv,
332 (array_func) Normal3dv,
333 };
334
335 /* Wrapper functions in case glSecondaryColor*EXT doesn't exist */
336 static void GLAPIENTRY SecondaryColor3bvEXT(const GLbyte *c)
337 {
338 GL_CALL(SecondaryColor3bvEXT)(c);
339 }
340
341 static void GLAPIENTRY SecondaryColor3ubvEXT(const GLubyte *c)
342 {
343 GL_CALL(SecondaryColor3ubvEXT)(c);
344 }
345
346 static void GLAPIENTRY SecondaryColor3svEXT(const GLshort *c)
347 {
348 GL_CALL(SecondaryColor3svEXT)(c);
349 }
350
351 static void GLAPIENTRY SecondaryColor3usvEXT(const GLushort *c)
352 {
353 GL_CALL(SecondaryColor3usvEXT)(c);
354 }
355
356 static void GLAPIENTRY SecondaryColor3ivEXT(const GLint *c)
357 {
358 GL_CALL(SecondaryColor3ivEXT)(c);
359 }
360
361 static void GLAPIENTRY SecondaryColor3uivEXT(const GLuint *c)
362 {
363 GL_CALL(SecondaryColor3uivEXT)(c);
364 }
365
366 static void GLAPIENTRY SecondaryColor3fvEXT(const GLfloat *c)
367 {
368 GL_CALL(SecondaryColor3fvEXT)(c);
369 }
370
371 static void GLAPIENTRY SecondaryColor3dvEXT(const GLdouble *c)
372 {
373 GL_CALL(SecondaryColor3dvEXT)(c);
374 }
375
376 static const array_func SecondaryColorFuncs[8] = {
377 (array_func) SecondaryColor3bvEXT,
378 (array_func) SecondaryColor3ubvEXT,
379 (array_func) SecondaryColor3svEXT,
380 (array_func) SecondaryColor3usvEXT,
381 (array_func) SecondaryColor3ivEXT,
382 (array_func) SecondaryColor3uivEXT,
383 (array_func) SecondaryColor3fvEXT,
384 (array_func) SecondaryColor3dvEXT,
385 };
386
387
388 /* Again, wrapper functions in case glSecondaryColor*EXT doesn't exist */
389 static void GLAPIENTRY FogCoordfvEXT(const GLfloat *f)
390 {
391 GL_CALL(FogCoordfvEXT)(f);
392 }
393
394 static void GLAPIENTRY FogCoorddvEXT(const GLdouble *f)
395 {
396 GL_CALL(FogCoorddvEXT)(f);
397 }
398
399 static const array_func FogCoordFuncs[8] = {
400 NULL,
401 NULL,
402 NULL,
403 NULL,
404 NULL,
405 NULL,
406 (array_func) FogCoordfvEXT,
407 (array_func) FogCoorddvEXT
408 };
409
410 /**********************************************************************/
411
412 /* GL_BYTE attributes */
413
414 static void GLAPIENTRY VertexAttrib1NbvNV(GLuint index, const GLbyte *v)
415 {
416 GL_CALL(VertexAttrib1fNV)(index, BYTE_TO_FLOAT(v[0]));
417 }
418
419 static void GLAPIENTRY VertexAttrib1bvNV(GLuint index, const GLbyte *v)
420 {
421 GL_CALL(VertexAttrib1fNV)(index, v[0]);
422 }
423
424 static void GLAPIENTRY VertexAttrib2NbvNV(GLuint index, const GLbyte *v)
425 {
426 GL_CALL(VertexAttrib2fNV)(index, BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1]));
427 }
428
429 static void GLAPIENTRY VertexAttrib2bvNV(GLuint index, const GLbyte *v)
430 {
431 GL_CALL(VertexAttrib2fNV)(index, v[0], v[1]);
432 }
433
434 static void GLAPIENTRY VertexAttrib3NbvNV(GLuint index, const GLbyte *v)
435 {
436 GL_CALL(VertexAttrib3fNV)(index, BYTE_TO_FLOAT(v[0]),
437 BYTE_TO_FLOAT(v[1]),
438 BYTE_TO_FLOAT(v[2]));
439 }
440
441 static void GLAPIENTRY VertexAttrib3bvNV(GLuint index, const GLbyte *v)
442 {
443 GL_CALL(VertexAttrib3fNV)(index, v[0], v[1], v[2]);
444 }
445
446 static void GLAPIENTRY VertexAttrib4NbvNV(GLuint index, const GLbyte *v)
447 {
448 GL_CALL(VertexAttrib4fNV)(index, BYTE_TO_FLOAT(v[0]),
449 BYTE_TO_FLOAT(v[1]),
450 BYTE_TO_FLOAT(v[2]),
451 BYTE_TO_FLOAT(v[3]));
452 }
453
454 static void GLAPIENTRY VertexAttrib4bvNV(GLuint index, const GLbyte *v)
455 {
456 GL_CALL(VertexAttrib4fNV)(index, v[0], v[1], v[2], v[3]);
457 }
458
459 /* GL_UNSIGNED_BYTE attributes */
460
461 static void GLAPIENTRY VertexAttrib1NubvNV(GLuint index, const GLubyte *v)
462 {
463 GL_CALL(VertexAttrib1fNV)(index, UBYTE_TO_FLOAT(v[0]));
464 }
465
466 static void GLAPIENTRY VertexAttrib1ubvNV(GLuint index, const GLubyte *v)
467 {
468 GL_CALL(VertexAttrib1fNV)(index, v[0]);
469 }
470
471 static void GLAPIENTRY VertexAttrib2NubvNV(GLuint index, const GLubyte *v)
472 {
473 GL_CALL(VertexAttrib2fNV)(index, UBYTE_TO_FLOAT(v[0]),
474 UBYTE_TO_FLOAT(v[1]));
475 }
476
477 static void GLAPIENTRY VertexAttrib2ubvNV(GLuint index, const GLubyte *v)
478 {
479 GL_CALL(VertexAttrib2fNV)(index, v[0], v[1]);
480 }
481
482 static void GLAPIENTRY VertexAttrib3NubvNV(GLuint index, const GLubyte *v)
483 {
484 GL_CALL(VertexAttrib3fNV)(index, UBYTE_TO_FLOAT(v[0]),
485 UBYTE_TO_FLOAT(v[1]),
486 UBYTE_TO_FLOAT(v[2]));
487 }
488 static void GLAPIENTRY VertexAttrib3ubvNV(GLuint index, const GLubyte *v)
489 {
490 GL_CALL(VertexAttrib3fNV)(index, v[0], v[1], v[2]);
491 }
492
493 static void GLAPIENTRY VertexAttrib4NubvNV(GLuint index, const GLubyte *v)
494 {
495 GL_CALL(VertexAttrib4fNV)(index, UBYTE_TO_FLOAT(v[0]),
496 UBYTE_TO_FLOAT(v[1]),
497 UBYTE_TO_FLOAT(v[2]),
498 UBYTE_TO_FLOAT(v[3]));
499 }
500
501 static void GLAPIENTRY VertexAttrib4ubvNV(GLuint index, const GLubyte *v)
502 {
503 GL_CALL(VertexAttrib4fNV)(index, v[0], v[1], v[2], v[3]);
504 }
505
506 /* GL_SHORT attributes */
507
508 static void GLAPIENTRY VertexAttrib1NsvNV(GLuint index, const GLshort *v)
509 {
510 GL_CALL(VertexAttrib1fNV)(index, SHORT_TO_FLOAT(v[0]));
511 }
512
513 static void GLAPIENTRY VertexAttrib1svNV(GLuint index, const GLshort *v)
514 {
515 GL_CALL(VertexAttrib1fNV)(index, v[0]);
516 }
517
518 static void GLAPIENTRY VertexAttrib2NsvNV(GLuint index, const GLshort *v)
519 {
520 GL_CALL(VertexAttrib2fNV)(index, SHORT_TO_FLOAT(v[0]),
521 SHORT_TO_FLOAT(v[1]));
522 }
523
524 static void GLAPIENTRY VertexAttrib2svNV(GLuint index, const GLshort *v)
525 {
526 GL_CALL(VertexAttrib2fNV)(index, v[0], v[1]);
527 }
528
529 static void GLAPIENTRY VertexAttrib3NsvNV(GLuint index, const GLshort *v)
530 {
531 GL_CALL(VertexAttrib3fNV)(index, SHORT_TO_FLOAT(v[0]),
532 SHORT_TO_FLOAT(v[1]),
533 SHORT_TO_FLOAT(v[2]));
534 }
535
536 static void GLAPIENTRY VertexAttrib3svNV(GLuint index, const GLshort *v)
537 {
538 GL_CALL(VertexAttrib3fNV)(index, v[0], v[1], v[2]);
539 }
540
541 static void GLAPIENTRY VertexAttrib4NsvNV(GLuint index, const GLshort *v)
542 {
543 GL_CALL(VertexAttrib4fNV)(index, SHORT_TO_FLOAT(v[0]),
544 SHORT_TO_FLOAT(v[1]),
545 SHORT_TO_FLOAT(v[2]),
546 SHORT_TO_FLOAT(v[3]));
547 }
548
549 static void GLAPIENTRY VertexAttrib4svNV(GLuint index, const GLshort *v)
550 {
551 GL_CALL(VertexAttrib4fNV)(index, v[0], v[1], v[2], v[3]);
552 }
553
554 /* GL_UNSIGNED_SHORT attributes */
555
556 static void GLAPIENTRY VertexAttrib1NusvNV(GLuint index, const GLushort *v)
557 {
558 GL_CALL(VertexAttrib1fNV)(index, USHORT_TO_FLOAT(v[0]));
559 }
560
561 static void GLAPIENTRY VertexAttrib1usvNV(GLuint index, const GLushort *v)
562 {
563 GL_CALL(VertexAttrib1fNV)(index, v[0]);
564 }
565
566 static void GLAPIENTRY VertexAttrib2NusvNV(GLuint index, const GLushort *v)
567 {
568 GL_CALL(VertexAttrib2fNV)(index, USHORT_TO_FLOAT(v[0]),
569 USHORT_TO_FLOAT(v[1]));
570 }
571
572 static void GLAPIENTRY VertexAttrib2usvNV(GLuint index, const GLushort *v)
573 {
574 GL_CALL(VertexAttrib2fNV)(index, v[0], v[1]);
575 }
576
577 static void GLAPIENTRY VertexAttrib3NusvNV(GLuint index, const GLushort *v)
578 {
579 GL_CALL(VertexAttrib3fNV)(index, USHORT_TO_FLOAT(v[0]),
580 USHORT_TO_FLOAT(v[1]),
581 USHORT_TO_FLOAT(v[2]));
582 }
583
584 static void GLAPIENTRY VertexAttrib3usvNV(GLuint index, const GLushort *v)
585 {
586 GL_CALL(VertexAttrib3fNV)(index, v[0], v[1], v[2]);
587 }
588
589 static void GLAPIENTRY VertexAttrib4NusvNV(GLuint index, const GLushort *v)
590 {
591 GL_CALL(VertexAttrib4fNV)(index, USHORT_TO_FLOAT(v[0]),
592 USHORT_TO_FLOAT(v[1]),
593 USHORT_TO_FLOAT(v[2]),
594 USHORT_TO_FLOAT(v[3]));
595 }
596
597 static void GLAPIENTRY VertexAttrib4usvNV(GLuint index, const GLushort *v)
598 {
599 GL_CALL(VertexAttrib4fNV)(index, v[0], v[1], v[2], v[3]);
600 }
601
602 /* GL_INT attributes */
603
604 static void GLAPIENTRY VertexAttrib1NivNV(GLuint index, const GLint *v)
605 {
606 GL_CALL(VertexAttrib1fNV)(index, INT_TO_FLOAT(v[0]));
607 }
608
609 static void GLAPIENTRY VertexAttrib1ivNV(GLuint index, const GLint *v)
610 {
611 GL_CALL(VertexAttrib1fNV)(index, v[0]);
612 }
613
614 static void GLAPIENTRY VertexAttrib2NivNV(GLuint index, const GLint *v)
615 {
616 GL_CALL(VertexAttrib2fNV)(index, INT_TO_FLOAT(v[0]),
617 INT_TO_FLOAT(v[1]));
618 }
619
620 static void GLAPIENTRY VertexAttrib2ivNV(GLuint index, const GLint *v)
621 {
622 GL_CALL(VertexAttrib2fNV)(index, v[0], v[1]);
623 }
624
625 static void GLAPIENTRY VertexAttrib3NivNV(GLuint index, const GLint *v)
626 {
627 GL_CALL(VertexAttrib3fNV)(index, INT_TO_FLOAT(v[0]),
628 INT_TO_FLOAT(v[1]),
629 INT_TO_FLOAT(v[2]));
630 }
631
632 static void GLAPIENTRY VertexAttrib3ivNV(GLuint index, const GLint *v)
633 {
634 GL_CALL(VertexAttrib3fNV)(index, v[0], v[1], v[2]);
635 }
636
637 static void GLAPIENTRY VertexAttrib4NivNV(GLuint index, const GLint *v)
638 {
639 GL_CALL(VertexAttrib4fNV)(index, INT_TO_FLOAT(v[0]),
640 INT_TO_FLOAT(v[1]),
641 INT_TO_FLOAT(v[2]),
642 INT_TO_FLOAT(v[3]));
643 }
644
645 static void GLAPIENTRY VertexAttrib4ivNV(GLuint index, const GLint *v)
646 {
647 GL_CALL(VertexAttrib4fNV)(index, v[0], v[1], v[2], v[3]);
648 }
649
650 /* GL_UNSIGNED_INT attributes */
651
652 static void GLAPIENTRY VertexAttrib1NuivNV(GLuint index, const GLuint *v)
653 {
654 GL_CALL(VertexAttrib1fNV)(index, UINT_TO_FLOAT(v[0]));
655 }
656
657 static void GLAPIENTRY VertexAttrib1uivNV(GLuint index, const GLuint *v)
658 {
659 GL_CALL(VertexAttrib1fNV)(index, v[0]);
660 }
661
662 static void GLAPIENTRY VertexAttrib2NuivNV(GLuint index, const GLuint *v)
663 {
664 GL_CALL(VertexAttrib2fNV)(index, UINT_TO_FLOAT(v[0]),
665 UINT_TO_FLOAT(v[1]));
666 }
667
668 static void GLAPIENTRY VertexAttrib2uivNV(GLuint index, const GLuint *v)
669 {
670 GL_CALL(VertexAttrib2fNV)(index, v[0], v[1]);
671 }
672
673 static void GLAPIENTRY VertexAttrib3NuivNV(GLuint index, const GLuint *v)
674 {
675 GL_CALL(VertexAttrib3fNV)(index, UINT_TO_FLOAT(v[0]),
676 UINT_TO_FLOAT(v[1]),
677 UINT_TO_FLOAT(v[2]));
678 }
679
680 static void GLAPIENTRY VertexAttrib3uivNV(GLuint index, const GLuint *v)
681 {
682 GL_CALL(VertexAttrib3fNV)(index, v[0], v[1], v[2]);
683 }
684
685 static void GLAPIENTRY VertexAttrib4NuivNV(GLuint index, const GLuint *v)
686 {
687 GL_CALL(VertexAttrib4fNV)(index, UINT_TO_FLOAT(v[0]),
688 UINT_TO_FLOAT(v[1]),
689 UINT_TO_FLOAT(v[2]),
690 UINT_TO_FLOAT(v[3]));
691 }
692
693 static void GLAPIENTRY VertexAttrib4uivNV(GLuint index, const GLuint *v)
694 {
695 GL_CALL(VertexAttrib4fNV)(index, v[0], v[1], v[2], v[3]);
696 }
697
698 /* GL_FLOAT attributes */
699
700 static void GLAPIENTRY VertexAttrib1fvNV(GLuint index, const GLfloat *v)
701 {
702 GL_CALL(VertexAttrib1fvNV)(index, v);
703 }
704
705 static void GLAPIENTRY VertexAttrib2fvNV(GLuint index, const GLfloat *v)
706 {
707 GL_CALL(VertexAttrib2fvNV)(index, v);
708 }
709
710 static void GLAPIENTRY VertexAttrib3fvNV(GLuint index, const GLfloat *v)
711 {
712 GL_CALL(VertexAttrib3fvNV)(index, v);
713 }
714
715 static void GLAPIENTRY VertexAttrib4fvNV(GLuint index, const GLfloat *v)
716 {
717 GL_CALL(VertexAttrib4fvNV)(index, v);
718 }
719
720 /* GL_DOUBLE attributes */
721
722 static void GLAPIENTRY VertexAttrib1dvNV(GLuint index, const GLdouble *v)
723 {
724 GL_CALL(VertexAttrib1dvNV)(index, v);
725 }
726
727 static void GLAPIENTRY VertexAttrib2dvNV(GLuint index, const GLdouble *v)
728 {
729 GL_CALL(VertexAttrib2dvNV)(index, v);
730 }
731
732 static void GLAPIENTRY VertexAttrib3dvNV(GLuint index, const GLdouble *v)
733 {
734 GL_CALL(VertexAttrib3dvNV)(index, v);
735 }
736
737 static void GLAPIENTRY VertexAttrib4dvNV(GLuint index, const GLdouble *v)
738 {
739 GL_CALL(VertexAttrib4dvNV)(index, v);
740 }
741
742
743 /*
744 * Array [size][type] of VertexAttrib functions
745 */
746 static attrib_func AttribFuncsNV[2][4][8] = {
747 {
748 /* non-normalized */
749 {
750 /* size 1 */
751 (attrib_func) VertexAttrib1bvNV,
752 (attrib_func) VertexAttrib1ubvNV,
753 (attrib_func) VertexAttrib1svNV,
754 (attrib_func) VertexAttrib1usvNV,
755 (attrib_func) VertexAttrib1ivNV,
756 (attrib_func) VertexAttrib1uivNV,
757 (attrib_func) VertexAttrib1fvNV,
758 (attrib_func) VertexAttrib1dvNV
759 },
760 {
761 /* size 2 */
762 (attrib_func) VertexAttrib2bvNV,
763 (attrib_func) VertexAttrib2ubvNV,
764 (attrib_func) VertexAttrib2svNV,
765 (attrib_func) VertexAttrib2usvNV,
766 (attrib_func) VertexAttrib2ivNV,
767 (attrib_func) VertexAttrib2uivNV,
768 (attrib_func) VertexAttrib2fvNV,
769 (attrib_func) VertexAttrib2dvNV
770 },
771 {
772 /* size 3 */
773 (attrib_func) VertexAttrib3bvNV,
774 (attrib_func) VertexAttrib3ubvNV,
775 (attrib_func) VertexAttrib3svNV,
776 (attrib_func) VertexAttrib3usvNV,
777 (attrib_func) VertexAttrib3ivNV,
778 (attrib_func) VertexAttrib3uivNV,
779 (attrib_func) VertexAttrib3fvNV,
780 (attrib_func) VertexAttrib3dvNV
781 },
782 {
783 /* size 4 */
784 (attrib_func) VertexAttrib4bvNV,
785 (attrib_func) VertexAttrib4ubvNV,
786 (attrib_func) VertexAttrib4svNV,
787 (attrib_func) VertexAttrib4usvNV,
788 (attrib_func) VertexAttrib4ivNV,
789 (attrib_func) VertexAttrib4uivNV,
790 (attrib_func) VertexAttrib4fvNV,
791 (attrib_func) VertexAttrib4dvNV
792 }
793 },
794 {
795 /* normalized (except for float/double) */
796 {
797 /* size 1 */
798 (attrib_func) VertexAttrib1NbvNV,
799 (attrib_func) VertexAttrib1NubvNV,
800 (attrib_func) VertexAttrib1NsvNV,
801 (attrib_func) VertexAttrib1NusvNV,
802 (attrib_func) VertexAttrib1NivNV,
803 (attrib_func) VertexAttrib1NuivNV,
804 (attrib_func) VertexAttrib1fvNV,
805 (attrib_func) VertexAttrib1dvNV
806 },
807 {
808 /* size 2 */
809 (attrib_func) VertexAttrib2NbvNV,
810 (attrib_func) VertexAttrib2NubvNV,
811 (attrib_func) VertexAttrib2NsvNV,
812 (attrib_func) VertexAttrib2NusvNV,
813 (attrib_func) VertexAttrib2NivNV,
814 (attrib_func) VertexAttrib2NuivNV,
815 (attrib_func) VertexAttrib2fvNV,
816 (attrib_func) VertexAttrib2dvNV
817 },
818 {
819 /* size 3 */
820 (attrib_func) VertexAttrib3NbvNV,
821 (attrib_func) VertexAttrib3NubvNV,
822 (attrib_func) VertexAttrib3NsvNV,
823 (attrib_func) VertexAttrib3NusvNV,
824 (attrib_func) VertexAttrib3NivNV,
825 (attrib_func) VertexAttrib3NuivNV,
826 (attrib_func) VertexAttrib3fvNV,
827 (attrib_func) VertexAttrib3dvNV
828 },
829 {
830 /* size 4 */
831 (attrib_func) VertexAttrib4NbvNV,
832 (attrib_func) VertexAttrib4NubvNV,
833 (attrib_func) VertexAttrib4NsvNV,
834 (attrib_func) VertexAttrib4NusvNV,
835 (attrib_func) VertexAttrib4NivNV,
836 (attrib_func) VertexAttrib4NuivNV,
837 (attrib_func) VertexAttrib4fvNV,
838 (attrib_func) VertexAttrib4dvNV
839 }
840 }
841 };
842
843 static void GLAPIENTRY EdgeFlagv(const GLboolean *flag)
844 {
845 GL_CALL(EdgeFlagv)(flag);
846 }
847
848 /**********************************************************************/
849
850
851 GLboolean _ae_create_context( GLcontext *ctx )
852 {
853 if (ctx->aelt_context)
854 return GL_TRUE;
855
856 ctx->aelt_context = MALLOC( sizeof(AEcontext) );
857 if (!ctx->aelt_context)
858 return GL_FALSE;
859
860 AE_CONTEXT(ctx)->NewState = ~0;
861 return GL_TRUE;
862 }
863
864
865 void _ae_destroy_context( GLcontext *ctx )
866 {
867 if ( AE_CONTEXT( ctx ) ) {
868 FREE( ctx->aelt_context );
869 ctx->aelt_context = NULL;
870 }
871 }
872
873
874 /**
875 * Make a list of per-vertex functions to call for each glArrayElement call.
876 * These functions access the array data (i.e. glVertex, glColor, glNormal,
877 * etc).
878 * Note: this may be called during display list construction.
879 */
880 static void _ae_update_state( GLcontext *ctx )
881 {
882 AEcontext *actx = AE_CONTEXT(ctx);
883 AEarray *aa = actx->arrays;
884 AEattrib *at = actx->attribs;
885 GLuint i;
886
887 /* conventional vertex arrays */
888 if (ctx->Array.Index.Enabled) {
889 aa->array = &ctx->Array.Index;
890 aa->func = IndexFuncs[TYPE_IDX(aa->array->Type)];
891 aa++;
892 }
893 if (ctx->Array.EdgeFlag.Enabled) {
894 aa->array = &ctx->Array.EdgeFlag;
895 aa->func = (array_func) EdgeFlagv;
896 aa++;
897 }
898 if (ctx->Array.Normal.Enabled) {
899 aa->array = &ctx->Array.Normal;
900 aa->func = NormalFuncs[TYPE_IDX(aa->array->Type)];
901 aa++;
902 }
903 if (ctx->Array.Color.Enabled) {
904 aa->array = &ctx->Array.Color;
905 aa->func = ColorFuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)];
906 aa++;
907 }
908 if (ctx->Array.SecondaryColor.Enabled) {
909 aa->array = &ctx->Array.SecondaryColor;
910 aa->func = SecondaryColorFuncs[TYPE_IDX(aa->array->Type)];
911 aa++;
912 }
913 if (ctx->Array.FogCoord.Enabled) {
914 aa->array = &ctx->Array.FogCoord;
915 aa->func = FogCoordFuncs[TYPE_IDX(aa->array->Type)];
916 aa++;
917 }
918 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
919 if (ctx->Array.TexCoord[i].Enabled) {
920 /* NOTE: we use generic glVertexAttrib functions here.
921 * If we ever de-alias conventional/generic vertex attribs this
922 * will have to change.
923 */
924 struct gl_client_array *attribArray = &ctx->Array.TexCoord[i];
925 at->array = attribArray;
926 at->func = AttribFuncsNV[at->array->Normalized][at->array->Size-1][TYPE_IDX(at->array->Type)];
927 at->index = VERT_ATTRIB_TEX0 + i;
928 at++;
929 }
930 }
931
932 /* generic vertex attribute arrays */
933 for (i = 1; i < VERT_ATTRIB_MAX; i++) { /* skip zero! */
934 if (ctx->Array.VertexAttrib[i].Enabled) {
935 struct gl_client_array *attribArray = &ctx->Array.VertexAttrib[i];
936 at->array = attribArray;
937 /* Note: we can't grab the _glapi_Dispatch->VertexAttrib1fvNV
938 * function pointer here (for float arrays) since the pointer may
939 * change from one execution of _ae_loopback_array_elt() to
940 * the next. Doing so caused UT to break.
941 */
942 at->func = AttribFuncsNV[at->array->Normalized][at->array->Size-1][TYPE_IDX(at->array->Type)];
943 at->index = i;
944 at++;
945 }
946 }
947
948 /* finally, vertex position */
949 if (ctx->Array.VertexAttrib[0].Enabled) {
950 /* Use glVertex(v) instead of glVertexAttrib(0, v) to be sure it's
951 * issued as the last (proviking) attribute).
952 */
953 aa->array = &ctx->Array.VertexAttrib[0];
954 assert(aa->array->Size >= 2); /* XXX fix someday? */
955 aa->func = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
956 aa++;
957 }
958 else if (ctx->Array.Vertex.Enabled) {
959 aa->array = &ctx->Array.Vertex;
960 aa->func = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
961 aa++;
962 }
963
964 ASSERT(at - actx->attribs <= VERT_ATTRIB_MAX);
965 ASSERT(aa - actx->arrays < 32);
966 at->func = NULL; /* terminate the list */
967 aa->func = NULL; /* terminate the list */
968
969 actx->NewState = 0;
970 }
971
972
973 /**
974 * Called via glArrayElement() and glDrawArrays().
975 * Issue the glNormal, glVertex, glColor, glVertexAttrib, etc functions
976 * for all enabled vertex arrays (for elt-th element).
977 * Note: this may be called during display list construction.
978 */
979 void GLAPIENTRY _ae_loopback_array_elt( GLint elt )
980 {
981 GET_CURRENT_CONTEXT(ctx);
982 const AEcontext *actx = AE_CONTEXT(ctx);
983 const AEarray *aa;
984 const AEattrib *at;
985
986 if (actx->NewState)
987 _ae_update_state( ctx );
988
989 /* generic attributes */
990 for (at = actx->attribs; at->func; at++) {
991 const GLubyte *src = at->array->BufferObj->Data
992 + (uintptr_t) at->array->Ptr
993 + elt * at->array->StrideB;
994 at->func( at->index, src );
995 }
996
997 /* conventional arrays */
998 for (aa = actx->arrays; aa->func ; aa++) {
999 const GLubyte *src = aa->array->BufferObj->Data
1000 + (uintptr_t) aa->array->Ptr
1001 + elt * aa->array->StrideB;
1002 aa->func( src );
1003 }
1004 }
1005
1006
1007 void _ae_invalidate_state( GLcontext *ctx, GLuint new_state )
1008 {
1009 AE_CONTEXT(ctx)->NewState |= new_state;
1010 }