c94c6c07a6e5168ef40773fbd5b2947f1092db1b
[mesa.git] / src / mesa / main / api_arrayelt.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 1999-2005 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 #include "glapioffsets.h"
37 #include "dispatch.h"
38
39 typedef void (GLAPIENTRY *array_func)( const void * );
40
41 typedef struct {
42 const struct gl_client_array *array;
43 int offset;
44 } AEarray;
45
46 typedef void (GLAPIENTRY *attrib_func)( GLuint indx, const void *data );
47
48 typedef struct {
49 const struct gl_client_array *array;
50 attrib_func func;
51 GLuint index;
52 } AEattrib;
53
54 typedef struct {
55 AEarray arrays[32];
56 AEattrib attribs[VERT_ATTRIB_MAX + 1];
57 GLuint NewState;
58 } AEcontext;
59
60 #define AE_CONTEXT(ctx) ((AEcontext *)(ctx)->aelt_context)
61
62
63 /*
64 * Convert GL_BYTE, GL_UNSIGNED_BYTE, .. GL_DOUBLE into an integer
65 * in the range [0, 7]. Luckily these type tokens are sequentially
66 * numbered in gl.h, except for GL_DOUBLE.
67 */
68 #define TYPE_IDX(t) ( (t) == GL_DOUBLE ? 7 : (t) & 7 )
69
70 static const int ColorFuncs[2][8] = {
71 {
72 _gloffset_Color3bv,
73 _gloffset_Color3ubv,
74 _gloffset_Color3sv,
75 _gloffset_Color3usv,
76 _gloffset_Color3iv,
77 _gloffset_Color3uiv,
78 _gloffset_Color3fv,
79 _gloffset_Color3dv,
80 },
81 {
82 _gloffset_Color4bv,
83 _gloffset_Color4ubv,
84 _gloffset_Color4sv,
85 _gloffset_Color4usv,
86 _gloffset_Color4iv,
87 _gloffset_Color4uiv,
88 _gloffset_Color4fv,
89 _gloffset_Color4dv,
90 },
91 };
92
93 static const int VertexFuncs[3][8] = {
94 {
95 -1,
96 -1,
97 _gloffset_Vertex2sv,
98 -1,
99 _gloffset_Vertex2iv,
100 -1,
101 _gloffset_Vertex2fv,
102 _gloffset_Vertex2dv,
103 },
104 {
105 -1,
106 -1,
107 _gloffset_Vertex3sv,
108 -1,
109 _gloffset_Vertex3iv,
110 -1,
111 _gloffset_Vertex3fv,
112 _gloffset_Vertex3dv,
113 },
114 {
115 -1,
116 -1,
117 _gloffset_Vertex4sv,
118 -1,
119 _gloffset_Vertex4iv,
120 -1,
121 _gloffset_Vertex4fv,
122 _gloffset_Vertex4dv,
123 },
124 };
125
126 static const int IndexFuncs[8] = {
127 -1,
128 _gloffset_Indexubv,
129 _gloffset_Indexsv,
130 -1,
131 _gloffset_Indexiv,
132 -1,
133 _gloffset_Indexfv,
134 _gloffset_Indexdv,
135 };
136
137 static const int NormalFuncs[8] = {
138 _gloffset_Normal3bv,
139 -1,
140 _gloffset_Normal3sv,
141 -1,
142 _gloffset_Normal3iv,
143 -1,
144 _gloffset_Normal3fv,
145 _gloffset_Normal3dv,
146 };
147
148 /* Note: _gloffset_* for these may not be a compile-time constant. */
149 static int SecondaryColorFuncs[8];
150 static int FogCoordFuncs[8];
151
152 /**********************************************************************/
153
154 /* GL_BYTE attributes */
155
156 static void GLAPIENTRY VertexAttrib1NbvNV(GLuint index, const GLbyte *v)
157 {
158 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0])));
159 }
160
161 static void GLAPIENTRY VertexAttrib1bvNV(GLuint index, const GLbyte *v)
162 {
163 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
164 }
165
166 static void GLAPIENTRY VertexAttrib2NbvNV(GLuint index, const GLbyte *v)
167 {
168 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1])));
169 }
170
171 static void GLAPIENTRY VertexAttrib2bvNV(GLuint index, const GLbyte *v)
172 {
173 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
174 }
175
176 static void GLAPIENTRY VertexAttrib3NbvNV(GLuint index, const GLbyte *v)
177 {
178 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
179 BYTE_TO_FLOAT(v[1]),
180 BYTE_TO_FLOAT(v[2])));
181 }
182
183 static void GLAPIENTRY VertexAttrib3bvNV(GLuint index, const GLbyte *v)
184 {
185 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
186 }
187
188 static void GLAPIENTRY VertexAttrib4NbvNV(GLuint index, const GLbyte *v)
189 {
190 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
191 BYTE_TO_FLOAT(v[1]),
192 BYTE_TO_FLOAT(v[2]),
193 BYTE_TO_FLOAT(v[3])));
194 }
195
196 static void GLAPIENTRY VertexAttrib4bvNV(GLuint index, const GLbyte *v)
197 {
198 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
199 }
200
201 /* GL_UNSIGNED_BYTE attributes */
202
203 static void GLAPIENTRY VertexAttrib1NubvNV(GLuint index, const GLubyte *v)
204 {
205 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0])));
206 }
207
208 static void GLAPIENTRY VertexAttrib1ubvNV(GLuint index, const GLubyte *v)
209 {
210 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
211 }
212
213 static void GLAPIENTRY VertexAttrib2NubvNV(GLuint index, const GLubyte *v)
214 {
215 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
216 UBYTE_TO_FLOAT(v[1])));
217 }
218
219 static void GLAPIENTRY VertexAttrib2ubvNV(GLuint index, const GLubyte *v)
220 {
221 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
222 }
223
224 static void GLAPIENTRY VertexAttrib3NubvNV(GLuint index, const GLubyte *v)
225 {
226 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
227 UBYTE_TO_FLOAT(v[1]),
228 UBYTE_TO_FLOAT(v[2])));
229 }
230 static void GLAPIENTRY VertexAttrib3ubvNV(GLuint index, const GLubyte *v)
231 {
232 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
233 }
234
235 static void GLAPIENTRY VertexAttrib4NubvNV(GLuint index, const GLubyte *v)
236 {
237 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
238 UBYTE_TO_FLOAT(v[1]),
239 UBYTE_TO_FLOAT(v[2]),
240 UBYTE_TO_FLOAT(v[3])));
241 }
242
243 static void GLAPIENTRY VertexAttrib4ubvNV(GLuint index, const GLubyte *v)
244 {
245 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
246 }
247
248 /* GL_SHORT attributes */
249
250 static void GLAPIENTRY VertexAttrib1NsvNV(GLuint index, const GLshort *v)
251 {
252 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0])));
253 }
254
255 static void GLAPIENTRY VertexAttrib1svNV(GLuint index, const GLshort *v)
256 {
257 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
258 }
259
260 static void GLAPIENTRY VertexAttrib2NsvNV(GLuint index, const GLshort *v)
261 {
262 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
263 SHORT_TO_FLOAT(v[1])));
264 }
265
266 static void GLAPIENTRY VertexAttrib2svNV(GLuint index, const GLshort *v)
267 {
268 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
269 }
270
271 static void GLAPIENTRY VertexAttrib3NsvNV(GLuint index, const GLshort *v)
272 {
273 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
274 SHORT_TO_FLOAT(v[1]),
275 SHORT_TO_FLOAT(v[2])));
276 }
277
278 static void GLAPIENTRY VertexAttrib3svNV(GLuint index, const GLshort *v)
279 {
280 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
281 }
282
283 static void GLAPIENTRY VertexAttrib4NsvNV(GLuint index, const GLshort *v)
284 {
285 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
286 SHORT_TO_FLOAT(v[1]),
287 SHORT_TO_FLOAT(v[2]),
288 SHORT_TO_FLOAT(v[3])));
289 }
290
291 static void GLAPIENTRY VertexAttrib4svNV(GLuint index, const GLshort *v)
292 {
293 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
294 }
295
296 /* GL_UNSIGNED_SHORT attributes */
297
298 static void GLAPIENTRY VertexAttrib1NusvNV(GLuint index, const GLushort *v)
299 {
300 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0])));
301 }
302
303 static void GLAPIENTRY VertexAttrib1usvNV(GLuint index, const GLushort *v)
304 {
305 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
306 }
307
308 static void GLAPIENTRY VertexAttrib2NusvNV(GLuint index, const GLushort *v)
309 {
310 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
311 USHORT_TO_FLOAT(v[1])));
312 }
313
314 static void GLAPIENTRY VertexAttrib2usvNV(GLuint index, const GLushort *v)
315 {
316 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
317 }
318
319 static void GLAPIENTRY VertexAttrib3NusvNV(GLuint index, const GLushort *v)
320 {
321 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
322 USHORT_TO_FLOAT(v[1]),
323 USHORT_TO_FLOAT(v[2])));
324 }
325
326 static void GLAPIENTRY VertexAttrib3usvNV(GLuint index, const GLushort *v)
327 {
328 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
329 }
330
331 static void GLAPIENTRY VertexAttrib4NusvNV(GLuint index, const GLushort *v)
332 {
333 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
334 USHORT_TO_FLOAT(v[1]),
335 USHORT_TO_FLOAT(v[2]),
336 USHORT_TO_FLOAT(v[3])));
337 }
338
339 static void GLAPIENTRY VertexAttrib4usvNV(GLuint index, const GLushort *v)
340 {
341 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
342 }
343
344 /* GL_INT attributes */
345
346 static void GLAPIENTRY VertexAttrib1NivNV(GLuint index, const GLint *v)
347 {
348 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0])));
349 }
350
351 static void GLAPIENTRY VertexAttrib1ivNV(GLuint index, const GLint *v)
352 {
353 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
354 }
355
356 static void GLAPIENTRY VertexAttrib2NivNV(GLuint index, const GLint *v)
357 {
358 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
359 INT_TO_FLOAT(v[1])));
360 }
361
362 static void GLAPIENTRY VertexAttrib2ivNV(GLuint index, const GLint *v)
363 {
364 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
365 }
366
367 static void GLAPIENTRY VertexAttrib3NivNV(GLuint index, const GLint *v)
368 {
369 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
370 INT_TO_FLOAT(v[1]),
371 INT_TO_FLOAT(v[2])));
372 }
373
374 static void GLAPIENTRY VertexAttrib3ivNV(GLuint index, const GLint *v)
375 {
376 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
377 }
378
379 static void GLAPIENTRY VertexAttrib4NivNV(GLuint index, const GLint *v)
380 {
381 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
382 INT_TO_FLOAT(v[1]),
383 INT_TO_FLOAT(v[2]),
384 INT_TO_FLOAT(v[3])));
385 }
386
387 static void GLAPIENTRY VertexAttrib4ivNV(GLuint index, const GLint *v)
388 {
389 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
390 }
391
392 /* GL_UNSIGNED_INT attributes */
393
394 static void GLAPIENTRY VertexAttrib1NuivNV(GLuint index, const GLuint *v)
395 {
396 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0])));
397 }
398
399 static void GLAPIENTRY VertexAttrib1uivNV(GLuint index, const GLuint *v)
400 {
401 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
402 }
403
404 static void GLAPIENTRY VertexAttrib2NuivNV(GLuint index, const GLuint *v)
405 {
406 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
407 UINT_TO_FLOAT(v[1])));
408 }
409
410 static void GLAPIENTRY VertexAttrib2uivNV(GLuint index, const GLuint *v)
411 {
412 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
413 }
414
415 static void GLAPIENTRY VertexAttrib3NuivNV(GLuint index, const GLuint *v)
416 {
417 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
418 UINT_TO_FLOAT(v[1]),
419 UINT_TO_FLOAT(v[2])));
420 }
421
422 static void GLAPIENTRY VertexAttrib3uivNV(GLuint index, const GLuint *v)
423 {
424 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
425 }
426
427 static void GLAPIENTRY VertexAttrib4NuivNV(GLuint index, const GLuint *v)
428 {
429 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
430 UINT_TO_FLOAT(v[1]),
431 UINT_TO_FLOAT(v[2]),
432 UINT_TO_FLOAT(v[3])));
433 }
434
435 static void GLAPIENTRY VertexAttrib4uivNV(GLuint index, const GLuint *v)
436 {
437 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
438 }
439
440 /* GL_FLOAT attributes */
441
442 static void GLAPIENTRY VertexAttrib1fvNV(GLuint index, const GLfloat *v)
443 {
444 CALL_VertexAttrib1fvNV(GET_DISPATCH(), (index, v));
445 }
446
447 static void GLAPIENTRY VertexAttrib2fvNV(GLuint index, const GLfloat *v)
448 {
449 CALL_VertexAttrib2fvNV(GET_DISPATCH(), (index, v));
450 }
451
452 static void GLAPIENTRY VertexAttrib3fvNV(GLuint index, const GLfloat *v)
453 {
454 CALL_VertexAttrib3fvNV(GET_DISPATCH(), (index, v));
455 }
456
457 static void GLAPIENTRY VertexAttrib4fvNV(GLuint index, const GLfloat *v)
458 {
459 CALL_VertexAttrib4fvNV(GET_DISPATCH(), (index, v));
460 }
461
462 /* GL_DOUBLE attributes */
463
464 static void GLAPIENTRY VertexAttrib1dvNV(GLuint index, const GLdouble *v)
465 {
466 CALL_VertexAttrib1dvNV(GET_DISPATCH(), (index, v));
467 }
468
469 static void GLAPIENTRY VertexAttrib2dvNV(GLuint index, const GLdouble *v)
470 {
471 CALL_VertexAttrib2dvNV(GET_DISPATCH(), (index, v));
472 }
473
474 static void GLAPIENTRY VertexAttrib3dvNV(GLuint index, const GLdouble *v)
475 {
476 CALL_VertexAttrib3dvNV(GET_DISPATCH(), (index, v));
477 }
478
479 static void GLAPIENTRY VertexAttrib4dvNV(GLuint index, const GLdouble *v)
480 {
481 CALL_VertexAttrib4dvNV(GET_DISPATCH(), (index, v));
482 }
483
484
485 /*
486 * Array [size][type] of VertexAttrib functions
487 */
488 static attrib_func AttribFuncsNV[2][4][8] = {
489 {
490 /* non-normalized */
491 {
492 /* size 1 */
493 (attrib_func) VertexAttrib1bvNV,
494 (attrib_func) VertexAttrib1ubvNV,
495 (attrib_func) VertexAttrib1svNV,
496 (attrib_func) VertexAttrib1usvNV,
497 (attrib_func) VertexAttrib1ivNV,
498 (attrib_func) VertexAttrib1uivNV,
499 (attrib_func) VertexAttrib1fvNV,
500 (attrib_func) VertexAttrib1dvNV
501 },
502 {
503 /* size 2 */
504 (attrib_func) VertexAttrib2bvNV,
505 (attrib_func) VertexAttrib2ubvNV,
506 (attrib_func) VertexAttrib2svNV,
507 (attrib_func) VertexAttrib2usvNV,
508 (attrib_func) VertexAttrib2ivNV,
509 (attrib_func) VertexAttrib2uivNV,
510 (attrib_func) VertexAttrib2fvNV,
511 (attrib_func) VertexAttrib2dvNV
512 },
513 {
514 /* size 3 */
515 (attrib_func) VertexAttrib3bvNV,
516 (attrib_func) VertexAttrib3ubvNV,
517 (attrib_func) VertexAttrib3svNV,
518 (attrib_func) VertexAttrib3usvNV,
519 (attrib_func) VertexAttrib3ivNV,
520 (attrib_func) VertexAttrib3uivNV,
521 (attrib_func) VertexAttrib3fvNV,
522 (attrib_func) VertexAttrib3dvNV
523 },
524 {
525 /* size 4 */
526 (attrib_func) VertexAttrib4bvNV,
527 (attrib_func) VertexAttrib4ubvNV,
528 (attrib_func) VertexAttrib4svNV,
529 (attrib_func) VertexAttrib4usvNV,
530 (attrib_func) VertexAttrib4ivNV,
531 (attrib_func) VertexAttrib4uivNV,
532 (attrib_func) VertexAttrib4fvNV,
533 (attrib_func) VertexAttrib4dvNV
534 }
535 },
536 {
537 /* normalized (except for float/double) */
538 {
539 /* size 1 */
540 (attrib_func) VertexAttrib1NbvNV,
541 (attrib_func) VertexAttrib1NubvNV,
542 (attrib_func) VertexAttrib1NsvNV,
543 (attrib_func) VertexAttrib1NusvNV,
544 (attrib_func) VertexAttrib1NivNV,
545 (attrib_func) VertexAttrib1NuivNV,
546 (attrib_func) VertexAttrib1fvNV,
547 (attrib_func) VertexAttrib1dvNV
548 },
549 {
550 /* size 2 */
551 (attrib_func) VertexAttrib2NbvNV,
552 (attrib_func) VertexAttrib2NubvNV,
553 (attrib_func) VertexAttrib2NsvNV,
554 (attrib_func) VertexAttrib2NusvNV,
555 (attrib_func) VertexAttrib2NivNV,
556 (attrib_func) VertexAttrib2NuivNV,
557 (attrib_func) VertexAttrib2fvNV,
558 (attrib_func) VertexAttrib2dvNV
559 },
560 {
561 /* size 3 */
562 (attrib_func) VertexAttrib3NbvNV,
563 (attrib_func) VertexAttrib3NubvNV,
564 (attrib_func) VertexAttrib3NsvNV,
565 (attrib_func) VertexAttrib3NusvNV,
566 (attrib_func) VertexAttrib3NivNV,
567 (attrib_func) VertexAttrib3NuivNV,
568 (attrib_func) VertexAttrib3fvNV,
569 (attrib_func) VertexAttrib3dvNV
570 },
571 {
572 /* size 4 */
573 (attrib_func) VertexAttrib4NbvNV,
574 (attrib_func) VertexAttrib4NubvNV,
575 (attrib_func) VertexAttrib4NsvNV,
576 (attrib_func) VertexAttrib4NusvNV,
577 (attrib_func) VertexAttrib4NivNV,
578 (attrib_func) VertexAttrib4NuivNV,
579 (attrib_func) VertexAttrib4fvNV,
580 (attrib_func) VertexAttrib4dvNV
581 }
582 }
583 };
584
585 /**********************************************************************/
586
587
588 GLboolean _ae_create_context( GLcontext *ctx )
589 {
590 if (ctx->aelt_context)
591 return GL_TRUE;
592
593 /* These _gloffset_* values may not be compile-time constants */
594 SecondaryColorFuncs[0] = _gloffset_SecondaryColor3bvEXT;
595 SecondaryColorFuncs[1] = _gloffset_SecondaryColor3ubvEXT;
596 SecondaryColorFuncs[2] = _gloffset_SecondaryColor3svEXT;
597 SecondaryColorFuncs[3] = _gloffset_SecondaryColor3usvEXT;
598 SecondaryColorFuncs[4] = _gloffset_SecondaryColor3ivEXT;
599 SecondaryColorFuncs[5] = _gloffset_SecondaryColor3uivEXT;
600 SecondaryColorFuncs[6] = _gloffset_SecondaryColor3fvEXT;
601 SecondaryColorFuncs[7] = _gloffset_SecondaryColor3dvEXT;
602
603 FogCoordFuncs[6] = _gloffset_FogCoordfvEXT;
604 FogCoordFuncs[7] = _gloffset_FogCoorddvEXT;
605
606 ctx->aelt_context = MALLOC( sizeof(AEcontext) );
607 if (!ctx->aelt_context)
608 return GL_FALSE;
609
610 AE_CONTEXT(ctx)->NewState = ~0;
611 return GL_TRUE;
612 }
613
614
615 void _ae_destroy_context( GLcontext *ctx )
616 {
617 if ( AE_CONTEXT( ctx ) ) {
618 FREE( ctx->aelt_context );
619 ctx->aelt_context = NULL;
620 }
621 }
622
623
624 /**
625 * Make a list of per-vertex functions to call for each glArrayElement call.
626 * These functions access the array data (i.e. glVertex, glColor, glNormal,
627 * etc).
628 * Note: this may be called during display list construction.
629 */
630 static void _ae_update_state( GLcontext *ctx )
631 {
632 AEcontext *actx = AE_CONTEXT(ctx);
633 AEarray *aa = actx->arrays;
634 AEattrib *at = actx->attribs;
635 GLuint i;
636
637 /* conventional vertex arrays */
638 if (ctx->Array.Index.Enabled) {
639 aa->array = &ctx->Array.Index;
640 aa->offset = IndexFuncs[TYPE_IDX(aa->array->Type)];
641 aa++;
642 }
643 if (ctx->Array.EdgeFlag.Enabled) {
644 aa->array = &ctx->Array.EdgeFlag;
645 aa->offset = _gloffset_EdgeFlagv;
646 aa++;
647 }
648 if (ctx->Array.Normal.Enabled) {
649 aa->array = &ctx->Array.Normal;
650 aa->offset = NormalFuncs[TYPE_IDX(aa->array->Type)];
651 aa++;
652 }
653 if (ctx->Array.Color.Enabled) {
654 aa->array = &ctx->Array.Color;
655 aa->offset = ColorFuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)];
656 aa++;
657 }
658 if (ctx->Array.SecondaryColor.Enabled) {
659 aa->array = &ctx->Array.SecondaryColor;
660 aa->offset = SecondaryColorFuncs[TYPE_IDX(aa->array->Type)];
661 aa++;
662 }
663 if (ctx->Array.FogCoord.Enabled) {
664 aa->array = &ctx->Array.FogCoord;
665 aa->offset = FogCoordFuncs[TYPE_IDX(aa->array->Type)];
666 aa++;
667 }
668 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
669 if (ctx->Array.TexCoord[i].Enabled && ctx->Array.TexCoord[i].Ptr) {
670 /* NOTE: we use generic glVertexAttrib functions here.
671 * If we ever de-alias conventional/generic vertex attribs this
672 * will have to change.
673 */
674 struct gl_client_array *attribArray = &ctx->Array.TexCoord[i];
675 at->array = attribArray;
676 at->func = AttribFuncsNV[at->array->Normalized][at->array->Size-1][TYPE_IDX(at->array->Type)];
677 at->index = VERT_ATTRIB_TEX0 + i;
678 at++;
679 }
680 }
681
682 /* generic vertex attribute arrays */
683 for (i = 1; i < VERT_ATTRIB_MAX; i++) { /* skip zero! */
684 if (ctx->Array.VertexAttrib[i].Enabled &&
685 ctx->Array.VertexAttrib[i].Ptr) {
686 struct gl_client_array *attribArray = &ctx->Array.VertexAttrib[i];
687 at->array = attribArray;
688 /* Note: we can't grab the _glapi_Dispatch->VertexAttrib1fvNV
689 * function pointer here (for float arrays) since the pointer may
690 * change from one execution of _ae_loopback_array_elt() to
691 * the next. Doing so caused UT to break.
692 */
693 at->func = AttribFuncsNV[at->array->Normalized][at->array->Size-1][TYPE_IDX(at->array->Type)];
694 at->index = i;
695 at++;
696 }
697 }
698
699 /* finally, vertex position */
700 if (ctx->Array.VertexAttrib[0].Enabled) {
701 /* Use glVertex(v) instead of glVertexAttrib(0, v) to be sure it's
702 * issued as the last (proviking) attribute).
703 */
704 aa->array = &ctx->Array.VertexAttrib[0];
705 assert(aa->array->Size >= 2); /* XXX fix someday? */
706 aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
707 aa++;
708 }
709 else if (ctx->Array.Vertex.Enabled) {
710 aa->array = &ctx->Array.Vertex;
711 aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
712 aa++;
713 }
714
715 ASSERT(at - actx->attribs <= VERT_ATTRIB_MAX);
716 ASSERT(aa - actx->arrays < 32);
717 at->func = NULL; /* terminate the list */
718 aa->offset = -1; /* terminate the list */
719
720 actx->NewState = 0;
721 }
722
723
724 /**
725 * Called via glArrayElement() and glDrawArrays().
726 * Issue the glNormal, glVertex, glColor, glVertexAttrib, etc functions
727 * for all enabled vertex arrays (for elt-th element).
728 * Note: this may be called during display list construction.
729 */
730 void GLAPIENTRY _ae_loopback_array_elt( GLint elt )
731 {
732 GET_CURRENT_CONTEXT(ctx);
733 const AEcontext *actx = AE_CONTEXT(ctx);
734 const AEarray *aa;
735 const AEattrib *at;
736 const struct _glapi_table * const disp = GET_DISPATCH();
737
738
739 if (actx->NewState)
740 _ae_update_state( ctx );
741
742 /* generic attributes */
743 for (at = actx->attribs; at->func; at++) {
744 const GLubyte *src
745 = ADD_POINTERS(at->array->BufferObj->Data, at->array->Ptr)
746 + elt * at->array->StrideB;
747 at->func( at->index, src );
748 }
749
750 /* conventional arrays */
751 for (aa = actx->arrays; aa->offset != -1 ; aa++) {
752 const GLubyte *src
753 = ADD_POINTERS(aa->array->BufferObj->Data, aa->array->Ptr)
754 + elt * aa->array->StrideB;
755 CALL_by_offset( disp, (array_func), aa->offset,
756 ((const void *) src) );
757 }
758 }
759
760
761 void _ae_invalidate_state( GLcontext *ctx, GLuint new_state )
762 {
763 AE_CONTEXT(ctx)->NewState |= new_state;
764 }