[MESA]
[reactos.git] / reactos / dll / opengl / mesa / main / api_arrayelt.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5.1
4 *
5 * Copyright (C) 1999-2006 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 /**
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 <keith@tungstengraphics.com>
35 */
36
37 #include "glheader.h"
38 #include "api_arrayelt.h"
39 #include "bufferobj.h"
40 #include "context.h"
41 #include "imports.h"
42 #include "macros.h"
43 #include "mfeatures.h"
44 #include "mtypes.h"
45 #include "main/dispatch.h"
46
47 typedef void (GLAPIENTRY *array_func)( const void * );
48
49 typedef struct {
50 const struct gl_client_array *array;
51 int offset;
52 } AEarray;
53
54 typedef void (GLAPIENTRY *attrib_func)( GLuint indx, const void *data );
55
56 typedef struct {
57 const struct gl_client_array *array;
58 attrib_func func;
59 GLuint index;
60 } AEattrib;
61
62 typedef struct {
63 AEarray arrays[32];
64 AEattrib attribs[VERT_ATTRIB_MAX + 1];
65 GLuint NewState;
66
67 struct gl_buffer_object *vbo[VERT_ATTRIB_MAX];
68 GLuint nr_vbos;
69 GLboolean mapped_vbos;
70
71 } AEcontext;
72
73 #define AE_CONTEXT(ctx) ((AEcontext *)(ctx)->aelt_context)
74
75
76 /*
77 * Convert GL_BYTE, GL_UNSIGNED_BYTE, .. GL_DOUBLE into an integer
78 * in the range [0, 7]. Luckily these type tokens are sequentially
79 * numbered in gl.h, except for GL_DOUBLE.
80 */
81 #define TYPE_IDX(t) ( (t) == GL_DOUBLE ? 7 : (t) & 7 )
82
83 #define NUM_TYPES 8
84
85
86 #if FEATURE_arrayelt
87
88
89 static const int ColorFuncs[2][NUM_TYPES] = {
90 {
91 _gloffset_Color3bv,
92 _gloffset_Color3ubv,
93 _gloffset_Color3sv,
94 _gloffset_Color3usv,
95 _gloffset_Color3iv,
96 _gloffset_Color3uiv,
97 _gloffset_Color3fv,
98 _gloffset_Color3dv,
99 },
100 {
101 _gloffset_Color4bv,
102 _gloffset_Color4ubv,
103 _gloffset_Color4sv,
104 _gloffset_Color4usv,
105 _gloffset_Color4iv,
106 _gloffset_Color4uiv,
107 _gloffset_Color4fv,
108 _gloffset_Color4dv,
109 },
110 };
111
112 static const int VertexFuncs[3][NUM_TYPES] = {
113 {
114 -1,
115 -1,
116 _gloffset_Vertex2sv,
117 -1,
118 _gloffset_Vertex2iv,
119 -1,
120 _gloffset_Vertex2fv,
121 _gloffset_Vertex2dv,
122 },
123 {
124 -1,
125 -1,
126 _gloffset_Vertex3sv,
127 -1,
128 _gloffset_Vertex3iv,
129 -1,
130 _gloffset_Vertex3fv,
131 _gloffset_Vertex3dv,
132 },
133 {
134 -1,
135 -1,
136 _gloffset_Vertex4sv,
137 -1,
138 _gloffset_Vertex4iv,
139 -1,
140 _gloffset_Vertex4fv,
141 _gloffset_Vertex4dv,
142 },
143 };
144
145 static const int IndexFuncs[NUM_TYPES] = {
146 -1,
147 _gloffset_Indexubv,
148 _gloffset_Indexsv,
149 -1,
150 _gloffset_Indexiv,
151 -1,
152 _gloffset_Indexfv,
153 _gloffset_Indexdv,
154 };
155
156 static const int NormalFuncs[NUM_TYPES] = {
157 _gloffset_Normal3bv,
158 -1,
159 _gloffset_Normal3sv,
160 -1,
161 _gloffset_Normal3iv,
162 -1,
163 _gloffset_Normal3fv,
164 _gloffset_Normal3dv,
165 };
166
167 /* Note: _gloffset_* for these may not be a compile-time constant. */
168 static int SecondaryColorFuncs[NUM_TYPES];
169 static int FogCoordFuncs[NUM_TYPES];
170
171
172 /**
173 ** GL_NV_vertex_program
174 **/
175
176 /* GL_BYTE attributes */
177
178 static void GLAPIENTRY
179 VertexAttrib1NbvNV(GLuint index, const GLbyte *v)
180 {
181 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0])));
182 }
183
184 static void GLAPIENTRY
185 VertexAttrib1bvNV(GLuint index, const GLbyte *v)
186 {
187 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
188 }
189
190 static void GLAPIENTRY
191 VertexAttrib2NbvNV(GLuint index, const GLbyte *v)
192 {
193 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1])));
194 }
195
196 static void GLAPIENTRY
197 VertexAttrib2bvNV(GLuint index, const GLbyte *v)
198 {
199 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
200 }
201
202 static void GLAPIENTRY
203 VertexAttrib3NbvNV(GLuint index, const GLbyte *v)
204 {
205 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
206 BYTE_TO_FLOAT(v[1]),
207 BYTE_TO_FLOAT(v[2])));
208 }
209
210 static void GLAPIENTRY
211 VertexAttrib3bvNV(GLuint index, const GLbyte *v)
212 {
213 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
214 }
215
216 static void GLAPIENTRY
217 VertexAttrib4NbvNV(GLuint index, const GLbyte *v)
218 {
219 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, BYTE_TO_FLOAT(v[0]),
220 BYTE_TO_FLOAT(v[1]),
221 BYTE_TO_FLOAT(v[2]),
222 BYTE_TO_FLOAT(v[3])));
223 }
224
225 static void GLAPIENTRY
226 VertexAttrib4bvNV(GLuint index, const GLbyte *v)
227 {
228 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
229 }
230
231 /* GL_UNSIGNED_BYTE attributes */
232
233 static void GLAPIENTRY
234 VertexAttrib1NubvNV(GLuint index, const GLubyte *v)
235 {
236 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0])));
237 }
238
239 static void GLAPIENTRY
240 VertexAttrib1ubvNV(GLuint index, const GLubyte *v)
241 {
242 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
243 }
244
245 static void GLAPIENTRY
246 VertexAttrib2NubvNV(GLuint index, const GLubyte *v)
247 {
248 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
249 UBYTE_TO_FLOAT(v[1])));
250 }
251
252 static void GLAPIENTRY
253 VertexAttrib2ubvNV(GLuint index, const GLubyte *v)
254 {
255 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
256 }
257
258 static void GLAPIENTRY
259 VertexAttrib3NubvNV(GLuint index, const GLubyte *v)
260 {
261 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
262 UBYTE_TO_FLOAT(v[1]),
263 UBYTE_TO_FLOAT(v[2])));
264 }
265 static void GLAPIENTRY
266 VertexAttrib3ubvNV(GLuint index, const GLubyte *v)
267 {
268 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0],
269 (GLfloat)v[1], (GLfloat)v[2]));
270 }
271
272 static void GLAPIENTRY
273 VertexAttrib4NubvNV(GLuint index, const GLubyte *v)
274 {
275 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, UBYTE_TO_FLOAT(v[0]),
276 UBYTE_TO_FLOAT(v[1]),
277 UBYTE_TO_FLOAT(v[2]),
278 UBYTE_TO_FLOAT(v[3])));
279 }
280
281 static void GLAPIENTRY
282 VertexAttrib4ubvNV(GLuint index, const GLubyte *v)
283 {
284 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0],
285 (GLfloat)v[1], (GLfloat)v[2],
286 (GLfloat)v[3]));
287 }
288
289 /* GL_SHORT attributes */
290
291 static void GLAPIENTRY
292 VertexAttrib1NsvNV(GLuint index, const GLshort *v)
293 {
294 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0])));
295 }
296
297 static void GLAPIENTRY
298 VertexAttrib1svNV(GLuint index, const GLshort *v)
299 {
300 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
301 }
302
303 static void GLAPIENTRY
304 VertexAttrib2NsvNV(GLuint index, const GLshort *v)
305 {
306 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
307 SHORT_TO_FLOAT(v[1])));
308 }
309
310 static void GLAPIENTRY
311 VertexAttrib2svNV(GLuint index, const GLshort *v)
312 {
313 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
314 }
315
316 static void GLAPIENTRY
317 VertexAttrib3NsvNV(GLuint index, const GLshort *v)
318 {
319 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
320 SHORT_TO_FLOAT(v[1]),
321 SHORT_TO_FLOAT(v[2])));
322 }
323
324 static void GLAPIENTRY
325 VertexAttrib3svNV(GLuint index, const GLshort *v)
326 {
327 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
328 (GLfloat)v[2]));
329 }
330
331 static void GLAPIENTRY
332 VertexAttrib4NsvNV(GLuint index, const GLshort *v)
333 {
334 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, SHORT_TO_FLOAT(v[0]),
335 SHORT_TO_FLOAT(v[1]),
336 SHORT_TO_FLOAT(v[2]),
337 SHORT_TO_FLOAT(v[3])));
338 }
339
340 static void GLAPIENTRY
341 VertexAttrib4svNV(GLuint index, const GLshort *v)
342 {
343 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
344 (GLfloat)v[2], (GLfloat)v[3]));
345 }
346
347 /* GL_UNSIGNED_SHORT attributes */
348
349 static void GLAPIENTRY
350 VertexAttrib1NusvNV(GLuint index, const GLushort *v)
351 {
352 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0])));
353 }
354
355 static void GLAPIENTRY
356 VertexAttrib1usvNV(GLuint index, const GLushort *v)
357 {
358 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
359 }
360
361 static void GLAPIENTRY
362 VertexAttrib2NusvNV(GLuint index, const GLushort *v)
363 {
364 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
365 USHORT_TO_FLOAT(v[1])));
366 }
367
368 static void GLAPIENTRY
369 VertexAttrib2usvNV(GLuint index, const GLushort *v)
370 {
371 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0],
372 (GLfloat)v[1]));
373 }
374
375 static void GLAPIENTRY
376 VertexAttrib3NusvNV(GLuint index, const GLushort *v)
377 {
378 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
379 USHORT_TO_FLOAT(v[1]),
380 USHORT_TO_FLOAT(v[2])));
381 }
382
383 static void GLAPIENTRY
384 VertexAttrib3usvNV(GLuint index, const GLushort *v)
385 {
386 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
387 (GLfloat)v[2]));
388 }
389
390 static void GLAPIENTRY
391 VertexAttrib4NusvNV(GLuint index, const GLushort *v)
392 {
393 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, USHORT_TO_FLOAT(v[0]),
394 USHORT_TO_FLOAT(v[1]),
395 USHORT_TO_FLOAT(v[2]),
396 USHORT_TO_FLOAT(v[3])));
397 }
398
399 static void GLAPIENTRY
400 VertexAttrib4usvNV(GLuint index, const GLushort *v)
401 {
402 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
403 (GLfloat)v[2], (GLfloat)v[3]));
404 }
405
406 /* GL_INT attributes */
407
408 static void GLAPIENTRY
409 VertexAttrib1NivNV(GLuint index, const GLint *v)
410 {
411 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0])));
412 }
413
414 static void GLAPIENTRY
415 VertexAttrib1ivNV(GLuint index, const GLint *v)
416 {
417 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
418 }
419
420 static void GLAPIENTRY
421 VertexAttrib2NivNV(GLuint index, const GLint *v)
422 {
423 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
424 INT_TO_FLOAT(v[1])));
425 }
426
427 static void GLAPIENTRY
428 VertexAttrib2ivNV(GLuint index, const GLint *v)
429 {
430 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
431 }
432
433 static void GLAPIENTRY
434 VertexAttrib3NivNV(GLuint index, const GLint *v)
435 {
436 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
437 INT_TO_FLOAT(v[1]),
438 INT_TO_FLOAT(v[2])));
439 }
440
441 static void GLAPIENTRY
442 VertexAttrib3ivNV(GLuint index, const GLint *v)
443 {
444 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
445 (GLfloat)v[2]));
446 }
447
448 static void GLAPIENTRY
449 VertexAttrib4NivNV(GLuint index, const GLint *v)
450 {
451 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, INT_TO_FLOAT(v[0]),
452 INT_TO_FLOAT(v[1]),
453 INT_TO_FLOAT(v[2]),
454 INT_TO_FLOAT(v[3])));
455 }
456
457 static void GLAPIENTRY
458 VertexAttrib4ivNV(GLuint index, const GLint *v)
459 {
460 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
461 (GLfloat)v[2], (GLfloat)v[3]));
462 }
463
464 /* GL_UNSIGNED_INT attributes */
465
466 static void GLAPIENTRY
467 VertexAttrib1NuivNV(GLuint index, const GLuint *v)
468 {
469 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0])));
470 }
471
472 static void GLAPIENTRY
473 VertexAttrib1uivNV(GLuint index, const GLuint *v)
474 {
475 CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
476 }
477
478 static void GLAPIENTRY
479 VertexAttrib2NuivNV(GLuint index, const GLuint *v)
480 {
481 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
482 UINT_TO_FLOAT(v[1])));
483 }
484
485 static void GLAPIENTRY
486 VertexAttrib2uivNV(GLuint index, const GLuint *v)
487 {
488 CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0],
489 (GLfloat)v[1]));
490 }
491
492 static void GLAPIENTRY
493 VertexAttrib3NuivNV(GLuint index, const GLuint *v)
494 {
495 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
496 UINT_TO_FLOAT(v[1]),
497 UINT_TO_FLOAT(v[2])));
498 }
499
500 static void GLAPIENTRY
501 VertexAttrib3uivNV(GLuint index, const GLuint *v)
502 {
503 CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
504 (GLfloat)v[2]));
505 }
506
507 static void GLAPIENTRY
508 VertexAttrib4NuivNV(GLuint index, const GLuint *v)
509 {
510 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, UINT_TO_FLOAT(v[0]),
511 UINT_TO_FLOAT(v[1]),
512 UINT_TO_FLOAT(v[2]),
513 UINT_TO_FLOAT(v[3])));
514 }
515
516 static void GLAPIENTRY
517 VertexAttrib4uivNV(GLuint index, const GLuint *v)
518 {
519 CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1],
520 (GLfloat)v[2], (GLfloat)v[3]));
521 }
522
523 /* GL_FLOAT attributes */
524
525 static void GLAPIENTRY
526 VertexAttrib1fvNV(GLuint index, const GLfloat *v)
527 {
528 CALL_VertexAttrib1fvNV(GET_DISPATCH(), (index, v));
529 }
530
531 static void GLAPIENTRY
532 VertexAttrib2fvNV(GLuint index, const GLfloat *v)
533 {
534 CALL_VertexAttrib2fvNV(GET_DISPATCH(), (index, v));
535 }
536
537 static void GLAPIENTRY
538 VertexAttrib3fvNV(GLuint index, const GLfloat *v)
539 {
540 CALL_VertexAttrib3fvNV(GET_DISPATCH(), (index, v));
541 }
542
543 static void GLAPIENTRY
544 VertexAttrib4fvNV(GLuint index, const GLfloat *v)
545 {
546 CALL_VertexAttrib4fvNV(GET_DISPATCH(), (index, v));
547 }
548
549 /* GL_DOUBLE attributes */
550
551 static void GLAPIENTRY
552 VertexAttrib1dvNV(GLuint index, const GLdouble *v)
553 {
554 CALL_VertexAttrib1dvNV(GET_DISPATCH(), (index, v));
555 }
556
557 static void GLAPIENTRY
558 VertexAttrib2dvNV(GLuint index, const GLdouble *v)
559 {
560 CALL_VertexAttrib2dvNV(GET_DISPATCH(), (index, v));
561 }
562
563 static void GLAPIENTRY
564 VertexAttrib3dvNV(GLuint index, const GLdouble *v)
565 {
566 CALL_VertexAttrib3dvNV(GET_DISPATCH(), (index, v));
567 }
568
569 static void GLAPIENTRY
570 VertexAttrib4dvNV(GLuint index, const GLdouble *v)
571 {
572 CALL_VertexAttrib4dvNV(GET_DISPATCH(), (index, v));
573 }
574
575
576 /*
577 * Array [size][type] of VertexAttrib functions
578 */
579 static attrib_func AttribFuncsNV[2][4][NUM_TYPES] = {
580 {
581 /* non-normalized */
582 {
583 /* size 1 */
584 (attrib_func) VertexAttrib1bvNV,
585 (attrib_func) VertexAttrib1ubvNV,
586 (attrib_func) VertexAttrib1svNV,
587 (attrib_func) VertexAttrib1usvNV,
588 (attrib_func) VertexAttrib1ivNV,
589 (attrib_func) VertexAttrib1uivNV,
590 (attrib_func) VertexAttrib1fvNV,
591 (attrib_func) VertexAttrib1dvNV
592 },
593 {
594 /* size 2 */
595 (attrib_func) VertexAttrib2bvNV,
596 (attrib_func) VertexAttrib2ubvNV,
597 (attrib_func) VertexAttrib2svNV,
598 (attrib_func) VertexAttrib2usvNV,
599 (attrib_func) VertexAttrib2ivNV,
600 (attrib_func) VertexAttrib2uivNV,
601 (attrib_func) VertexAttrib2fvNV,
602 (attrib_func) VertexAttrib2dvNV
603 },
604 {
605 /* size 3 */
606 (attrib_func) VertexAttrib3bvNV,
607 (attrib_func) VertexAttrib3ubvNV,
608 (attrib_func) VertexAttrib3svNV,
609 (attrib_func) VertexAttrib3usvNV,
610 (attrib_func) VertexAttrib3ivNV,
611 (attrib_func) VertexAttrib3uivNV,
612 (attrib_func) VertexAttrib3fvNV,
613 (attrib_func) VertexAttrib3dvNV
614 },
615 {
616 /* size 4 */
617 (attrib_func) VertexAttrib4bvNV,
618 (attrib_func) VertexAttrib4ubvNV,
619 (attrib_func) VertexAttrib4svNV,
620 (attrib_func) VertexAttrib4usvNV,
621 (attrib_func) VertexAttrib4ivNV,
622 (attrib_func) VertexAttrib4uivNV,
623 (attrib_func) VertexAttrib4fvNV,
624 (attrib_func) VertexAttrib4dvNV
625 }
626 },
627 {
628 /* normalized (except for float/double) */
629 {
630 /* size 1 */
631 (attrib_func) VertexAttrib1NbvNV,
632 (attrib_func) VertexAttrib1NubvNV,
633 (attrib_func) VertexAttrib1NsvNV,
634 (attrib_func) VertexAttrib1NusvNV,
635 (attrib_func) VertexAttrib1NivNV,
636 (attrib_func) VertexAttrib1NuivNV,
637 (attrib_func) VertexAttrib1fvNV,
638 (attrib_func) VertexAttrib1dvNV
639 },
640 {
641 /* size 2 */
642 (attrib_func) VertexAttrib2NbvNV,
643 (attrib_func) VertexAttrib2NubvNV,
644 (attrib_func) VertexAttrib2NsvNV,
645 (attrib_func) VertexAttrib2NusvNV,
646 (attrib_func) VertexAttrib2NivNV,
647 (attrib_func) VertexAttrib2NuivNV,
648 (attrib_func) VertexAttrib2fvNV,
649 (attrib_func) VertexAttrib2dvNV
650 },
651 {
652 /* size 3 */
653 (attrib_func) VertexAttrib3NbvNV,
654 (attrib_func) VertexAttrib3NubvNV,
655 (attrib_func) VertexAttrib3NsvNV,
656 (attrib_func) VertexAttrib3NusvNV,
657 (attrib_func) VertexAttrib3NivNV,
658 (attrib_func) VertexAttrib3NuivNV,
659 (attrib_func) VertexAttrib3fvNV,
660 (attrib_func) VertexAttrib3dvNV
661 },
662 {
663 /* size 4 */
664 (attrib_func) VertexAttrib4NbvNV,
665 (attrib_func) VertexAttrib4NubvNV,
666 (attrib_func) VertexAttrib4NsvNV,
667 (attrib_func) VertexAttrib4NusvNV,
668 (attrib_func) VertexAttrib4NivNV,
669 (attrib_func) VertexAttrib4NuivNV,
670 (attrib_func) VertexAttrib4fvNV,
671 (attrib_func) VertexAttrib4dvNV
672 }
673 }
674 };
675
676 /**********************************************************************/
677
678
679 GLboolean _ae_create_context( struct gl_context *ctx )
680 {
681 if (ctx->aelt_context)
682 return GL_TRUE;
683
684 /* These _gloffset_* values may not be compile-time constants */
685 SecondaryColorFuncs[0] = _gloffset_SecondaryColor3bvEXT;
686 SecondaryColorFuncs[1] = _gloffset_SecondaryColor3ubvEXT;
687 SecondaryColorFuncs[2] = _gloffset_SecondaryColor3svEXT;
688 SecondaryColorFuncs[3] = _gloffset_SecondaryColor3usvEXT;
689 SecondaryColorFuncs[4] = _gloffset_SecondaryColor3ivEXT;
690 SecondaryColorFuncs[5] = _gloffset_SecondaryColor3uivEXT;
691 SecondaryColorFuncs[6] = _gloffset_SecondaryColor3fvEXT;
692 SecondaryColorFuncs[7] = _gloffset_SecondaryColor3dvEXT;
693
694 FogCoordFuncs[0] = -1;
695 FogCoordFuncs[1] = -1;
696 FogCoordFuncs[2] = -1;
697 FogCoordFuncs[3] = -1;
698 FogCoordFuncs[4] = -1;
699 FogCoordFuncs[5] = -1;
700 FogCoordFuncs[6] = _gloffset_FogCoordfvEXT;
701 FogCoordFuncs[7] = _gloffset_FogCoorddvEXT;
702
703 ctx->aelt_context = CALLOC( sizeof(AEcontext) );
704 if (!ctx->aelt_context)
705 return GL_FALSE;
706
707 AE_CONTEXT(ctx)->NewState = ~0;
708 return GL_TRUE;
709 }
710
711
712 void _ae_destroy_context( struct gl_context *ctx )
713 {
714 if ( AE_CONTEXT( ctx ) ) {
715 FREE( ctx->aelt_context );
716 ctx->aelt_context = NULL;
717 }
718 }
719
720 static void check_vbo( AEcontext *actx,
721 struct gl_buffer_object *vbo )
722 {
723 if (_mesa_is_bufferobj(vbo) && !_mesa_bufferobj_mapped(vbo)) {
724 GLuint i;
725 for (i = 0; i < actx->nr_vbos; i++)
726 if (actx->vbo[i] == vbo)
727 return;
728 assert(actx->nr_vbos < VERT_ATTRIB_MAX);
729 actx->vbo[actx->nr_vbos++] = vbo;
730 }
731 }
732
733
734 /**
735 * Make a list of per-vertex functions to call for each glArrayElement call.
736 * These functions access the array data (i.e. glVertex, glColor, glNormal,
737 * etc).
738 * Note: this may be called during display list construction.
739 */
740 static void _ae_update_state( struct gl_context *ctx )
741 {
742 AEcontext *actx = AE_CONTEXT(ctx);
743 AEarray *aa = actx->arrays;
744 AEattrib *at = actx->attribs;
745 struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
746
747 actx->nr_vbos = 0;
748
749 /* conventional vertex arrays */
750 if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) {
751 aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX];
752 aa->offset = IndexFuncs[TYPE_IDX(aa->array->Type)];
753 check_vbo(actx, aa->array->BufferObj);
754 aa++;
755 }
756 if (arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) {
757 aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG];
758 aa->offset = _gloffset_EdgeFlagv;
759 check_vbo(actx, aa->array->BufferObj);
760 aa++;
761 }
762 if (arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) {
763 aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL];
764 aa->offset = NormalFuncs[TYPE_IDX(aa->array->Type)];
765 check_vbo(actx, aa->array->BufferObj);
766 aa++;
767 }
768 if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) {
769 aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0];
770 aa->offset = ColorFuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)];
771 check_vbo(actx, aa->array->BufferObj);
772 aa++;
773 }
774 if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) {
775 aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1];
776 aa->offset = SecondaryColorFuncs[TYPE_IDX(aa->array->Type)];
777 check_vbo(actx, aa->array->BufferObj);
778 aa++;
779 }
780 if (arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) {
781 aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_FOG];
782 aa->offset = FogCoordFuncs[TYPE_IDX(aa->array->Type)];
783 check_vbo(actx, aa->array->BufferObj);
784 aa++;
785 }
786 {
787 struct gl_client_array *attribArray = &arrayObj->VertexAttrib[VERT_ATTRIB_TEX];
788 if (attribArray->Enabled) {
789 /* NOTE: we use generic glVertexAttribNV functions here.
790 * If we ever remove GL_NV_vertex_program this will have to change.
791 */
792 at->array = attribArray;
793 ASSERT(!at->array->Normalized);
794 at->func = AttribFuncsNV[at->array->Normalized]
795 [at->array->Size-1]
796 [TYPE_IDX(at->array->Type)];
797 at->index = VERT_ATTRIB_TEX;
798 check_vbo(actx, at->array->BufferObj);
799 at++;
800 }
801 }
802
803 /* finally, vertex position */
804 if (arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) {
805 aa->array = &arrayObj->VertexAttrib[VERT_ATTRIB_POS];
806 aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
807 check_vbo(actx, aa->array->BufferObj);
808 aa++;
809 }
810
811 check_vbo(actx, arrayObj->ElementArrayBufferObj);
812
813 ASSERT(at - actx->attribs <= VERT_ATTRIB_MAX);
814 ASSERT(aa - actx->arrays < 32);
815 at->func = NULL; /* terminate the list */
816 aa->offset = -1; /* terminate the list */
817
818 actx->NewState = 0;
819 }
820
821 void _ae_map_vbos( struct gl_context *ctx )
822 {
823 AEcontext *actx = AE_CONTEXT(ctx);
824 GLuint i;
825
826 if (actx->mapped_vbos)
827 return;
828
829 if (actx->NewState)
830 _ae_update_state(ctx);
831
832 for (i = 0; i < actx->nr_vbos; i++)
833 ctx->Driver.MapBufferRange(ctx, 0,
834 actx->vbo[i]->Size,
835 GL_MAP_READ_BIT,
836 actx->vbo[i]);
837
838 if (actx->nr_vbos)
839 actx->mapped_vbos = GL_TRUE;
840 }
841
842 void _ae_unmap_vbos( struct gl_context *ctx )
843 {
844 AEcontext *actx = AE_CONTEXT(ctx);
845 GLuint i;
846
847 if (!actx->mapped_vbos)
848 return;
849
850 assert (!actx->NewState);
851
852 for (i = 0; i < actx->nr_vbos; i++)
853 ctx->Driver.UnmapBuffer(ctx, actx->vbo[i]);
854
855 actx->mapped_vbos = GL_FALSE;
856 }
857
858
859 /**
860 * Called via glArrayElement() and glDrawArrays().
861 * Issue the glNormal, glVertex, glColor, glVertexAttrib, etc functions
862 * for all enabled vertex arrays (for elt-th element).
863 * Note: this may be called during display list construction.
864 */
865 void GLAPIENTRY _ae_ArrayElement( GLint elt )
866 {
867 GET_CURRENT_CONTEXT(ctx);
868 const AEcontext *actx = AE_CONTEXT(ctx);
869 const AEarray *aa;
870 const AEattrib *at;
871 const struct _glapi_table * const disp = GET_DISPATCH();
872 GLboolean do_map;
873
874 if (actx->NewState) {
875 assert(!actx->mapped_vbos);
876 _ae_update_state( ctx );
877 }
878
879 /* Determine if we need to map/unmap VBOs */
880 do_map = actx->nr_vbos && !actx->mapped_vbos;
881
882 if (do_map)
883 _ae_map_vbos(ctx);
884
885 /* emit generic attribute elements */
886 for (at = actx->attribs; at->func; at++) {
887 const GLubyte *src
888 = ADD_POINTERS(at->array->BufferObj->Pointer, at->array->Ptr)
889 + elt * at->array->StrideB;
890 at->func( at->index, src );
891 }
892
893 /* emit conventional arrays elements */
894 for (aa = actx->arrays; aa->offset != -1 ; aa++) {
895 const GLubyte *src
896 = ADD_POINTERS(aa->array->BufferObj->Pointer, aa->array->Ptr)
897 + elt * aa->array->StrideB;
898 CALL_by_offset( disp, (array_func), aa->offset,
899 ((const void *) src) );
900 }
901
902 if (do_map)
903 _ae_unmap_vbos(ctx);
904 }
905
906
907 void _ae_invalidate_state( struct gl_context *ctx, GLuint new_state )
908 {
909 AEcontext *actx = AE_CONTEXT(ctx);
910
911
912 /* Only interested in this subset of mesa state. Need to prune
913 * this down as both tnl/ and the drivers can raise statechanges
914 * for arcane reasons in the middle of seemingly atomic operations
915 * like DrawElements, over which we'd like to keep a known set of
916 * arrays and vbo's mapped.
917 *
918 * Luckily, neither the drivers nor tnl muck with the state that
919 * concerns us here:
920 */
921 new_state &= _NEW_ARRAY;
922 if (new_state) {
923 assert(!actx->mapped_vbos);
924 actx->NewState |= new_state;
925 }
926 }
927
928
929 void _mesa_install_arrayelt_vtxfmt(struct _glapi_table *disp,
930 const GLvertexformat *vfmt)
931 {
932 SET_ArrayElement(disp, vfmt->ArrayElement);
933 }
934
935
936 #endif /* FEATURE_arrayelt */