Subversion Repositories shark

Rev

Rev 56 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
56 pj 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
 
72 giacomo 38
#include "t_vtx_api.h"
56 pj 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
      _mesa_debug(NULL, "%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
         _mesa_debug(NULL, "%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
}