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
);
364 static void GLAPIENTRY
_tnl_VertexAttrib1fNV( GLuint index
, GLfloat x
)
366 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
367 DISPATCH_ATTR1F( index
, x
);
370 static void GLAPIENTRY
_tnl_VertexAttrib1fvNV( GLuint index
,
373 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
374 DISPATCH_ATTR1FV( index
, v
);
377 static void GLAPIENTRY
_tnl_VertexAttrib2fNV( GLuint index
, GLfloat x
,
380 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
381 DISPATCH_ATTR2F( index
, x
, y
);
384 static void GLAPIENTRY
_tnl_VertexAttrib2fvNV( GLuint index
,
387 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
388 DISPATCH_ATTR2FV( index
, v
);
391 static void GLAPIENTRY
_tnl_VertexAttrib3fNV( GLuint index
, GLfloat x
,
392 GLfloat y
, GLfloat z
)
394 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
395 DISPATCH_ATTR3F( index
, x
, y
, z
);
398 static void GLAPIENTRY
_tnl_VertexAttrib3fvNV( GLuint index
,
401 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
402 DISPATCH_ATTR3FV( index
, v
);
405 static void GLAPIENTRY
_tnl_VertexAttrib4fNV( GLuint index
, GLfloat x
,
406 GLfloat y
, GLfloat z
,
409 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
410 DISPATCH_ATTR4F( index
, x
, y
, z
, w
);
413 static void GLAPIENTRY
_tnl_VertexAttrib4fvNV( GLuint index
,
416 if (index
>= VERT_ATTRIB_MAX
) index
= ERROR_ATTRIB
;
417 DISPATCH_ATTR4FV( index
, v
);
421 /* Install the generic versions of the 2nd level dispatch
422 * functions. Some of these have a codegen alternative.
424 void _tnl_generic_exec_vtxfmt_init( GLcontext
*ctx
)
426 GLvertexformat
*vfmt
= &(TNL_CONTEXT(ctx
)->exec_vtxfmt
);
428 vfmt
->Color3f
= _tnl_Color3f
;
429 vfmt
->Color3fv
= _tnl_Color3fv
;
430 vfmt
->Color4f
= _tnl_Color4f
;
431 vfmt
->Color4fv
= _tnl_Color4fv
;
432 vfmt
->FogCoordfEXT
= _tnl_FogCoordfEXT
;
433 vfmt
->FogCoordfvEXT
= _tnl_FogCoordfvEXT
;
434 vfmt
->MultiTexCoord1fARB
= _tnl_MultiTexCoord1f
;
435 vfmt
->MultiTexCoord1fvARB
= _tnl_MultiTexCoord1fv
;
436 vfmt
->MultiTexCoord2fARB
= _tnl_MultiTexCoord2f
;
437 vfmt
->MultiTexCoord2fvARB
= _tnl_MultiTexCoord2fv
;
438 vfmt
->MultiTexCoord3fARB
= _tnl_MultiTexCoord3f
;
439 vfmt
->MultiTexCoord3fvARB
= _tnl_MultiTexCoord3fv
;
440 vfmt
->MultiTexCoord4fARB
= _tnl_MultiTexCoord4f
;
441 vfmt
->MultiTexCoord4fvARB
= _tnl_MultiTexCoord4fv
;
442 vfmt
->Normal3f
= _tnl_Normal3f
;
443 vfmt
->Normal3fv
= _tnl_Normal3fv
;
444 vfmt
->SecondaryColor3fEXT
= _tnl_SecondaryColor3fEXT
;
445 vfmt
->SecondaryColor3fvEXT
= _tnl_SecondaryColor3fvEXT
;
446 vfmt
->TexCoord1f
= _tnl_TexCoord1f
;
447 vfmt
->TexCoord1fv
= _tnl_TexCoord1fv
;
448 vfmt
->TexCoord2f
= _tnl_TexCoord2f
;
449 vfmt
->TexCoord2fv
= _tnl_TexCoord2fv
;
450 vfmt
->TexCoord3f
= _tnl_TexCoord3f
;
451 vfmt
->TexCoord3fv
= _tnl_TexCoord3fv
;
452 vfmt
->TexCoord4f
= _tnl_TexCoord4f
;
453 vfmt
->TexCoord4fv
= _tnl_TexCoord4fv
;
454 vfmt
->Vertex2f
= _tnl_Vertex2f
;
455 vfmt
->Vertex2fv
= _tnl_Vertex2fv
;
456 vfmt
->Vertex3f
= _tnl_Vertex3f
;
457 vfmt
->Vertex3fv
= _tnl_Vertex3fv
;
458 vfmt
->Vertex4f
= _tnl_Vertex4f
;
459 vfmt
->Vertex4fv
= _tnl_Vertex4fv
;
460 vfmt
->VertexAttrib1fNV
= _tnl_VertexAttrib1fNV
;
461 vfmt
->VertexAttrib1fvNV
= _tnl_VertexAttrib1fvNV
;
462 vfmt
->VertexAttrib2fNV
= _tnl_VertexAttrib2fNV
;
463 vfmt
->VertexAttrib2fvNV
= _tnl_VertexAttrib2fvNV
;
464 vfmt
->VertexAttrib3fNV
= _tnl_VertexAttrib3fNV
;
465 vfmt
->VertexAttrib3fvNV
= _tnl_VertexAttrib3fvNV
;
466 vfmt
->VertexAttrib4fNV
= _tnl_VertexAttrib4fNV
;
467 vfmt
->VertexAttrib4fvNV
= _tnl_VertexAttrib4fvNV
;