another checkpoint of struct immediate replacement code
[mesa.git] / src / mesa / tnl / t_vtx_api.c
1 /* $XFree86$ */
2 /**************************************************************************
3
4 Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
5
6 All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 on the rights to use, copy, modify, merge, publish, distribute, sub
12 license, and/or sell copies of the Software, and to permit persons to whom
13 the Software is furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice (including the next
16 paragraph) shall be included in all copies or substantial portions of the
17 Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Keith Whitwell <keith@tungstengraphics.com>
32 */
33 #include "mtypes.h"
34 #include "colormac.h"
35 #include "simple_list.h"
36 #include "vtxfmt.h"
37
38 #include "tnl_vtx_api.h"
39
40 /* Fallback versions of all the entrypoints for situations where
41 * codegen isn't available. This is slowed significantly by all the
42 * gumph necessary to get to the tnl pointer.
43 */
44
45
46 /* MultiTexcoord ends up with both of these branches, unfortunately
47 * (it may get its own version of the macro after size-tracking is
48 * working).
49 *
50 * Errors (VertexAttribNV when ATTR>15) are handled at a higher level.
51 */
52 #define ATTRF( ATTR, N, A, B, C, D ) \
53 { \
54 GET_CURRENT_CONTEXT( ctx ); \
55 TNLcontext *tnl = TNL_CONTEXT(ctx); \
56 \
57 if ((ATTR) == 0) { \
58 int i; \
59 \
60 if (N>0) tnl->vbptr[0].f = A; \
61 if (N>1) tnl->vbptr[1].f = B; \
62 if (N>2) tnl->vbptr[2].f = C; \
63 if (N>3) tnl->vbptr[3].f = D; \
64 \
65 for (i = N; i < tnl->vertex_size; i++) \
66 *tnl->vbptr[i].i = tnl->vertex[i].i; \
67 \
68 tnl->vbptr += tnl->vertex_size; \
69 \
70 if (--tnl->counter == 0) \
71 tnl->notify(); \
72 } \
73 else { \
74 GLfloat *dest = tnl->attrptr[ATTR]; \
75 if (N>0) dest[0] = A; \
76 if (N>1) dest[1] = B; \
77 if (N>2) dest[2] = C; \
78 if (N>3) dest[3] = D; \
79 } \
80 }
81
82 #define ATTR4F( ATTR, A, B, C, D ) ATTRF( ATTR, 4, A, B, C, D )
83 #define ATTR3F( ATTR, A, B, C, D ) ATTRF( ATTR, 3, A, B, C, 1 )
84 #define ATTR2F( ATTR, A, B, C, D ) ATTRF( ATTR, 2, A, B, 0, 1 )
85 #define ATTR1F( ATTR, A, B, C, D ) ATTRF( ATTR, 1, A, 0, 0, 1 )
86
87 #define ATTR3UB( ATTR, A, B, C ) \
88 ATTR3F( ATTR, \
89 UBYTE_TO_FLOAT(A), \
90 UBYTE_TO_FLOAT(B), \
91 UBYTE_TO_FLOAT(C))
92
93
94 #define ATTR4UB( ATTR, A, B, C, D ) \
95 ATTR4F( ATTR, \
96 UBYTE_TO_FLOAT(A), \
97 UBYTE_TO_FLOAT(B), \
98 UBYTE_TO_FLOAT(C), \
99 UBYTE_TO_FLOAT(D))
100
101
102 /* Vertex
103 */
104 static void tnl_Vertex2f( GLfloat x, GLfloat y )
105 {
106 ATTR2F( VERT_ATTRIB_POS, x, y );
107 }
108
109 static void tnl_Vertex2fv( const GLfloat *v )
110 {
111 ATTR2F( VERT_ATTRIB_POS, v[0], v[1] );
112 }
113
114 static void tnl_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
115 {
116 ATTR3F( VERT_ATTRIB_POS, x, y, z );
117 }
118
119 static void tnl_Vertex3fv( const GLfloat *v )
120 {
121 ATTR3F( VERT_ATTRIB_POS, v[0], v[1], v[2] );
122 }
123
124 static void tnl_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
125 {
126 ATTR4F( VERT_ATTRIB_POS, x, y, z, w );
127 }
128
129 static void tnl_Vertex4fv( const GLfloat *v )
130 {
131 ATTR4F( VERT_ATTRIB_POS, v[0], v[1], v[2], v[3] );
132 }
133
134
135 /* Color
136 */
137 static void tnl_Color3ub( GLubyte r, GLubyte g, GLubyte b )
138 {
139 ATTR3UB( VERT_ATTRIB_COLOR0, r, g, b );
140 }
141
142 static void tnl_Color3ubv( const GLubyte *v )
143 {
144 ATTR3UB( VERT_ATTRIB_COLOR0, v[0], v[1], v[2] );
145 }
146
147 static void tnl_Color4ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
148 {
149 ATTR4UB( VERT_ATTRIB_COLOR0, r, g, b, a );
150 }
151
152 static void tnl_Color4ubv( const GLubyte *v )
153 {
154 ATTR4UB( VERT_ATTRIB_COLOR0, v[0], v[1], v[2], v[3] );
155 }
156
157 static void tnl_Color3f( GLfloat r, GLfloat g, GLfloat b )
158 {
159 ATTR3F( VERT_ATTRIB_COLOR0, r, g, b );
160 }
161
162 static void tnl_Color3fv( const GLfloat *v )
163 {
164 ATTR3F( VERT_ATTRIB_COLOR0, v[0], v[1], v[2] );
165 }
166
167 static void tnl_Color4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
168 {
169 ATTR4F( VERT_ATTRIB_COLOR0, r, g, b, a );
170 }
171
172 static void tnl_Color4fv( const GLfloat *v )
173 {
174 ATTR4F( VERT_ATTRIB_COLOR0, v[0], v[1], v[2], v[3] );
175 }
176
177
178 /* Secondary Color
179 */
180 static void tnl_SecondaryColor3ubEXT( GLubyte r, GLubyte g, GLubyte b )
181 {
182 ATTR3UB( VERT_ATTRIB_COLOR1, r, g, b );
183 }
184
185 static void tnl_SecondaryColor3ubvEXT( const GLubyte *v )
186 {
187 ATTR3UB( VERT_ATTRIB_COLOR1, v[0], v[1], v[2] );
188 }
189
190 static void tnl_SecondaryColor3fEXT( GLfloat r, GLfloat g, GLfloat b )
191 {
192 ATTR3F( VERT_ATTRIB_COLOR1, r, g, b );
193 }
194
195 static void tnl_SecondaryColor3fvEXT( const GLfloat *v )
196 {
197 ATTR3F( VERT_ATTRIB_COLOR1, v[0], v[1], v[2] );
198 }
199
200
201
202 /* Fog Coord
203 */
204 static void tnl_FogCoordfEXT( GLfloat f )
205 {
206 ATTR1F( VERT_ATTRIB_FOG, f );
207 }
208
209 static void tnl_FogCoordfvEXT( const GLfloat *v )
210 {
211 ATTR1F( VERT_ATTRIB_FOG, v[0] );
212 }
213
214
215
216 /* Normal
217 */
218 static void tnl_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 )
219 {
220 ATTR3F( VERT_ATTRIB_NORMAL, n0, n1, n2 );
221 }
222
223 static void tnl_Normal3fv( const GLfloat *v )
224 {
225 ATTR3F( VERT_ATTRIB_COLOR1, v[0], v[1], v[2] );
226 }
227
228
229 /* TexCoord
230 */
231 static void tnl_TexCoord1f( GLfloat s )
232 {
233 ATTR1F( VERT_ATTRIB_TEX0, s );
234 }
235
236 static void tnl_TexCoord1fv( const GLfloat *v )
237 {
238 ATTR1F( VERT_ATTRIB_TEX0, v[0] );
239 }
240
241 static void tnl_TexCoord2f( GLfloat s, GLfloat t )
242 {
243 ATTR2F( VERT_ATTRIB_TEX0, s, t );
244 }
245
246 static void tnl_TexCoord2fv( const GLfloat *v )
247 {
248 ATTR2F( VERT_ATTRIB_TEX0, v[0], v[1] );
249 }
250
251 static void tnl_TexCoord3f( GLfloat s, GLfloat t, GLfloat r )
252 {
253 ATTR3F( VERT_ATTRIB_TEX0, s, t, r );
254 }
255
256 static void tnl_TexCoord3fv( const GLfloat *v )
257 {
258 ATTR3F( VERT_ATTRIB_TEX0, v[0], v[1], v[2] );
259 }
260
261 static void tnl_TexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q )
262 {
263 ATTR4F( VERT_ATTRIB_TEX0, s, t, r, q );
264 }
265
266 static void tnl_TexCoord4fv( const GLfloat *v )
267 {
268 ATTR4F( VERT_ATTRIB_TEX0, v[0], v[1], v[2], v[3] );
269 }
270
271
272 /* Miscellaneous:
273 *
274 * These don't alias NV attributes, but still need similar treatment.
275 * Basically these are attributes with numbers greater than 16.
276 */
277 static void tnl_EdgeFlag( GLboolean flag )
278 {
279 GLfloat f = flag ? 1 : 0;
280 ATTR1F( VERT_ATTRIB_EDGEFLAG, f);
281 }
282
283 static void tnl_EdgeFlagv( const GLboolean *flag )
284 {
285 GLfloat f = flag[0] ? 1 : 0;
286 ATTR1F( VERT_ATTRIB_EDGEFLAG, f);
287 }
288
289 static void tnl_Indexi( GLint idx )
290 {
291 ATTR1F( VERT_ATTRIB_INDEX, idx );
292 }
293
294 static void tnl_Indexiv( const GLint *idx )
295 {
296 ATTR1F( VERT_ATTRIB_INDEX, idx );
297 }
298
299 /* Use dispatch switching to build 'ranges' of eval vertices for each
300 * type, avoiding need for flags. (Make
301 * evalcoords/evalpoints/vertices/attr0 mutually exclusive)
302 */
303 static void _tnl_EvalCoord1f( GLfloat u )
304 {
305 ATTR1F( VERT_ATTRIB_POS, u );
306 }
307
308 static void _tnl_EvalCoord1fv( const GLfloat *v )
309 {
310 ATTR1F( VERT_ATTRIB_POS, v[0] );
311 }
312
313 static void _tnl_EvalCoord2f( GLfloat u, GLfloat v )
314 {
315 ATTR2F( VERT_ATTRIB_POS, u, v );
316 }
317
318 static void _tnl_EvalCoord2fv( const GLfloat *v )
319 {
320 ATTR2F( VERT_ATTRIB_POS, v[0], v[1] );
321 }
322
323
324
325 /* Second level dispatch table for MultiTexCoord, Material and
326 * VertexAttribNV.
327 *
328 * Need this because we want to track things like vertex attribute
329 * sizes, presence/otherwise of attribs in recorded vertices, etc, by
330 * manipulating the state of dispatch tables. Need therefore a
331 * dispatch slot for each value of 'index' or 'unit' in VertexAttribNV
332 * and MultiTexCoordARB. Also need a mechnism for keeping this data
333 * consistent with what's coming in via the Vertex/Normal/etc api
334 * above (where aliasing exists with the traditional entrypoints).
335 * Note that MultiTexCoordARB aliases with TexCoord when unit==0.
336 *
337 * Need presence tracking for material components, too, but not size
338 * tracking or help with aliasing. Could move material to seperate
339 * dispatch without the "*4" below, or even do the checks every time.
340 */
341 struct attr_dispatch_tab {
342 void (*tab[32*4])( void );
343 void (*swapped[32*4])( void );
344 int swapcount;
345 int installed_sizes[32];
346 };
347
348 #define DISPATCH_ATTR1F( ATTR, N, )
349 tnl->vb.attr_dispatch
350
351 /* Result at the back end after second dispatch -- could further
352 * specialize for attr zero -- maybe just in the codegen version.
353 */
354 static void tnl_Attr1f( GLint attr, GLfloat s )
355 {
356 ATTR1F( attr, s );
357 }
358
359 static void tnl_Attr1fv( GLint attr, const GLfloat *v )
360 {
361 ATTR1F( attr, v[0] );
362 }
363
364 static void tnl_Attr2f( GLint attr, GLfloat s, GLfloat t )
365 {
366 ATTR2F( attr, s, t );
367 }
368
369 static void tnl_Attr2fv( GLint attr, const GLfloat *v )
370 {
371 ATTR2F( attr, v[0], v[1] );
372 }
373
374 static void tnl_Attr3f( GLint attr, GLfloat s, GLfloat t, GLfloat r )
375 {
376 ATTR3F( attr, s, t, r );
377 }
378
379 static void tnl_Attr3fv( GLint attr, const GLfloat *v )
380 {
381 ATTR3F( attr, v[0], v[1], v[2] );
382 }
383
384 static void tnl_Attr4f( GLint attr, GLfloat s, GLfloat t, GLfloat r, GLfloat q )
385 {
386 ATTR4F( attr, s, t, r, q );
387 }
388
389 static void tnl_Attr4fv( GLint attr, const GLfloat *v )
390 {
391 ATTR4F( attr, v[0], v[1], v[2], v[3] );
392 }
393
394
395 /* MultiTexcoord: Send through second level dispatch.
396 */
397 static void tnl_MultiTexCoord1fARB( GLenum target, GLfloat s )
398 {
399 GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
400 if (attr < MAX_VERT_ATTRS)
401 DISPATCH_ATTR1F( attr, s );
402 }
403
404 static void tnl_MultiTexCoord1fvARB( GLenum target, const GLfloat *v )
405 {
406 GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
407 if (attr < MAX_VERT_ATTRS)
408 DISPATCH_ATTR1F( attr, v[0] );
409 }
410
411 static void tnl_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t )
412 {
413 GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
414 if (attr < MAX_VERT_ATTRS)
415 DISPATCH_ATTR2F( attr, s, t );
416 }
417
418 static void tnl_MultiTexCoord2fvARB( GLenum target, const GLfloat *v )
419 {
420 GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
421 if (attr < MAX_VERT_ATTRS)
422 DISPATCH_ATTR2F( attr, v[0], v[1] );
423 }
424
425 static void tnl_MultiTexCoord3fARB( GLenum target, GLfloat s, GLfloat t,
426 GLfloat r)
427 {
428 GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
429 if (attr < MAX_VERT_ATTRS)
430 DISPATCH_ATTR3F( attr, s, t, r );
431 }
432
433 static void tnl_MultiTexCoord3fvARB( GLenum target, const GLfloat *v )
434 {
435 GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
436 if (attr < MAX_VERT_ATTRS)
437 DISPATCH_ATTR3F( attr, v[0], v[1], v[2] );
438 }
439
440 static void tnl_MultiTexCoord4fARB( GLenum target, GLfloat s, GLfloat t,
441 GLfloat r, GLfloat q )
442 {
443 GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
444 if (attr < MAX_VERT_ATTRS)
445 DISPATCH_ATTR4F( attr, s, t, r, q );
446 }
447
448 static void tnl_MultiTexCoord4fvARB( GLenum target, const GLfloat *v )
449 {
450 GLuint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
451 if (attr < MAX_VERT_ATTRS)
452 DISPATCH_ATTR4F( attr, v[0], v[1], v[2], v[3] );
453 }
454
455
456 /* NV_vertex_program:
457 *
458 * Check for errors & reroute through second dispatch layer to get
459 * size tracking per-attribute.
460 */
461 static void tnl_VertexAttrib1fNV( GLuint index, GLfloat s )
462 {
463 if (index < MAX_VERT_ATTRS)
464 DISPATCH_ATTR1F( index, s );
465 else
466 DISPATCH_ERROR;
467 }
468
469 static void tnl_VertexAttrib1fvNV( GLuint index, const GLfloat *v )
470 {
471 if (index < MAX_VERT_ATTRS)
472 DISPATCH_ATTR1F( index, v[0] );
473 else
474 DISPATCH_ERROR;
475 }
476
477 static void tnl_VertexAttrib2fNV( GLuint index, GLfloat s, GLfloat t )
478 {
479 if (index < MAX_VERT_ATTRS)
480 DISPATCH_ATTR2F( index, s, t );
481 else
482 DISPATCH_ERROR;
483 }
484
485 static void tnl_VertexAttrib2fvNV( GLuint index, const GLfloat *v )
486 {
487 if (index < MAX_VERT_ATTRS)
488 DISPATCH_ATTR2F( index, v[0], v[1] );
489 else
490 DISPATCH_ERROR;
491 }
492
493 static void tnl_VertexAttrib3fNV( GLuint index, GLfloat s, GLfloat t,
494 GLfloat r )
495 {
496 if (index < MAX_VERT_ATTRS)
497 DISPATCH_ATTR3F( index, s, t, r );
498 else
499 DISPATCH_ERROR;
500 }
501
502 static void tnl_VertexAttrib3fvNV( GLuint index, const GLfloat *v )
503 {
504 if (index < MAX_VERT_ATTRS)
505 DISPATCH_ATTR3F( index, v[0], v[1], v[2] );
506 else
507 DISPATCH_ERROR;
508 }
509
510 static void tnl_VertexAttrib4fNV( GLuint index, GLfloat s, GLfloat t,
511 GLfloat r, GLfloat q )
512 {
513 if (index < MAX_VERT_ATTRS)
514 DISPATCH_ATTR4F( index, s, t, r, q );
515 else
516 DISPATCH_ERROR;
517 }
518
519 static void tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
520 {
521 if (index < MAX_VERT_ATTRS)
522 DISPATCH_ATTR4F( index, v[0], v[1], v[2], v[3] );
523 else
524 DISPATCH_ERROR;
525 }
526
527
528
529
530
531
532
533 /* Materials:
534 *
535 * These are treated as per-vertex attributes, at indices above where
536 * the NV_vertex_program leaves off. There are a lot of good things
537 * about treating materials this way.
538 *
539 * *** Need a dispatch step (like VertexAttribute GLint attr, and MultiTexCoord)
540 * *** to expand vertex size, etc. Use the same second level dispatch
541 * *** (keyed by attr number) as above.
542 */
543 #define MAT( ATTR, face, params ) \
544 do { \
545 if (face != GL_BACK) \
546 DISPATCH_ATTRF( ATTR, N, params ); \
547 if (face != GL_FRONT) \
548 DISPATCH_ATTRF( ATTR+7, N, params ); \
549 } while (0)
550
551
552 /* NOTE: Have to remove/dealwith colormaterial crossovers, probably
553 * later on - in the meantime just store everything.
554 */
555 static void _tnl_Materialfv( GLenum face, GLenum pname,
556 const GLfloat *params )
557 {
558 switch (pname) {
559 case GL_EMISSION:
560 MAT( VERT_ATTRIB_FRONT_EMMISSION, 4, face, params );
561 break;
562 case GL_AMBIENT:
563 MAT( VERT_ATTRIB_FRONT_AMBIENT, 4, face, params );
564 break;
565 case GL_DIFFUSE:
566 MAT( VERT_ATTRIB_FRONT_DIFFUSE, 4, face, params );
567 break;
568 case GL_SPECULAR:
569 MAT( VERT_ATTRIB_FRONT_SPECULAR, 4, face, params );
570 break;
571 case GL_SHININESS:
572 MAT( VERT_ATTRIB_FRONT_SHININESS, 1, face, params );
573 break;
574 case GL_COLOR_INDEXES:
575 MAT( VERT_ATTRIB_FRONT_EMMISSION, 3, face, params );
576 break;
577 case GL_AMBIENT_AND_DIFFUSE:
578 MAT( VERT_ATTRIB_FRONT_AMBIENT, 4, face, params );
579 MAT( VERT_ATTRIB_FRONT_DIFFUSE, 4, face, params );
580 break;
581 default:
582 _mesa_error( ctx, GL_INVALID_ENUM, where );
583 return;
584 }
585 }
586
587
588
589
590 /* Codegen support
591 */
592 static struct dynfn *lookup( struct dynfn *l, int key )
593 {
594 struct dynfn *f;
595
596 foreach( f, l ) {
597 if (f->key == key)
598 return f;
599 }
600
601 return 0;
602 }
603
604 /* Vertex descriptor
605 */
606 struct _tnl_vertex_descriptor {
607 GLuint attr_bits[4];
608 };
609
610
611 /* Can't use the loopback template for this:
612 */
613 #define CHOOSE(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 ) \
614 static void choose_##FN ARGS1 \
615 { \
616 int key = tnl->vertex_format & (MASK|ACTIVE); \
617 struct dynfn *dfn = lookup( &tnl->dfn_cache.FN, key ); \
618 \
619 if (dfn == 0) \
620 dfn = tnl->codegen.FN( &vb, key ); \
621 else if (MESA_VERBOSE & DEBUG_CODEGEN) \
622 fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \
623 \
624 if (dfn) \
625 tnl->context->Exec->FN = (FNTYPE)(dfn->code); \
626 else { \
627 if (MESA_VERBOSE & DEBUG_CODEGEN) \
628 fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
629 tnl->context->Exec->FN = tnl_##FN; \
630 } \
631 \
632 tnl->context->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
633 tnl->context->Exec->FN ARGS2; \
634 }
635
636
637
638 CHOOSE(Normal3f, p3f, 3, VERT_ATTRIB_NORMAL,
639 (GLfloat a,GLfloat b,GLfloat c), (a,b,c))
640 CHOOSE(Normal3fv, pfv, 3, VERT_ATTRIB_NORMAL,
641 (const GLfloat *v), (v))
642
643 CHOOSE(Color4ub, p4ub, 4, VERT_ATTRIB_COLOR0,
644 (GLubyte a,GLubyte b, GLubyte c, GLubyte d), (a,b,c,d))
645 CHOOSE(Color4ubv, pubv, 4, VERT_ATTRIB_COLOR0,
646 (const GLubyte *v), (v))
647 CHOOSE(Color3ub, p3ub, 3, VERT_ATTRIB_COLOR0,
648 (GLubyte a,GLubyte b, GLubyte c), (a,b,c))
649 CHOOSE(Color3ubv, pubv, 3, VERT_ATTRIB_COLOR0,
650 (const GLubyte *v), (v))
651
652 CHOOSE(Color4f, p4f, 4, VERT_ATTRIB_COLOR0,
653 (GLfloat a,GLfloat b, GLfloat c, GLfloat d), (a,b,c,d))
654 CHOOSE(Color4fv, pfv, 4, VERT_ATTRIB_COLOR0,
655 (const GLfloat *v), (v))
656 CHOOSE(Color3f, p3f, 3, VERT_ATTRIB_COLOR0,
657 (GLfloat a,GLfloat b, GLfloat c), (a,b,c))
658 CHOOSE(Color3fv, pfv, 3, VERT_ATTRIB_COLOR0,
659 (const GLfloat *v), (v))
660
661
662 CHOOSE(SecondaryColor3ubEXT, p3ub, VERT_ATTRIB_COLOR1,
663 (GLubyte a,GLubyte b, GLubyte c), (a,b,c))
664 CHOOSE(SecondaryColor3ubvEXT, pubv, VERT_ATTRIB_COLOR1,
665 (const GLubyte *v), (v))
666 CHOOSE(SecondaryColor3fEXT, p3f, VERT_ATTRIB_COLOR1,
667 (GLfloat a,GLfloat b, GLfloat c), (a,b,c))
668 CHOOSE(SecondaryColor3fvEXT, pfv, VERT_ATTRIB_COLOR1,
669 (const GLfloat *v), (v))
670
671 CHOOSE(TexCoord2f, p2f, VERT_ATTRIB_TEX0,
672 (GLfloat a,GLfloat b), (a,b))
673 CHOOSE(TexCoord2fv, pfv, VERT_ATTRIB_TEX0,
674 (const GLfloat *v), (v))
675 CHOOSE(TexCoord1f, p1f, VERT_ATTRIB_TEX0,
676 (GLfloat a), (a))
677 CHOOSE(TexCoord1fv, pfv, VERT_ATTRIB_TEX0,
678 (const GLfloat *v), (v))
679
680 CHOOSE(MultiTexCoord2fARB, pe2f, VERT_ATTRIB_TEX0,
681 (GLenum u,GLfloat a,GLfloat b), (u,a,b))
682 CHOOSE(MultiTexCoord2fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL,
683 (GLenum u,const GLfloat *v), (u,v))
684 CHOOSE(MultiTexCoord1fARB, pe1f, MASK_ST_ALL, ACTIVE_ST_ALL,
685 (GLenum u,GLfloat a), (u,a))
686 CHOOSE(MultiTexCoord1fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL,
687 (GLenum u,const GLfloat *v), (u,v))
688
689 CHOOSE(Vertex3f, p3f, VERT_ATTRIB_POS,
690 (GLfloat a,GLfloat b,GLfloat c), (a,b,c))
691 CHOOSE(Vertex3fv, pfv, VERT_ATTRIB_POS,
692 (const GLfloat *v), (v))
693 CHOOSE(Vertex2f, p2f, VERT_ATTRIB_POS,
694 (GLfloat a,GLfloat b), (a,b))
695 CHOOSE(Vertex2fv, pfv, VERT_ATTRIB_POS,
696 (const GLfloat *v), (v))
697
698
699
700
701
702 void _tnl_InitVtxfmtChoosers( GLvertexformat *vfmt )
703 {
704 vfmt->Color3f = choose_Color3f;
705 vfmt->Color3fv = choose_Color3fv;
706 vfmt->Color3ub = choose_Color3ub;
707 vfmt->Color3ubv = choose_Color3ubv;
708 vfmt->Color4f = choose_Color4f;
709 vfmt->Color4fv = choose_Color4fv;
710 vfmt->Color4ub = choose_Color4ub;
711 vfmt->Color4ubv = choose_Color4ubv;
712 vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT;
713 vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT;
714 vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT;
715 vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT;
716 vfmt->MultiTexCoord1fARB = dd_MultiTexCoord1fARB;
717 vfmt->MultiTexCoord1fvARB = dd_MultiTexCoord1fvARB;
718 vfmt->MultiTexCoord2fARB = dd_MultiTexCoord2fARB;
719 vfmt->MultiTexCoord2fvARB = dd_MultiTexCoord2fvARB;
720 vfmt->MultiTexCoord3fARB = dd_MultiTexCoord3fARB;
721 vfmt->MultiTexCoord3fvARB = dd_MultiTexCoord3fvARB;
722 vfmt->MultiTexCoord4fARB = dd_MultiTexCoord4fARB;
723 vfmt->MultiTexCoord4fvARB = dd_MultiTexCoord4fvARB;
724 vfmt->Normal3f = choose_Normal3f;
725 vfmt->Normal3fv = choose_Normal3fv;
726 vfmt->TexCoord1f = choose_TexCoord1f;
727 vfmt->TexCoord1fv = choose_TexCoord1fv;
728 vfmt->TexCoord2f = choose_TexCoord2f;
729 vfmt->TexCoord2fv = choose_TexCoord2fv;
730 vfmt->TexCoord3f = choose_TexCoord3f;
731 vfmt->TexCoord3fv = choose_TexCoord3fv;
732 vfmt->TexCoord4f = choose_TexCoord4f;
733 vfmt->TexCoord4fv = choose_TexCoord4fv;
734 vfmt->Vertex2f = choose_Vertex2f;
735 vfmt->Vertex2fv = choose_Vertex2fv;
736 vfmt->Vertex3f = choose_Vertex3f;
737 vfmt->Vertex3fv = choose_Vertex3fv;
738 vfmt->Vertex4f = choose_Vertex4f;
739 vfmt->Vertex4fv = choose_Vertex4fv;
740 vfmt->FogCoordfvEXT = choose_FogCoordfvEXT;
741 vfmt->FogCoordfEXT = choose_FogCoordfEXT;
742 vfmt->EdgeFlag = choose_EdgeFlag;
743 vfmt->EdgeFlagv = choose_EdgeFlagv;
744 vfmt->Indexi = choose_Indexi;
745 vfmt->Indexiv = choose_Indexiv;
746 vfmt->EvalCoord1f = choose_EvalCoord1f;
747 vfmt->EvalCoord1fv = choose_EvalCoord1fv;
748 vfmt->EvalCoord2f = choose_EvalCoord2f;
749 vfmt->EvalCoord2fv = choose_EvalCoord2fv;
750 vfmt->Materialfv = dd_Materialfv;
751 }
752
753
754 static struct dynfn *codegen_noop( struct _vb *vb, int key )
755 {
756 (void) vb; (void) key;
757 return 0;
758 }
759
760 void _tnl_InitCodegen( struct dfn_generators *gen )
761 {
762 /* Generate an attribute or vertex command.
763 */
764 gen->Attr1f = codegen_noop;
765 gen->Attr1fv = codegen_noop;
766 gen->Attr2f = codegen_noop;
767 gen->Attr2fv = codegen_noop;
768 gen->Attr3f = codegen_noop;
769 gen->Attr3fv = codegen_noop;
770 gen->Attr4f = codegen_noop;
771 gen->Attr4fv = codegen_noop;
772
773 /* Index is never zero for these...
774 */
775 gen->Attr3ub = codegen_noop;
776 gen->Attr3ubv = codegen_noop;
777 gen->Attr4ub = codegen_noop;
778 gen->Attr4ubv = codegen_noop;
779
780 /* As above, but deal with the extra (redundant by now) index
781 * argument to the generated function.
782 */
783 gen->NVAttr1f = codegen_noop;
784 gen->NVAttr1fv = codegen_noop;
785 gen->NVAttr2f = codegen_noop;
786 gen->NVAttr2fv = codegen_noop;
787 gen->NVAttr3f = codegen_noop;
788 gen->NVAttr3fv = codegen_noop;
789 gen->NVAttr4f = codegen_noop;
790 gen->NVAttr4fv = codegen_noop;
791
792
793 if (!getenv("MESA_NO_CODEGEN")) {
794 #if defined(USE_X86_ASM)
795 _tnl_InitX86Codegen( gen );
796 #endif
797
798 #if defined(USE_SSE_ASM)
799 _tnl_InitSSECodegen( gen );
800 #endif
801
802 #if defined(USE_3DNOW_ASM)
803 #endif
804
805 #if defined(USE_SPARC_ASM)
806 #endif
807 }
808 }