diff options
Diffstat (limited to 'src/mesa/swrast_setup')
-rw-r--r-- | src/mesa/swrast_setup/NOTES | 79 | ||||
-rw-r--r-- | src/mesa/swrast_setup/ss_context.c | 103 | ||||
-rw-r--r-- | src/mesa/swrast_setup/ss_context.h | 33 | ||||
-rw-r--r-- | src/mesa/swrast_setup/ss_triangle.c | 12 | ||||
-rw-r--r-- | src/mesa/swrast_setup/ss_tritmp.h | 22 | ||||
-rw-r--r-- | src/mesa/swrast_setup/ss_vb.c | 218 | ||||
-rw-r--r-- | src/mesa/swrast_setup/ss_vbtmp.h | 238 | ||||
-rw-r--r-- | src/mesa/swrast_setup/swrast_setup.h | 50 |
8 files changed, 426 insertions, 329 deletions
diff --git a/src/mesa/swrast_setup/NOTES b/src/mesa/swrast_setup/NOTES index 4445b332d9..c6cb4ab348 100644 --- a/src/mesa/swrast_setup/NOTES +++ b/src/mesa/swrast_setup/NOTES @@ -6,10 +6,8 @@ swrast vertices from the t&l vertex_buffer structs, and to use them to perform triangle setup functions not implemented in the software rasterizer. -The module provides a RasterSetup function to plug into the t&l driver -interface. This hook had previously been used for hardware -rasterizers, with the software rasterizer taking its data directly -from the vertex buffer. +The module implements a full set of functions to plug into the +t_vb_render.c driver interface (tnl->Driver.Render.*). There are strong advantages to decoupling the software rasterizer from the t&l module, primarily allowing hardware drivers better control @@ -18,63 +16,50 @@ rasterizer in the t&l module, allowing the two modules to evolve independently and allowing either to be substituted with equivalent functionality from another codebase. -This module provides helpers for triangle/quad setup for offset, -unfilled and twoside-lit triangles. The software rasterizer doesn't -handle these primitives directly. +This module implements triangle/quad setup for offset, unfilled and +twoside-lit triangles. The software rasterizer doesn't handle these +primitives directly. -Hardware rasterization drivers probably have little use for this -module. Rather, they might provide a layer that translates their -native (hardware) vertices to swrast vertices before calling into the -swrast module for fallbacks. +Hardware rasterization drivers typically use this module in situations +where no hardware rasterization is possible, ie during total +fallbacks. STATE -This module associates an array of SWvertex structs with each VB. -Thus there are: - - GLboolean _swsetup_RegisterVB( struct vertex_buffer *VB ); - void _swsetup_UnregisterVB( struct vertex_buffer *VB ); - -Which must be called to create and destroy internal vertex storage for -this module. - -To create and destroy the module itself: +To create and destroy the module: GLboolean _swsetup_CreateContext( GLcontext *ctx ); void _swsetup_DestroyContext( GLcontext *ctx ); -Like the software rasterizer, this module tracks state changes -internally and maintains a set of entry points which will always -reflect the current state. For this to work, the driver must call: - - void _swsetup_InvalidateState( GLcontext *ctx, GLuint new_state ); +The module is not active by default, and must be installed by calling +_swrast_Wakeup(). This function installs internal swrast_setup +functions into all the tnl->Driver.Render driver hooks, thus taking +over the task of rasterization entirely: -SERVICES + void _swrast_Wakeup( GLcontext *ctx ); -The module provides the following entrypoints: + +This module tracks state changes internally and maintains derived +values based on the current state. For this to work, the driver +ensure the following funciton is called whenever the state changes and +the swsetup module is 'awake': - void _swrast_RasterSetup( struct vertex_buffer *VB, - GLuint start, GLuint end ); - -Build SWvertices for <VB> between indices start and end. - - void _swsetup_Quad( GLcontext *ctx, GLuint v0, GLuint v1, - GLuint v2, GLuint v3, GLuint pv ); - - void _swsetup_Triangle( GLcontext *ctx, GLuint v0, GLuint v1, - GLuint v2, GLuint pv ); + void _swsetup_InvalidateState( GLcontext *ctx, GLuint new_state ); - void _swsetup_Line( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv ); +There is no explicit call to put the swsetup module to sleep. Simply +install other function pointers into all the tnl->Driver.Render.* +hooks, and (optionally) cease calling _swsetup_InvalidateState(). +DRIVER INTERFACE - void _swsetup_Points( GLcontext *ctx, GLuint first, GLuint last ); +The module offers a minimal driver interface: -Draw quad, triangle, line, points. Note that these are in the format -expected by core mesa. The Quad and Triangle functions handle -unfilled, offset, twoside-lit and flat-shaded primitives correctly. + void (*Start)( GLcontext *ctx ); + void (*Finish)( GLcontext *ctx ); + +These are called before and after the completion of all swrast drawing +activity. As swrast doesn't call callbacks during triangle, line or +point rasterization, these are necessary to provide locking hooks for +some drivers. They may otherwise be left null. -These functions can thus be plugged into the ctx->Driver struct and -left permanently in place, providing the InvalidateState() routine is -correctly called on state changes. -
\ No newline at end of file diff --git a/src/mesa/swrast_setup/ss_context.c b/src/mesa/swrast_setup/ss_context.c index def9e4f43c..2e92342e07 100644 --- a/src/mesa/swrast_setup/ss_context.c +++ b/src/mesa/swrast_setup/ss_context.c @@ -1,4 +1,4 @@ -/* $Id: ss_context.c,v 1.13 2001/03/12 00:48:43 gareth Exp $ */ +/* $Id: ss_context.c,v 1.14 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -32,12 +32,14 @@ #include "ss_context.h" #include "ss_triangle.h" #include "ss_vb.h" -#include "ss_interp.h" #include "swrast_setup.h" +#include "tnl/tnl.h" #include "tnl/t_context.h" +#include "tnl/t_pipeline.h" #define _SWSETUP_NEW_VERTS (_NEW_RENDERMODE| \ + _NEW_POLYGON| \ _NEW_LIGHT| \ _NEW_TEXTURE| \ _NEW_COLOR| \ @@ -47,47 +49,6 @@ #define _SWSETUP_NEW_RENDERINDEX (_NEW_POLYGON|_NEW_LIGHT) -/* Dispatch from these fixed entrypoints to the state-dependent - * functions. - * - * The design of swsetup suggests that we could really program - * ctx->Driver.TriangleFunc directly from _swsetup_RenderStart, and - * avoid this second level of indirection. However, this is more - * convient for fallback cases in hardware rasterization drivers. - */ -void -_swsetup_Quad( GLcontext *ctx, GLuint v0, GLuint v1, - GLuint v2, GLuint v3 ) -{ - SWSETUP_CONTEXT(ctx)->Quad( ctx, v0, v1, v2, v3 ); -} - -void -_swsetup_Triangle( GLcontext *ctx, GLuint v0, GLuint v1, - GLuint v2 ) -{ - SWSETUP_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 ); -} - -void -_swsetup_Line( GLcontext *ctx, GLuint v0, GLuint v1 ) -{ - SWSETUP_CONTEXT(ctx)->Line( ctx, v0, v1 ); -} - -void -_swsetup_Points( GLcontext *ctx, GLuint first, GLuint last ) -{ - SWSETUP_CONTEXT(ctx)->Points( ctx, first, last ); -} - -void -_swsetup_BuildProjectedVertices( GLcontext *ctx, GLuint start, GLuint end, - GLuint new_inputs ) -{ - SWSETUP_CONTEXT(ctx)->BuildProjVerts( ctx, start, end, new_inputs ); -} - GLboolean _swsetup_CreateContext( GLcontext *ctx ) @@ -98,7 +59,8 @@ _swsetup_CreateContext( GLcontext *ctx ) if (!swsetup) return GL_FALSE; - swsetup->verts = (SWvertex *) ALIGN_MALLOC( sizeof(SWvertex) * tnl->vb.Size, 32); + swsetup->verts = (SWvertex *) ALIGN_MALLOC( sizeof(SWvertex) * tnl->vb.Size, + 32); if (!swsetup->verts) { FREE(swsetup); return GL_FALSE; @@ -108,7 +70,6 @@ _swsetup_CreateContext( GLcontext *ctx ) swsetup->NewState = ~0; _swsetup_vb_init( ctx ); - _swsetup_interp_init( ctx ); _swsetup_trifuncs_init( ctx ); return GL_TRUE; @@ -126,17 +87,16 @@ _swsetup_DestroyContext( GLcontext *ctx ) } } -void +static void _swsetup_RenderPrimitive( GLcontext *ctx, GLenum mode ) { SWSETUP_CONTEXT(ctx)->render_prim = mode; } -void +static void _swsetup_RenderStart( GLcontext *ctx ) { SScontext *swsetup = SWSETUP_CONTEXT(ctx); - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; GLuint new_state = swsetup->NewState; if (new_state & _SWSETUP_NEW_RENDERINDEX) { @@ -149,16 +109,19 @@ _swsetup_RenderStart( GLcontext *ctx ) swsetup->NewState = 0; - if (VB->ClipMask && VB->importable_data) - VB->import_data( ctx, - VB->importable_data, - VEC_NOT_WRITEABLE|VEC_BAD_STRIDE); + if (swsetup->Driver.Start) + swsetup->Driver.Start( ctx ); } -void +static void _swsetup_RenderFinish( GLcontext *ctx ) { + SScontext *swsetup = SWSETUP_CONTEXT(ctx); + _swrast_flush( ctx ); + + if (swsetup->Driver.Finish) + swsetup->Driver.Finish( ctx ); } void @@ -166,23 +129,29 @@ _swsetup_InvalidateState( GLcontext *ctx, GLuint new_state ) { SScontext *swsetup = SWSETUP_CONTEXT(ctx); swsetup->NewState |= new_state; - - if (new_state & _SWSETUP_NEW_INTERP) { - swsetup->RenderInterp = _swsetup_validate_interp; - swsetup->RenderCopyPV = _swsetup_validate_copypv; - } } -void -_swsetup_RenderInterp( GLcontext *ctx, GLfloat t, - GLuint dst, GLuint out, GLuint in, - GLboolean force_boundary ) -{ - SWSETUP_CONTEXT(ctx)->RenderInterp( ctx, t, dst, out, in, force_boundary ); -} void -_swsetup_RenderCopyPV( GLcontext *ctx, GLuint dst, GLuint src ) +_swsetup_Wakeup( GLcontext *ctx ) { - SWSETUP_CONTEXT(ctx)->RenderCopyPV( ctx, dst, src ); + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.Start = _swsetup_RenderStart; + tnl->Driver.Render.Finish = _swsetup_RenderFinish; + tnl->Driver.Render.PrimitiveNotify = _swsetup_RenderPrimitive; + /* interp */ + /* copypv */ + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; /* new */ + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; /* new */ + /* points */ + /* line */ + /* triangle */ + /* quad */ + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + /* buildvertices */ + tnl->Driver.Render.Multipass = 0; + _tnl_need_projected_coords( ctx, GL_TRUE ); + _swsetup_InvalidateState( ctx, ~0 ); } diff --git a/src/mesa/swrast_setup/ss_context.h b/src/mesa/swrast_setup/ss_context.h index 895fb1b03e..f477f850cd 100644 --- a/src/mesa/swrast_setup/ss_context.h +++ b/src/mesa/swrast_setup/ss_context.h @@ -1,4 +1,4 @@ -/* $Id: ss_context.h,v 1.7 2001/03/12 00:48:43 gareth Exp $ */ +/* $Id: ss_context.h,v 1.8 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -36,35 +36,14 @@ typedef struct { GLuint NewState; - GLuint StateChanges; - - /* Function hooks, trigger lazy state updates. - */ - void (*InvalidateState)( GLcontext *ctx, GLuint new_state ); - - void (*BuildProjVerts)( GLcontext *ctx, - GLuint start, GLuint end, GLuint new_inputs ); - - void (*Quad)( GLcontext *ctx, GLuint v0, GLuint v1, - GLuint v2, GLuint v3 ); - - void (*Triangle)( GLcontext *ctx, GLuint v0, GLuint v1, - GLuint v2 ); - - void (*Line)( GLcontext *ctx, GLuint v0, GLuint v1 ); - - void (*Points)( GLcontext *ctx, GLuint first, GLuint last ); - - void (*RenderCopyPV)( GLcontext *ctx, GLuint dst, GLuint src ); - - void (*RenderInterp)( GLcontext *ctx, GLfloat t, - GLuint dst, GLuint out, GLuint in, - GLboolean force_boundary ); - - SWvertex *verts; GLenum render_prim; + GLuint SetupIndex; + struct { + void (*Start)( GLcontext * ); + void (*Finish)( GLcontext * ); + } Driver; } SScontext; #define SWSETUP_CONTEXT(ctx) ((SScontext *)ctx->swsetup_context) diff --git a/src/mesa/swrast_setup/ss_triangle.c b/src/mesa/swrast_setup/ss_triangle.c index a12429e26d..7b2d638213 100644 --- a/src/mesa/swrast_setup/ss_triangle.c +++ b/src/mesa/swrast_setup/ss_triangle.c @@ -1,4 +1,4 @@ -/* $Id: ss_triangle.c,v 1.13 2001/04/28 08:39:18 keithw Exp $ */ +/* $Id: ss_triangle.c,v 1.14 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -262,7 +262,7 @@ static void swsetup_line( GLcontext *ctx, GLuint v0, GLuint v1 ) void _swsetup_choose_trifuncs( GLcontext *ctx ) { - SScontext *swsetup = SWSETUP_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint ind = 0; if (ctx->Polygon._OffsetAny) @@ -277,8 +277,8 @@ void _swsetup_choose_trifuncs( GLcontext *ctx ) if (ctx->Visual.rgbMode) ind |= SS_RGBA_BIT; - swsetup->Triangle = tri_tab[ind]; - swsetup->Quad = quad_tab[ind]; - swsetup->Line = swsetup_line; - swsetup->Points = swsetup_points; + tnl->Driver.Render.Triangle = tri_tab[ind]; + tnl->Driver.Render.Quad = quad_tab[ind]; + tnl->Driver.Render.Line = swsetup_line; + tnl->Driver.Render.Points = swsetup_points; } diff --git a/src/mesa/swrast_setup/ss_tritmp.h b/src/mesa/swrast_setup/ss_tritmp.h index 0db792ba2b..49e92acf1c 100644 --- a/src/mesa/swrast_setup/ss_tritmp.h +++ b/src/mesa/swrast_setup/ss_tritmp.h @@ -1,4 +1,4 @@ -/* $Id: ss_tritmp.h,v 1.12 2001/04/28 08:39:18 keithw Exp $ */ +/* $Id: ss_tritmp.h,v 1.13 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -62,13 +62,15 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) if (IND & SS_TWOSIDE_BIT) { if (IND & SS_RGBA_BIT) { GLfloat (*vbcolor)[4] = (GLfloat (*)[4])VB->ColorPtr[1]->Ptr; - GLfloat (*vbspec)[4] = (GLfloat (*)[4])VB->SecondaryColorPtr[1]->Ptr; SS_COLOR(v[0]->color, vbcolor[e0]); SS_COLOR(v[1]->color, vbcolor[e1]); SS_COLOR(v[2]->color, vbcolor[e2]); - SS_SPEC(v[0]->specular, vbspec[e0]); - SS_SPEC(v[1]->specular, vbspec[e1]); - SS_SPEC(v[2]->specular, vbspec[e2]); + if (VB->SecondaryColorPtr[1]) { + GLfloat (*vbspec)[4] = (GLfloat (*)[4])VB->SecondaryColorPtr[1]->Ptr; + SS_SPEC(v[0]->specular, vbspec[e0]); + SS_SPEC(v[1]->specular, vbspec[e1]); + SS_SPEC(v[2]->specular, vbspec[e2]); + } } else { GLuint *vbindex = VB->IndexPtr[1]->data; SS_IND(v[0]->index, vbindex[e0]); @@ -135,13 +137,15 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) if (facing == 1) { if (IND & SS_RGBA_BIT) { GLfloat (*vbcolor)[4] = (GLfloat (*)[4])VB->ColorPtr[0]->Ptr; - GLfloat (*vbspec)[4] = (GLfloat (*)[4])VB->SecondaryColorPtr[0]->Ptr; SS_COLOR(v[0]->color, vbcolor[e0]); SS_COLOR(v[1]->color, vbcolor[e1]); SS_COLOR(v[2]->color, vbcolor[e2]); - SS_SPEC(v[0]->specular, vbspec[e0]); - SS_SPEC(v[1]->specular, vbspec[e1]); - SS_SPEC(v[2]->specular, vbspec[e2]); + if (VB->SecondaryColorPtr[0]) { + GLfloat (*vbspec)[4] = (GLfloat (*)[4])VB->SecondaryColorPtr[0]->Ptr; + SS_SPEC(v[0]->specular, vbspec[e0]); + SS_SPEC(v[1]->specular, vbspec[e1]); + SS_SPEC(v[2]->specular, vbspec[e2]); + } } else { GLuint *vbindex = VB->IndexPtr[0]->data; SS_IND(v[0]->index, vbindex[e0]); diff --git a/src/mesa/swrast_setup/ss_vb.c b/src/mesa/swrast_setup/ss_vb.c index f9d1d01997..7afb646769 100644 --- a/src/mesa/swrast_setup/ss_vb.c +++ b/src/mesa/swrast_setup/ss_vb.c @@ -1,4 +1,4 @@ -/* $Id: ss_vb.c,v 1.12 2001/03/29 21:16:26 keithw Exp $ */ +/* $Id: ss_vb.c,v 1.13 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -46,8 +46,6 @@ * in this module, but not the rest of the swrast module. */ -typedef void (*SetupFunc)( GLcontext *ctx, - GLuint start, GLuint end, GLuint newinputs ); #define COLOR 0x1 #define INDEX 0x2 @@ -58,7 +56,9 @@ typedef void (*SetupFunc)( GLcontext *ctx, #define POINT 0x40 #define MAX_SETUPFUNC 0x80 -static SetupFunc setup_func[MAX_SETUPFUNC]; +static setup_func setup_tab[MAX_SETUPFUNC]; +static interp_func interp_tab[MAX_SETUPFUNC]; +static copy_pv_func copy_pv_tab[MAX_SETUPFUNC]; #define IND (0) @@ -165,84 +165,150 @@ static SetupFunc setup_func[MAX_SETUPFUNC]; #define TAG(x) x##_index #include "ss_vbtmp.h" -#define IND (INDEX|TEX0) -#define TAG(x) x##_index_tex0 -#include "ss_vbtmp.h" - #define IND (INDEX|FOG) #define TAG(x) x##_index_fog #include "ss_vbtmp.h" -#define IND (INDEX|TEX0|FOG) -#define TAG(x) x##_index_tex0_fog -#include "ss_vbtmp.h" - #define IND (INDEX|POINT) #define TAG(x) x##_index_point #include "ss_vbtmp.h" -#define IND (INDEX|TEX0|POINT) -#define TAG(x) x##_index_tex0_point -#include "ss_vbtmp.h" - #define IND (INDEX|FOG|POINT) #define TAG(x) x##_index_fog_point #include "ss_vbtmp.h" -#define IND (INDEX|TEX0|FOG|POINT) -#define TAG(x) x##_index_tex0_fog_point -#include "ss_vbtmp.h" + +/*********************************************************************** + * Additional setup and interp for back color and edgeflag. + ***********************************************************************/ + +#define GET_COLOR(ptr, idx) (((GLfloat (*)[4])((ptr)->Ptr))[idx]) + +static void interp_extras( GLcontext *ctx, + GLfloat t, + GLuint dst, GLuint out, GLuint in, + GLboolean force_boundary ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (VB->ColorPtr[1]) { + INTERP_4F( t, + GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], out), + GET_COLOR(VB->ColorPtr[1], in) ); + + if (VB->SecondaryColorPtr[1]) { + INTERP_3F( t, + GET_COLOR(VB->SecondaryColorPtr[1], dst), + GET_COLOR(VB->SecondaryColorPtr[1], out), + GET_COLOR(VB->SecondaryColorPtr[1], in) ); + } + } + else if (VB->IndexPtr[1]) { + VB->IndexPtr[1]->data[dst] = (GLuint) (GLint) + LINTERP( t, + (GLfloat) VB->IndexPtr[1]->data[out], + (GLfloat) VB->IndexPtr[1]->data[in] ); + } + + if (VB->EdgeFlag) { + VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary; + } + + interp_tab[SWSETUP_CONTEXT(ctx)->SetupIndex](ctx, t, dst, out, in, + force_boundary); +} + +static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (VB->ColorPtr[1]) { + COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], src) ); + + if (VB->SecondaryColorPtr[1]) { + COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst), + GET_COLOR(VB->SecondaryColorPtr[1], src) ); + } + } + else if (VB->IndexPtr[1]) { + VB->IndexPtr[1]->data[dst] = VB->IndexPtr[1]->data[src]; + } + + copy_pv_tab[SWSETUP_CONTEXT(ctx)->SetupIndex](ctx, dst, src); +} + +/*********************************************************************** + * Initialization + ***********************************************************************/ + + + static void -rs_invalid( GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs ) +emit_invalid( GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs ) { fprintf(stderr, "swrast_setup: invalid setup function\n"); (void) (ctx && start && end && newinputs); } -void -_swsetup_vb_init( GLcontext *ctx ) +static void +interp_invalid( GLcontext *ctx, GLfloat t, + GLuint edst, GLuint eout, GLuint ein, + GLboolean force_boundary ) +{ + fprintf(stderr, "swrast_setup: invalid interp function\n"); + (void) (ctx && t && edst && eout && ein && force_boundary); +} + +static void +copy_pv_invalid( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + fprintf(stderr, "swrast_setup: invalid copy_pv function\n"); + (void) (ctx && edst && esrc ); +} + +static void init_standard( void ) { GLuint i; - (void) ctx; - for (i = 0 ; i < Elements(setup_func) ; i++) - setup_func[i] = rs_invalid; - - setup_func[0] = rs_none; - setup_func[COLOR] = rs_color; - setup_func[COLOR|SPEC] = rs_color_spec; - setup_func[COLOR|FOG] = rs_color_fog; - setup_func[COLOR|SPEC|FOG] = rs_color_spec_fog; - setup_func[COLOR|TEX0] = rs_color_tex0; - setup_func[COLOR|TEX0|SPEC] = rs_color_tex0_spec; - setup_func[COLOR|TEX0|FOG] = rs_color_tex0_fog; - setup_func[COLOR|TEX0|SPEC|FOG] = rs_color_tex0_spec_fog; - setup_func[COLOR|MULTITEX] = rs_color_multitex; - setup_func[COLOR|MULTITEX|SPEC] = rs_color_multitex_spec; - setup_func[COLOR|MULTITEX|FOG] = rs_color_multitex_fog; - setup_func[COLOR|MULTITEX|SPEC|FOG] = rs_color_multitex_spec_fog; - setup_func[COLOR|POINT] = rs_color_point; - setup_func[COLOR|SPEC|POINT] = rs_color_spec_point; - setup_func[COLOR|FOG|POINT] = rs_color_fog_point; - setup_func[COLOR|SPEC|FOG|POINT] = rs_color_spec_fog_point; - setup_func[COLOR|TEX0|POINT] = rs_color_tex0_point; - setup_func[COLOR|TEX0|SPEC|POINT] = rs_color_tex0_spec_point; - setup_func[COLOR|TEX0|FOG|POINT] = rs_color_tex0_fog_point; - setup_func[COLOR|TEX0|SPEC|FOG|POINT] = rs_color_tex0_spec_fog_point; - setup_func[COLOR|MULTITEX|POINT] = rs_color_multitex_point; - setup_func[COLOR|MULTITEX|SPEC|POINT] = rs_color_multitex_spec_point; - setup_func[COLOR|MULTITEX|FOG|POINT] = rs_color_multitex_fog_point; - setup_func[COLOR|MULTITEX|SPEC|FOG|POINT] = rs_color_multitex_spec_fog_point; - setup_func[INDEX] = rs_index; - setup_func[INDEX|TEX0] = rs_index_tex0; - setup_func[INDEX|FOG] = rs_index_fog; - setup_func[INDEX|TEX0|FOG] = rs_index_tex0_fog; - setup_func[INDEX|POINT] = rs_index_point; - setup_func[INDEX|TEX0|POINT] = rs_index_tex0_point; - setup_func[INDEX|FOG|POINT] = rs_index_fog_point; - setup_func[INDEX|TEX0|FOG|POINT] = rs_index_tex0_fog_point; + for (i = 0 ; i < Elements(setup_tab) ; i++) { + setup_tab[i] = emit_invalid; + interp_tab[i] = interp_invalid; + copy_pv_tab[i] = copy_pv_invalid; + } + + init_none(); + init_color(); + init_color_spec(); + init_color_fog(); + init_color_spec_fog(); + init_color_tex0(); + init_color_tex0_spec(); + init_color_tex0_fog(); + init_color_tex0_spec_fog(); + init_color_multitex(); + init_color_multitex_spec(); + init_color_multitex_fog(); + init_color_multitex_spec_fog(); + init_color_point(); + init_color_spec_point(); + init_color_fog_point(); + init_color_spec_fog_point(); + init_color_tex0_point(); + init_color_tex0_spec_point(); + init_color_tex0_fog_point(); + init_color_tex0_spec_fog_point(); + init_color_multitex_point(); + init_color_multitex_spec_point(); + init_color_multitex_fog_point(); + init_color_multitex_spec_fog_point(); + init_index(); + init_index_fog(); + init_index_point(); + init_index_fog_point(); } static void printSetupFlags(char *msg, GLuint flags ) @@ -260,10 +326,12 @@ static void printSetupFlags(char *msg, GLuint flags ) } + void _swsetup_choose_rastersetup_func(GLcontext *ctx) { SScontext *swsetup = SWSETUP_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); int funcindex = 0; if (ctx->RenderMode == GL_RENDER) { @@ -275,8 +343,7 @@ _swsetup_choose_rastersetup_func(GLcontext *ctx) else if (ctx->Texture._ReallyEnabled & 0xf) funcindex |= TEX0; - if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR || - ctx->Fog.ColorSumEnabled) + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) funcindex |= SPEC; } else { @@ -293,12 +360,33 @@ _swsetup_choose_rastersetup_func(GLcontext *ctx) if (ctx->Visual.rgbMode) funcindex = (COLOR | TEX0); /* is feedback color subject to fogging? */ else - funcindex = (INDEX | TEX0); + funcindex = INDEX; } else funcindex = 0; + + swsetup->SetupIndex = funcindex; + tnl->Driver.Render.BuildVertices = setup_tab[funcindex]; - if (0) printSetupFlags("software setup func", funcindex); - swsetup->BuildProjVerts = setup_func[funcindex]; - ASSERT(setup_func[funcindex] != rs_invalid); + if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { + tnl->Driver.Render.Interp = interp_extras; + tnl->Driver.Render.CopyPV = copy_pv_extras; + } + else { + tnl->Driver.Render.Interp = interp_tab[funcindex]; + tnl->Driver.Render.CopyPV = copy_pv_tab[funcindex]; + } + + ASSERT(tnl->Driver.Render.BuildVertices); + ASSERT(tnl->Driver.Render.BuildVertices != emit_invalid); +} + + +void +_swsetup_vb_init( GLcontext *ctx ) +{ + (void) ctx; + init_standard(); + (void) printSetupFlags; } + diff --git a/src/mesa/swrast_setup/ss_vbtmp.h b/src/mesa/swrast_setup/ss_vbtmp.h index 9ef51a3c20..4a83cf2301 100644 --- a/src/mesa/swrast_setup/ss_vbtmp.h +++ b/src/mesa/swrast_setup/ss_vbtmp.h @@ -1,4 +1,4 @@ -/* $Id: ss_vbtmp.h,v 1.15 2001/04/30 09:04:00 keithw Exp $ */ +/* $Id: ss_vbtmp.h,v 1.16 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -28,19 +28,23 @@ */ -static void TAG(rs)(GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs ) +static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end, + GLuint newinputs ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; SWvertex *v; - GLfloat (*proj)[4]; /* projected clip coordinates */ - GLfloat (*tc[MAX_TEXTURE_UNITS])[4]; - GLfloat (*color)[4]; - GLfloat (*spec)[4]; + GLfloat *proj; /* projected clip coordinates */ + GLfloat *tc[MAX_TEXTURE_UNITS]; + GLfloat *color; + GLfloat *spec; GLuint *index; GLfloat *fog; GLfloat *pointSize; GLuint tsz[MAX_TEXTURE_UNITS]; + GLuint tstride[MAX_TEXTURE_UNITS]; + GLuint proj_stride, color_stride, spec_stride, index_stride; + GLuint fog_stride, pointSize_stride; GLuint i; GLfloat *m = ctx->Viewport._WindowMap.m; const GLfloat sx = m[0]; @@ -51,94 +55,200 @@ static void TAG(rs)(GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs ) const GLfloat tz = m[14]; GLuint maxtex = 0; - /* Only the most basic optimization for cva: - */ - if (!newinputs) - return; - - /* TODO: Get import_client_data to pad vectors out to 4 cleanly. - * - * NOTE: This has the effect of converting any remaining ubyte - * colors to floats... As they're already there 90% of the - * time, this isn't a bad thing. - */ - if (VB->importable_data) - VB->import_data( ctx, VB->importable_data & newinputs, - (VB->ClipOrMask - ? VEC_NOT_WRITEABLE|VEC_BAD_STRIDE - : VEC_BAD_STRIDE)); - if (IND & TEX0) { - tc[0] = VB->TexCoordPtr[0]->data; + tc[0] = (GLfloat *)VB->TexCoordPtr[0]->data; tsz[0] = VB->TexCoordPtr[0]->size; + tstride[0] = VB->TexCoordPtr[0]->stride; } if (IND & MULTITEX) { for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { if (VB->TexCoordPtr[i]) { maxtex = i+1; - tc[i] = VB->TexCoordPtr[i]->data; + tc[i] = (GLfloat *)VB->TexCoordPtr[i]->data; tsz[i] = VB->TexCoordPtr[i]->size; + tstride[i] = VB->TexCoordPtr[i]->stride; } else tc[i] = 0; } } - /* Tie up some dangling pointers for flat/twoside code in ss_tritmp.h - */ - if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) == 0) { - VB->SecondaryColorPtr[0] = VB->ColorPtr[0]; - VB->SecondaryColorPtr[1] = VB->ColorPtr[1]; - } - + proj = VB->ProjectedClipPtr->data[0]; + proj_stride = VB->ProjectedClipPtr->stride; - proj = VB->ProjectedClipPtr->data; - if (IND & FOG) + if (IND & FOG) { fog = VB->FogCoordPtr->data; - if (IND & COLOR) - color = (GLfloat (*)[4])VB->ColorPtr[0]->Ptr; - if (IND & SPEC) - spec = (GLfloat (*)[4])VB->SecondaryColorPtr[0]->Ptr; - if (IND & INDEX) + fog_stride = VB->FogCoordPtr->stride; + } + if (IND & COLOR) { + color = VB->ColorPtr[0]->Ptr; + color_stride = VB->ColorPtr[0]->StrideB; + } + if (IND & SPEC) { + spec = VB->SecondaryColorPtr[0]->Ptr; + spec_stride = VB->SecondaryColorPtr[0]->StrideB; + } + if (IND & INDEX) { index = VB->IndexPtr[0]->data; - if (IND & POINT) + index_stride = VB->IndexPtr[0]->stride; + } + if (IND & POINT) { pointSize = VB->PointSizePtr->data; + pointSize_stride = VB->PointSizePtr->stride; + } v = &(SWSETUP_CONTEXT(ctx)->verts[start]); for (i=start; i < end; i++, v++) { if (VB->ClipMask[i] == 0) { - v->win[0] = sx * proj[i][0] + tx; - v->win[1] = sy * proj[i][1] + ty; - v->win[2] = sz * proj[i][2] + tz; - v->win[3] = proj[i][3]; - - if (IND & TEX0) - COPY_CLEAN_4V( v->texcoord[0], tsz[0], tc[0][i] ); - - if (IND & MULTITEX) { - GLuint u; - for (u = 0 ; u < maxtex ; u++) - if (tc[u]) - COPY_CLEAN_4V( v->texcoord[u], tsz[u], tc[u][i] ); - } + v->win[0] = sx * proj[0] + tx; + v->win[1] = sy * proj[1] + ty; + v->win[2] = sz * proj[2] + tz; + v->win[3] = proj[3]; + } + STRIDE_F(proj, proj_stride); + + if (IND & TEX0) { + COPY_CLEAN_4V( v->texcoord[0], tsz[0], tc[0] ); + STRIDE_F(tc[0], tstride[0]); + } + + if (IND & MULTITEX) { + GLuint u; + for (u = 0 ; u < maxtex ; u++) + if (tc[u]) { + COPY_CLEAN_4V( v->texcoord[u], tsz[u], tc[u] ); + STRIDE_F(tc[u], tstride[u]); + } + } - if (IND & COLOR) - UNCLAMPED_FLOAT_TO_RGBA_CHAN(v->color, color[i]); + if (IND & COLOR) { + UNCLAMPED_FLOAT_TO_RGBA_CHAN(v->color, color); + STRIDE_F(color, color_stride); +/* COPY_CHAN4(v->color, color); */ +/* STRIDE_CHAN(color, color_stride); */ + } - if (IND & SPEC) - UNCLAMPED_FLOAT_TO_RGBA_CHAN(v->specular, spec[i]); + if (IND & SPEC) { + UNCLAMPED_FLOAT_TO_RGB_CHAN(v->specular, spec); + STRIDE_F(spec, spec_stride); +/* COPY_CHAN4(v->specular, spec); */ +/* STRIDE_CHAN(spec, spec_stride); */ + } - if (IND & FOG) - v->fog = fog[i]; + if (IND & FOG) { + v->fog = fog[0]; + STRIDE_F(fog, fog_stride); + } - if (IND & INDEX) - v->index = index[i]; + if (IND & INDEX) { + v->index = index[0]; + STRIDE_UI(index, index_stride); + } - if (IND & POINT) - v->pointSize = pointSize[i]; + if (IND & POINT) { + v->pointSize = pointSize[0]; + STRIDE_F(pointSize, pointSize_stride); } + + } +} + + + +static void TAG(interp)( GLcontext *ctx, + GLfloat t, + GLuint edst, GLuint eout, GLuint ein, + GLboolean force_boundary ) +{ + SScontext *swsetup = SWSETUP_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLfloat *m = ctx->Viewport._WindowMap.m; + GLfloat *clip = VB->ClipPtr->data[edst]; + + SWvertex *dst = &swsetup->verts[edst]; + SWvertex *in = &swsetup->verts[ein]; + SWvertex *out = &swsetup->verts[eout]; + + /* Avoid division by zero by rearranging order of clip planes? + */ + if (clip[3] != 0.0) { + GLfloat oow = 1.0F / clip[3]; + dst->win[0] = m[0] * clip[0] * oow + m[12]; + dst->win[1] = m[5] * clip[1] * oow + m[13]; + dst->win[2] = m[10] * clip[2] * oow + m[14]; + dst->win[3] = oow; } + +/* fprintf(stderr, "%s edst %d win %f %f %f %f\n", */ +/* __FUNCTION__, edst, */ +/* dst->win[0], dst->win[1], dst->win[2], dst->win[3]); */ + + if (IND & TEX0) { + INTERP_4F( t, dst->texcoord[0], out->texcoord[0], in->texcoord[0] ); + } + + if (IND & MULTITEX) { + GLuint u; + GLuint maxtex = ctx->Const.MaxTextureUnits; + for (u = 0 ; u < maxtex ; u++) + if (VB->TexCoordPtr[u]) { + INTERP_4F( t, dst->texcoord[u], out->texcoord[u], in->texcoord[u] ); + } + } + + if (IND & COLOR) { + INTERP_CHAN( t, dst->color[0], out->color[0], in->color[0] ); + INTERP_CHAN( t, dst->color[1], out->color[1], in->color[1] ); + INTERP_CHAN( t, dst->color[2], out->color[2], in->color[2] ); + INTERP_CHAN( t, dst->color[3], out->color[3], in->color[3] ); + } + + if (IND & SPEC) { + INTERP_CHAN( t, dst->specular[0], out->specular[0], in->specular[0] ); + INTERP_CHAN( t, dst->specular[1], out->specular[1], in->specular[1] ); + INTERP_CHAN( t, dst->specular[2], out->specular[2], in->specular[2] ); + } + + if (IND & FOG) { + INTERP_F( t, dst->fog, out->fog, in->fog ); + } + + if (IND & INDEX) { + INTERP_UI( t, dst->index, out->index, in->index ); + } + + if (IND & POINT) { + INTERP_F( t, dst->pointSize, out->pointSize, in->pointSize ); + } +} + + +static void TAG(copy_pv)( GLcontext *ctx, GLuint edst, GLuint esrc ) +{ + SScontext *swsetup = SWSETUP_CONTEXT(ctx); + SWvertex *dst = &swsetup->verts[edst]; + SWvertex *src = &swsetup->verts[esrc]; + + if (IND & COLOR) { + COPY_CHAN4( dst->color, src->color ); + } + + if (IND & SPEC) { + COPY_3V( dst->specular, src->specular ); + } + + if (IND & INDEX) { + dst->index = src->index; + } +} + + +static void TAG(init)( void ) +{ + setup_tab[IND] = TAG(emit); + interp_tab[IND] = TAG(interp); + copy_pv_tab[IND] = TAG(copy_pv); } #undef TAG diff --git a/src/mesa/swrast_setup/swrast_setup.h b/src/mesa/swrast_setup/swrast_setup.h index bec8d90c1f..1a4b036442 100644 --- a/src/mesa/swrast_setup/swrast_setup.h +++ b/src/mesa/swrast_setup/swrast_setup.h @@ -1,4 +1,4 @@ -/* $Id: swrast_setup.h,v 1.8 2001/03/12 00:48:43 gareth Exp $ */ +/* $Id: swrast_setup.h,v 1.9 2001/07/12 22:09:21 keithw Exp $ */ /* * Mesa 3-D graphics library @@ -30,6 +30,10 @@ /* Public interface to the swrast_setup module. This module provides * an implementation of the driver interface to t_vb_render.c, and uses * the software rasterizer (swrast) to perform actual rasterization. + * + * The internals of the implementation are private, but can be hooked + * into tnl at any time (except between RenderStart/RenderEnd) by + * calling _swsetup_Wakeup(). */ #ifndef SWRAST_SETUP_H @@ -45,48 +49,6 @@ extern void _swsetup_InvalidateState( GLcontext *ctx, GLuint new_state ); extern void -_swsetup_BuildProjectedVertices( GLcontext *ctx, - GLuint start, - GLuint end, - GLuint new_inputs ); - -extern void -_swsetup_Quad( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3 ); - -extern void -_swsetup_Triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2 ); - -extern void -_swsetup_Line( GLcontext *ctx, GLuint v0, GLuint v1 ); - -extern void -_swsetup_Points( GLcontext *ctx, GLuint first, GLuint last ); - -extern void -_swsetup_RenderPrimitive( GLcontext *ctx, GLenum mode ); - -extern void -_swsetup_RenderStart( GLcontext *ctx ); - -extern void -_swsetup_RenderFinish( GLcontext *ctx ); - -extern void -_swsetup_RenderProjectInterpVerts( GLcontext *ctx ); - -extern void -_swsetup_RenderInterp( GLcontext *ctx, GLfloat t, - GLuint dst, GLuint out, GLuint in, - GLboolean force_boundary ); -extern void -_swsetup_RenderCopyPV( GLcontext *ctx, GLuint dst, GLuint src ); - -extern void -_swsetup_RenderClippedPolygon( GLcontext *ctx, const GLuint *elts, GLuint n ); - -extern void -_swsetup_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ); - - +_swsetup_Wakeup( GLcontext *ctx ); #endif |