1 /**************************************************************************
3 Copyright 2004 Tungsten Graphics Inc., Cedar Park, Texas.
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 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
30 * Keith Whitwell <keith@tungstengraphics.com>
40 #include "api_arrayelt.h"
42 #include "t_vtx_api.h"
45 /* Versions of all the entrypoints for situations where codegen isn't
48 * Note: Only one size for each attribute may be active at once.
49 * Eg. if Color3f is installed/active, then Color4f may not be, even
50 * if the vertex actually contains 4 color coordinates. This is
51 * because the 3f version won't otherwise set color[3] to 1.0 -- this
52 * is the job of the chooser function when switching between Color4f
55 #define ATTRFV( ATTR, N ) \
56 static void attrib_##ATTR##_##N( const GLfloat *v ) \
58 GET_CURRENT_CONTEXT( ctx ); \
59 TNLcontext *tnl = TNL_CONTEXT(ctx); \
64 if (N>0) tnl->vtx.vbptr[0] = v[0]; \
65 if (N>1) tnl->vtx.vbptr[1] = v[1]; \
66 if (N>2) tnl->vtx.vbptr[2] = v[2]; \
67 if (N>3) tnl->vtx.vbptr[3] = v[3]; \
69 for (i = N; i < tnl->vtx.vertex_size; i++) \
70 tnl->vtx.vbptr[i] = tnl->vtx.vertex[i]; \
72 tnl->vtx.vbptr += tnl->vtx.vertex_size; \
74 if (--tnl->vtx.counter == 0) \
75 _tnl_wrap_filled_vertex( ctx ); \
78 GLfloat *dest = tnl->vtx.attrptr[ATTR]; \
79 if (N>0) dest[0] = v[0]; \
80 if (N>1) dest[1] = v[1]; \
81 if (N>2) dest[2] = v[2]; \
82 if (N>3) dest[3] = v[3]; \
86 #define INIT(TAB, ATTR) \
87 TAB[ATTR][0] = attrib_##ATTR##_1; \
88 TAB[ATTR][1] = attrib_##ATTR##_2; \
89 TAB[ATTR][2] = attrib_##ATTR##_3; \
90 TAB[ATTR][3] = attrib_##ATTR##_4;
93 #define ATTRS( ATTRIB ) \
116 void _tnl_generic_attr_table_init( tnl_attrfv_func (*tab
)[4] )
136 /* These can be made efficient with codegen. Further, by adding more
137 * logic to do_choose(), the double-dispatch for legacy entrypoints
138 * like glVertex3f() can be removed.
140 #define DISPATCH_ATTRFV( ATTR, COUNT, P ) \
142 GET_CURRENT_CONTEXT( ctx ); \
143 TNLcontext *tnl = TNL_CONTEXT(ctx); \
144 tnl->vtx.tabfv[ATTR][COUNT-1]( P ); \
147 #define DISPATCH_ATTR1FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 1, V )
148 #define DISPATCH_ATTR2FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 2, V )
149 #define DISPATCH_ATTR3FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 3, V )
150 #define DISPATCH_ATTR4FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 4, V )
152 #define DISPATCH_ATTR1F( ATTR, S ) DISPATCH_ATTRFV( ATTR, 1, &(S) )
154 #if defined(USE_X86_ASM) && 0 /* will break register calling convention */
157 #define DISPATCH_ATTR2F( ATTR, S,T ) DISPATCH_ATTRFV( ATTR, 2, &(S) )
158 #define DISPATCH_ATTR3F( ATTR, S,T,R ) DISPATCH_ATTRFV( ATTR, 3, &(S) )
159 #define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) DISPATCH_ATTRFV( ATTR, 4, &(S) )
163 #define DISPATCH_ATTR2F( ATTR, S,T ) \
166 v[0] = S; v[1] = T; \
167 DISPATCH_ATTR2FV( ATTR, v ); \
169 #define DISPATCH_ATTR3F( ATTR, S,T,R ) \
172 v[0] = S; v[1] = T; v[2] = R; \
173 DISPATCH_ATTR3FV( ATTR, v ); \
175 #define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) \
178 v[0] = S; v[1] = T; v[2] = R; v[3] = Q; \
179 DISPATCH_ATTR4FV( ATTR, v ); \
184 static void GLAPIENTRY
_tnl_Vertex2f( GLfloat x
, GLfloat y
)
186 DISPATCH_ATTR2F( _TNL_ATTRIB_POS
, x
, y
);
189 static void GLAPIENTRY
_tnl_Vertex2fv( const GLfloat
*v
)
191 DISPATCH_ATTR2FV( _TNL_ATTRIB_POS
, v
);
194 static void GLAPIENTRY
_tnl_Vertex3f( GLfloat x
, GLfloat y
, GLfloat z
)
196 DISPATCH_ATTR3F( _TNL_ATTRIB_POS
, x
, y
, z
);
199 static void GLAPIENTRY
_tnl_Vertex3fv( const GLfloat
*v
)
201 DISPATCH_ATTR3FV( _TNL_ATTRIB_POS
, v
);
204 static void GLAPIENTRY
_tnl_Vertex4f( GLfloat x
, GLfloat y
, GLfloat z
,
207 DISPATCH_ATTR4F( _TNL_ATTRIB_POS
, x
, y
, z
, w
);
210 static void GLAPIENTRY
_tnl_Vertex4fv( const GLfloat
*v
)
212 DISPATCH_ATTR4FV( _TNL_ATTRIB_POS
, v
);
215 static void GLAPIENTRY
_tnl_TexCoord1f( GLfloat x
)
217 DISPATCH_ATTR1F( _TNL_ATTRIB_TEX0
, x
);
220 static void GLAPIENTRY
_tnl_TexCoord1fv( const GLfloat
*v
)
222 DISPATCH_ATTR1FV( _TNL_ATTRIB_TEX0
, v
);
225 static void GLAPIENTRY
_tnl_TexCoord2f( GLfloat x
, GLfloat y
)
227 DISPATCH_ATTR2F( _TNL_ATTRIB_TEX0
, x
, y
);
230 static void GLAPIENTRY
_tnl_TexCoord2fv( const GLfloat
*v
)
232 DISPATCH_ATTR2FV( _TNL_ATTRIB_TEX0
, v
);
235 static void GLAPIENTRY
_tnl_TexCoord3f( GLfloat x
, GLfloat y
, GLfloat z
)
237 DISPATCH_ATTR3F( _TNL_ATTRIB_TEX0
, x
, y
, z
);
240 static void GLAPIENTRY
_tnl_TexCoord3fv( const GLfloat
*v
)
242 DISPATCH_ATTR3FV( _TNL_ATTRIB_TEX0
, v
);
245 static void GLAPIENTRY
_tnl_TexCoord4f( GLfloat x
, GLfloat y
, GLfloat z
,
248 DISPATCH_ATTR4F( _TNL_ATTRIB_TEX0
, x
, y
, z
, w
);
251 static void GLAPIENTRY
_tnl_TexCoord4fv( const GLfloat
*v
)
253 DISPATCH_ATTR4FV( _TNL_ATTRIB_TEX0
, v
);
256 static void GLAPIENTRY
_tnl_Normal3f( GLfloat x
, GLfloat y
, GLfloat z
)
258 DISPATCH_ATTR3F( _TNL_ATTRIB_NORMAL
, x
, y
, z
);
261 static void GLAPIENTRY
_tnl_Normal3fv( const GLfloat
*v
)
263 DISPATCH_ATTR3FV( _TNL_ATTRIB_NORMAL
, v
);
266 static void GLAPIENTRY
_tnl_FogCoordfEXT( GLfloat x
)
268 DISPATCH_ATTR1F( _TNL_ATTRIB_FOG
, x
);
271 static void GLAPIENTRY
_tnl_FogCoordfvEXT( const GLfloat
*v
)
273 DISPATCH_ATTR1FV( _TNL_ATTRIB_FOG
, v
);
276 static void GLAPIENTRY
_tnl_Color3f( GLfloat x
, GLfloat y
, GLfloat z
)
278 DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR0
, x
, y
, z
);
281 static void GLAPIENTRY
_tnl_Color3fv( const GLfloat
*v
)
283 DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR0
, v
);
286 static void GLAPIENTRY
_tnl_Color4f( GLfloat x
, GLfloat y
, GLfloat z
,
289 DISPATCH_ATTR4F( _TNL_ATTRIB_COLOR0
, x
, y
, z
, w
);
292 static void GLAPIENTRY
_tnl_Color4fv( const GLfloat
*v
)
294 DISPATCH_ATTR4FV( _TNL_ATTRIB_COLOR0
, v
);
297 static void GLAPIENTRY
_tnl_SecondaryColor3fEXT( GLfloat x
, GLfloat y
,
300 DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR1
, x
, y
, z
);
303 static void GLAPIENTRY
_tnl_SecondaryColor3fvEXT( const GLfloat
*v
)
305 DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR1
, v
);
308 static void GLAPIENTRY
_tnl_MultiTexCoord1f( GLenum target
, GLfloat x
)
310 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
311 DISPATCH_ATTR1F( attr
, x
);
314 static void GLAPIENTRY
_tnl_MultiTexCoord1fv( GLenum target
,
317 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
318 DISPATCH_ATTR1FV( attr
, v
);
321 static void GLAPIENTRY
_tnl_MultiTexCoord2f( GLenum target
, GLfloat x
,
324 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
325 DISPATCH_ATTR2F( attr
, x
, y
);
328 static void GLAPIENTRY
_tnl_MultiTexCoord2fv( GLenum target
,
331 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
332 DISPATCH_ATTR2FV( attr
, v
);
335 static void GLAPIENTRY
_tnl_MultiTexCoord3f( GLenum target
, GLfloat x
,
336 GLfloat y
, GLfloat z
)
338 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
339 DISPATCH_ATTR3F( attr
, x
, y
, z
);
342 static void GLAPIENTRY
_tnl_MultiTexCoord3fv( GLenum target
,
345 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
346 DISPATCH_ATTR3FV( attr
, v
);
349 static void GLAPIENTRY
_tnl_MultiTexCoord4f( GLenum target
, GLfloat x
,
350 GLfloat y
, GLfloat z
,
353 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
354 DISPATCH_ATTR4F( attr
, x
, y
, z
, w
);
357 static void GLAPIENTRY
_tnl_MultiTexCoord4fv( GLenum target
,
360 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
361 DISPATCH_ATTR4FV( attr
, v
);
365 static void GLAPIENTRY
_tnl_VertexAttrib1fNV( GLuint index
, GLfloat x
)
367 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
368 DISPATCH_ATTR1F( index
, x
);
371 static void GLAPIENTRY
_tnl_VertexAttrib1fvNV( GLuint index
,
374 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
375 DISPATCH_ATTR1FV( index
, v
);
378 static void GLAPIENTRY
_tnl_VertexAttrib2fNV( GLuint index
, GLfloat x
,
381 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
382 DISPATCH_ATTR2F( index
, x
, y
);
385 static void GLAPIENTRY
_tnl_VertexAttrib2fvNV( GLuint index
,
388 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
389 DISPATCH_ATTR2FV( index
, v
);
392 static void GLAPIENTRY
_tnl_VertexAttrib3fNV( GLuint index
, GLfloat x
,
393 GLfloat y
, GLfloat z
)
395 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
396 DISPATCH_ATTR3F( index
, x
, y
, z
);
399 static void GLAPIENTRY
_tnl_VertexAttrib3fvNV( GLuint index
,
402 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
403 DISPATCH_ATTR3FV( index
, v
);
406 static void GLAPIENTRY
_tnl_VertexAttrib4fNV( GLuint index
, GLfloat x
,
407 GLfloat y
, GLfloat z
,
410 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
411 DISPATCH_ATTR4F( index
, x
, y
, z
, w
);
414 static void GLAPIENTRY
_tnl_VertexAttrib4fvNV( GLuint index
,
417 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
418 DISPATCH_ATTR4FV( index
, v
);
426 static void GLAPIENTRY
_tnl_VertexAttrib1fARB( GLuint index
, GLfloat x
)
428 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
429 DISPATCH_ATTR1F( index
, x
);
432 static void GLAPIENTRY
_tnl_VertexAttrib1fvARB( GLuint index
,
435 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
436 DISPATCH_ATTR1FV( index
, v
);
439 static void GLAPIENTRY
_tnl_VertexAttrib2fARB( GLuint index
, GLfloat x
,
442 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
443 DISPATCH_ATTR2F( index
, x
, y
);
446 static void GLAPIENTRY
_tnl_VertexAttrib2fvARB( GLuint index
,
449 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
450 DISPATCH_ATTR2FV( index
, v
);
453 static void GLAPIENTRY
_tnl_VertexAttrib3fARB( GLuint index
, GLfloat x
,
454 GLfloat y
, GLfloat z
)
456 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
457 DISPATCH_ATTR3F( index
, x
, y
, z
);
460 static void GLAPIENTRY
_tnl_VertexAttrib3fvARB( GLuint index
,
463 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
464 DISPATCH_ATTR3FV( index
, v
);
467 static void GLAPIENTRY
_tnl_VertexAttrib4fARB( GLuint index
, GLfloat x
,
468 GLfloat y
, GLfloat z
,
471 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
472 DISPATCH_ATTR4F( index
, x
, y
, z
, w
);
475 static void GLAPIENTRY
_tnl_VertexAttrib4fvARB( GLuint index
,
478 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
479 DISPATCH_ATTR4FV( index
, v
);
483 /* Install the generic versions of the 2nd level dispatch
484 * functions. Some of these have a codegen alternative.
486 void _tnl_generic_exec_vtxfmt_init( GLcontext
*ctx
)
488 GLvertexformat
*vfmt
= &(TNL_CONTEXT(ctx
)->exec_vtxfmt
);
490 vfmt
->Color3f
= _tnl_Color3f
;
491 vfmt
->Color3fv
= _tnl_Color3fv
;
492 vfmt
->Color4f
= _tnl_Color4f
;
493 vfmt
->Color4fv
= _tnl_Color4fv
;
494 vfmt
->FogCoordfEXT
= _tnl_FogCoordfEXT
;
495 vfmt
->FogCoordfvEXT
= _tnl_FogCoordfvEXT
;
496 vfmt
->MultiTexCoord1fARB
= _tnl_MultiTexCoord1f
;
497 vfmt
->MultiTexCoord1fvARB
= _tnl_MultiTexCoord1fv
;
498 vfmt
->MultiTexCoord2fARB
= _tnl_MultiTexCoord2f
;
499 vfmt
->MultiTexCoord2fvARB
= _tnl_MultiTexCoord2fv
;
500 vfmt
->MultiTexCoord3fARB
= _tnl_MultiTexCoord3f
;
501 vfmt
->MultiTexCoord3fvARB
= _tnl_MultiTexCoord3fv
;
502 vfmt
->MultiTexCoord4fARB
= _tnl_MultiTexCoord4f
;
503 vfmt
->MultiTexCoord4fvARB
= _tnl_MultiTexCoord4fv
;
504 vfmt
->Normal3f
= _tnl_Normal3f
;
505 vfmt
->Normal3fv
= _tnl_Normal3fv
;
506 vfmt
->SecondaryColor3fEXT
= _tnl_SecondaryColor3fEXT
;
507 vfmt
->SecondaryColor3fvEXT
= _tnl_SecondaryColor3fvEXT
;
508 vfmt
->TexCoord1f
= _tnl_TexCoord1f
;
509 vfmt
->TexCoord1fv
= _tnl_TexCoord1fv
;
510 vfmt
->TexCoord2f
= _tnl_TexCoord2f
;
511 vfmt
->TexCoord2fv
= _tnl_TexCoord2fv
;
512 vfmt
->TexCoord3f
= _tnl_TexCoord3f
;
513 vfmt
->TexCoord3fv
= _tnl_TexCoord3fv
;
514 vfmt
->TexCoord4f
= _tnl_TexCoord4f
;
515 vfmt
->TexCoord4fv
= _tnl_TexCoord4fv
;
516 vfmt
->Vertex2f
= _tnl_Vertex2f
;
517 vfmt
->Vertex2fv
= _tnl_Vertex2fv
;
518 vfmt
->Vertex3f
= _tnl_Vertex3f
;
519 vfmt
->Vertex3fv
= _tnl_Vertex3fv
;
520 vfmt
->Vertex4f
= _tnl_Vertex4f
;
521 vfmt
->Vertex4fv
= _tnl_Vertex4fv
;
522 vfmt
->VertexAttrib1fNV
= _tnl_VertexAttrib1fNV
;
523 vfmt
->VertexAttrib1fvNV
= _tnl_VertexAttrib1fvNV
;
524 vfmt
->VertexAttrib2fNV
= _tnl_VertexAttrib2fNV
;
525 vfmt
->VertexAttrib2fvNV
= _tnl_VertexAttrib2fvNV
;
526 vfmt
->VertexAttrib3fNV
= _tnl_VertexAttrib3fNV
;
527 vfmt
->VertexAttrib3fvNV
= _tnl_VertexAttrib3fvNV
;
528 vfmt
->VertexAttrib4fNV
= _tnl_VertexAttrib4fNV
;
529 vfmt
->VertexAttrib4fvNV
= _tnl_VertexAttrib4fvNV
;
530 vfmt
->VertexAttrib1fARB
= _tnl_VertexAttrib1fARB
;
531 vfmt
->VertexAttrib1fvARB
= _tnl_VertexAttrib1fvARB
;
532 vfmt
->VertexAttrib2fARB
= _tnl_VertexAttrib2fARB
;
533 vfmt
->VertexAttrib2fvARB
= _tnl_VertexAttrib2fvARB
;
534 vfmt
->VertexAttrib3fARB
= _tnl_VertexAttrib3fARB
;
535 vfmt
->VertexAttrib3fvARB
= _tnl_VertexAttrib3fvARB
;
536 vfmt
->VertexAttrib4fARB
= _tnl_VertexAttrib4fARB
;
537 vfmt
->VertexAttrib4fvARB
= _tnl_VertexAttrib4fvARB
;