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 ) \
99 /* conventional attribs */
117 /* generic attribs */
136 void _tnl_generic_attr_table_init( tnl_attrfv_func (*tab
)[4] )
138 /* conventional attribs */
156 /* generic attribs */
175 /* These can be made efficient with codegen. Further, by adding more
176 * logic to do_choose(), the double-dispatch for legacy entrypoints
177 * like glVertex3f() can be removed.
179 #define DISPATCH_ATTRFV( ATTR, COUNT, P ) \
181 GET_CURRENT_CONTEXT( ctx ); \
182 TNLcontext *tnl = TNL_CONTEXT(ctx); \
183 tnl->vtx.tabfv[ATTR][COUNT-1]( P ); \
186 #define DISPATCH_ATTR1FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 1, V )
187 #define DISPATCH_ATTR2FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 2, V )
188 #define DISPATCH_ATTR3FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 3, V )
189 #define DISPATCH_ATTR4FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 4, V )
191 #define DISPATCH_ATTR1F( ATTR, S ) DISPATCH_ATTRFV( ATTR, 1, &(S) )
193 #if defined(USE_X86_ASM) && 0 /* will break register calling convention */
196 #define DISPATCH_ATTR2F( ATTR, S,T ) DISPATCH_ATTRFV( ATTR, 2, &(S) )
197 #define DISPATCH_ATTR3F( ATTR, S,T,R ) DISPATCH_ATTRFV( ATTR, 3, &(S) )
198 #define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) DISPATCH_ATTRFV( ATTR, 4, &(S) )
202 #define DISPATCH_ATTR2F( ATTR, S,T ) \
205 v[0] = S; v[1] = T; \
206 DISPATCH_ATTR2FV( ATTR, v ); \
208 #define DISPATCH_ATTR3F( ATTR, S,T,R ) \
211 v[0] = S; v[1] = T; v[2] = R; \
212 DISPATCH_ATTR3FV( ATTR, v ); \
214 #define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) \
217 v[0] = S; v[1] = T; v[2] = R; v[3] = Q; \
218 DISPATCH_ATTR4FV( ATTR, v ); \
223 static void GLAPIENTRY
_tnl_Vertex2f( GLfloat x
, GLfloat y
)
225 DISPATCH_ATTR2F( _TNL_ATTRIB_POS
, x
, y
);
228 static void GLAPIENTRY
_tnl_Vertex2fv( const GLfloat
*v
)
230 DISPATCH_ATTR2FV( _TNL_ATTRIB_POS
, v
);
233 static void GLAPIENTRY
_tnl_Vertex3f( GLfloat x
, GLfloat y
, GLfloat z
)
235 DISPATCH_ATTR3F( _TNL_ATTRIB_POS
, x
, y
, z
);
238 static void GLAPIENTRY
_tnl_Vertex3fv( const GLfloat
*v
)
240 DISPATCH_ATTR3FV( _TNL_ATTRIB_POS
, v
);
243 static void GLAPIENTRY
_tnl_Vertex4f( GLfloat x
, GLfloat y
, GLfloat z
,
246 DISPATCH_ATTR4F( _TNL_ATTRIB_POS
, x
, y
, z
, w
);
249 static void GLAPIENTRY
_tnl_Vertex4fv( const GLfloat
*v
)
251 DISPATCH_ATTR4FV( _TNL_ATTRIB_POS
, v
);
254 static void GLAPIENTRY
_tnl_TexCoord1f( GLfloat x
)
256 DISPATCH_ATTR1F( _TNL_ATTRIB_TEX0
, x
);
259 static void GLAPIENTRY
_tnl_TexCoord1fv( const GLfloat
*v
)
261 DISPATCH_ATTR1FV( _TNL_ATTRIB_TEX0
, v
);
264 static void GLAPIENTRY
_tnl_TexCoord2f( GLfloat x
, GLfloat y
)
266 DISPATCH_ATTR2F( _TNL_ATTRIB_TEX0
, x
, y
);
269 static void GLAPIENTRY
_tnl_TexCoord2fv( const GLfloat
*v
)
271 DISPATCH_ATTR2FV( _TNL_ATTRIB_TEX0
, v
);
274 static void GLAPIENTRY
_tnl_TexCoord3f( GLfloat x
, GLfloat y
, GLfloat z
)
276 DISPATCH_ATTR3F( _TNL_ATTRIB_TEX0
, x
, y
, z
);
279 static void GLAPIENTRY
_tnl_TexCoord3fv( const GLfloat
*v
)
281 DISPATCH_ATTR3FV( _TNL_ATTRIB_TEX0
, v
);
284 static void GLAPIENTRY
_tnl_TexCoord4f( GLfloat x
, GLfloat y
, GLfloat z
,
287 DISPATCH_ATTR4F( _TNL_ATTRIB_TEX0
, x
, y
, z
, w
);
290 static void GLAPIENTRY
_tnl_TexCoord4fv( const GLfloat
*v
)
292 DISPATCH_ATTR4FV( _TNL_ATTRIB_TEX0
, v
);
295 static void GLAPIENTRY
_tnl_Normal3f( GLfloat x
, GLfloat y
, GLfloat z
)
297 DISPATCH_ATTR3F( _TNL_ATTRIB_NORMAL
, x
, y
, z
);
300 static void GLAPIENTRY
_tnl_Normal3fv( const GLfloat
*v
)
302 DISPATCH_ATTR3FV( _TNL_ATTRIB_NORMAL
, v
);
305 static void GLAPIENTRY
_tnl_FogCoordfEXT( GLfloat x
)
307 DISPATCH_ATTR1F( _TNL_ATTRIB_FOG
, x
);
310 static void GLAPIENTRY
_tnl_FogCoordfvEXT( const GLfloat
*v
)
312 DISPATCH_ATTR1FV( _TNL_ATTRIB_FOG
, v
);
315 static void GLAPIENTRY
_tnl_Color3f( GLfloat x
, GLfloat y
, GLfloat z
)
317 DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR0
, x
, y
, z
);
320 static void GLAPIENTRY
_tnl_Color3fv( const GLfloat
*v
)
322 DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR0
, v
);
325 static void GLAPIENTRY
_tnl_Color4f( GLfloat x
, GLfloat y
, GLfloat z
,
328 DISPATCH_ATTR4F( _TNL_ATTRIB_COLOR0
, x
, y
, z
, w
);
331 static void GLAPIENTRY
_tnl_Color4fv( const GLfloat
*v
)
333 DISPATCH_ATTR4FV( _TNL_ATTRIB_COLOR0
, v
);
336 static void GLAPIENTRY
_tnl_Indexf( GLfloat v
)
338 DISPATCH_ATTR1F( _TNL_ATTRIB_COLOR_INDEX
, v
);
341 static void GLAPIENTRY
_tnl_Indexfv( const GLfloat
*v
)
343 DISPATCH_ATTR1FV( _TNL_ATTRIB_COLOR_INDEX
, v
);
346 static void GLAPIENTRY
_tnl_SecondaryColor3fEXT( GLfloat x
, GLfloat y
,
349 DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR1
, x
, y
, z
);
352 static void GLAPIENTRY
_tnl_SecondaryColor3fvEXT( const GLfloat
*v
)
354 DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR1
, v
);
357 static void GLAPIENTRY
_tnl_MultiTexCoord1f( GLenum target
, GLfloat x
)
359 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
360 DISPATCH_ATTR1F( attr
, x
);
363 static void GLAPIENTRY
_tnl_MultiTexCoord1fv( GLenum target
, const GLfloat
*v
)
365 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
366 DISPATCH_ATTR1FV( attr
, v
);
369 static void GLAPIENTRY
_tnl_MultiTexCoord2f( GLenum target
, GLfloat x
, GLfloat y
)
371 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
372 DISPATCH_ATTR2F( attr
, x
, y
);
375 static void GLAPIENTRY
_tnl_MultiTexCoord2fv( GLenum target
, const GLfloat
*v
)
377 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
378 DISPATCH_ATTR2FV( attr
, v
);
381 static void GLAPIENTRY
_tnl_MultiTexCoord3f( GLenum target
, GLfloat x
,
382 GLfloat y
, GLfloat z
)
384 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
385 DISPATCH_ATTR3F( attr
, x
, y
, z
);
388 static void GLAPIENTRY
_tnl_MultiTexCoord3fv( GLenum target
, const GLfloat
*v
)
390 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
391 DISPATCH_ATTR3FV( attr
, v
);
394 static void GLAPIENTRY
_tnl_MultiTexCoord4f( GLenum target
, GLfloat x
,
395 GLfloat y
, GLfloat z
,
398 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
399 DISPATCH_ATTR4F( attr
, x
, y
, z
, w
);
402 static void GLAPIENTRY
_tnl_MultiTexCoord4fv( GLenum target
, const GLfloat
*v
)
404 GLuint attr
= (target
& 0x7) + _TNL_ATTRIB_TEX0
;
405 DISPATCH_ATTR4FV( attr
, v
);
410 * GL_NV_vertex_program Vertex Attributes
411 * Note that these attributes DO alias the conventional attributes.
412 * Also, calling glVertexAttribNV(0, xxx) is equivalent to glVertex(xxx).
415 static void GLAPIENTRY
_tnl_VertexAttrib1fNV( GLuint index
, GLfloat x
)
417 if (index
>= MAX_VERTEX_PROGRAM_ATTRIBS
)
418 index
= _TNL_ATTRIB_ERROR
;
419 DISPATCH_ATTR1F( index
, x
);
422 static void GLAPIENTRY
_tnl_VertexAttrib1fvNV( GLuint index
, const GLfloat
*v
)
424 if (index
>= MAX_VERTEX_PROGRAM_ATTRIBS
)
425 index
= _TNL_ATTRIB_ERROR
;
426 DISPATCH_ATTR1FV( index
, v
);
429 static void GLAPIENTRY
_tnl_VertexAttrib2fNV(GLuint index
, GLfloat x
, GLfloat y
)
431 if (index
>= MAX_VERTEX_PROGRAM_ATTRIBS
)
432 index
= _TNL_ATTRIB_ERROR
;
433 DISPATCH_ATTR2F( index
, x
, y
);
436 static void GLAPIENTRY
_tnl_VertexAttrib2fvNV( GLuint index
, const GLfloat
*v
)
438 if (index
>= MAX_VERTEX_PROGRAM_ATTRIBS
)
439 index
= _TNL_ATTRIB_ERROR
;
440 DISPATCH_ATTR2FV( index
, v
);
443 static void GLAPIENTRY
_tnl_VertexAttrib3fNV( GLuint index
, GLfloat x
,
444 GLfloat y
, GLfloat z
)
446 if (index
>= MAX_VERTEX_PROGRAM_ATTRIBS
)
447 index
= _TNL_ATTRIB_ERROR
;
448 DISPATCH_ATTR3F( index
, x
, y
, z
);
451 static void GLAPIENTRY
_tnl_VertexAttrib3fvNV( GLuint index
, const GLfloat
*v
)
453 if (index
>= MAX_VERTEX_PROGRAM_ATTRIBS
)
454 index
= _TNL_ATTRIB_ERROR
;
455 DISPATCH_ATTR3FV( index
, v
);
458 static void GLAPIENTRY
_tnl_VertexAttrib4fNV( GLuint index
, GLfloat x
,
459 GLfloat y
, GLfloat z
,
462 if (index
>= MAX_VERTEX_PROGRAM_ATTRIBS
)
463 index
= _TNL_ATTRIB_ERROR
;
464 DISPATCH_ATTR4F( index
, x
, y
, z
, w
);
467 static void GLAPIENTRY
_tnl_VertexAttrib4fvNV( GLuint index
, const GLfloat
*v
)
469 if (index
>= MAX_VERTEX_PROGRAM_ATTRIBS
)
470 index
= _TNL_ATTRIB_ERROR
;
471 DISPATCH_ATTR4FV( index
, v
);
477 * GL_ARB_vertex_program Vertex Attributes
478 * Note that these attributes do NOT alias the conventional attributes.
479 * Also, calling glVertexAttribARB(0, xxx) is equivalent to glVertex(xxx).
482 static void GLAPIENTRY
_tnl_VertexAttrib1fARB( GLuint index
, GLfloat x
)
484 if (index
>= MAX_VERTEX_ATTRIBS
)
485 index
= _TNL_ATTRIB_ERROR
;
487 index
+= VERT_ATTRIB_GENERIC0
;
488 DISPATCH_ATTR1F( index
, x
);
491 static void GLAPIENTRY
_tnl_VertexAttrib1fvARB(GLuint index
, const GLfloat
*v
)
493 if (index
>= MAX_VERTEX_ATTRIBS
)
494 index
= _TNL_ATTRIB_ERROR
;
496 index
+= VERT_ATTRIB_GENERIC0
;
497 DISPATCH_ATTR1FV( index
, v
);
500 static void GLAPIENTRY
_tnl_VertexAttrib2fARB( GLuint index
, GLfloat x
,
503 if (index
>= MAX_VERTEX_ATTRIBS
)
504 index
= _TNL_ATTRIB_ERROR
;
506 index
+= VERT_ATTRIB_GENERIC0
;
507 DISPATCH_ATTR2F( index
, x
, y
);
510 static void GLAPIENTRY
_tnl_VertexAttrib2fvARB(GLuint index
, const GLfloat
*v
)
512 if (index
>= MAX_VERTEX_ATTRIBS
)
513 index
= _TNL_ATTRIB_ERROR
;
515 index
+= VERT_ATTRIB_GENERIC0
;
516 DISPATCH_ATTR2FV( index
, v
);
519 static void GLAPIENTRY
_tnl_VertexAttrib3fARB(GLuint index
, GLfloat x
,
520 GLfloat y
, GLfloat z
)
522 if (index
>= MAX_VERTEX_ATTRIBS
)
523 index
= _TNL_ATTRIB_ERROR
;
525 index
+= VERT_ATTRIB_GENERIC0
;
526 DISPATCH_ATTR3F( index
, x
, y
, z
);
529 static void GLAPIENTRY
_tnl_VertexAttrib3fvARB(GLuint index
, const GLfloat
*v
)
531 if (index
>= MAX_VERTEX_ATTRIBS
)
532 index
= _TNL_ATTRIB_ERROR
;
534 index
+= VERT_ATTRIB_GENERIC0
;
535 DISPATCH_ATTR3FV( index
, v
);
538 static void GLAPIENTRY
_tnl_VertexAttrib4fARB(GLuint index
, GLfloat x
,
539 GLfloat y
, GLfloat z
, GLfloat w
)
541 if (index
>= MAX_VERTEX_ATTRIBS
)
542 index
= _TNL_ATTRIB_ERROR
;
544 index
+= VERT_ATTRIB_GENERIC0
;
545 DISPATCH_ATTR4F( index
, x
, y
, z
, w
);
548 static void GLAPIENTRY
_tnl_VertexAttrib4fvARB(GLuint index
, const GLfloat
*v
)
550 if (index
>= MAX_VERTEX_ATTRIBS
)
551 index
= _TNL_ATTRIB_ERROR
;
553 index
+= VERT_ATTRIB_GENERIC0
;
554 DISPATCH_ATTR4FV( index
, v
);
558 /* Install the generic versions of the 2nd level dispatch
559 * functions. Some of these have a codegen alternative.
561 void _tnl_generic_exec_vtxfmt_init( GLcontext
*ctx
)
563 GLvertexformat
*vfmt
= &(TNL_CONTEXT(ctx
)->exec_vtxfmt
);
565 vfmt
->Color3f
= _tnl_Color3f
;
566 vfmt
->Color3fv
= _tnl_Color3fv
;
567 vfmt
->Color4f
= _tnl_Color4f
;
568 vfmt
->Color4fv
= _tnl_Color4fv
;
569 vfmt
->Indexf
= _tnl_Indexf
;
570 vfmt
->Indexfv
= _tnl_Indexfv
;
571 vfmt
->FogCoordfEXT
= _tnl_FogCoordfEXT
;
572 vfmt
->FogCoordfvEXT
= _tnl_FogCoordfvEXT
;
573 vfmt
->MultiTexCoord1fARB
= _tnl_MultiTexCoord1f
;
574 vfmt
->MultiTexCoord1fvARB
= _tnl_MultiTexCoord1fv
;
575 vfmt
->MultiTexCoord2fARB
= _tnl_MultiTexCoord2f
;
576 vfmt
->MultiTexCoord2fvARB
= _tnl_MultiTexCoord2fv
;
577 vfmt
->MultiTexCoord3fARB
= _tnl_MultiTexCoord3f
;
578 vfmt
->MultiTexCoord3fvARB
= _tnl_MultiTexCoord3fv
;
579 vfmt
->MultiTexCoord4fARB
= _tnl_MultiTexCoord4f
;
580 vfmt
->MultiTexCoord4fvARB
= _tnl_MultiTexCoord4fv
;
581 vfmt
->Normal3f
= _tnl_Normal3f
;
582 vfmt
->Normal3fv
= _tnl_Normal3fv
;
583 vfmt
->SecondaryColor3fEXT
= _tnl_SecondaryColor3fEXT
;
584 vfmt
->SecondaryColor3fvEXT
= _tnl_SecondaryColor3fvEXT
;
585 vfmt
->TexCoord1f
= _tnl_TexCoord1f
;
586 vfmt
->TexCoord1fv
= _tnl_TexCoord1fv
;
587 vfmt
->TexCoord2f
= _tnl_TexCoord2f
;
588 vfmt
->TexCoord2fv
= _tnl_TexCoord2fv
;
589 vfmt
->TexCoord3f
= _tnl_TexCoord3f
;
590 vfmt
->TexCoord3fv
= _tnl_TexCoord3fv
;
591 vfmt
->TexCoord4f
= _tnl_TexCoord4f
;
592 vfmt
->TexCoord4fv
= _tnl_TexCoord4fv
;
593 vfmt
->Vertex2f
= _tnl_Vertex2f
;
594 vfmt
->Vertex2fv
= _tnl_Vertex2fv
;
595 vfmt
->Vertex3f
= _tnl_Vertex3f
;
596 vfmt
->Vertex3fv
= _tnl_Vertex3fv
;
597 vfmt
->Vertex4f
= _tnl_Vertex4f
;
598 vfmt
->Vertex4fv
= _tnl_Vertex4fv
;
599 vfmt
->VertexAttrib1fNV
= _tnl_VertexAttrib1fNV
;
600 vfmt
->VertexAttrib1fvNV
= _tnl_VertexAttrib1fvNV
;
601 vfmt
->VertexAttrib2fNV
= _tnl_VertexAttrib2fNV
;
602 vfmt
->VertexAttrib2fvNV
= _tnl_VertexAttrib2fvNV
;
603 vfmt
->VertexAttrib3fNV
= _tnl_VertexAttrib3fNV
;
604 vfmt
->VertexAttrib3fvNV
= _tnl_VertexAttrib3fvNV
;
605 vfmt
->VertexAttrib4fNV
= _tnl_VertexAttrib4fNV
;
606 vfmt
->VertexAttrib4fvNV
= _tnl_VertexAttrib4fvNV
;
607 vfmt
->VertexAttrib1fARB
= _tnl_VertexAttrib1fARB
;
608 vfmt
->VertexAttrib1fvARB
= _tnl_VertexAttrib1fvARB
;
609 vfmt
->VertexAttrib2fARB
= _tnl_VertexAttrib2fARB
;
610 vfmt
->VertexAttrib2fvARB
= _tnl_VertexAttrib2fvARB
;
611 vfmt
->VertexAttrib3fARB
= _tnl_VertexAttrib3fARB
;
612 vfmt
->VertexAttrib3fvARB
= _tnl_VertexAttrib3fvARB
;
613 vfmt
->VertexAttrib4fARB
= _tnl_VertexAttrib4fARB
;
614 vfmt
->VertexAttrib4fvARB
= _tnl_VertexAttrib4fvARB
;