summaryrefslogtreecommitdiffstats
path: root/src/mesa/swrast_setup
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/swrast_setup')
-rw-r--r--src/mesa/swrast_setup/NOTES79
-rw-r--r--src/mesa/swrast_setup/ss_context.c103
-rw-r--r--src/mesa/swrast_setup/ss_context.h33
-rw-r--r--src/mesa/swrast_setup/ss_triangle.c12
-rw-r--r--src/mesa/swrast_setup/ss_tritmp.h22
-rw-r--r--src/mesa/swrast_setup/ss_vb.c218
-rw-r--r--src/mesa/swrast_setup/ss_vbtmp.h238
-rw-r--r--src/mesa/swrast_setup/swrast_setup.h50
8 files changed, 426 insertions, 329 deletions
diff --git a/src/mesa/swrast_setup/NOTES b/src/mesa/swrast_setup/NOTES
index 4445b332d96..c6cb4ab3484 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 def9e4f43c8..2e92342e079 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 895fb1b03ed..f477f850cd3 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 a12429e26df..7b2d638213d 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 0db792ba2b5..49e92acf1c3 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 f9d1d019975..7afb646769f 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 9ef51a3c205..4a83cf23019 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 bec8d90c1f3..1a4b0364429 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