diff options
Diffstat (limited to 'src/mesa/tnl_dd/imm')
-rw-r--r-- | src/mesa/tnl_dd/imm/NOTES.imm | 112 | ||||
-rw-r--r-- | src/mesa/tnl_dd/imm/t_dd_imm_capi.h | 419 | ||||
-rw-r--r-- | src/mesa/tnl_dd/imm/t_dd_imm_napi.h | 226 | ||||
-rw-r--r-- | src/mesa/tnl_dd/imm/t_dd_imm_primtmp.h | 570 | ||||
-rw-r--r-- | src/mesa/tnl_dd/imm/t_dd_imm_tapi.h | 75 | ||||
-rw-r--r-- | src/mesa/tnl_dd/imm/t_dd_imm_vapi.h | 159 | ||||
-rw-r--r-- | src/mesa/tnl_dd/imm/t_dd_imm_vb.c | 204 | ||||
-rw-r--r-- | src/mesa/tnl_dd/imm/t_dd_imm_vbtmp.h | 268 |
8 files changed, 2033 insertions, 0 deletions
diff --git a/src/mesa/tnl_dd/imm/NOTES.imm b/src/mesa/tnl_dd/imm/NOTES.imm new file mode 100644 index 00000000000..9b2bd65e4bf --- /dev/null +++ b/src/mesa/tnl_dd/imm/NOTES.imm @@ -0,0 +1,112 @@ + +NOTE: + +These files are incomplete. They do not yet form a working +implementation of hte concepts discused below. + + +OVERVIEW + +The t_dd_imm_* files form a set of templates to produce driver - +specific software tnl modules for a small subset of transformation and +lighting states. + +The approach is quite different to the large vertex buffers of the +src/tnl module, and is based around a cache of four recent vertices +and a 'current' vertex which is updated directly from the Color, +Normal, Texcoord, SecondaryColor and Fog entrypoints. + +The current vertex is actually a composite of the ctx->Current values +and a partial hardware vertex maintained where the hardware values +differ from those in ctx->Current. For example, clamped color values +are kept in the hardware vertex, while texcoords remain in +ctx->Current. + +A crude diagram: + + +--------------+ +-------------------+ + | ctx->Current | | Current-HW-vertex | + +--------------+ +-------------------+ + \ / + \ / + \ / + \ / + --------- -------- + | | + v v + +--------+ +--------+ +--------+ +--------+ + | vert-0 | | vert-1 | | vert-2 | | vert-3 | + +--------+ +--------+ +--------+ +--------+ + | + | + v + + DMA + + +Here values from ctx->Current and current-HW-vertex are merged to +build vert-2, which is then dumped to hardware (DMA). A state machine +determines which vertex is built in turn, and how the vertices are +used to present primitives to hardware. These actions all occur +during a call to Vertex{234}f{v}. + +Each vert-n includes clip coordinates and a clipmask in addition to +the hardware (window) coordinates. This information allows clipping +to take place directly on these vertices, if need be. + +t_dd_imm_capi.h + + Color{34}{fub}{v}() implementations. These update both + ctx->Current (unclamped float colors) and current-HW-vertex + with hardware-specific color values (typically unsigned + bytes). + + When lighting is enabled, the functions from src/api_noop.c + should be used, which just update ctx->Current. (The + current-hw-vertex colors are produced from lighting, which is + keyed to Normal3f). + +t_dd_imm_vb.c + + Support functions for clipping and fallback. See + t_dd_imm_primtmp.h. + +t_dd_imm_napi.c +t_dd_imm_napi.h + + Versions of Normal3f{v} to perform lighting with one or more + infinite lights. Updates ctx->Current.Normal and the current + HW colors. + + When lighting is disabled, use the functions from api_noop.c + instead. + + +t_dd_imm_primtmp.h + + State machine to control emission of vertices and primitives + to hardware. Called indirectly from Vertex{234}f{v}. Capable + of supporting hardware strip and fan primitives, and of + decomposing to discreet primitives for clipping or fallback, + or where the native primitive is unavailable. + +t_dd_imm_tapi.h + + Implementations of TexCoord{v} and MultiTexCoord4f{v}ARB to + fire a callback when transitioning to projective texture. + Most drivers will need to change vertex format at this point, + some may need to enable a software rasterization fallback. + +t_dd_imm_vapi.h + + Implementations of Vertex{234}f{v}. These perform + transformation and cliptesting on their arguments, then jump + into the state machine implemented in primtmp.h. + +t_dd_imm_vertex.h + + Support functions for building and clip-interpolating hardware + vertices. Called from primtmp.h. + + +Keith Whitwell, June 2001.
\ No newline at end of file diff --git a/src/mesa/tnl_dd/imm/t_dd_imm_capi.h b/src/mesa/tnl_dd/imm/t_dd_imm_capi.h new file mode 100644 index 00000000000..77f3a4ab497 --- /dev/null +++ b/src/mesa/tnl_dd/imm/t_dd_imm_capi.h @@ -0,0 +1,419 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Gareth Hughes <[email protected]> + */ + +/* Template for immediate mode color functions. + * + * FIXME: Floating-point color versions of these... + */ + + +static void TAG(Color3f)( GLfloat r, GLfloat g, GLfloat b ) +{ + GET_CURRENT; +#ifdef COLOR_IS_FLOAT + CURRENT_COLOR( RCOMP ) = CLAMP(r, 0.0f, 1.0f); + CURRENT_COLOR( GCOMP ) = CLAMP(g, 0.0f, 1.0f); + CURRENT_COLOR( BCOMP ) = CLAMP(b, 0.0f, 1.0f); + CURRENT_COLOR( ACOMP ) = 1.0f; +#else + UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( RCOMP ), r ); + UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( GCOMP ), g ); + UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( BCOMP ), b ); + CURRENT_COLOR( ACOMP ) = 255; +#endif +} + +static void TAG(Color3fv)( const GLfloat *v ) +{ + GET_CURRENT; +#ifdef COLOR_IS_FLOAT + CURRENT_COLOR( RCOMP ) = CLAMP(v[0], 0.0f, 1.0f); + CURRENT_COLOR( GCOMP ) = CLAMP(v[1], 0.0f, 1.0f); + CURRENT_COLOR( BCOMP ) = CLAMP(v[2], 0.0f, 1.0f); + CURRENT_COLOR( ACOMP ) = 1.0f; +#else + UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( RCOMP ), v[0] ); + UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( GCOMP ), v[1] ); + UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( BCOMP ), v[2] ); + CURRENT_COLOR( ACOMP ) = 255; +#endif +} + +static void TAG(Color3ub)( GLubyte r, GLubyte g, GLubyte b ) +{ + GET_CURRENT; +#ifdef COLOR_IS_FLOAT + CURRENT_COLOR( RCOMP ) = UBYTE_TO_FLOAT( r ); + CURRENT_COLOR( GCOMP ) = UBYTE_TO_FLOAT( g ); + CURRENT_COLOR( BCOMP ) = UBYTE_TO_FLOAT( b ); + CURRENT_COLOR( ACOMP ) = 1.0f; +#else + CURRENT_COLOR( RCOMP ) = r; + CURRENT_COLOR( GCOMP ) = g; + CURRENT_COLOR( BCOMP ) = b; + CURRENT_COLOR( ACOMP ) = 255; +#endif +} + +static void TAG(Color3ubv)( const GLubyte *v ) +{ + GET_CURRENT; +#ifdef COLOR_IS_FLOAT + CURRENT_COLOR( RCOMP ) = UBYTE_TO_FLOAT( v[0] ); + CURRENT_COLOR( GCOMP ) = UBYTE_TO_FLOAT( v[1] ); + CURRENT_COLOR( BCOMP ) = UBYTE_TO_FLOAT( v[2] ); + CURRENT_COLOR( ACOMP ) = 1.0f; +#else + CURRENT_COLOR( RCOMP ) = v[0]; + CURRENT_COLOR( GCOMP ) = v[1]; + CURRENT_COLOR( BCOMP ) = v[2]; + CURRENT_COLOR( ACOMP ) = 255; +#endif +} + +static void TAG(Color4f)( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) +{ + GET_CURRENT; +#ifdef COLOR_IS_FLOAT + CURRENT_COLOR( RCOMP ) = CLAMP(r, 0.0f, 1.0f); + CURRENT_COLOR( GCOMP ) = CLAMP(g, 0.0f, 1.0f); + CURRENT_COLOR( BCOMP ) = CLAMP(b, 0.0f, 1.0f); + CURRENT_COLOR( ACOMP ) = CLAMP(a, 0.0f, 1.0f); +#else + UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( RCOMP ), r ); + UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( GCOMP ), g ); + UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( BCOMP ), b ); + UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( ACOMP ), a ); +#endif +} + +static void TAG(Color4fv)( const GLfloat *v ) +{ + GET_CURRENT; +#ifdef COLOR_IS_FLOAT + CURRENT_COLOR( RCOMP ) = CLAMP(v[0], 0.0f, 1.0f); + CURRENT_COLOR( GCOMP ) = CLAMP(v[1], 0.0f, 1.0f); + CURRENT_COLOR( BCOMP ) = CLAMP(v[2], 0.0f, 1.0f); + CURRENT_COLOR( ACOMP ) = CLAMP(v[3], 0.0f, 1.0f); +#else + UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( RCOMP ), v[0] ); + UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( GCOMP ), v[1] ); + UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( BCOMP ), v[2] ); + UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( ACOMP ), v[3] ); +#endif +} + +static void TAG(Color4ub)( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + GET_CURRENT; +#ifdef COLOR_IS_FLOAT + CURRENT_COLOR( RCOMP ) = UBYTE_TO_FLOAT( r ); + CURRENT_COLOR( GCOMP ) = UBYTE_TO_FLOAT( g ); + CURRENT_COLOR( BCOMP ) = UBYTE_TO_FLOAT( b ); + CURRENT_COLOR( ACOMP ) = UBYTE_TO_FLOAT( a ); +#else + CURRENT_COLOR( RCOMP ) = r; + CURRENT_COLOR( GCOMP ) = g; + CURRENT_COLOR( BCOMP ) = b; + CURRENT_COLOR( ACOMP ) = a; +#endif +} + +static void TAG(Color4ubv)( const GLubyte *v ) +{ + GET_CURRENT; +#ifdef COLOR_IS_FLOAT + CURRENT_COLOR( RCOMP ) = UBYTE_TO_FLOAT( v[0] ); + CURRENT_COLOR( GCOMP ) = UBYTE_TO_FLOAT( v[1] ); + CURRENT_COLOR( BCOMP ) = UBYTE_TO_FLOAT( v[2] ); + CURRENT_COLOR( ACOMP ) = UBYTE_TO_FLOAT( v[3] ); +#else + CURRENT_COLOR( RCOMP ) = v[0]; + CURRENT_COLOR( GCOMP ) = v[1]; + CURRENT_COLOR( BCOMP ) = v[2]; + CURRENT_COLOR( ACOMP ) = v[3]; +#endif +} + + +static void TAG(ColorMaterial3f)( GLfloat r, GLfloat g, GLfloat b ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + + color[0] = r; + color[1] = g; + color[2] = b; + color[3] = 1.0; + + _mesa_update_color_material( ctx, color ); + RECALC_BASE_COLOR( ctx ); +} + +static void TAG(ColorMaterial3fv)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + + color[0] = v[0]; + color[1] = v[1]; + color[2] = v[2]; + color[3] = 1.0; + + _mesa_update_color_material( ctx, color ); + RECALC_BASE_COLOR( ctx ); +} + +static void TAG(ColorMaterial3ub)( GLubyte r, GLubyte g, GLubyte b ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + + color[0] = UBYTE_TO_FLOAT( r ); + color[1] = UBYTE_TO_FLOAT( g ); + color[2] = UBYTE_TO_FLOAT( b ); + color[3] = 1.0; + + _mesa_update_color_material( ctx, color ); + RECALC_BASE_COLOR( ctx ); +} + +static void TAG(ColorMaterial3ubv)( const GLubyte *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + + color[0] = UBYTE_TO_FLOAT( v[0] ); + color[1] = UBYTE_TO_FLOAT( v[1] ); + color[2] = UBYTE_TO_FLOAT( v[2] ); + color[3] = 1.0; + + _mesa_update_color_material( ctx, color ); + RECALC_BASE_COLOR( ctx ); +} + +static void TAG(ColorMaterial4f)( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + + color[0] = r; + color[1] = g; + color[2] = b; + color[3] = a; + + _mesa_update_color_material( ctx, color ); + RECALC_BASE_COLOR( ctx ); +} + +static void TAG(ColorMaterial4fv)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + + color[0] = v[0]; + color[1] = v[1]; + color[2] = v[2]; + color[3] = v[3]; + + _mesa_update_color_material( ctx, color ); + RECALC_BASE_COLOR( ctx ); +} + +static void TAG(ColorMaterial4ub)( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + + color[0] = UBYTE_TO_FLOAT( r ); + color[1] = UBYTE_TO_FLOAT( g ); + color[2] = UBYTE_TO_FLOAT( b ); + color[3] = UBYTE_TO_FLOAT( a ); + + _mesa_update_color_material( ctx, color ); + RECALC_BASE_COLOR( ctx ); +} + +static void TAG(ColorMaterial4ubv)( const GLubyte *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + + color[0] = UBYTE_TO_FLOAT( v[0] ); + color[1] = UBYTE_TO_FLOAT( v[1] ); + color[2] = UBYTE_TO_FLOAT( v[2] ); + color[3] = UBYTE_TO_FLOAT( v[3] ); + + _mesa_update_color_material( ctx, color ); + RECALC_BASE_COLOR( ctx ); +} + + + + + +/* ============================================================= + * Color chooser functions: + */ + +static void TAG(choose_Color3f)( GLfloat r, GLfloat g, GLfloat b ) +{ + GET_CURRENT_CONTEXT(ctx); + + if ( ctx->Light.Enabled ) { + if ( ctx->Light.ColorMaterialEnabled ) { + ctx->Exec->Color3f = TAG(ColorMaterial3f); + } else { + ctx->Exec->Color3f = _mesa_noop_Color3f; + } + } else { + ctx->Exec->Color3f = TAG(Color3f); + } + glColor3f( r, g, b ); +} + +static void TAG(choose_Color3fv)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + + if ( ctx->Light.Enabled ) { + if ( ctx->Light.ColorMaterialEnabled ) { + ctx->Exec->Color3fv = TAG(ColorMaterial3fv); + } else { + ctx->Exec->Color3fv = _mesa_noop_Color3fv; + } + } else { + ctx->Exec->Color3fv = TAG(Color3fv); + } + glColor3fv( v ); +} + +static void TAG(choose_Color3ub)( GLubyte r, GLubyte g, GLubyte b ) +{ + GET_CURRENT_CONTEXT(ctx); + + if ( ctx->Light.Enabled ) { + if ( ctx->Light.ColorMaterialEnabled ) { + ctx->Exec->Color3ub = TAG(ColorMaterial3ub); + } else { + ctx->Exec->Color3ub = _mesa_noop_Color3ub; + } + } else { + ctx->Exec->Color3ub = TAG(Color3ub); + } + glColor3ub( r, g, b ); +} + +static void TAG(choose_Color3ubv)( const GLubyte *v ) +{ + GET_CURRENT_CONTEXT(ctx); + + if ( ctx->Light.Enabled ) { + if ( ctx->Light.ColorMaterialEnabled ) { + ctx->Exec->Color3ubv = TAG(ColorMaterial3ubv); + } else { + ctx->Exec->Color3ubv = _mesa_noop_Color3ubv; + } + } else { + ctx->Exec->Color3ubv = TAG(Color3ubv); + } + glColor3ubv( v ); +} + +static void TAG(choose_Color4f)( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) +{ + GET_CURRENT_CONTEXT(ctx); + + if ( ctx->Light.Enabled ) { + if ( ctx->Light.ColorMaterialEnabled ) { + ctx->Exec->Color4f = TAG(ColorMaterial4f); + } else { + ctx->Exec->Color4f = _mesa_noop_Color4f; + } + } else { + ctx->Exec->Color4f = TAG(Color4f); + } + glColor4f( r, g, b, a ); +} + +static void TAG(choose_Color4fv)( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + + if ( ctx->Light.Enabled ) { + if ( ctx->Light.ColorMaterialEnabled ) { + ctx->Exec->Color4fv = TAG(ColorMaterial4fv); + } else { + ctx->Exec->Color4fv = _mesa_noop_Color4fv; + } + } else { + ctx->Exec->Color4fv = TAG(Color4fv); + } + glColor4fv( v ); +} + +static void TAG(choose_Color4ub)( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + GET_CURRENT_CONTEXT(ctx); + + if ( ctx->Light.Enabled ) { + if ( ctx->Light.ColorMaterialEnabled ) { + ctx->Exec->Color4ub = TAG(ColorMaterial4ub); + } else { + ctx->Exec->Color4ub = _mesa_noop_Color4ub; + } + } else { + ctx->Exec->Color4ub = TAG(Color4ub); + } + glColor4ub( r, g, b, a ); +} + +static void TAG(choose_Color4ubv)( const GLubyte *v ) +{ + GET_CURRENT_CONTEXT(ctx); + + if ( ctx->Light.Enabled ) { + if ( ctx->Light.ColorMaterialEnabled ) { + ctx->Exec->Color4ubv = TAG(ColorMaterial4ubv); + } else { + ctx->Exec->Color4ubv = _mesa_noop_Color4ubv; + } + } else { + ctx->Exec->Color4ubv = TAG(Color4ubv); + } + glColor4ubv( v ); +} + + + +#undef GET_CURRENT +#undef CURRENT_COLOR +#undef CURRENT_SPECULAR +#undef COLOR_IS_FLOAT +#undef RECALC_BASE_COLOR +#undef TAG diff --git a/src/mesa/tnl_dd/imm/t_dd_imm_napi.h b/src/mesa/tnl_dd/imm/t_dd_imm_napi.h new file mode 100644 index 00000000000..9844f615ffe --- /dev/null +++ b/src/mesa/tnl_dd/imm/t_dd_imm_napi.h @@ -0,0 +1,226 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Gareth Hughes <[email protected]> + * Keith Whitwell <[email protected]> + */ + +/* Template for immediate mode normal functions. Optimize for infinite + * lights when doing software lighting. + */ + +static void TAG(Normal3f_single)( GLfloat x, GLfloat y, GLfloat z ) +{ + GET_CURRENT_VERTEX; + const struct gl_light *light = ctx->Light.EnabledList.prev; + GLfloat n_dot_h, n_dot_VP, spec, sum[3]; + GLfloat *normal = ctx->Current.Normal; + GLfloat scale = 1.0; + + ASSIGN_3V( normal, x, y, z ); + COPY_3V( sum, BASE_COLOR ); + + if ( IND & NORM_RESCALE ) { + scale = ctx->_ModelViewInvScale; + } else if ( IND & NORM_NORMALIZE ) { + scale = LEN_3FV( normal ); + if ( scale != 0.0 ) scale = 1.0 / scale; + } + + n_dot_VP = DOT3( normal, light->_VP_inf_norm ) * scale; + if ( n_dot_VP > 0.0F ) { + ACC_SCALE_SCALAR_3V( sum, n_dot_VP, light->_MatDiffuse[0] ); + n_dot_h = DOT3( normal, light->_h_inf_norm ) * scale; + if ( n_dot_h > 0.0F ) { + GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec ); + ACC_SCALE_SCALAR_3V( sum, spec, light->_MatSpecular[0] ); + } + } + +#ifdef LIT_COLOR_IS_FLOAT + LIT_COLOR ( RCOMP ) = CLAMP(sum[0], 0.0f, 0.1f); + LIT_COLOR ( GCOMP ) = CLAMP(sum[1], 0.0f, 0.1f); + LIT_COLOR ( BCOMP ) = CLAMP(sum[2], 0.0f, 0.1f); +#else + UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( RCOMP ), sum[0] ); + UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( GCOMP ), sum[1] ); + UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( BCOMP ), sum[2] ); +#endif + LIT_COLOR( ACOMP ) = LIT_ALPHA; +} + +static void TAG(Normal3fv_single)( const GLfloat *normal ) +{ + GET_CURRENT_VERTEX; + const struct gl_light *light = ctx->Light.EnabledList.prev; + GLfloat n_dot_h, n_dot_VP, spec, sum[3]; + GLfloat scale = 1.0; + + COPY_3V( ctx->Current.Normal, normal ); + COPY_3V( sum, BASE_COLOR ); + + if ( IND & NORM_RESCALE ) { + scale = ctx->_ModelViewInvScale; + } else if ( IND & NORM_NORMALIZE ) { + scale = LEN_3FV( normal ); + if ( scale != 0.0 ) scale = 1.0 / scale; + } + + n_dot_VP = DOT3( normal, light->_VP_inf_norm ) * scale; + if ( n_dot_VP > 0.0F ) { + ACC_SCALE_SCALAR_3V( sum, n_dot_VP, light->_MatDiffuse[0] ); + n_dot_h = DOT3( normal, light->_h_inf_norm ) * scale; + if ( n_dot_h > 0.0F ) { + GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec ); + ACC_SCALE_SCALAR_3V( sum, spec, light->_MatSpecular[0] ); + } + } + +#ifdef LIT_COLOR_IS_FLOAT + LIT_COLOR ( RCOMP ) = CLAMP(sum[0], 0.0f, 0.1f); + LIT_COLOR ( GCOMP ) = CLAMP(sum[1], 0.0f, 0.1f); + LIT_COLOR ( BCOMP ) = CLAMP(sum[2], 0.0f, 0.1f); +#else + UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( RCOMP ), sum[0] ); + UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( GCOMP ), sum[1] ); + UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( BCOMP ), sum[2] ); +#endif + LIT_COLOR( ACOMP ) = LIT_ALPHA; +} + + +static void TAG(Normal3f_multi)( GLfloat x, GLfloat y, GLfloat z ) +{ + GET_CURRENT_VERTEX; + struct gl_light *light; + GLfloat n_dot_h, n_dot_VP, spec, sum[3], tmp[3]; + GLfloat *normal; + + ASSIGN_3V( ctx->Current.Normal, x, y, z ); + COPY_3V( sum, BASE_COLOR ); + + if ( IND & NORM_RESCALE ) { + normal = tmp; + ASSIGN_3V( normal, x, y, z ); + SELF_SCALE_SCALAR_3V( normal, ctx->_ModelViewInvScale ); + } else if ( IND & NORM_NORMALIZE ) { + normal = tmp; + ASSIGN_3V( normal, x, y, z ); + NORMALIZE_3FV( normal ); + } else { + normal = ctx->Current.Normal; + } + + foreach ( light, &ctx->Light.EnabledList ) { + n_dot_VP = DOT3( normal, light->_VP_inf_norm ); + if ( n_dot_VP > 0.0F ) { + ACC_SCALE_SCALAR_3V( sum, n_dot_VP, light->_MatDiffuse[0] ); + n_dot_h = DOT3( normal, light->_h_inf_norm ); + if ( n_dot_h > 0.0F ) { + GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec ); + ACC_SCALE_SCALAR_3V( sum, spec, light->_MatSpecular[0] ); + } + } + } + +#ifdef LIT_COLOR_IS_FLOAT + LIT_COLOR ( RCOMP ) = CLAMP(sum[0], 0.0f, 0.1f); + LIT_COLOR ( GCOMP ) = CLAMP(sum[1], 0.0f, 0.1f); + LIT_COLOR ( BCOMP ) = CLAMP(sum[2], 0.0f, 0.1f); +#else + UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( RCOMP ), sum[0] ); + UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( GCOMP ), sum[1] ); + UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( BCOMP ), sum[2] ); +#endif + LIT_COLOR( ACOMP ) = LIT_ALPHA; +} + +static void TAG(Normal3fv_multi)( const GLfloat *n ) +{ + GET_CURRENT_VERTEX; + struct gl_light *light; + GLfloat n_dot_h, n_dot_VP, spec, sum[3], tmp[3]; + GLfloat *normal; + + COPY_3V( ctx->Current.Normal, n ); + COPY_3V( sum, BASE_COLOR ); + + if ( IND & NORM_RESCALE ) { + normal = tmp; + COPY_3V( normal, n ); + SELF_SCALE_SCALAR_3V( normal, ctx->_ModelViewInvScale ); + } else if ( IND & NORM_NORMALIZE ) { + normal = tmp; + COPY_3V( normal, n ); + NORMALIZE_3FV( normal ); + } else { + normal = ctx->Current.Normal; + } + + foreach ( light, &ctx->Light.EnabledList ) { + n_dot_VP = DOT3( normal, light->_VP_inf_norm ); + if ( n_dot_VP > 0.0F ) { + ACC_SCALE_SCALAR_3V( sum, n_dot_VP, light->_MatDiffuse[0] ); + n_dot_h = DOT3( normal, light->_h_inf_norm ); + if ( n_dot_h > 0.0F ) { + GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec ); + ACC_SCALE_SCALAR_3V( sum, spec, light->_MatSpecular[0] ); + } + } + } + +#ifdef LIT_COLOR_IS_FLOAT + LIT_COLOR ( RCOMP ) = CLAMP(sum[0], 0.0f, 0.1f); + LIT_COLOR ( GCOMP ) = CLAMP(sum[1], 0.0f, 0.1f); + LIT_COLOR ( BCOMP ) = CLAMP(sum[2], 0.0f, 0.1f); +#else + UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( RCOMP ), sum[0] ); + UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( GCOMP ), sum[1] ); + UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( BCOMP ), sum[2] ); +#endif + LIT_COLOR( ACOMP ) = LIT_ALPHA; +} + + + +static void TAG(init_norm)( void ) +{ + norm_tab[IND].normal3f_single = TAG(Normal3f_single); + norm_tab[IND].normal3fv_single = TAG(Normal3fv_single); + norm_tab[IND].normal3f_multi = TAG(Normal3f_multi); + norm_tab[IND].normal3fv_multi = TAG(Normal3fv_multi); +} + + + +#ifndef PRESERVE_NORMAL_DEFS +#undef GET_CURRENT +#undef GET_CURRENT_VERTEX +#undef LIT_COLOR +#undef LIT_COLOR_IS_FLOAT +#endif +#undef PRESERVE_NORMAL_DEFS +#undef IND +#undef TAG diff --git a/src/mesa/tnl_dd/imm/t_dd_imm_primtmp.h b/src/mesa/tnl_dd/imm/t_dd_imm_primtmp.h new file mode 100644 index 00000000000..97dca3fd421 --- /dev/null +++ b/src/mesa/tnl_dd/imm/t_dd_imm_primtmp.h @@ -0,0 +1,570 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell <[email protected]> + * Gareth Hughes <[email protected]> + */ + +/* Template for immediate mode vertices. + * + * Probably instantiate once for each vertex format used: + * - TINY_VERTICES + * - TEX0_VERTICES + * - TEX1_VERTICES + * - PTEX_VERTICES + * + * Have to handle TEX->PTEX transition somehow. + */ + +#define DBG 0 + + + +/* ============================================================= + * GL_POINTS + */ + +static void TAG(flush_point_0)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + if ( !v0->mask ) { + LOCAL_VARS; + DRAW_POINT( v0 ); + } +} + + +/* ============================================================= + * GL_LINES + */ + +static void TAG(flush_line_1)( GLcontext *ctx, TNL_VERTEX *v0 ); + +static void TAG(flush_line_0)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + FLUSH_VERTEX = TAG(flush_line_1); + ACTIVE_VERTEX = IMM_VERTICES( 1 ); +} + +static void TAG(flush_line_1)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + TNL_VERTEX *v1 = v0 - 1; + ACTIVE_VERTEX = IMM_VERTICES( 0 ); + FLUSH_VERTEX = TAG(flush_line_0); + if (FALLBACK_OR_CLIPPING) + CLIP_OR_DRAW_LINE( ctx, v1, v0 ); + else + DRAW_LINE( ctx, v1, v0 ); +} + + +/* ============================================================= + * GL_LINE_LOOP + */ + +static void TAG(flush_line_loop_2)( GLcontext *ctx, TNL_VERTEX *v0 ); +static void TAG(flush_line_loop_1)( GLcontext *ctx, TNL_VERTEX *v0 ); + +static void TAG(flush_line_loop_0)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + + ACTIVE_VERTEX = v0 + 1; + FLUSH_VERTEX = TAG(flush_line_loop_1); +} + +#define DRAW_LINELOOP_LINE( a, b ) \ + if (!HAVE_LINE_STRIP || FALLBACK_OR_CLIPPING) { \ + CLIP_OR_DRAW_LINE( ctx, a, b ); \ + } else if (EXTEND_PRIM( 1 )) { \ + EMIT_VERTEX( b ); \ + } else { \ + BEGIN_PRIM( GL_LINE_STRIP, 2 ); \ + EMIT_VERTEX( a ); \ + EMIT_VERTEX( b ); \ + } + +static void TAG(flush_line_loop_1)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + TNL_VERTEX *v1 = v0 - 1; + ACTIVE_VERTEX = v1; + FLUSH_VERTEX = TAG(flush_line_loop_2); + DRAW_LINELOOP_LINE( v1, v0 ); +} + +static void TAG(flush_line_loop_2)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + TNL_VERTEX *v1 = v0 + 1; + ACTIVE_VERTEX = v1; + FLUSH_VERTEX = TAG(flush_line_loop_1); + DRAW_LINELOOP_LINE( v1, v0 ); +} + +static void TAG(end_line_loop)( GLcontext *ctx ) +{ + LOCAL_VARS; + + if ( FLUSH_VERTEX != TAG(flush_line_loop_0) ) { + TNL_VERTEX *v1 = ACTIVE_VERTEX; + TNL_VERTEX *v0 = IMM_VERTICES( 0 ); + DRAW_LINELOOP_LINE( v1, v0 ); + } +} + + + +/* ============================================================= + * GL_LINE_STRIP + */ + +static void TAG(flush_line_strip_2)( GLcontext *ctx, TNL_VERTEX *v0 ); +static void TAG(flush_line_strip_1)( GLcontext *ctx, TNL_VERTEX *v0 ); + +static void TAG(flush_line_strip_0)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + + ACTIVE_VERTEX = v0 + 1; + FLUSH_VERTEX = TAG(flush_line_strip_0b); +} + + +static void TAG(flush_line_strip_1)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + TNL_VERTEX *v1 = v0 - 1; + + ACTIVE_VERTEX = v1; + FLUSH_VERTEX = TAG(flush_line_strip_2); + + if (!HAVE_LINE_STRIP || FALLBACK_OR_CLIPPING) + CLIP_OR_DRAW_LINE( ctx, v1, v0 ); + else if (EXTEND_PRIM( 1 )) { + EMIT_VERTEX( v0 ); + } else { + BEGIN_PRIM( GL_LINE_STRIP, 2 ); + EMIT_VERTEX( v1 ); + EMIT_VERTEX( v0 ); + } +} + +static void TAG(flush_line_strip_2)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + TNL_VERTEX *v1 = v0 + 1; + + ACTIVE_VERTEX = v1; + FLUSH_VERTEX = TAG(flush_line_strip_1); + + if (!HAVE_LINE_STRIP || FALLBACK_OR_CLIPPING) + CLIP_OR_DRAW_LINE( ctx, v1, v0 ); + else if (EXTEND_PRIM( 1 )) { + EMIT_VERTEX( v0 ); + } else { + BEGIN_PRIM( GL_LINE_STRIP, 2 ); + EMIT_VERTEX( v1 ); + EMIT_VERTEX( v0 ); + } +} + + + +/* ============================================================= + * GL_TRIANGLES + */ + +static void TAG(flush_triangle_2)( GLcontext *ctx, TNL_VERTEX *v0 ); +static void TAG(flush_triangle_1)( GLcontext *ctx, TNL_VERTEX *v0 ); + +static void TAG(flush_triangle_0)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + + if ( DBG ) fprintf( stderr, __FUNCTION__ "\n" ); + + ACTIVE_VERTEX = v0 + 1; + FLUSH_VERTEX = TAG(flush_triangle_1); + BEGIN_PRIM( GL_TRIANGLES, 0 ); +} + +static void TAG(flush_triangle_1)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + + if ( DBG ) fprintf( stderr, __FUNCTION__ "\n" ); + + ACTIVE_VERTEX = v0 + 1; + FLUSH_VERTEX = TAG(flush_triangle_2); +} + +static void TAG(flush_triangle_2)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + TNL_VERTEX *v2 = v0 - 2; + TNL_VERTEX *v1 = v0 - 1; + + if ( DBG ) fprintf( stderr, __FUNCTION__ "\n" ); + + ACTIVE_VERTEX = v2; + FLUSH_VERTEX = TAG(flush_triangle_0); + + /* nothing gained by trying to emit as hw primitives -- that + * happens normally in this case. + */ + if (FALLBACK_OR_CLIPPING) + CLIP_OR_DRAW_TRI( ctx, v2, v1, v0 ); + else + DRAW_TRI( ctx, v2, v1, v0 ); +} + + + + +/* ============================================================= + * GL_TRIANGLE_STRIP + */ + +static void TAG(flush_tri_strip_3)( GLcontext *ctx, TNL_VERTEX *v0 ); +static void TAG(flush_tri_strip_2)( GLcontext *ctx, TNL_VERTEX *v0 ); +static void TAG(flush_tri_strip_1)( GLcontext *ctx, TNL_VERTEX *v0 ); + +static void TAG(flush_tri_strip_0)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + ACTIVE_VERTEX = IMM_VERTICES( 1 ); + FLUSH_VERTEX = TAG(flush_tri_strip_1); +} + +static void TAG(flush_tri_strip_1)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + ACTIVE_VERTEX = IMM_VERTICES( 2 ); + FLUSH_VERTEX = TAG(flush_tri_strip_2); +} + +#define DO_TRISTRIP_TRI( vert0, vert1 ) \ + if (!HAVE_TRI_STRIP || FALLBACK_OR_CLIPPING) { \ + TNL_VERTEX *v2 = IMM_VERTICES( vert0 ); \ + TNL_VERTEX *v1 = IMM_VERTICES( vert1 ); \ + TAG(draw_tri)( ctx, v2, v1, v0 ); \ + } else if (EXTEND_PRIM( 1 )) { \ + EMIT_VERTEX( v0 ); \ + } else { \ + TNL_VERTEX *v2 = IMM_VERTICES( vert0 ); \ + TNL_VERTEX *v1 = IMM_VERTICES( vert1 ); \ + BEGIN_PRIM( GL_TRIANGLE_STRIP, 3 ); \ + EMIT_VERTEX( v2 ); \ + EMIT_VERTEX( v1 ); \ + EMIT_VERTEX( v0 ); \ + } + +static void TAG(flush_tri_strip_2)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + FLUSH_VERTEX = TAG(flush_tri_strip_3); + ACTIVE_VERTEX = IMM_VERTICES( 3 ); + DO_TRISTRIP_TRI( 0, 1 ); +} + +static void TAG(flush_tri_strip_3)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + FLUSH_VERTEX = TAG(flush_tri_strip_4); + ACTIVE_VERTEX = IMM_VERTICES( 0 ); + DO_TRISTRIP_TRI( 1, 2 ); +} + +static void TAG(flush_tri_strip_4)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + FLUSH_VERTEX = TAG(flush_tri_strip_5); + ACTIVE_VERTEX = IMM_VERTICES( 1 ); + DO_TRISTRIP_TRI( 2, 3 ); +} + +static void TAG(flush_tri_strip_5)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + FLUSH_VERTEX = TAG(flush_tri_strip_2); + ACTIVE_VERTEX = IMM_VERTICES( 2 ); + DO_TRISTRIP_TRI( 0, 3 ); +} + + + +/* ============================================================= + * GL_TRIANGLE_FAN + */ + +static void TAG(flush_tri_fan_2)( GLcontext *ctx, TNL_VERTEX *v0 ); +static void TAG(flush_tri_fan_1)( GLcontext *ctx, TNL_VERTEX *v0 ); + +static void TAG(flush_tri_fan_0)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + + ACTIVE_VERTEX = v0 + 1; + FLUSH_VERTEX = TAG(flush_tri_fan_1); +} + +static void TAG(flush_tri_fan_1)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + + ACTIVE_VERTEX = v0 + 1; + FLUSH_VERTEX = TAG(flush_tri_fan_2); +} + +#define DO_TRIFAN_TRI( vert0, vert1 ) \ + if (!HAVE_TRI_FAN || FALLBACK_OR_CLIPPING) { \ + TNL_VERTEX *v2 = IMM_VERTICES( vert0 ); \ + TNL_VERTEX *v1 = IMM_VERTICES( vert1 ); \ + TAG(draw_tri)( ctx, v2, v1, v0 ); \ + } else if (EXTEND_PRIM( 1 )) { \ + EMIT_VERTEX( v0 ); \ + } else { \ + TNL_VERTEX *v2 = IMM_VERTICES( vert0 ); \ + TNL_VERTEX *v1 = IMM_VERTICES( vert1 ); \ + BEGIN_PRIM( GL_TRIANGLE_FAN, 3 ); \ + EMIT_VERTEX( v2 ); \ + EMIT_VERTEX( v1 ); \ + EMIT_VERTEX( v0 ); \ + } + +static void TAG(flush_tri_fan_2)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + ACTIVE_VERTEX = IMM_VERTICES( 1 ); + FLUSH_VERTEX = TAG(flush_tri_fan_3 ); + DO_TRIFAN_TRI( 0, 1 ); +} + +static void TAG(flush_tri_fan_3)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + ACTIVE_VERTEX = IMM_VERTICES( 2 ); + FLUSH_VERTEX = TAG(flush_tri_fan_2 ); + DO_TRIFAN_TRI( 0, 2 ); +} + + + +/* ============================================================= + * GL_QUADS + */ + +static void TAG(flush_quad_3)( GLcontext *ctx, TNL_VERTEX *v0 ); +static void TAG(flush_quad_2)( GLcontext *ctx, TNL_VERTEX *v0 ); +static void TAG(flush_quad_1)( GLcontext *ctx, TNL_VERTEX *v0 ); + +static void TAG(flush_quad_0)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + IMM_VERTEX( v0 ) = v0 + 1; + FLUSH_VERTEX = TAG(flush_quad_1); +} + +static void TAG(flush_quad_1)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + IMM_VERTEX( v0 ) = v0 + 1; + FLUSH_VERTEX = TAG(flush_quad_2); +} + +static void TAG(flush_quad_2)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + IMM_VERTEX( v0 ) = v0 + 1; + FLUSH_VERTEX = TAG(flush_quad_3); +} + +static void TAG(flush_quad_3)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + TNL_VERTEX *v3 = v0 - 3; + TNL_VERTEX *v2 = v0 - 2; + TNL_VERTEX *v1 = v0 - 1; + + IMM_VERTEX( v0 ) = v3; + FLUSH_VERTEX = TAG(flush_quad_0); + + if (!HAVE_HW_QUADS || FALLBACK_OR_CLIPPING) { + CLIP_OR_DRAW_TRI( ctx, v3, v2, v0 ); + CLIP_OR_DRAW_TRI( ctx, v2, v1, v0 ); + } else { + EXTEND_PRIM_NF( GL_QUADS, 4 ); + EMIT_VERTEX( v3 ); + EMIT_VERTEX( v2 ); + EMIT_VERTEX( v1 ); + EMIT_VERTEX( v0 ); + } +} + + + +/* ============================================================= + * GL_QUAD_STRIP + */ + +static void TAG(flush_quad_strip_3)( GLcontext *ctx, TNL_VERTEX *v0 ); +static void TAG(flush_quad_strip_2)( GLcontext *ctx, TNL_VERTEX *v0 ); +static void TAG(flush_quad_strip_1)( GLcontext *ctx, TNL_VERTEX *v0 ); + +static void TAG(flush_quad_strip_0)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + + IMM_VERTEX( v3 ) = v0; + IMM_VERTEX( v0 ) = v0 + 1; + FLUSH_VERTEX = TAG(flush_quad_strip_1); +} + +static void TAG(flush_quad_strip_1)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + + IMM_VERTEX( v2 ) = v0; + IMM_VERTEX( v0 ) = v0 + 1; + FLUSH_VERTEX = TAG(flush_quad_strip_2); +} + +static void TAG(flush_quad_strip_2)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + + IMM_VERTEX( v1 ) = v0; + IMM_VERTEX( v0 ) = v0 + 1; + FLUSH_VERTEX = TAG(flush_quad_strip_3); +} + +static void TAG(flush_quad_strip_3)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + TNL_VERTEX *v3 = IMM_VERTEX( v3 ); + TNL_VERTEX *v2 = IMM_VERTEX( v2 ); + TNL_VERTEX *v1 = IMM_VERTEX( v1 ); + + IMM_VERTEX( v0 ) = v3; + IMM_VERTEX( v2 ) = v0; + IMM_VERTEX( v3 ) = v1; + FLUSH_VERTEX = TAG(flush_quad_strip_2); + + if (FALLBACK_OR_CLIPPING) { + CLIP_OR_DRAW_TRI( ctx, v3, v2, v0 ); + CLIP_OR_DRAW_TRI( ctx, v2, v1, v0 ); + } else { + DRAW_TRI( ctx, v3, v2, v0 ); + DRAW_TRI( ctx, v2, v1, v0 ); + } +} + + + +/* ============================================================= + * GL_POLYGON + */ + +static void TAG(flush_poly_2)( GLcontext *ctx, TNL_VERTEX *v0 ); +static void TAG(flush_poly_1)( GLcontext *ctx, TNL_VERTEX *v0 ); + +static void TAG(flush_poly_0)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + ACTIVE_VERTEX = IMM_VERTICES( 1 ); + FLUSH_VERTEX = TAG(flush_poly_1); +} + +static void TAG(flush_poly_1)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + ACTIVE_VERTEX = IMM_VERTICES( 2 ); + FLUSH_VERTEX = TAG(flush_poly_2); +} + +#define DO_POLY_TRI( vert0, vert1 ) \ + if (!HAVE_POLYGONS || FALLBACK_OR_CLIPPING) { \ + TNL_VERTEX *v2 = IMM_VERTICES( vert0 ); \ + TNL_VERTEX *v1 = IMM_VERTICES( vert1 ); \ + TAG(draw_tri)( ctx, v1, v0, v2 ); \ + } else if (EXTEND_PRIM( 1 )) { \ + EMIT_VERTEX( v0 ); \ + } else { \ + TNL_VERTEX *v2 = IMM_VERTICES( vert0 ); \ + TNL_VERTEX *v1 = IMM_VERTICES( vert1 ); \ + BEGIN_PRIM( GL_POLYGON, 3 ); \ + EMIT_VERTEX( v2 ); \ + EMIT_VERTEX( v1 ); \ + EMIT_VERTEX( v0 ); \ + } + +static void TAG(flush_poly_2)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + ACTIVE_VERTEX = IMM_VERTICES( 1 ); + FLUSH_VERTEX = TAG(flush_poly_3); + DO_POLY_TRI( 0, 1 ); +} + +static void TAG(flush_poly_3)( GLcontext *ctx, TNL_VERTEX *v0 ) +{ + LOCAL_VARS; + ACTIVE_VERTEX = IMM_VERTICES( 2 ); + FLUSH_VERTEX = TAG(flush_poly_2); + DO_POLY_TRI( 0, 2 ); +} + + +void (*TAG(flush_tab)[GL_POLYGON+1])( GLcontext *, TNL_VERTEX * ) = +{ + TAG(flush_point), + TAG(flush_line_0), + TAG(flush_line_loop_0), + TAG(flush_line_strip_0), + TAG(flush_triangle_0), + TAG(flush_tri_strip_0), + TAG(flush_tri_fan_0), + TAG(flush_quad_0), + TAG(flush_quad_strip_0), + TAG(flush_poly_0), +}; + + +#ifndef PRESERVE_PRIM_DEFS +#undef LOCAL_VARS +#undef GET_INTERP_FUNC +#undef IMM_VERTEX +#undef IMM_VERTICES +#undef FLUSH_VERTEX +#endif +#undef PRESERVE_PRIM_DEFS +#undef EXTEND_PRIM +#undef EMIT_VERTEX +#undef EMIT_VERTEX_TRI +#undef EMIT_VERTEX_LINE +#undef EMIT_VERTEX_POINT +#undef TAG diff --git a/src/mesa/tnl_dd/imm/t_dd_imm_tapi.h b/src/mesa/tnl_dd/imm/t_dd_imm_tapi.h new file mode 100644 index 00000000000..b82a9abebff --- /dev/null +++ b/src/mesa/tnl_dd/imm/t_dd_imm_tapi.h @@ -0,0 +1,75 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Gareth Hughes <[email protected]> + * Keith Whitwell <[email protected]> + */ + +/* Template for immediate mode texture coordinate functions. + */ + +#ifndef DO_PROJ_TEX +#error "Need to define DO_PROJ_TEX" +#endif + + +/* ============================================================= + * Notify on calls to texture4f, to allow switch to projected texture + * vertex format: + */ + +static void TAG(TexCoord4f)( GLfloat s, GLfloat t, GLfloat r, GLfloat q ) +{ + GET_CURRENT; + DO_PROJ_TEX; + TEXCOORD4( s, t, r, q ); +} + +static void TAG(TexCoord4fv)( const GLfloat *v ) +{ + GET_CURRENT; + DO_PROJ_TEX; + TEXCOORD4( v[0], v[1], v[2], v[3] ); +} + +static void TAG(MultiTexCoord4fARB)( GLenum target, GLfloat s, + GLfloat t, GLfloat r, GLfloat q ) +{ + GET_CURRENT; + DO_PROJ_TEX; + MULTI_TEXCOORD4( unit, s, t, r, q ); +} + +static void TAG(MultiTexCoord4fvARB)( GLenum target, const GLfloat *v ) +{ + GET_CURRENT; + DO_PROJ_TEX; + MULTI_TEXCOORD4( unit, v[0], v[1], v[2], v[3] ); +} + + + +#undef DO_PROJ_TEX +#undef TAG diff --git a/src/mesa/tnl_dd/imm/t_dd_imm_vapi.h b/src/mesa/tnl_dd/imm/t_dd_imm_vapi.h new file mode 100644 index 00000000000..95e93b1c839 --- /dev/null +++ b/src/mesa/tnl_dd/imm/t_dd_imm_vapi.h @@ -0,0 +1,159 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Gareth Hughes <[email protected]> + * Keith Whitwell <[email protected]> + */ + +/* Template for immediate mode vertex functions. + */ + +#define DBG 0 + +#define VERTEX( ox, oy, oz, ow ) +do { + GET_CURRENT_VERTEX; + GLfloat w; + GLuint mask; + const GLfloat * const m = ctx->_ModelProjectMatrix.m; + + if (DO_FULL_MATRIX) { + VERTEX_CLIP(0) = m[0] * ox + m[4] * oy + m[8] * oz + m[12] * ow; + VERTEX_CLIP(1) = m[1] * ox + m[5] * oy + m[9] * oz + m[13] * ow; + VERTEX_CLIP(2) = m[2] * ox + m[6] * oy + m[10] * oz + m[14] * ow; + VERTEX_CLIP(3) = m[3] * ox + m[7] * oy + m[11] * oz + m[15] * ow; + w = VERTEX_CLIP(3); + } + else if (DO_NOROT_MATRIX) { + VERTEX_CLIP(0) = m[0] * ox + m[12] * ow; + VERTEX_CLIP(1) = m[5] * oy + m[13] * ow; + VERTEX_CLIP(2) = m[10] * oz + m[14] * ow; + VERTEX_CLIP(3) = ow; + w = ow; + } + else { + ASSERT (DO_IDENTITY_MATRIX); + VERTEX_CLIP(0) = ox; + VERTEX_CLIP(1) = oy; + VERTEX_CLIP(2) = oz; + VERTEX_CLIP(3) = ow; + w = ow; + } + + mask = 0; + if (DO_CLIP_TEST) { + if ( VERTEX_CLIP(0) > w ) mask |= CLIP_RIGHT_BIT; + if ( VERTEX_CLIP(0) < -w ) mask |= CLIP_LEFT_BIT; + if ( VERTEX_CLIP(1) > w ) mask |= CLIP_TOP_BIT; + if ( VERTEX_CLIP(1) < -w ) mask |= CLIP_BOTTOM_BIT; + if ( VERTEX_CLIP(2) > w ) mask |= CLIP_FAR_BIT; + if ( VERTEX_CLIP(2) < -w ) mask |= CLIP_NEAR_BIT; + VERTEX_MASK(v) = mask; + } + + if (!mask) { + if (HAVE_VERTEX_WIN) { + if (!HAVE_HW_VIEWPORT) { + const GLfloat *s = GET_VIEWPORT_MATRIX(); + if (HAVE_W && HAVE_HW_DIVIDE) { + VERTEX_WIN( 0 ) = s[0] * VERTEX_CLIP( 0 ) + s[12]; + VERTEX_WIN( 1 ) = s[5] * VERTEX_CLIP( 1 ) + s[13]; + VERTEX_WIN( 2 ) = s[10] * VERTEX_CLIP( 2 ) + s[14]; + VERTEX_WIN( 3 ) = w; + } + else { + const GLfloat oow = 1.0/w; /* possibly opt away */ + VERTEX_WIN( 0 ) = s[0] * VERTEX_CLIP( 0 ) * oow + s[12]; + VERTEX_WIN( 1 ) = s[5] * VERTEX_CLIP( 1 ) * oow + s[13]; + VERTEX_WIN( 2 ) = s[10] * VERTEX_CLIP( 2 ) * oow + s[14]; + if (HAVE_W) + VERTEX_WIN( 3 ) = oow; + } + } + else if (HAVE_W && HAVE_HW_DIVIDE) { + if (!VERTEX_WIN_IS_VERTEX_CLIP) { + VERTEX_WIN( 0 ) = VERTEX_CLIP( 0 ); + VERTEX_WIN( 1 ) = VERTEX_CLIP( 1 ); + VERTEX_WIN( 2 ) = VERTEX_CLIP( 2 ); + VERTEX_WIN( 3 ) = w; + } + } + else { + const GLfloat oow = 1.0/w; /* possibly opt away */ + VERTEX_WIN( 0 ) = VERTEX_CLIP( 0 ) * oow; + VERTEX_WIN( 1 ) = VERTEX_CLIP( 1 ) * oow; + VERTEX_WIN( 2 ) = VERTEX_CLIP( 2 ) * oow; + if (HAVE_W) + VERTEX_WIN( 3 ) = oow; + } + } + } else if (!FALLBACK_OR_CLIPPING) { + SET_CLIPPING(); /* transition to clipping */ + } + + COPY_VERTEX_FROM_CURRENT; + BUILD_PRIM_FROM_VERTEX; +} + +/* Let the compiler optimize away the constant operations: + */ +static void VTAG(Vertex2f)( GLfloat ox, GLfloat oy ) +{ + /* Cliptest on clip[2] could also be eliminated... + */ + VERTEX( ox, oy, 0, 1 ); +} + +static void VTAG(Vertex2fv)( const GLfloat *obj ) +{ + /* Cliptest on clip[2] could also be eliminated... + */ + VERTEX( obj[0], obj[1], 0, 1 ); +} + +static void VTAG(Vertex3f)( GLfloat ox, GLfloat oy, GLfloat oz ) +{ + VERTEX( ox, oy, oz, 1 ); +} + +static void VTAG(Vertex3fv)( const GLfloat *obj ) +{ + VERTEX( obj[0], obj[1], obj[2], 1 ); +} + +static void VTAG(Vertex4f)( GLfloat ox, GLfloat oy, GLfloat oz, GLfloat ow ) +{ + VERTEX( ox, oy, oz, ow ); +} + +static void VTAG(Vertex4fv)( const GLfloat *obj ) +{ + VERTEX( obj[0], obj[1], obj[2], obj[3] ); +} + + +#undef DO_FULL_MATRIX +#undef VTAG +#undef VERTEX diff --git a/src/mesa/tnl_dd/imm/t_dd_imm_vb.c b/src/mesa/tnl_dd/imm/t_dd_imm_vb.c new file mode 100644 index 00000000000..0c4462f556f --- /dev/null +++ b/src/mesa/tnl_dd/imm/t_dd_imm_vb.c @@ -0,0 +1,204 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell <[email protected]> + */ + +/* Template to build clipping routines to support t_dd_imm_primtmp.h. + * + * The TAG(draw_line) and TAG(draw_triangle) routines are called in + * clipping and fallback scenarios, and when the native hardware + * primitive (eg polygons) is unavailable. + */ + + +#define CLIP_DOTPROD(K, A, B, C, D) \ + (CLIP_X(K)*A + CLIP_Y(K)*B + \ + CLIP_Z(K)*C + CLIP_W(K)*D) + +#define POLY_CLIP( PLANE, A, B, C, D ) \ +do { \ + if (mask & PLANE) { \ + TNL_VERTEX **indata = inlist[in]; \ + TNL_VERTEX **outdata = inlist[in ^= 1]; \ + TNL_VERTEX *J = indata[0]; \ + GLfloat dpJ = CLIP_DOTPROD(J, A, B, C, D ); \ + GLuint outcount = 0; \ + GLuint i; \ + \ + indata[n] = indata[0]; /* prevent rotation of vertices */ \ + for (i = 1; i <= n; i++) { \ + TNL_VERTEX *I = indata[i]; \ + GLfloat dpI = CLIP_DOTPROD(idx, A, B, C, D ); \ + \ + if (!NEGATIVE(dpPrev)) { \ + outdata[outcount++] = J; \ + } \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + TNL_VERTEX *O = verts++; \ + outdata[outcount++] = O; \ + if (NEGATIVE(dpI)) { \ + /* Going out of bounds. Avoid division by zero as we \ + * know dp != dpPrev from DIFFERENT_SIGNS, above. \ + */ \ + GLfloat t = dpI / (dpI - dpJ); \ + INTERP( ctx, t, O, I, J ); \ + } else { \ + /* Coming back in. \ + */ \ + GLfloat t = dpJ / (dpJ - dpI); \ + INTERP( ctx, t, O, J, I ); \ + } \ + } \ + \ + J = I; \ + dpJ = dpI; \ + } \ + \ + if (outcount < 3) \ + return; \ + \ + nr = outcount; \ + } \ +} while (0) + + +#define LINE_CLIP(PLANE, A, B, C, D ) \ +do { \ + if (mask & PLANE) { \ + GLfloat dpI = CLIP_DOTPROD( I, A, B, C, D ); \ + GLfloat dpJ = CLIP_DOTPROD( J, A, B, C, D ); \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + TNL_VERTEX *O = verts++; \ + if (NEGATIVE(dpJ)) { \ + GLfloat t = dpI / (dpI - dpJ); \ + INTERP( ctx, t, O, I, J ); \ + J = O; \ + } else { \ + GLfloat t = dpJ / (dpJ - dpI); \ + INTERP( ctx, t, O, J, I ); \ + I = O; \ + } \ + } \ + else if (NEGATIVE(dpI)) \ + return; \ + } \ +} while (0) + + + +/* Clip a line against the viewport and user clip planes. + */ +static void TAG(clip_draw_line)( GLcontext *ctx, + TNL_VERTEX *I, + TNL_VERTEX *J, + GLuint mask ) +{ + LOCAL_VARS; + GET_INTERP_FUNC; + TNL_VERTEX tmp[MAX_CLIPPED_VERTICES]; + TNL_VERTEX *verts = tmp; + TNL_VERTEX *pv = J; + + LINE_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); + LINE_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); + LINE_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); + LINE_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); + LINE_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); + LINE_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); + + if ((ctx->_TriangleCaps & DD_FLATSHADE) && J != pv) + COPY_PV( ctx, J, pv ); + + DRAW_LINE( I, J ); +} + + +/* Clip a triangle against the viewport and user clip planes. + */ +static void TAG(clip_draw_triangle)( GLcontext *ctx, + TNL_VERTEX *v0, + TNL_VERTEX *v1, + TNL_VERTEX *v2, + GLuint mask ) +{ + LOCAL_VARS; + GET_INTERP_FUNC; + TNL_VERTEX tmp[MAX_CLIPPED_VERTICES]; + TNL_VERTEX *verts = tmp; + TNL_VERTEX *(inlist[2][MAX_CLIPPED_VERTICES]); + TNL_VERTEX **out; + GLuint in = 0; + GLuint n = 3; + GLuint i; + + ASSIGN_3V(inlist, v2, v0, v1 ); /* pv rotated to slot zero */ + + POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); + POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); + POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); + POLY_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); + POLY_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); + POLY_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); + + if ((ctx->_TriangleCaps & DD_FLATSHADE) && v2 != inlist[0]) + COPY_PV( ctx, inlist[0], v2 ); + + out = inlist[in]; + DRAW_POLYGON( out, n ); +} + + +static __inline void TAG(draw_triangle)( GLcontext *ctx, + TNL_VERTEX *v0, + TNL_VERTEX *v1, + TNL_VERTEX *v2 ) +{ + LOCAL_VARS; + GLubyte ormask = (v0->mask | v1->mask | v2->mask); + + if ( !ormask ) { + DRAW_TRI( v0, v1, v2 ); + } else if ( !(v0->mask & v1->mask & v2->mask) ) { + TAG(clip_draw_triangle)( ctx, v0, v1, v2, ormask ); + } +} + +static __inline void TAG(draw_line)( GLcontext *ctx, + TNL_VERTEX *v0, + TNL_VERTEX *v1 ) +{ + LOCAL_VARS; + GLubyte ormask = (v0->mask | v1->mask); + + if ( !ormask ) { + DRAW_LINE( v0, v1 ); + } else if ( !(v0->mask & v1->mask) ) { + TAG(clip_draw_line)( ctx, v0, v1, ormask ); + } +} + diff --git a/src/mesa/tnl_dd/imm/t_dd_imm_vbtmp.h b/src/mesa/tnl_dd/imm/t_dd_imm_vbtmp.h new file mode 100644 index 00000000000..2f76553cff9 --- /dev/null +++ b/src/mesa/tnl_dd/imm/t_dd_imm_vbtmp.h @@ -0,0 +1,268 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell <[email protected]> + */ + +/* Template to build support for t_dd_imm_* tnl module using vertices + * as defined in t_dd_vertex.h. + * + * See t_dd_vbtmp.h for definitions of arguments to this file. + * Unfortunately it seems necessary to duplicate a lot of that code. + */ + +#ifndef LOCALVARS +#define LOCALVARS +#endif + + + +/* COPY_VERTEX_FROM_CURRENT in t_dd_imm_vapi.c + */ +static void TAG(emit_vfmt)( GLcontext *ctx, VERTEX *v ) +{ + LOCALVARS + ; + + /* This template assumes (like t_dd_vbtmp.h) that color is ubyte. + */ + if (DO_TEX0 || DO_TEX1 || !HAVE_TINY_VERTICES) + { + const GLubyte *col = GET_HARDWARE_COLOR(); + if (HAVE_RGBA_COLOR) { + v->v.ui[4] = *(GLuint *)&col; + } else { + v->v.color.blue = col[2]; + v->v.color.green = col[1]; + v->v.color.red = col[0]; + v->v.color.alpha = col[3]; + } + } + else { + if (HAVE_RGBA_COLOR) { + v->v.ui[3] = *(GLuint *)col; + } + else { + v->tv.color.blue = col[2]; + v->tv.color.green = col[1]; + v->tv.color.red = col[0]; + v->tv.color.alpha = col[3]; + } + } + + if (DO_TEX0) { + GLfloat *tc = ctx->Current.Texture[0]; + v->v.u0 = tc[0]; + v->v.v0 = tc[1]; + if (DO_PTEX) { + if (HAVE_PTEX_VERTICES) { + v->pv.q0 = tc[3]; + } + else { + float rhw = 1.0 / tc[3]; + v->v.w *= tc[3]; + v->v.u0 *= rhw; + v->v.v0 *= rhw; + } + } + } + if (DO_TEX1) { + GLfloat *tc = ctx->Current.Texture[1]; + if (DO_PTEX) { + v->pv.u1 = tc[0]; + v->pv.v1 = tc[1]; + v->pv.q1 = tc[3]; + } + else { + v->v.u1 = tc[0]; + v->v.v1 = tc[1]; + } + } + else if (DO_PTEX) { + *(GLuint *)&v->pv.q1 = 0; /* avoid culling on radeon */ + } + if (DO_TEX2) { + GLfloat *tc = ctx->Current.Texture[2]; + if (DO_PTEX) { + v->pv.u2 = tc[0]; + v->pv.v2 = tc[1]; + v->pv.q2 = tc[3]; + } + else { + v->v.u2 = tc[0]; + v->v.v2 = tc[1]; + } + } + if (DO_TEX3) { + GLfloat *tc = ctx->Current.Texture[3]; + if (DO_PTEX) { + v->pv.u3 = tc[0]; + v->pv.v3 = tc[1]; + v->pv.q3 = tc[3]; + } + else { + v->v.u3 = tc[0]; + v->v.v3 = tc[1]; + } + } +} + + + + +static void TAG(interp)( GLcontext *ctx, + GLfloat t, + TNL_VERTEX *dst, + TNL_VERTEX *in, + TNL_VERTEX *out ) +{ + LOCALVARS + const GLfloat *s = GET_VIEWPORT_MAT(); + GLfloat w; + + (void)s; + + if (HAVE_HW_DIVIDE) { + VIEWPORT_X( dst->v.v.x, dst->clip[0] ); + VIEWPORT_Y( dst->v.v.y, dst->clip[1] ); + VIEWPORT_Z( dst->v.v.z, dst->clip[2] ); + w = dstclip[3]; + } + else { + w = 1.0 / dst->clip[3]; + VIEWPORT_X( dst->v.v.x, dst->clip[0] * w ); + VIEWPORT_Y( dst->v.v.y, dst->clip[1] * w ); + VIEWPORT_Z( dst->v.v.z, dst->clip[2] * w ); + } + + if (HAVE_HW_DIVIDE || DO_TEX0) { + + dst->v.v.w = w; + + INTERP_UB( t, dst->v.ub4[4][0], out->v.ub4[4][0], in->v.ub4[4][0] ); + INTERP_UB( t, dst->v.ub4[4][1], out->v.ub4[4][1], in->v.ub4[4][1] ); + INTERP_UB( t, dst->v.ub4[4][2], out->v.ub4[4][2], in->v.ub4[4][2] ); + INTERP_UB( t, dst->v.ub4[4][3], out->v.ub4[4][3], in->v.ub4[4][3] ); + + if (DO_TEX0) { + if (DO_PTEX) { + if (HAVE_PTEX_VERTICES) { + INTERP_F( t, dst->v.pv.u0, out->v.pv.u0, in->v.pv.u0 ); + INTERP_F( t, dst->v.pv.v0, out->v.pv.v0, in->v.pv.v0 ); + INTERP_F( t, dst->v.pv.q0, out->v.pv.q0, in->v.pv.q0 ); + } else { + GLfloat wout = out->clip[3]; /* projected clip */ + GLfloat win = in->clip[3]; /* projected clip */ + GLfloat qout = out->v.pv.w / wout; + GLfloat qin = in->v.pv.w / win; + GLfloat qdst, rqdst; + + ASSERT( !HAVE_HW_DIVIDE ); /* assert win, wout projected clip */ + + INTERP_F( t, dst->v.v.u0, out->v.v.u0 * qout, in->v.v.u0 * qin ); + INTERP_F( t, dst->v.v.v0, out->v.v.v0 * qout, in->v.v.v0 * qin ); + INTERP_F( t, qdst, qout, qin ); + + rqdst = 1.0 / qdst; + dst->v.v.u0 *= rqdst; + dst->v.v.v0 *= rqdst; + dst->v.v.w *= rqdst; + } + } + else { + INTERP_F( t, dst->v.v.u0, out->v.v.u0, in->v.v.u0 ); + INTERP_F( t, dst->v.v.v0, out->v.v.v0, in->v.v.v0 ); + } + } + if (DO_TEX1) { + if (DO_PTEX) { + INTERP_F( t, dst->v.pv.u1, out->v.pv.u1, in->v.pv.u1 ); + INTERP_F( t, dst->v.pv.v1, out->v.pv.v1, in->v.pv.v1 ); + INTERP_F( t, dst->v.pv.q1, out->v.pv.q1, in->v.pv.q1 ); + } else { + INTERP_F( t, dst->v.v.u1, out->v.v.u1, in->v.v.u1 ); + INTERP_F( t, dst->v.v.v1, out->v.v.v1, in->v.v.v1 ); + } + } + else if (DO_PTEX) { + dst->v.pv.q0 = 0.0; /* must be a valid float on radeon */ + } + if (DO_TEX2) { + if (DO_PTEX) { + INTERP_F( t, dst->v.pv.u2, out->v.pv.u2, in->v.pv.u2 ); + INTERP_F( t, dst->v.pv.v2, out->v.pv.v2, in->v.pv.v2 ); + INTERP_F( t, dst->v.pv.q2, out->v.pv.q2, in->v.pv.q2 ); + } else { + INTERP_F( t, dst->v.v.u2, out->v.v.u2, in->v.v.u2 ); + INTERP_F( t, dst->v.v.v2, out->v.v.v2, in->v.v.v2 ); + } + } + if (DO_TEX3) { + if (DO_PTEX) { + INTERP_F( t, dst->v.pv.u3, out->v.pv.u3, in->v.pv.u3 ); + INTERP_F( t, dst->v.pv.v3, out->v.pv.v3, in->v.pv.v3 ); + INTERP_F( t, dst->v.pv.q3, out->v.pv.q3, in->v.pv.q3 ); + } else { + INTERP_F( t, dst->v.v.u3, out->v.v.u3, in->v.v.u3 ); + INTERP_F( t, dst->v.v.v3, out->v.v.v3, in->v.v.v3 ); + } + } + } else { + /* 4-dword vertex. Color is in v[3] and there is no oow coordinate. + */ + INTERP_UB( t, dst->v.ub4[3][0], out->v.ub4[3][0], in->v.ub4[3][0] ); + INTERP_UB( t, dst->v.ub4[3][1], out->v.ub4[3][1], in->v.ub4[3][1] ); + INTERP_UB( t, dst->v.ub4[3][2], out->v.ub4[3][2], in->v.ub4[3][2] ); + INTERP_UB( t, dst->v.ub4[3][3], out->v.ub4[3][3], in->v.ub4[3][3] ); + } +} + + +static __inline void TAG(copy_pv)( GLcontext *ctx, + TNL_VERTEX *dst, + TNL_VERTEX *src ) +{ + if (DO_TEX0 || DO_TEX1 || !HAVE_TINY_VERTICES) { + dst->v.v.ui[4] = src->v.v.ui[4]; + } + else { + dst->v.v.ui[3] = src->v.v.ui[3]; + } +} + + + +static void TAG(init)( void ) +{ + setup_tab[IND].emit = TAG(emit_vfmt); + setup_tab[IND].interp = TAG(interp_vfmt); +} + + +#undef IND +#undef TAG + + + |