Core of the future vertex engine. Isn't built yet, nor will be for a while...
[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 its own version of the macro after size-tracking is working).
48 */
49 #define ATTRF( ATTR, N, A, B, C, D ) \
50 { \
51 GET_CURRENT_CONTEXT( ctx ); \
52 TNLcontext *tnl = TNL_CONTEXT(ctx); \
53 \
54 if (((ATTR) & 0xf) == 0) { \
55 int i; \
56 \
57 if (N>0) tnl->dmaptr[0].f = A; \
58 if (N>1) tnl->dmaptr[1].f = B; \
59 if (N>2) tnl->dmaptr[2].f = C; \
60 if (N>3) tnl->dmaptr[3].f = D; \
61 \
62 for (i = N; i < tnl->vertex_size; i++) \
63 *tnl->dmaptr[i].i = tnl->vertex[i].i; \
64 \
65 tnl->dmaptr += tnl->vertex_size; \
66 \
67 if (--tnl->counter == 0) \
68 tnl->notify(); \
69 } \
70 else { \
71 GLfloat *dest = tnl->attrptr[(ATTR) & 0xf]; \
72 if (N>0) dest[0] = A; \
73 if (N>1) dest[1] = B; \
74 if (N>2) dest[2] = C; \
75 if (N>3) dest[3] = D; \
76 } \
77 }
78
79 #define ATTR4F( ATTR, A, B, C, D ) ATTRF( ATTR, 4, A, B, C, D )
80 #define ATTR3F( ATTR, A, B, C, D ) ATTRF( ATTR, 3, A, B, C, 1 )
81 #define ATTR2F( ATTR, A, B, C, D ) ATTRF( ATTR, 2, A, B, 0, 1 )
82 #define ATTR1F( ATTR, A, B, C, D ) ATTRF( ATTR, 1, A, 0, 0, 1 )
83
84 #define ATTR3UB( ATTR, A, B, C ) \
85 ATTR3F( ATTR, \
86 UBYTE_TO_FLOAT(A), \
87 UBYTE_TO_FLOAT(B), \
88 UBYTE_TO_FLOAT(C))
89
90
91 #define ATTR4UB( ATTR, A, B, C, D ) \
92 ATTR4F( ATTR, \
93 UBYTE_TO_FLOAT(A), \
94 UBYTE_TO_FLOAT(B), \
95 UBYTE_TO_FLOAT(C), \
96 UBYTE_TO_FLOAT(D))
97
98
99 /* Vertex
100 */
101 static void tnl_Vertex2f( GLfloat x, GLfloat y )
102 {
103 ATTR2F( VERT_ATTRIB_POS, x, y );
104 }
105
106 static void tnl_Vertex2fv( const GLfloat *v )
107 {
108 ATTR2F( VERT_ATTRIB_POS, v[0], v[1] );
109 }
110
111 static void tnl_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
112 {
113 ATTR3F( VERT_ATTRIB_POS, x, y, z );
114 }
115
116 static void tnl_Vertex3fv( const GLfloat *v )
117 {
118 ATTR3F( VERT_ATTRIB_POS, v[0], v[1], v[2] );
119 }
120
121 static void tnl_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
122 {
123 ATTR4F( VERT_ATTRIB_POS, x, y, z, w );
124 }
125
126 static void tnl_Vertex4fv( const GLfloat *v )
127 {
128 ATTR4F( VERT_ATTRIB_POS, v[0], v[1], v[2], v[3] );
129 }
130
131
132 /* Color
133 */
134 static void tnl_Color3ub( GLubyte r, GLubyte g, GLubyte b )
135 {
136 ATTR3UB( VERT_ATTRIB_COLOR0, r, g, b );
137 }
138
139 static void tnl_Color3ubv( const GLubyte *v )
140 {
141 ATTR3UB( VERT_ATTRIB_COLOR0, v[0], v[1], v[2] );
142 }
143
144 static void tnl_Color4ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
145 {
146 ATTR4UB( VERT_ATTRIB_COLOR0, r, g, b, a );
147 }
148
149 static void tnl_Color4ubv( const GLubyte *v )
150 {
151 ATTR4UB( VERT_ATTRIB_COLOR0, v[0], v[1], v[2], v[3] );
152 }
153
154 static void tnl_Color3f( GLfloat r, GLfloat g, GLfloat b )
155 {
156 ATTR3F( VERT_ATTRIB_COLOR0, r, g, b );
157 }
158
159 static void tnl_Color3fv( const GLfloat *v )
160 {
161 ATTR3F( VERT_ATTRIB_COLOR0, v[0], v[1], v[2] );
162 }
163
164 static void tnl_Color4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
165 {
166 ATTR4F( VERT_ATTRIB_COLOR0, r, g, b, a );
167 }
168
169 static void tnl_Color4fv( const GLfloat *v )
170 {
171 ATTR4F( VERT_ATTRIB_COLOR0, v[0], v[1], v[2], v[3] );
172 }
173
174
175 /* Secondary Color
176 */
177 static void tnl_SecondaryColor3ubEXT( GLubyte r, GLubyte g, GLubyte b )
178 {
179 ATTR3UB( VERT_ATTRIB_COLOR1, r, g, b );
180 }
181
182 static void tnl_SecondaryColor3ubvEXT( const GLubyte *v )
183 {
184 ATTR3UB( VERT_ATTRIB_COLOR1, v[0], v[1], v[2] );
185 }
186
187 static void tnl_SecondaryColor3fEXT( GLfloat r, GLfloat g, GLfloat b )
188 {
189 ATTR3F( VERT_ATTRIB_COLOR1, r, g, b );
190 }
191
192 static void tnl_SecondaryColor3fvEXT( const GLfloat *v )
193 {
194 ATTR3F( VERT_ATTRIB_COLOR1, v[0], v[1], v[2] );
195 }
196
197
198
199 /* Fog Coord
200 */
201 static void tnl_FogCoordfEXT( GLfloat f )
202 {
203 ATTR1F( VERT_ATTRIB_FOG, f );
204 }
205
206 static void tnl_FogCoordfvEXT( const GLfloat *v )
207 {
208 ATTR1F( VERT_ATTRIB_FOG, v[0] );
209 }
210
211
212
213 /* Normal
214 */
215 static void tnl_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 )
216 {
217 ATTR3F( VERT_ATTRIB_NORMAL, n0, n1, n2 );
218 }
219
220 static void tnl_Normal3fv( const GLfloat *v )
221 {
222 ATTR3F( VERT_ATTRIB_COLOR1, v[0], v[1], v[2] );
223 }
224
225
226 /* TexCoord
227 */
228 static void tnl_TexCoord1f( GLfloat s )
229 {
230 ATTR1F( VERT_ATTRIB_TEX0, s );
231 }
232
233 static void tnl_TexCoord1fv( const GLfloat *v )
234 {
235 ATTR1F( VERT_ATTRIB_TEX0, v[0] );
236 }
237
238 static void tnl_TexCoord2f( GLfloat s, GLfloat t )
239 {
240 ATTR2F( VERT_ATTRIB_TEX0, s, t );
241 }
242
243 static void tnl_TexCoord2fv( const GLfloat *v )
244 {
245 ATTR2F( VERT_ATTRIB_TEX0, v[0], v[1] );
246 }
247
248 static void tnl_TexCoord3f( GLfloat s, GLfloat t, GLfloat r )
249 {
250 ATTR3F( VERT_ATTRIB_TEX0, s, t, r );
251 }
252
253 static void tnl_TexCoord3fv( const GLfloat *v )
254 {
255 ATTR3F( VERT_ATTRIB_TEX0, v[0], v[1], v[2] );
256 }
257
258 static void tnl_TexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q )
259 {
260 ATTR4F( VERT_ATTRIB_TEX0, s, t, r, q );
261 }
262
263 static void tnl_TexCoord4fv( const GLfloat *v )
264 {
265 ATTR4F( VERT_ATTRIB_TEX0, v[0], v[1], v[2], v[3] );
266 }
267
268
269 /* MultiTexcoord
270 */
271 static void tnl_MultiTexCoord1fARB( GLenum target, GLfloat s )
272 {
273 GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
274 ATTR1F( attr, s );
275 }
276
277 static void tnl_MultiTexCoord1fvARB( GLenum target, const GLfloat *v )
278 {
279 GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
280 ATTR1F( attr, v[0] );
281 }
282
283 static void tnl_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t )
284 {
285 GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
286 ATTR2F( attr, s, t );
287 }
288
289 static void tnl_MultiTexCoord2fvARB( GLenum target, const GLfloat *v )
290 {
291 GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
292 ATTR2F( attr, v[0], v[1] );
293 }
294
295 static void tnl_MultiTexCoord3fARB( GLenum target, GLfloat s, GLfloat t,
296 GLfloat r)
297 {
298 GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
299 ATTR3F( attr, s, t, r );
300 }
301
302 static void tnl_MultiTexCoord3fvARB( GLenum target, const GLfloat *v )
303 {
304 GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
305 ATTR3F( attr, v[0], v[1], v[2] );
306 }
307
308 static void tnl_MultiTexCoord4fARB( GLenum target, GLfloat s, GLfloat t,
309 GLfloat r, GLfloat q )
310 {
311 GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
312 ATTR4F( attr, s, t, r, q );
313 }
314
315 static void tnl_MultiTexCoord4fvARB( GLenum target, const GLfloat *v )
316 {
317 GLint attr = (target - GL_TEXTURE0_ARB) + VERT_ATTRIB_TEX0;
318 ATTR4F( attr, v[0], v[1], v[2], v[3] );
319 }
320
321
322 /* NV_vertex_program:
323 *
324 * *** Need second dispatch layer above this for size tracking. One
325 * *** dispatch layer handles both VertexAttribute and MultiTexCoord
326 */
327 static void tnl_VertexAttrib1fNV( GLuint index, GLfloat s )
328 {
329 ATTR1F( index, s );
330 }
331
332 static void tnl_VertexAttrib1fvNV( GLuint index, const GLfloat *v )
333 {
334 ATTR1F( index, v[0] );
335 }
336
337 static void tnl_VertexAttrib2fNV( GLuint index, GLfloat s, GLfloat t )
338 {
339 ATTR2F( index, s, t );
340 }
341
342 static void tnl_VertexAttrib2fvNV( GLuint index, const GLfloat *v )
343 {
344 ATTR2F( index, v[0], v[1] );
345 }
346
347 static void tnl_VertexAttrib3fNV( GLuint index, GLfloat s, GLfloat t,
348 GLfloat r )
349 {
350 ATTR3F( index, s, t, r );
351 }
352
353 static void tnl_VertexAttrib3fvNV( GLuint index, const GLfloat *v )
354 {
355 ATTR3F( index, v[0], v[1], v[2] );
356 }
357
358 static void tnl_VertexAttrib4fNV( GLuint index, GLfloat s, GLfloat t,
359 GLfloat r, GLfloat q )
360 {
361 ATTR4F( index, s, t, r, q );
362 }
363
364 static void tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
365 {
366 ATTR4F( index, v[0], v[1], v[2], v[3] );
367 }
368
369
370 /* Miscellaneous: (These don't alias NV attributes, right?)
371 */
372 static void tnl_EdgeFlag( GLboolean flag )
373 {
374 GET_TNL;
375 tnl->edgeflagptr[0] = flag;
376 }
377
378 static void tnl_EdgeFlagv( const GLboolean *flag )
379 {
380 GET_TNL;
381 tnl->edgeflagptr[0] = *flag;
382 }
383
384 static void tnl_Indexi( GLint idx )
385 {
386 GET_TNL;
387 tnl->indexptr[0] = idx;
388 }
389
390 static void tnl_Indexiv( const GLint *idx )
391 {
392 GET_TNL;
393 tnl->indexptr[0] = *idx;
394 }
395
396
397
398 /* Could use dispatch switching to build 'ranges' of eval vertices for
399 * each type, avoiding need for flags. (Make
400 * evalcoords/evalpoints/vertices/attr0 mutually exclusive)
401 * --> In which case, may as well use Vertex{12}f{v} here.
402 */
403 static void _tnl_EvalCoord1f( GLfloat u )
404 {
405 ATTR1F( VERT_ATTRIB_POS, u );
406 }
407
408 static void _tnl_EvalCoord1fv( const GLfloat *v )
409 {
410 ATTR1F( VERT_ATTRIB_POS, v[0] );
411 }
412
413 static void _tnl_EvalCoord2f( GLfloat u, GLfloat v )
414 {
415 ATTR2F( VERT_ATTRIB_POS, u, v );
416 }
417
418 static void _tnl_EvalCoord2fv( const GLfloat *v )
419 {
420 ATTR2F( VERT_ATTRIB_POS, v[0], v[1] );
421 }
422
423
424 /* Materials:
425 * *** Treat as more vertex attributes
426 */
427 static void _tnl_Materialfv( GLenum face, GLenum pname,
428 const GLfloat *params )
429 {
430 if (MESA_VERBOSE & DEBUG_VFMT)
431 fprintf(stderr, "%s\n", __FUNCTION__);
432
433 if (tnl->prim[0] != GL_POLYGON+1) {
434 VFMT_FALLBACK( __FUNCTION__ );
435 glMaterialfv( face, pname, params );
436 return;
437 }
438 _mesa_noop_Materialfv( face, pname, params );
439 }
440
441
442
443
444 /* Codegen support
445 */
446 static struct dynfn *lookup( struct dynfn *l, int key )
447 {
448 struct dynfn *f;
449
450 foreach( f, l ) {
451 if (f->key == key)
452 return f;
453 }
454
455 return 0;
456 }
457
458 /* Can't use the loopback template for this:
459 */
460 #define CHOOSE(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 ) \
461 static void choose_##FN ARGS1 \
462 { \
463 int key = tnl->vertex_format & (MASK|ACTIVE); \
464 struct dynfn *dfn = lookup( &tnl->dfn_cache.FN, key ); \
465 \
466 if (dfn == 0) \
467 dfn = tnl->codegen.FN( &vb, key ); \
468 else if (MESA_VERBOSE & DEBUG_CODEGEN) \
469 fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \
470 \
471 if (dfn) \
472 tnl->context->Exec->FN = (FNTYPE)(dfn->code); \
473 else { \
474 if (MESA_VERBOSE & DEBUG_CODEGEN) \
475 fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \
476 tnl->context->Exec->FN = tnl_##FN; \
477 } \
478 \
479 tnl->context->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
480 tnl->context->Exec->FN ARGS2; \
481 }
482
483
484
485 CHOOSE(Normal3f, p3f, 3, VERT_ATTRIB_NORMAL,
486 (GLfloat a,GLfloat b,GLfloat c), (a,b,c))
487 CHOOSE(Normal3fv, pfv, 3, VERT_ATTRIB_NORMAL,
488 (const GLfloat *v), (v))
489
490 CHOOSE(Color4ub, p4ub, 4, VERT_ATTRIB_COLOR0,
491 (GLubyte a,GLubyte b, GLubyte c, GLubyte d), (a,b,c,d))
492 CHOOSE(Color4ubv, pubv, 4, VERT_ATTRIB_COLOR0,
493 (const GLubyte *v), (v))
494 CHOOSE(Color3ub, p3ub, 3, VERT_ATTRIB_COLOR0,
495 (GLubyte a,GLubyte b, GLubyte c), (a,b,c))
496 CHOOSE(Color3ubv, pubv, 3, VERT_ATTRIB_COLOR0,
497 (const GLubyte *v), (v))
498
499 CHOOSE(Color4f, p4f, 4, VERT_ATTRIB_COLOR0,
500 (GLfloat a,GLfloat b, GLfloat c, GLfloat d), (a,b,c,d))
501 CHOOSE(Color4fv, pfv, 4, VERT_ATTRIB_COLOR0,
502 (const GLfloat *v), (v))
503 CHOOSE(Color3f, p3f, 3, VERT_ATTRIB_COLOR0,
504 (GLfloat a,GLfloat b, GLfloat c), (a,b,c))
505 CHOOSE(Color3fv, pfv, 3, VERT_ATTRIB_COLOR0,
506 (const GLfloat *v), (v))
507
508
509 CHOOSE(SecondaryColor3ubEXT, p3ub, VERT_ATTRIB_COLOR1,
510 (GLubyte a,GLubyte b, GLubyte c), (a,b,c))
511 CHOOSE(SecondaryColor3ubvEXT, pubv, VERT_ATTRIB_COLOR1,
512 (const GLubyte *v), (v))
513 CHOOSE(SecondaryColor3fEXT, p3f, VERT_ATTRIB_COLOR1,
514 (GLfloat a,GLfloat b, GLfloat c), (a,b,c))
515 CHOOSE(SecondaryColor3fvEXT, pfv, VERT_ATTRIB_COLOR1,
516 (const GLfloat *v), (v))
517
518 CHOOSE(TexCoord2f, p2f, VERT_ATTRIB_TEX0,
519 (GLfloat a,GLfloat b), (a,b))
520 CHOOSE(TexCoord2fv, pfv, VERT_ATTRIB_TEX0,
521 (const GLfloat *v), (v))
522 CHOOSE(TexCoord1f, p1f, VERT_ATTRIB_TEX0,
523 (GLfloat a), (a))
524 CHOOSE(TexCoord1fv, pfv, VERT_ATTRIB_TEX0,
525 (const GLfloat *v), (v))
526
527 CHOOSE(MultiTexCoord2fARB, pe2f, VERT_ATTRIB_TEX0,
528 (GLenum u,GLfloat a,GLfloat b), (u,a,b))
529 CHOOSE(MultiTexCoord2fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL,
530 (GLenum u,const GLfloat *v), (u,v))
531 CHOOSE(MultiTexCoord1fARB, pe1f, MASK_ST_ALL, ACTIVE_ST_ALL,
532 (GLenum u,GLfloat a), (u,a))
533 CHOOSE(MultiTexCoord1fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL,
534 (GLenum u,const GLfloat *v), (u,v))
535
536 CHOOSE(Vertex3f, p3f, VERT_ATTRIB_POS,
537 (GLfloat a,GLfloat b,GLfloat c), (a,b,c))
538 CHOOSE(Vertex3fv, pfv, VERT_ATTRIB_POS,
539 (const GLfloat *v), (v))
540 CHOOSE(Vertex2f, p2f, VERT_ATTRIB_POS,
541 (GLfloat a,GLfloat b), (a,b))
542 CHOOSE(Vertex2fv, pfv, VERT_ATTRIB_POS,
543 (const GLfloat *v), (v))
544
545
546
547
548
549 void _tnl_InitVtxfmtChoosers( GLvertexformat *vfmt )
550 {
551 vfmt->Color3f = choose_Color3f;
552 vfmt->Color3fv = choose_Color3fv;
553 vfmt->Color3ub = choose_Color3ub;
554 vfmt->Color3ubv = choose_Color3ubv;
555 vfmt->Color4f = choose_Color4f;
556 vfmt->Color4fv = choose_Color4fv;
557 vfmt->Color4ub = choose_Color4ub;
558 vfmt->Color4ubv = choose_Color4ubv;
559 vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT;
560 vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT;
561 vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT;
562 vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT;
563 vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB;
564 vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB;
565 vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB;
566 vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB;
567 vfmt->Normal3f = choose_Normal3f;
568 vfmt->Normal3fv = choose_Normal3fv;
569 vfmt->TexCoord1f = choose_TexCoord1f;
570 vfmt->TexCoord1fv = choose_TexCoord1fv;
571 vfmt->TexCoord2f = choose_TexCoord2f;
572 vfmt->TexCoord2fv = choose_TexCoord2fv;
573 vfmt->Vertex2f = choose_Vertex2f;
574 vfmt->Vertex2fv = choose_Vertex2fv;
575 vfmt->Vertex3f = choose_Vertex3f;
576 vfmt->Vertex3fv = choose_Vertex3fv;
577 vfmt->TexCoord3f = choose_TexCoord3f;
578 vfmt->TexCoord3fv = choose_TexCoord3fv;
579 vfmt->TexCoord4f = choose_TexCoord4f;
580 vfmt->TexCoord4fv = choose_TexCoord4fv;
581 vfmt->MultiTexCoord3fARB = choose_MultiTexCoord3fARB;
582 vfmt->MultiTexCoord3fvARB = choose_MultiTexCoord3fvARB;
583 vfmt->MultiTexCoord4fARB = choose_MultiTexCoord4fARB;
584 vfmt->MultiTexCoord4fvARB = choose_MultiTexCoord4fvARB;
585 vfmt->Vertex4f = choose_Vertex4f;
586 vfmt->Vertex4fv = choose_Vertex4fv;
587 vfmt->FogCoordfvEXT = choose_FogCoordfvEXT;
588 vfmt->FogCoordfEXT = choose_FogCoordfEXT;
589 vfmt->EdgeFlag = choose_EdgeFlag;
590 vfmt->EdgeFlagv = choose_EdgeFlagv;
591 vfmt->Indexi = choose_Indexi;
592 vfmt->Indexiv = choose_Indexiv;
593 vfmt->EvalCoord1f = choose_EvalCoord1f;
594 vfmt->EvalCoord1fv = choose_EvalCoord1fv;
595 vfmt->EvalCoord2f = choose_EvalCoord2f;
596 vfmt->EvalCoord2fv = choose_EvalCoord2fv;
597 vfmt->EvalMesh1 = choose_EvalMesh1;
598 vfmt->EvalMesh2 = choose_EvalMesh2;
599 vfmt->EvalPoint1 = choose_EvalPoint1;
600 vfmt->EvalPoint2 = choose_EvalPoint2;
601
602 vfmt->Materialfv = _tnl_Materialfv;
603 }
604
605
606 static struct dynfn *codegen_noop( struct _vb *vb, int key )
607 {
608 (void) vb; (void) key;
609 return 0;
610 }
611
612 void _tnl_InitCodegen( struct dfn_generators *gen )
613 {
614 gen->Vertex2f = codegen_noop;
615 gen->Vertex2fv = codegen_noop;
616 gen->Vertex3f = codegen_noop;
617 gen->Vertex3fv = codegen_noop;
618 gen->Vertex4f = codegen_noop;
619 gen->Vertex4fv = codegen_noop;
620
621 gen->Attr1f = codegen_noop;
622 gen->Attr1fv = codegen_noop;
623 gen->Attr2f = codegen_noop;
624 gen->Attr2fv = codegen_noop;
625 gen->Attr3f = codegen_noop;
626 gen->Attr3fv = codegen_noop;
627 gen->Attr4f = codegen_noop;
628 gen->Attr4fv = codegen_noop;
629 gen->Attr3ub = codegen_noop;
630 gen->Attr3ubv = codegen_noop;
631 gen->Attr4ub = codegen_noop;
632 gen->Attr4ubv = codegen_noop;
633
634 /* Probably need two versions of this, one for the front end
635 * (double dispatch), one for the back end (do the work) -- but
636 * will also need a second level of CHOOSE functions?
637 * -- Generate the dispatch layer using the existing templates somehow.
638 * -- Generate the backend and 2nd level choosers here.
639 * -- No need for a chooser on the top level.
640 * -- Can aliasing help -- ie can NVAttr1f == Attr1f/Vertex2f at this level (index is known)
641 */
642 gen->NVAttr1f = codegen_noop;
643 gen->NVAttr1fv = codegen_noop;
644 gen->NVAttr2f = codegen_noop;
645 gen->NVAttr2fv = codegen_noop;
646 gen->NVAttr3f = codegen_noop;
647 gen->NVAttr3fv = codegen_noop;
648 gen->NVAttr4f = codegen_noop;
649 gen->NVAttr4fv = codegen_noop;
650
651 gen->MTAttr1f = codegen_noop;
652 gen->MTAttr1fv = codegen_noop;
653 gen->MTAttr2f = codegen_noop;
654 gen->MTAttr2fv = codegen_noop;
655 gen->MTAttr3f = codegen_noop;
656 gen->MTAttr3fv = codegen_noop;
657 gen->MTAttr4f = codegen_noop;
658 gen->MTAttr4fv = codegen_noop;
659
660 if (!getenv("MESA_NO_CODEGEN")) {
661 #if defined(USE_X86_ASM)
662 _tnl_InitX86Codegen( gen );
663 #endif
664
665 #if defined(USE_SSE_ASM)
666 _tnl_InitSSECodegen( gen );
667 #endif
668
669 #if defined(USE_3DNOW_ASM)
670 #endif
671
672 #if defined(USE_SPARC_ASM)
673 #endif
674 }
675 }