Rename some of the tnl->Driver.* functions to tnl->Driver.Render.*, to make it
authorKeith Whitwell <keith@tungstengraphics.com>
Thu, 12 Jul 2001 22:09:21 +0000 (22:09 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Thu, 12 Jul 2001 22:09:21 +0000 (22:09 +0000)
clear that these are owned by t_vb_render.c.

Make swrast_setup opaque - it now hooks itself directly into
tnl->Driver.Render.*.  Add a _swsetup_Wakeup() call that does this.

Update X11 (tested), osmesa and FX drivers for this change.

FX compiles but is probably broken as the changes there are large.  It was the
only remaining driver that used the internal _swsetup_ functions for
interp and copy_pv.  This usage has been replaced with code from the DRI
tdfx driver.

24 files changed:
src/mesa/Makefile.X11
src/mesa/drivers/glide/fxdd.c
src/mesa/drivers/glide/fxdrv.h
src/mesa/drivers/glide/fxsetup.c
src/mesa/drivers/glide/fxtris.c
src/mesa/drivers/glide/fxvb.c
src/mesa/drivers/glide/fxvbtmp.h
src/mesa/drivers/osmesa/osmesa.c
src/mesa/drivers/x11/xm_dd.c
src/mesa/main/Makefile.X11
src/mesa/swrast/s_context.c
src/mesa/swrast_setup/NOTES
src/mesa/swrast_setup/ss_context.c
src/mesa/swrast_setup/ss_context.h
src/mesa/swrast_setup/ss_triangle.c
src/mesa/swrast_setup/ss_tritmp.h
src/mesa/swrast_setup/ss_vb.c
src/mesa/swrast_setup/ss_vbtmp.h
src/mesa/swrast_setup/swrast_setup.h
src/mesa/tnl/t_context.c
src/mesa/tnl/t_context.h
src/mesa/tnl/t_pipeline.h
src/mesa/tnl/t_vb_cliptmp.h
src/mesa/tnl/t_vb_render.c

index 255ab695f44c80fa4a2c5581e82030f541686d42..28980575a530d4e1652ecc6c9ea42d487e66c531 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile.X11,v 1.55 2001/06/27 12:52:12 keithw Exp $
+# $Id: Makefile.X11,v 1.56 2001/07/12 22:09:21 keithw Exp $
 
 # Mesa 3-D graphics library
 # Version:  3.5
@@ -21,6 +21,9 @@ LIBDIR = ../lib
 
 
 CORE_SOURCES = \
+       swrast_setup/ss_context.c \
+       swrast_setup/ss_triangle.c \
+       swrast_setup/ss_vb.c \
        api_arrayelt.c \
        api_loopback.c \
        api_noop.c \
@@ -118,10 +121,6 @@ CORE_SOURCES = \
        swrast/s_texstore.c \
        swrast/s_triangle.c \
        swrast/s_zoom.c \
-       swrast_setup/ss_context.c \
-       swrast_setup/ss_triangle.c \
-       swrast_setup/ss_vb.c \
-       swrast_setup/ss_interp.c \
        tnl/t_array_api.c \
        tnl/t_array_import.c \
        tnl/t_context.c \
index 117e9d7dead52339316ca413f63bfad561be96cc..e645f65be6818be69bd4fd649ba41c6d6a5adbe6 100644 (file)
@@ -674,11 +674,6 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
    if (getenv("FX_EMULATE_SINGLE_TMU"))
       fxMesa->haveTwoTMUs = GL_FALSE;
 
-   fxMesa->emulateTwoTMUs = fxMesa->haveTwoTMUs;
-
-   if (!getenv("FX_DONT_FAKE_MULTITEX"))
-      fxMesa->emulateTwoTMUs = GL_TRUE;
-
    if (getenv("FX_GLIDE_SWAPINTERVAL"))
       fxMesa->swapInterval = atoi(getenv("FX_GLIDE_SWAPINTERVAL"));
    else
@@ -754,7 +749,7 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
 
    fxMesa->textureAlign = FX_grGetInteger(FX_TEXTURE_ALIGN);
    fxMesa->glCtx->Const.MaxTextureLevels = 9;
-   fxMesa->glCtx->Const.MaxTextureUnits = fxMesa->emulateTwoTMUs ? 2 : 1;
+   fxMesa->glCtx->Const.MaxTextureUnits = fxMesa->haveTwoTMUs ? 2 : 1;
    fxMesa->new_state = _NEW_ALL;
 
    /* Initialize the software rasterizer and helper modules.
@@ -783,10 +778,6 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
 
    fxDDInitExtensions(fxMesa->glCtx);
 
-#ifdef FXVTXFMT
-   fxDDInitVtxfmt(fxMesa->glCtx);
-#endif
-
    FX_grGlideGetState((GrState *) fxMesa->state);
 
    /* Run the config file */
@@ -830,7 +821,7 @@ fxDDInitExtensions(GLcontext * ctx)
    if (fxMesa->haveTwoTMUs)
       _mesa_enable_extension(ctx, "GL_EXT_texture_env_add");
 
-   if (fxMesa->emulateTwoTMUs)
+   if (fxMesa->haveTwoTMUs)
       _mesa_enable_extension(ctx, "GL_ARB_multitexture");
 }
 
@@ -843,8 +834,8 @@ fxDDInitExtensions(GLcontext * ctx)
  *
  * Performs similar work to fxDDChooseRenderState() - should be merged.
  */
-static GLboolean
-fxIsInHardware(GLcontext * ctx)
+GLboolean
+fx_check_IsInHardware(GLcontext * ctx)
 {
    fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
 
@@ -868,7 +859,7 @@ fxIsInHardware(GLcontext * ctx)
    }
    /* Unsupported texture/multitexture cases */
 
-   if (fxMesa->emulateTwoTMUs) {
+   if (fxMesa->haveTwoTMUs) {
       if (ctx->Texture._ReallyEnabled & (TEXTURE0_3D | TEXTURE1_3D))
         return GL_FALSE;       /* can't do 3D textures */
       if (ctx->Texture._ReallyEnabled & (TEXTURE0_1D | TEXTURE1_1D))
@@ -939,6 +930,9 @@ fxIsInHardware(GLcontext * ctx)
    return GL_TRUE;
 }
 
+
+
+
 static void
 update_texture_scales(GLcontext * ctx)
 {
@@ -980,79 +974,34 @@ fxDDUpdateDDPointers(GLcontext * ctx, GLuint new_state)
 
    if (new_state & (_FX_NEW_IS_IN_HARDWARE |
                    _FX_NEW_RENDERSTATE |
-                   _FX_NEW_SETUP_FUNCTION | _NEW_TEXTURE)) {
+                   _FX_NEW_SETUP_FUNCTION | 
+                   _NEW_TEXTURE)) {
 
       if (new_state & _FX_NEW_IS_IN_HARDWARE)
-        fxMesa->is_in_hardware = fxIsInHardware(ctx);
+        fxCheckIsInHardware(ctx);
 
       if (fxMesa->new_state)
         fxSetupFXUnits(ctx);
 
-      if (new_state & _FX_NEW_RENDERSTATE)
-        fxDDChooseRenderState(ctx);
+      if (fxMesa->is_in_hardware) {
+        if (new_state & _FX_NEW_RENDERSTATE)
+           fxDDChooseRenderState(ctx);
 
-      if (new_state & _FX_NEW_SETUP_FUNCTION)
-        tnl->Driver.BuildProjectedVertices = fx_validate_BuildProjVerts;
+        if (new_state & _FX_NEW_SETUP_FUNCTION)
+           fxDDChooseSetupState(ctx);
+      }
 
       if (new_state & _NEW_TEXTURE)
         update_texture_scales(ctx);
-
-   }
-
-#ifdef FXVTXFMT
-   if (fxMesa->allow_vfmt) {
-      if (new_state & _NEW_LIGHT)
-        fx_update_lighting(ctx);
-
-      if (new_state & _FX_NEW_VTXFMT)
-        fxDDCheckVtxfmt(ctx);
-   }
-#endif
-}
-
-static void
-fxDDRenderPrimitive(GLcontext * ctx, GLenum mode)
-{
-   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
-
-   if (!fxMesa->is_in_hardware) {
-      _swsetup_RenderPrimitive(ctx, mode);
-   }
-   else {
-      fxMesa->render_prim = mode;
    }
 }
 
 
-static void
-fxDDRenderStart(GLcontext * ctx)
-{
-   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
-
-   _swsetup_RenderStart(ctx);
-
-   if (fxMesa->new_state) {
-      fxSetupFXUnits(ctx);
-   }
-}
-
-static void
-fxDDRenderFinish(GLcontext * ctx)
-{
-   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
-
-   if (!fxMesa->is_in_hardware) {
-      _swsetup_RenderFinish(ctx);
-   }
-}
-
 
 
 void
 fxSetupDDPointers(GLcontext * ctx)
 {
-   TNLcontext *tnl = TNL_CONTEXT(ctx);
-
    if (MESA_VERBOSE & VERBOSE_DRIVER) {
       fprintf(stderr, "fxmesa: fxSetupDDPointers()\n");
    }
@@ -1106,16 +1055,6 @@ fxSetupDDPointers(GLcontext * ctx)
    ctx->Driver.ShadeModel = fxDDShadeModel;
    ctx->Driver.Enable = fxDDEnable;
 
-   tnl->Driver.RunPipeline = _tnl_run_pipeline;
-   tnl->Driver.RenderStart = fxDDRenderStart;
-   tnl->Driver.RenderFinish = fxDDRenderFinish;
-   tnl->Driver.ResetLineStipple = _swrast_ResetLineStipple;
-   tnl->Driver.RenderPrimitive = fxDDRenderPrimitive;
-   tnl->Driver.RenderInterp = _swsetup_RenderInterp;
-   tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
-   tnl->Driver.RenderClippedLine = _swsetup_RenderClippedLine;
-   tnl->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon;
-
    fxSetupDDSpanPointers(ctx);
    fxDDUpdateDDPointers(ctx, ~0);
 }
index 0d4c7a45bd29bfcdc0eccce822e7b80f2eb4cf55..09674680c97e5ce0622c0b4cb327d3d9177ce65d 100644 (file)
@@ -94,37 +94,6 @@ extern float gl_ubyte_to_float_255_color_tab[256];
 
 
 
-/* Should have size == 16 * sizeof(float).
- */
-typedef union
-{
-   GrVertex v;
-   GLfloat f[16];
-   GLuint ui[16];
-}
-fxVertex;
-
-/* Used in the fxvtxfmt t&l engine.
- */
-typedef struct
-{
-   GrVertex v;
-   GLfloat clip[4];
-   GLfloat texcoord[2][2];
-   GLubyte mask;
-   GLfloat normal[3];          /* for replay & fallback */
-}
-fxClipVertex;
-
-
-
-typedef void (*vfmt_project_func) (GLcontext * ctx, fxClipVertex * v);
-typedef void (*vfmt_interpolate_func) (GLfloat t,
-                                      fxClipVertex * O,
-                                      const fxClipVertex * I,
-                                      const fxClipVertex * J);
-
-
 
 #if defined(FXMESA_USE_ARGB)
 #define FXCOLOR4( c ) (      \
@@ -147,14 +116,15 @@ typedef void (*vfmt_interpolate_func) (GLfloat t,
 
 
 
-/* fastpath/vtxfmt flags first
+/* fastpath flags first
  */
 #define SETUP_TMU0 0x1
 #define SETUP_TMU1 0x2
 #define SETUP_RGBA 0x4
 #define SETUP_SNAP 0x8
 #define SETUP_XYZW 0x10
-#define MAX_SETUP  0x20
+#define SETUP_PTEX 0x20
+#define MAX_SETUP  0x40
 
 
 #define FX_NUM_TMU 2
@@ -356,6 +326,7 @@ tfxUnitsState;
                             _DD_NEW_POINT_SIZE |       \
                             _NEW_LINE)
 
+
 /* Covers the state referenced by fxDDChooseSetupFunction.
  */
 #define _FX_NEW_SETUP_FUNCTION (_NEW_LIGHT|    \
@@ -364,18 +335,6 @@ tfxUnitsState;
                                _NEW_COLOR)     \
 
 
-/* Covers the state referenced in fxDDCheckVtxfmt.
- */
-#define _FX_NEW_VTXFMT (_NEW_TEXTURE |                 \
-                       _NEW_TEXTURE_MATRIX |           \
-                       _NEW_TRANSFORM |                \
-                       _NEW_LIGHT |                    \
-                       _NEW_PROJECTION |               \
-                       _NEW_MODELVIEW |                \
-                       _TNL_NEW_NEED_EYE_COORDS |      \
-                       _FX_NEW_RENDERSTATE)
-
-
 /* These lookup table are used to extract RGB values in [0,255] from
  * 16-bit pixel values.
  */
@@ -384,11 +343,9 @@ extern GLubyte FX_PixelToG[0x10000];
 extern GLubyte FX_PixelToB[0x10000];
 
 
-typedef void (*fx_tri_func) (GLcontext *, const fxVertex *,
-                            const fxVertex *, const fxVertex *);
-typedef void (*fx_line_func) (GLcontext *, const fxVertex *,
-                             const fxVertex *);
-typedef void (*fx_point_func) (GLcontext *, const fxVertex *);
+typedef void (*fx_tri_func) (fxMesaContext, GrVertex *, GrVertex *, GrVertex *);
+typedef void (*fx_line_func) (fxMesaContext, GrVertex *, GrVertex *);
+typedef void (*fx_point_func) (fxMesaContext, GrVertex *);
 
 struct tfxMesaContext
 {
@@ -434,19 +391,18 @@ struct tfxMesaContext
    /* Vertex building and storage:
     */
    GLuint tmu_source[FX_NUM_TMU];
-   GLuint tex_dest[MAX_TEXTURE_UNITS];
-   GLuint setupindex;
-   GLuint setup_gone;          /* for multipass */
+   GLuint SetupIndex;
    GLuint stw_hint_state;      /* for grHints */
-   fxVertex *verts;
+   GrVertex *verts;
    GLboolean snapVertices;      /* needed for older Voodoo hardware */
+   struct gl_client_array UbyteColor;
 
    /* Rasterization:
     */
    GLuint render_index;
-   GLuint passes, multipass;
    GLuint is_in_hardware;
-   GLenum render_prim;
+   GLenum render_primitive;
+   GLenum raster_primitive;
 
    /* Current rasterization functions 
     */
@@ -454,15 +410,6 @@ struct tfxMesaContext
    fx_line_func draw_line;
    fx_tri_func draw_tri;
 
-   /* System to turn culling on/off for tris/lines/points.
-    */
-   fx_point_func initial_point;
-   fx_line_func initial_line;
-   fx_tri_func initial_tri;
-
-   fx_point_func subsequent_point;
-   fx_line_func subsequent_line;
-   fx_tri_func subsequent_tri;
 
    /* Keep texture scales somewhere handy:
     */
@@ -485,7 +432,6 @@ struct tfxMesaContext
 
    GLboolean verbose;
    GLboolean haveTwoTMUs;      /* True if we really have 2 tmu's  */
-   GLboolean emulateTwoTMUs;   /* True if we present 2 tmu's to mesa.  */
    GLboolean haveAlphaBuffer;
    GLboolean haveZBuffer;
    GLboolean haveDoubleBuffer;
@@ -502,37 +448,8 @@ struct tfxMesaContext
    int clipMaxX;
    int clipMinY;
    int clipMaxY;
-
-   /* fxvtxfmt
-    */
-   GLboolean allow_vfmt;
-   GLvertexformat vtxfmt;
-   fxClipVertex current;
-   fxClipVertex *vert;         /* points into verts[] */
-   void (*fire_on_vertex) (GLcontext *);
-   void (*fire_on_end) (GLcontext *);
-   void (*fire_on_fallback) (GLcontext *);
-
-   vfmt_project_func project_vertex;
-   vfmt_interpolate_func interpolate_vertices;
-
-   int vtxfmt_fallback_count;
-   int vtxfmt_installed;
-   void (*old_begin) (GLenum);
-   GLenum prim;
-
-   GLuint accel_light;
-   GLfloat basecolor[4];
-
-
-   /* Projected vertices, fastpath data:
-    */
-   GLvector1ui clipped_elements;
-   fxVertex *last_vert;
-   GLuint size;
 };
 
-typedef void (*tfxSetupFunc) (GLcontext * ctx, GLuint, GLuint);
 
 extern GrHwConfiguration glbHWConfig;
 extern int glbCurrentBoard;
@@ -540,17 +457,20 @@ extern int glbCurrentBoard;
 extern void fxSetupFXUnits(GLcontext *);
 extern void fxSetupDDPointers(GLcontext *);
 
-/* fxvsetup:
+/* fxvb.c:
  */
-extern void fxDDSetupInit(void);
 extern void fxAllocVB(GLcontext * ctx);
 extern void fxFreeVB(GLcontext * ctx);
-extern void fxPrintSetupFlags(const char *msg, GLuint flags);
-extern void fx_BuildProjVerts(GLcontext * ctx,
-                             GLuint start, GLuint count, GLuint newinputs);
-extern void fx_validate_BuildProjVerts(GLcontext * ctx,
-                                      GLuint start, GLuint count,
-                                      GLuint newinputs);
+extern void fxPrintSetupFlags(char *msg, GLuint flags );
+extern void fxCheckTexSizes( GLcontext *ctx );
+extern void fxBuildVertices( GLcontext *ctx, GLuint start, GLuint count,
+                            GLuint newinputs );
+extern void fxChooseVertexState( GLcontext *ctx );
+
+
+
+
+
 
 /* fxtrifuncs:
  */
@@ -655,14 +575,4 @@ extern void fxTMMoveInTM_NoLock(fxMesaContext fxMesa,
 extern void fxInitPixelTables(fxMesaContext fxMesa, GLboolean bgrOrder);
 
 
-/* fxvtxfmt:
- */
-extern void fxDDCheckVtxfmt(GLcontext * ctx);
-extern void fx_update_lighting(GLcontext * ctx);
-extern void fxDDInitVtxfmt(GLcontext * ctx);
-
-/* fxsimplerender
- */
-extern const struct gl_pipeline_stage fx_render_stage;
-
 #endif
index 2e33bd47e3d7b4cdf0c0cb31c0b50b106104b717..ca79cc4e192dbdf2e3b7b436ae0c52632f7f0c22 100644 (file)
@@ -55,8 +55,6 @@
 #include "enums.h"
 #include "tnl/t_context.h"
 
-/*static GLboolean fxMultipassTexture(GLcontext *, GLuint);*/
-
 static void
 fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj)
 {
@@ -531,23 +529,8 @@ fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset)
                                  localc, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
       break;
    case GL_BLEND:
-#if 0
-      FX_grAlphaCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER,
-                              GR_COMBINE_FACTOR_LOCAL,
-                              locala, GR_COMBINE_OTHER_TEXTURE, FXFALSE);
-      if (ifmt == GL_ALPHA)
-        FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_LOCAL,
-                                 GR_COMBINE_FACTOR_NONE,
-                                 localc, GR_COMBINE_OTHER_NONE, FXFALSE);
-      else
-        FX_grColorCombine_NoLock(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
-                                 GR_COMBINE_FACTOR_LOCAL,
-                                 localc, GR_COMBINE_OTHER_TEXTURE, FXTRUE);
-      ctx->Driver.MultipassFunc = fxMultipassBlend;
-#else
       if (MESA_VERBOSE & VERBOSE_DRIVER)
         fprintf(stderr, "fx Driver: GL_BLEND not yet supported\n");
-#endif
       break;
    case GL_REPLACE:
       if ((ifmt == GL_RGB) || (ifmt == GL_LUMINANCE))
@@ -1037,7 +1020,7 @@ fxSetupTexture_NoLock(GLcontext * ctx)
     */
    tex2Denabled = (ctx->Texture._ReallyEnabled & TEXTURE0_2D);
 
-   if (fxMesa->emulateTwoTMUs)
+   if (fxMesa->haveTwoTMUs)
       tex2Denabled |= (ctx->Texture._ReallyEnabled & TEXTURE1_2D);
 
    switch (tex2Denabled) {
@@ -1055,7 +1038,6 @@ fxSetupTexture_NoLock(GLcontext * ctx)
            fprintf(stderr, "fxmesa: enabling fake multitexture\n");
 
         fxSetupTextureSingleTMU_NoLock(ctx, 0);
-        /*ctx->Driver.MultipassFunc = fxMultipassTexture;*/
       }
       break;
    default:
@@ -1547,7 +1529,8 @@ fxSetupCull(GLcontext * ctx)
    else
       FX_CONTEXT(ctx)->cullMode = GR_CULL_DISABLE;
 
-   FX_grCullMode(FX_CONTEXT(ctx)->cullMode);
+   if (FX_CONTEXT(ctx)->raster_primitive == GL_TRIANGLES)
+      FX_grCullMode(FX_CONTEXT(ctx)->cullMode);
 }
 
 
@@ -1616,129 +1599,7 @@ fxDDEnable(GLcontext * ctx, GLenum cap, GLboolean state)
    }
 }
 
-#if 0
-/*
-  Multipass to do GL_BLEND texture functions
-  Cf*(1-Ct) has already been written to the buffer during the first pass
-  Cc*Ct gets written during the second pass (in this function)
-  Everything gets reset in the third call (in this function)
-*/
-static GLboolean
-fxMultipassBlend(struct vertex_buffer *VB, GLuint pass)
-{
-   GLcontext *ctx = VB->ctx;
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-
-   switch (pass) {
-   case 1:
-      /* Add Cc*Ct */
-      fxMesa->restoreUnitsState = fxMesa->unitsState;
-      if (ctx->Depth.Mask) {
-        /* We don't want to check or change the depth buffers */
-        switch (ctx->Depth.Func) {
-        case GL_NEVER:
-        case GL_ALWAYS:
-           break;
-        default:
-           fxDDDepthFunc(ctx, GL_EQUAL);
-           break;
-        }
-        fxDDDepthMask(ctx, FALSE);
-      }
-      /* Enable Cc*Ct mode */
-      /* XXX Set the Constant Color ? */
-      fxDDEnable(ctx, GL_BLEND, GL_TRUE);
-      fxDDBlendFunc(ctx, XXX, XXX);
-      fxSetupTextureSingleTMU(ctx, XXX);
-      fxSetupBlend(ctx);
-      fxSetupDepthTest(ctx);
-      break;
-
-   case 2:
-      /* Reset everything back to normal */
-      fxMesa->unitsState = fxMesa->restoreUnitsState;
-      fxMesa->setup_gone |= XXX;
-      fxSetupTextureSingleTMU(ctx, XXX);
-      fxSetupBlend(ctx);
-      fxSetupDepthTest(ctx);
-      break;
-   }
-
-   return pass == 1;
-}
-#endif
 
-/************************************************************************/
-/******************** Fake Multitexture Support *************************/
-/************************************************************************/
-
-/* Its considered cheeky to try to fake ARB multitexture by doing
- * multipass rendering, because it is not possible to emulate the full
- * spec in this way.  The fact is that the voodoo 2 supports only a
- * subset of the possible multitexturing modes, and it is possible to
- * support almost the same subset using multipass blending on the
- * voodoo 1.  In all other cases for both voodoo 1 and 2, we fall back
- * to software rendering, satisfying the spec if not the user.  
- */
-static GLboolean
-fxMultipassTexture(GLcontext * ctx, GLuint pass)
-{
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   TNLcontext *tnl = TNL_CONTEXT(ctx);
-   fxVertex *v = fxMesa->verts;
-   fxVertex *last = fxMesa->verts + tnl->vb.Count;
-
-   switch (pass) {
-   case 1:
-      if (MESA_VERBOSE &
-         (VERBOSE_DRIVER | VERBOSE_PIPELINE | VERBOSE_TEXTURE))
-           fprintf(stderr, "fxmesa: Second texture pass\n");
-
-      for (; v != last; v++) {
-        v->f[S0COORD] = v->f[S1COORD];
-        v->f[T0COORD] = v->f[T1COORD];
-      }
-
-      fxMesa->restoreUnitsState = fxMesa->unitsState;
-      fxMesa->tmu_source[0] = 1;
-
-      if (ctx->Depth.Mask) {
-        switch (ctx->Depth.Func) {
-        case GL_NEVER:
-        case GL_ALWAYS:
-           break;
-        default:
-           fxDDDepthFunc(ctx, GL_EQUAL);
-           break;
-        }
-
-        fxDDDepthMask(ctx, GL_FALSE);
-      }
-
-      if (ctx->Texture.Unit[1].EnvMode == GL_MODULATE) {
-        fxDDEnable(ctx, GL_BLEND, GL_TRUE);
-        fxDDBlendFunc(ctx, GL_DST_COLOR, GL_ZERO);
-      }
-
-      fxSetupTextureSingleTMU(ctx, 1);
-      fxSetupBlend(ctx);
-      fxSetupDepthTest(ctx);
-      break;
-
-   case 2:
-      /* Restore original state.  
-       */
-      fxMesa->tmu_source[0] = 0;
-      fxMesa->unitsState = fxMesa->restoreUnitsState;
-      fxMesa->setup_gone |= SETUP_TMU0;
-      fxSetupTextureSingleTMU(ctx, 0);
-      fxSetupBlend(ctx);
-      fxSetupDepthTest(ctx);
-      break;
-   }
-
-   return pass == 1;
-}
 
 
 /************************************************************************/
@@ -1809,9 +1670,6 @@ fxSetupFXUnits(GLcontext * ctx)
       if (newstate & FX_NEW_CULL)
         fxSetupCull(ctx);
 
-      fxMesa->draw_point = fxMesa->initial_point;
-      fxMesa->draw_line = fxMesa->initial_line;
-      fxMesa->draw_tri = fxMesa->initial_tri;
       fxMesa->new_state = 0;
    }
 }
index 829aabe74926ca9c68c5e32fd12e71ea27b6a28b..5129a94476b66fce7c6d279f3eb95b9acc1e93da 100644 (file)
+/* -*- mode: c; c-basic-offset: 3 -*-
+ *
+ * Copyright 2000 VA Linux Systems Inc., Fremont, California.
+ *
+ * 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/fx/fxtris.c,v 1.5 2000/09/24 13:51:04 alanh Exp $ */
 
+/* Authors:
+ *    Keith Whitwell <keithw@valinux.com>
+ */
 
-#ifdef HAVE_CONFIG_H
-#include "conf.h"
-#endif
+#include <stdio.h>
+#include <math.h>
 
-#if defined(FX)
+#include "glheader.h"
+#include "mtypes.h"
+#include "macros.h"
+#include "colormac.h"
 
-#include "mmath.h"
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
-
 #include "tnl/t_context.h"
 #include "tnl/t_pipeline.h"
 
 #include "fxdrv.h"
-#include "fxglidew.h"
 
 
-
-
-
-
-
-
-static void
-fx_draw_point(GLcontext * ctx, const fxVertex * v)
+/*
+ * Subpixel offsets to adjust Mesa's (true) window coordinates to
+ * Glide coordinates.  We need these to ensure precise rasterization.
+ * Otherwise, we'll fail a bunch of conformance tests.
+ */
+#define TRI_X_OFFSET    ( 0.0F)
+#define TRI_Y_OFFSET    ( 0.0F)
+#define LINE_X_OFFSET   ( 0.0F)
+#define LINE_Y_OFFSET   ( 0.125F)
+#define PNT_X_OFFSET    ( 0.375F)
+#define PNT_Y_OFFSET    ( 0.375F)
+
+static void fxRasterPrimitive( GLcontext *ctx, GLenum prim );
+static void fxRenderPrimitive( GLcontext *ctx, GLenum prim );
+
+/***********************************************************************
+ *          Macros for t_dd_tritmp.h to draw basic primitives          *
+ ***********************************************************************/
+
+#define TRI( a, b, c )                         \
+do {                                           \
+   if (DO_FALLBACK)                            \
+      fxMesa->draw_tri( fxMesa, a, b, c );     \
+   else                                                \
+      grDrawTriangle( a, b, c );       \
+} while (0)                                    \
+
+#define QUAD( a, b, c, d )                     \
+do {                                           \
+   if (DO_FALLBACK) {                          \
+      fxMesa->draw_tri( fxMesa, a, b, d );     \
+      fxMesa->draw_tri( fxMesa, b, c, d );     \
+   } else {                                    \
+      grDrawTriangle( a, b, d );       \
+      grDrawTriangle( b, c, d );       \
+   }                                           \
+} while (0)
+
+#define LINE( v0, v1 )                         \
+do {                                           \
+   if (DO_FALLBACK)                            \
+      fxMesa->draw_line( fxMesa, v0, v1 );     \
+   else {                                      \
+      v0->x += LINE_X_OFFSET - TRI_X_OFFSET;   \
+      v0->y += LINE_Y_OFFSET - TRI_Y_OFFSET;   \
+      v1->x += LINE_X_OFFSET - TRI_X_OFFSET;   \
+      v1->y += LINE_Y_OFFSET - TRI_Y_OFFSET;   \
+      grDrawLine( v0, v1 );    \
+      v0->x -= LINE_X_OFFSET - TRI_X_OFFSET;   \
+      v0->y -= LINE_Y_OFFSET - TRI_Y_OFFSET;   \
+      v1->x -= LINE_X_OFFSET - TRI_X_OFFSET;   \
+      v1->y -= LINE_Y_OFFSET - TRI_Y_OFFSET;   \
+   }                                           \
+} while (0)
+
+#define POINT( v0 )                            \
+do {                                           \
+   if (DO_FALLBACK)                            \
+      fxMesa->draw_point( fxMesa, v0 );                \
+   else {                                      \
+      v0->x += PNT_X_OFFSET - TRI_X_OFFSET;    \
+      v0->y += PNT_Y_OFFSET - TRI_Y_OFFSET;    \
+      grDrawPoint( v0 );               \
+      v0->x -= PNT_X_OFFSET - TRI_X_OFFSET;    \
+      v0->y -= PNT_Y_OFFSET - TRI_Y_OFFSET;    \
+   }                                           \
+} while (0)
+
+
+/***********************************************************************
+ *              Fallback to swrast for basic primitives                *
+ ***********************************************************************/
+
+/* Build an SWvertex from a hardware vertex. 
+ *
+ * This code is hit only when a mix of accelerated and unaccelerated
+ * primitives are being drawn, and only for the unaccelerated
+ * primitives.  
+ */
+static void 
+fx_translate_vertex( GLcontext *ctx, const GrVertex *src, SWvertex *dst)
 {
-   GLfloat sz = ctx->Point._Size;
-
-   if (sz <= 1.0) {
-      grDrawPoint(&(v->v));
-   }
-   else {
-      GrVertex verts[4];
-
-      sz *= .5;
+   fxMesaContext fxMesa = FX_CONTEXT(ctx);
+   GLuint ts0 = fxMesa->tmu_source[0];
+   GLuint ts1 = fxMesa->tmu_source[1];
+   GLfloat w = 1.0 / src->oow;
 
-      verts[0] = v->v;
-      verts[1] = v->v;
-      verts[2] = v->v;
-      verts[3] = v->v;
+   dst->win[0] = src->x;
+   dst->win[1] = src->y;
+   dst->win[2] = src->ooz;
+   dst->win[3] = src->oow;
 
-      verts[0].x = v->v.x - sz;
-      verts[0].y = v->v.y - sz;
+   dst->color[0] = (GLubyte) src->r;
+   dst->color[1] = (GLubyte) src->g;
+   dst->color[2] = (GLubyte) src->b;
+   dst->color[3] = (GLubyte) src->a;
 
-      verts[1].x = v->v.x + sz;
-      verts[1].y = v->v.y - sz;
+   dst->texcoord[ts0][0] = fxMesa->inv_s0scale * src->tmuvtx[0].sow * w;
+   dst->texcoord[ts0][1] = fxMesa->inv_t0scale * src->tmuvtx[0].tow * w;
 
-      verts[2].x = v->v.x + sz;
-      verts[2].y = v->v.y + sz;
+   if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU0)
+      dst->texcoord[ts0][3] = src->tmuvtx[0].oow * w;
+   else
+      dst->texcoord[ts0][3] = 1.0;
 
-      verts[3].x = v->v.x - sz;
-      verts[3].y = v->v.y + sz;
+   if (fxMesa->SetupIndex & SETUP_TMU1) {
+      dst->texcoord[ts1][0] = fxMesa->inv_s1scale * src->tmuvtx[1].sow * w;
+      dst->texcoord[ts1][1] = fxMesa->inv_t1scale * src->tmuvtx[1].tow * w;
 
-      grDrawTriangle(&verts[0], &verts[1], &verts[3]);
-      grDrawTriangle(&verts[1], &verts[2], &verts[3]);
+      if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU1)
+        dst->texcoord[ts1][3] = src->tmuvtx[1].oow * w;
+      else
+        dst->texcoord[ts1][3] = 1.0;
    }
+
+   dst->pointSize = ctx->Point._Size;
 }
 
 
-static void
-fx_draw_line(GLcontext * ctx, const fxVertex * v0, const fxVertex * v1)
+static void 
+fx_fallback_tri( fxMesaContext fxMesa, 
+                  GrVertex *v0, 
+                  GrVertex *v1, 
+                  GrVertex *v2 )
 {
-   float width = ctx->Line.Width;
-
-   if (width <= 1.0) {
-      grDrawLine(&(v0->v), &(v1->v));
-   }
-   else {
-      GrVertex verts[4];
-      float dx, dy, ix, iy;
-
-      dx = v0->v.x - v1->v.x;
-      dy = v0->v.y - v1->v.y;
-
-      if (dx * dx > dy * dy) {
-        iy = width * .5;
-        ix = 0;
-      }
-      else {
-        iy = 0;
-        ix = width * .5;
-      }
-
-
-      verts[0] = v0->v;
-      verts[0].x -= ix;
-      verts[0].y -= iy;
+   GLcontext *ctx = fxMesa->glCtx;
+   SWvertex v[3];
+   fx_translate_vertex( ctx, v0, &v[0] );
+   fx_translate_vertex( ctx, v1, &v[1] );
+   fx_translate_vertex( ctx, v2, &v[2] );
+   _swrast_Triangle( ctx, &v[0], &v[1], &v[2] );
+}
 
-      verts[1] = v0->v;
-      verts[1].x += ix;
-      verts[1].y += iy;
 
-      verts[2] = v1->v;
-      verts[2].x += ix;
-      verts[2].y += iy;
+static void 
+fx_fallback_line( fxMesaContext fxMesa,
+                   GrVertex *v0,
+                   GrVertex *v1 )
+{
+   GLcontext *ctx = fxMesa->glCtx;
+   SWvertex v[2];
+   fx_translate_vertex( ctx, v0, &v[0] );
+   fx_translate_vertex( ctx, v1, &v[1] );
+   _swrast_Line( ctx, &v[0], &v[1] );
+}
 
-      verts[3] = v1->v;
-      verts[3].x -= ix;
-      verts[3].y -= iy;
 
-      grDrawTriangle(&verts[0], &verts[1], &verts[3]);
-      grDrawTriangle(&verts[1], &verts[2], &verts[3]);
-   }
+static void 
+fx_fallback_point( fxMesaContext fxMesa, 
+                    GrVertex *v0 )
+{
+   GLcontext *ctx = fxMesa->glCtx;
+   SWvertex v[1];
+   fx_translate_vertex( ctx, v0, &v[0] );
+   _swrast_Point( ctx, &v[0] );
 }
 
-static void
-fx_draw_tri(GLcontext * ctx, const fxVertex * v0, const fxVertex * v1,
-           const fxVertex * v2)
+/***********************************************************************
+ *                 Functions to draw basic primitives                  *
+ ***********************************************************************/
+
+static void fx_print_vertex( GLcontext *ctx, const GrVertex *v )
 {
-   grDrawTriangle(&(v0->v), &(v1->v), &(v2->v));
+   fprintf(stderr, "vertex at %p\n", v);
+
+   fprintf(stderr, "x %f y %f z %f oow %f\n", 
+          v->x, v->y, v->ooz, v->oow);
+   fprintf(stderr, "r %f g %f b %f a %f\n", 
+          v->r,
+          v->g,
+          v->b,
+          v->a);
+   
+   fprintf(stderr, "\n");
 }
 
+#define DO_FALLBACK 0
 
-
-#define FX_COLOR(vert, c) {                            \
-  GLfloat *col = c;                                    \
-  UNCLAMPED_FLOAT_TO_UBYTE(vert->v.r, col[0]);         \
-  UNCLAMPED_FLOAT_TO_UBYTE(vert->v.g, col[1]);         \
-  UNCLAMPED_FLOAT_TO_UBYTE(vert->v.b, col[2]);         \
-  UNCLAMPED_FLOAT_TO_UBYTE(vert->v.a, col[3]);         \
+/* Need to do clip loop at each triangle when mixing swrast and hw
+ * rendering.  These functions are only used when mixed-mode rendering
+ * is occurring.
+ */
+static void fx_draw_quad( fxMesaContext fxMesa,
+                         GrVertex *v0,
+                         GrVertex *v1,
+                         GrVertex *v2,
+                         GrVertex *v3 )
+{
+   QUAD( v0, v1, v2, v3 );
 }
 
-#define FX_COPY_COLOR( dst, src ) {            \
-   dst->v.r = src->v.r;                                \
-   dst->v.g = src->v.g;                                \
-   dst->v.b = src->v.b;                                \
-   dst->v.a = src->v.a;                                \
+static void fx_draw_triangle( fxMesaContext fxMesa,
+                               GrVertex *v0,
+                               GrVertex *v1,
+                               GrVertex *v2 )
+{
+   TRI( v0, v1, v2 );
 }
 
+static void fx_draw_line( fxMesaContext fxMesa,
+                           GrVertex *v0,
+                           GrVertex *v1 )
+{
+   /* No support for wide lines (avoid wide/aa line fallback).
+    */
+   LINE(v0, v1);
+}
 
-
-#define FX_FLAT_BIT            0x01
-#define FX_OFFSET_BIT          0x02
-#define FX_TWOSIDE_BIT         0x04
-#define FX_UNFILLED_BIT                0x10
-#define FX_FALLBACK_BIT                0x20
-#define FX_MAX_TRIFUNC          0x40
-
-static struct
+static void fx_draw_point( fxMesaContext fxMesa,
+                            GrVertex *v0 )
 {
-   points_func points;
-   line_func line;
-   triangle_func triangle;
-   quad_func quad;
+   /* No support for wide points.
+    */
+   POINT( v0 );
 }
-rast_tab[FX_MAX_TRIFUNC];
 
+#undef DO_FALLBACK
+
+
+#define FX_UNFILLED_BIT    0x1
+#define FX_OFFSET_BIT       0x2
+#define FX_TWOSIDE_BIT     0x4
+#define FX_FLAT_BIT        0x8
+#define FX_FALLBACK_BIT    0x10
+#define FX_MAX_TRIFUNC     0x20
+
+static struct {
+   points_func         points;
+   line_func           line;
+   triangle_func       triangle;
+   quad_func           quad;
+} rast_tab[FX_MAX_TRIFUNC];
+
+#define DO_FALLBACK (IND & FX_FALLBACK_BIT)
+#define DO_OFFSET   (IND & FX_OFFSET_BIT)
+#define DO_UNFILLED (IND & FX_UNFILLED_BIT)
+#define DO_TWOSIDE  (IND & FX_TWOSIDE_BIT)
+#define DO_FLAT     (IND & FX_FLAT_BIT)
+#define DO_TRI       1
+#define DO_QUAD      1
+#define DO_LINE      1
+#define DO_POINTS    1
+#define DO_FULL_QUAD 1
+
+#define HAVE_RGBA   1
+#define HAVE_SPEC   0
+#define HAVE_HW_FLATSHADE 0
+#define HAVE_BACK_COLORS  0
+#define VERTEX GrVertex
+#define TAB rast_tab
+
+#define DEPTH_SCALE 1.0
+#define UNFILLED_TRI unfilled_tri
+#define UNFILLED_QUAD unfilled_quad
+#define VERT_X(_v) _v->x
+#define VERT_Y(_v) _v->y
+#define VERT_Z(_v) _v->ooz
+#define AREA_IS_CCW( a ) (a < 0)
+#define GET_VERTEX(e) (fxMesa->verts + e)
+
+#define VERT_SET_RGBA( dst, f )                   \
+do {                                           \
+   dst->r = CLAMP( f[0], 0, 1 ) * 255.0;       \
+   dst->g = CLAMP( f[1], 0, 1 ) * 255.0;       \
+   dst->b = CLAMP( f[2], 0, 1 ) * 255.0;       \
+   dst->a = CLAMP( f[3], 0, 1 ) * 255.0;       \
+} while (0)
+
+#define VERT_COPY_RGBA( v0, v1 )               \
+do {                                           \
+   v0->r = v1->r;                              \
+   v0->g = v1->g;                              \
+   v0->b = v1->b;                              \
+   v0->a = v1->a;                              \
+} while (0)
+
+#define VERT_SAVE_RGBA( idx )                          \
+do {                                           \
+   color[idx][0] = v[idx]->r;                  \
+   color[idx][1] = v[idx]->g;                  \
+   color[idx][1] = v[idx]->b;                  \
+   color[idx][3] = v[idx]->a;                  \
+} while (0)
+
+
+#define VERT_RESTORE_RGBA( idx )               \
+do {                                           \
+   v[idx]->r = color[idx][0];                  \
+   v[idx]->g = color[idx][1];                  \
+   v[idx]->b = color[idx][2];                  \
+   v[idx]->a = color[idx][3];                  \
+} while (0)
+
+
+#define LOCAL_VARS(n)                                  \
+   fxMesaContext fxMesa = FX_CONTEXT(ctx);             \
+   GLfloat color[n][4];                                        \
+   (void) color; 
+
+
+
+/***********************************************************************
+ *            Functions to draw basic unfilled primitives              *
+ ***********************************************************************/
+
+#define RASTERIZE(x) if (fxMesa->raster_primitive != x) \
+                        fxRasterPrimitive( ctx, x )
+#define RENDER_PRIMITIVE fxMesa->render_primitive
+#define IND FX_FALLBACK_BIT
+#define TAG(x) x
+#include "tnl_dd/t_dd_unfilled.h"
+#undef IND
+
+/***********************************************************************
+ *                 Functions to draw GL primitives                     *
+ ***********************************************************************/
 
 #define IND (0)
 #define TAG(x) x
-#include "fxtritmp.h"
-
-#define IND (FX_FLAT_BIT)
-#define TAG(x) x##_flat
-#include "fxtritmp.h"
+#include "tnl_dd/t_dd_tritmp.h"
 
 #define IND (FX_OFFSET_BIT)
 #define TAG(x) x##_offset
-#include "fxtritmp.h"
-
-#define IND (FX_OFFSET_BIT | FX_FLAT_BIT)
-#define TAG(x) x##_offset_flat
-#include "fxtritmp.h"
+#include "tnl_dd/t_dd_tritmp.h"
 
 #define IND (FX_TWOSIDE_BIT)
 #define TAG(x) x##_twoside
-#include "fxtritmp.h"
-
-#define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT)
-#define TAG(x) x##_twoside_flat
-#include "fxtritmp.h"
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT)
+#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT)
 #define TAG(x) x##_twoside_offset
-#include "fxtritmp.h"
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT)
-#define TAG(x) x##_twoside_offset_flat
-#include "fxtritmp.h"
+#define IND (FX_UNFILLED_BIT)
+#define TAG(x) x##_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT)
+#define TAG(x) x##_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT)
+#define TAG(x) x##_twoside_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT)
+#define TAG(x) x##_twoside_offset_unfilled
+#include "tnl_dd/t_dd_tritmp.h"
 
 #define IND (FX_FALLBACK_BIT)
 #define TAG(x) x##_fallback
-#include "fxtritmp.h"
-
-#define IND (FX_FLAT_BIT | FX_FALLBACK_BIT)
-#define TAG(x) x##_flat_fallback
-#include "fxtritmp.h"
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_OFFSET_BIT | FX_FALLBACK_BIT)
+#define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT)
 #define TAG(x) x##_offset_fallback
-#include "fxtritmp.h"
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT)
-#define TAG(x) x##_offset_flat_fallback
-#include "fxtritmp.h"
-
-#define IND (FX_TWOSIDE_BIT | FX_FALLBACK_BIT)
+#define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT)
 #define TAG(x) x##_twoside_fallback
-#include "fxtritmp.h"
-
-#define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT)
-#define TAG(x) x##_twoside_flat_fallback
-#include "fxtritmp.h"
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FALLBACK_BIT)
+#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT)
 #define TAG(x) x##_twoside_offset_fallback
-#include "fxtritmp.h"
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT)
-#define TAG(x) x##_twoside_offset_flat_fallback
-#include "fxtritmp.h"
+#define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT)
+#define TAG(x) x##_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_UNFILLED_BIT)
-#define TAG(x) x##_unfilled
-#include "fxtritmp.h"
+#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT)
+#define TAG(x) x##_offset_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_FLAT_BIT | FX_UNFILLED_BIT)
-#define TAG(x) x##_flat_unfilled
-#include "fxtritmp.h"
+#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT)
+#define TAG(x) x##_twoside_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_OFFSET_BIT | FX_UNFILLED_BIT)
-#define TAG(x) x##_offset_unfilled
-#include "fxtritmp.h"
+#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \
+            FX_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_OFFSET_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT)
-#define TAG(x) x##_offset_flat_unfilled
-#include "fxtritmp.h"
 
-#define IND (FX_TWOSIDE_BIT | FX_UNFILLED_BIT)
-#define TAG(x) x##_twoside_unfilled
-#include "fxtritmp.h"
+/* Fx doesn't support provoking-vertex flat-shading?
+ */
+#define IND (FX_FLAT_BIT)
+#define TAG(x) x##_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT)
-#define TAG(x) x##_twoside_flat_unfilled
-#include "fxtritmp.h"
+#define IND (FX_OFFSET_BIT|FX_FLAT_BIT)
+#define TAG(x) x##_offset_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_UNFILLED_BIT)
-#define TAG(x) x##_twoside_offset_unfilled
-#include "fxtritmp.h"
+#define IND (FX_TWOSIDE_BIT|FX_FLAT_BIT)
+#define TAG(x) x##_twoside_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT)
-#define TAG(x) x##_twoside_offset_flat_unfilled
-#include "fxtritmp.h"
+#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FLAT_BIT)
+#define TAG(x) x##_twoside_offset_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_FALLBACK_BIT | FX_UNFILLED_BIT)
-#define TAG(x) x##_fallback_unfilled
-#include "fxtritmp.h"
+#define IND (FX_UNFILLED_BIT|FX_FLAT_BIT)
+#define TAG(x) x##_unfilled_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
-#define TAG(x) x##_flat_fallback_unfilled
-#include "fxtritmp.h"
+#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT)
+#define TAG(x) x##_offset_unfilled_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_OFFSET_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
-#define TAG(x) x##_offset_fallback_unfilled
-#include "fxtritmp.h"
+#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT)
+#define TAG(x) x##_twoside_unfilled_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
-#define TAG(x) x##_offset_flat_fallback_unfilled
-#include "fxtritmp.h"
+#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT)
+#define TAG(x) x##_twoside_offset_unfilled_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_TWOSIDE_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
-#define TAG(x) x##_twoside_fallback_unfilled
-#include "fxtritmp.h"
+#define IND (FX_FALLBACK_BIT|FX_FLAT_BIT)
+#define TAG(x) x##_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
-#define TAG(x) x##_twoside_flat_fallback_unfilled
-#include "fxtritmp.h"
+#define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
+#define TAG(x) x##_offset_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
-#define TAG(x) x##_twoside_offset_fallback_unfilled
-#include "fxtritmp.h"
+#define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
+#define TAG(x) x##_twoside_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
-#define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
-#define TAG(x) x##_twoside_offset_flat_fallback_unfilled
-#include "fxtritmp.h"
+#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
+#define TAG(x) x##_twoside_offset_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
+#define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
+#define TAG(x) x##_unfilled_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
+#define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
+#define TAG(x) x##_offset_unfilled_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
+#define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
+#define TAG(x) x##_twoside_unfilled_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
+#define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \
+            FX_FALLBACK_BIT|FX_FLAT_BIT)
+#define TAG(x) x##_twoside_offset_unfilled_fallback_flat
+#include "tnl_dd/t_dd_tritmp.h"
 
 
-void
-fxDDTrifuncInit(void)
+static void init_rast_tab( void )
 {
    init();
-   init_flat();
    init_offset();
-   init_offset_flat();
    init_twoside();
-   init_twoside_flat();
    init_twoside_offset();
-   init_twoside_offset_flat();
+   init_unfilled();
+   init_offset_unfilled();
+   init_twoside_unfilled();
+   init_twoside_offset_unfilled();
    init_fallback();
-   init_flat_fallback();
    init_offset_fallback();
-   init_offset_flat_fallback();
    init_twoside_fallback();
-   init_twoside_flat_fallback();
    init_twoside_offset_fallback();
-   init_twoside_offset_flat_fallback();
+   init_unfilled_fallback();
+   init_offset_unfilled_fallback();
+   init_twoside_unfilled_fallback();
+   init_twoside_offset_unfilled_fallback();
 
-   init_unfilled();
-   init_flat_unfilled();
-   init_offset_unfilled();
-   init_offset_flat_unfilled();
-   init_twoside_unfilled();
-   init_twoside_flat_unfilled();
-   init_twoside_offset_unfilled();
-   init_twoside_offset_flat_unfilled();
-   init_fallback_unfilled();
-   init_flat_fallback_unfilled();
-   init_offset_fallback_unfilled();
-   init_offset_flat_fallback_unfilled();
-   init_twoside_fallback_unfilled();
-   init_twoside_flat_fallback_unfilled();
-   init_twoside_offset_fallback_unfilled();
-   init_twoside_offset_flat_fallback_unfilled();
+   init_flat();
+   init_offset_flat();
+   init_twoside_flat();
+   init_twoside_offset_flat();
+   init_unfilled_flat();
+   init_offset_unfilled_flat();
+   init_twoside_unfilled_flat();
+   init_twoside_offset_unfilled_flat();
+   init_fallback_flat();
+   init_offset_fallback_flat();
+   init_twoside_fallback_flat();
+   init_twoside_offset_fallback_flat();
+   init_unfilled_fallback_flat();
+   init_offset_unfilled_fallback_flat();
+   init_twoside_unfilled_fallback_flat();
+   init_twoside_offset_unfilled_fallback_flat();
 }
 
 
-/* Build an SWvertex from a GrVertex.  This is workable because in
- * states where the GrVertex is insufficent (eg separate-specular),
- * the driver initiates a total fallback, and builds SWvertices
- * directly -- it recognizes that it will never have use for the
- * GrVertex. 
- *
- * This code is hit only when a mix of accelerated and unaccelerated
- * primitives are being drawn, and only for the unaccelerated
- * primitives. 
- */
-static void
-fx_translate_vertex(GLcontext * ctx, const fxVertex * src, SWvertex * dst)
-{
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   GLuint ts0 = fxMesa->tmu_source[0];
-   GLuint ts1 = fxMesa->tmu_source[1];
-   GLfloat w = 1.0 / src->v.oow;
-
-   dst->win[0] = src->v.x;
-   dst->win[1] = src->v.y;
-   dst->win[2] = src->v.ooz;
-   dst->win[3] = src->v.oow;
-
-   dst->color[0] = (GLubyte) src->v.r;
-   dst->color[1] = (GLubyte) src->v.g;
-   dst->color[2] = (GLubyte) src->v.b;
-   dst->color[3] = (GLubyte) src->v.a;
-
-   dst->texcoord[ts0][0] = fxMesa->inv_s0scale * src->v.tmuvtx[0].sow * w;
-   dst->texcoord[ts0][1] = fxMesa->inv_t0scale * src->v.tmuvtx[0].tow * w;
 
-   if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU0)
-      dst->texcoord[ts0][3] = src->v.tmuvtx[0].oow * w;
-   else
-      dst->texcoord[ts0][3] = 1.0;
+/**********************************************************************/
+/*            Render whole (indexed) begin/end objects                */
+/**********************************************************************/
 
-   dst->texcoord[ts1][0] = fxMesa->inv_s1scale * src->v.tmuvtx[1].sow * w;
-   dst->texcoord[ts1][1] = fxMesa->inv_t1scale * src->v.tmuvtx[1].tow * w;
 
-   if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU1)
-      dst->texcoord[ts1][3] = src->v.tmuvtx[1].oow * w;
-   else
-      dst->texcoord[ts1][3] = 1.0;
-}
+#define VERT(x) (vertptr + x)
 
+#define RENDER_POINTS( start, count )          \
+   for ( ; start < count ; start++)            \
+      grDrawPoint( VERT(ELT(start)) );
 
-static void
-fx_fallback_tri(GLcontext * ctx,
-               const fxVertex * v0, const fxVertex * v1, const fxVertex * v2)
-{
-   SWvertex v[3];
-   fx_translate_vertex(ctx, v0, &v[0]);
-   fx_translate_vertex(ctx, v1, &v[1]);
-   fx_translate_vertex(ctx, v2, &v[2]);
-   _swrast_Triangle(ctx, &v[0], &v[1], &v[2]);
-}
+#define RENDER_LINE( v0, v1 ) \
+   grDrawLine( VERT(v0), VERT(v1) )
 
+#define RENDER_TRI( v0, v1, v2 )  \
+   grDrawTriangle( VERT(v0), VERT(v1), VERT(v2) )
 
-static void
-fx_fallback_line(GLcontext * ctx, const fxVertex * v0, const fxVertex * v1)
-{
-   SWvertex v[2];
-   fx_translate_vertex(ctx, v0, &v[0]);
-   fx_translate_vertex(ctx, v1, &v[1]);
-   _swrast_Line(ctx, &v[0], &v[1]);
-}
+#define RENDER_QUAD( v0, v1, v2, v3 ) \
+   fx_draw_quad( fxMesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
 
+#define INIT(x) fxRenderPrimitive( ctx, x )
 
-static void
-fx_fallback_point(GLcontext * ctx, const fxVertex * v0)
-{
-   SWvertex v[1];
-   fx_translate_vertex(ctx, v0, &v[0]);
-   _swrast_Point(ctx, &v[0]);
-}
+#undef LOCAL_VARS
+#define LOCAL_VARS                                             \
+    fxMesaContext fxMesa = FX_CONTEXT(ctx);                    \
+    GrVertex *vertptr = fxMesa->verts;         \
+    const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;      \
+    (void) elt;
 
+#define RESET_STIPPLE 
+#define RESET_OCCLUSION 
+#define PRESERVE_VB_DEFS
 
-/* System to turn culling off for rasterized lines and points, and
- * back on for rasterized triangles.
+/* Elts, no clipping.
  */
-static void
-fx_cull_draw_tri(GLcontext * ctx,
-                const fxVertex * v0, const fxVertex * v1,
-                const fxVertex * v2)
-{
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-
-   FX_grCullMode(fxMesa->cullMode);
-
-   fxMesa->draw_line = fxMesa->initial_line;
-   fxMesa->draw_point = fxMesa->initial_point;
-   fxMesa->draw_tri = fxMesa->subsequent_tri;
-
-   fxMesa->draw_tri(ctx, v0, v1, v2);
-}
+#undef ELT
+#undef TAG
+#define TAG(x) fx_##x##_elts
+#define ELT(x) elt[x]
+#include "tnl_dd/t_dd_rendertmp.h"
 
+/* Verts, no clipping.
+ */
+#undef ELT
+#undef TAG
+#define TAG(x) fx_##x##_verts
+#define ELT(x) x
+#include "tnl_dd/t_dd_rendertmp.h"
 
-static void
-fx_cull_draw_line(GLcontext * ctx, const fxVertex * v0, const fxVertex * v1)
-{
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
 
-   FX_grCullMode(GR_CULL_DISABLE);
 
-   fxMesa->draw_point = fxMesa->initial_point;
-   fxMesa->draw_tri = fxMesa->initial_tri;
-   fxMesa->draw_line = fxMesa->subsequent_line;
+/**********************************************************************/
+/*                   Render clipped primitives                        */
+/**********************************************************************/
 
-   fxMesa->draw_line(ctx, v0, v1);
-}
 
 
-static void
-fx_cull_draw_point(GLcontext * ctx, const fxVertex * v0)
+static void fxRenderClippedPoly( GLcontext *ctx, const GLuint *elts, 
+                                  GLuint n )
 {
    fxMesaContext fxMesa = FX_CONTEXT(ctx);
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct vertex_buffer *VB = &tnl->vb;
+   GLuint prim = fxMesa->render_primitive;
+
+   /* Render the new vertices as an unclipped polygon. 
+    */
+   {
+      GLuint *tmp = VB->Elts;
+      VB->Elts = (GLuint *)elts;
+      tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, 
+                                                 PRIM_BEGIN|PRIM_END );
+      VB->Elts = tmp;
+   }
 
-   FX_grCullMode(GR_CULL_DISABLE);
-
-   fxMesa->draw_line = fxMesa->initial_line;
-   fxMesa->draw_tri = fxMesa->initial_tri;
-   fxMesa->draw_point = fxMesa->subsequent_point;
-
-   fxMesa->draw_point(ctx, v0);
+   /* Restore the render primitive
+    */
+   if (prim != GL_POLYGON)
+      tnl->Driver.Render.PrimitiveNotify( ctx, prim );
 }
 
 
-static void
-fx_null_tri(GLcontext * ctx,
-           const fxVertex * v0, const fxVertex * v1, const fxVertex * v2)
+static void fxFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, 
+                                      GLuint n )
 {
-   (void) v0;
-   (void) v1;
-   (void) v2;
+   fxMesaContext fxMesa = FX_CONTEXT( ctx );
+   GrVertex *vertptr = fxMesa->verts;                  
+   const GrVertex *start = VERT(elts[0]);
+   int i;
+
+   for (i = 2 ; i < n ; i++) {
+      grDrawTriangle( start, VERT(elts[i-1]), VERT(elts[i]) );
+   }
 }
 
+/**********************************************************************/
+/*                    Choose render functions                         */
+/**********************************************************************/
 
 
+#define POINT_FALLBACK (DD_POINT_SMOOTH)
+#define LINE_FALLBACK (DD_LINE_STIPPLE)
+#define TRI_FALLBACK (DD_TRI_SMOOTH)
+#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|DD_TRI_STIPPLE)
+#define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET| \
+                         DD_TRI_UNFILLED)
 
-/**********************************************************************/
-/*                 Render whole begin/end objects                     */
-/**********************************************************************/
 
 
-/* Vertices, no clipping.
- */
-#define RENDER_POINTS( start, count )          \
-   for ( ; start < count ; start++)            \
-      grDrawPoint( &v[ELT(start)].v );
+static void fxChooseRenderState(GLcontext *ctx)
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   fxMesaContext fxMesa = FX_CONTEXT(ctx);
+   GLuint flags = ctx->_TriangleCaps;
+   GLuint index = 0;
 
-#define RENDER_LINE( i1, i )                   \
-   grDrawLine( &v[i1].v, &v[i].v )
+/*     fprintf(stderr, "%s\n", __FUNCTION__); */
 
-#define RENDER_TRI( i2, i1, i )                                \
-   grDrawTriangle( &v[i2].v, &v[i1].v, &v[i].v )
+   if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) {
+      if (flags & ANY_RASTER_FLAGS) {
+        if (flags & DD_TRI_LIGHT_TWOSIDE)    index |= FX_TWOSIDE_BIT;
+        if (flags & DD_TRI_OFFSET)           index |= FX_OFFSET_BIT;
+        if (flags & DD_TRI_UNFILLED)         index |= FX_UNFILLED_BIT;
+        if (flags & DD_FLATSHADE)            index |= FX_FLAT_BIT;
+      }
 
-#define RENDER_QUAD( i3, i2, i1, i )                   \
-   grDrawTriangle( &v[i3].v, &v[i2].v, &v[i].v );      \
-   grDrawTriangle( &v[i2].v, &v[i1].v, &v[i].v )
+      fxMesa->draw_point = fx_draw_point;
+      fxMesa->draw_line = fx_draw_line;
+      fxMesa->draw_tri = fx_draw_triangle;
 
-#define TAG(x) fx_##x##_verts
-#define LOCAL_VARS                                             \
-    fxVertex *v = FX_CONTEXT(ctx)->verts;                      \
-    const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;      \
-    (void) elt;
+      /* Hook in fallbacks for specific primitives.
+       *
+       *
+       */
+      if (flags & (POINT_FALLBACK|
+                  LINE_FALLBACK|
+                  TRI_FALLBACK))
+      {
+        if (flags & POINT_FALLBACK)
+           fxMesa->draw_point = fx_fallback_point;
 
-/* Verts, no clipping.
- */
-#define ELT(x) x
-#define RESET_STIPPLE
-#define RESET_OCCLUSION
-#define PRESERVE_VB_DEFS
-#include "tnl/t_vb_rendertmp.h"
+        if (flags & LINE_FALLBACK)
+           fxMesa->draw_line = fx_fallback_line;
 
+        if (flags & TRI_FALLBACK)
+           fxMesa->draw_tri = fx_fallback_tri;
 
-/* Elts, no clipping.
- */
-#undef ELT
-#undef TAG
-#define TAG(x) fx_##x##_elts
-#define ELT(x) elt[x]
-#include "tnl/t_vb_rendertmp.h"
+        index |= FX_FALLBACK_BIT;
+      }
+   }
 
+   tnl->Driver.Render.Points = rast_tab[index].points;
+   tnl->Driver.Render.Line = rast_tab[index].line;
+   tnl->Driver.Render.ClippedLine = rast_tab[index].line;
+   tnl->Driver.Render.Triangle = rast_tab[index].triangle;
+   tnl->Driver.Render.Quad = rast_tab[index].quad;
+
+   if (index == 0) {
+      tnl->Driver.Render.PrimTabVerts = fx_render_tab_verts;
+      tnl->Driver.Render.PrimTabElts = fx_render_tab_elts;
+      tnl->Driver.Render.ClippedPolygon = fxFastRenderClippedPoly;
+   } else {
+      tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
+      tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
+      tnl->Driver.Render.ClippedPolygon = fxRenderClippedPoly;
+   }
+}
 
 /**********************************************************************/
-/*                    Choose render functions                         */
+/*                Runtime render state and callbacks                  */
 /**********************************************************************/
 
 
+static GLenum reduced_prim[GL_POLYGON+1] = {
+   GL_POINTS,
+   GL_LINES,
+   GL_LINES,
+   GL_LINES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES,
+   GL_TRIANGLES
+};
 
 
-#define POINT_FALLBACK (DD_POINT_SMOOTH )
-#define LINE_FALLBACK  (DD_LINE_STIPPLE)
-#define TRI_FALLBACK   (DD_TRI_SMOOTH | DD_TRI_STIPPLE )
-#define ANY_FALLBACK   (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK)
 
+/* Always called between RenderStart and RenderFinish --> We already
+ * hold the lock.
+ */
+static void fxRasterPrimitive( GLcontext *ctx, GLenum prim )
+{
+   fxMesaContext fxMesa = FX_CONTEXT( ctx );
 
-#define ANY_RENDER_FLAGS (DD_FLATSHADE |               \
-                         DD_TRI_LIGHT_TWOSIDE |        \
-                         DD_TRI_OFFSET |               \
-                         DD_TRI_UNFILLED)
+   fxMesa->raster_primitive = prim;
+   if (prim == GL_TRIANGLES)
+      grCullMode( fxMesa->cullMode );
+   else
+      grCullMode( GR_CULL_DISABLE );
+}
 
 
 
-/* Setup the Point, Line, Triangle and Quad functions based on the
- * current rendering state.  Wherever possible, use the hardware to
- * render the primitive.  Otherwise, fallback to software rendering.
+/* Determine the rasterized primitive when not drawing unfilled 
+ * polygons.
  */
-void
-fxDDChooseRenderState(GLcontext * ctx)
+static void fxRenderPrimitive( GLcontext *ctx, GLenum prim )
 {
-   TNLcontext *tnl = TNL_CONTEXT(ctx);
    fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   GLuint flags = ctx->_TriangleCaps;
-   GLuint index = 0;
+   GLuint rprim = reduced_prim[prim];
 
-   if (!fxMesa->is_in_hardware) {
-      /* Build software vertices directly.  No acceleration is
-       * possible.  GrVertices may be insufficient for this mode.
-       */
-      tnl->Driver.PointsFunc = _swsetup_Points;
-      tnl->Driver.LineFunc = _swsetup_Line;
-      tnl->Driver.TriangleFunc = _swsetup_Triangle;
-      tnl->Driver.QuadFunc = _swsetup_Quad;
-      tnl->Driver.RenderTabVerts = _tnl_render_tab_verts;
-      tnl->Driver.RenderTabElts = _tnl_render_tab_elts;
-
-      fxMesa->render_index = FX_FALLBACK_BIT;
-      return;
-   }
+   fxMesa->render_primitive = prim;
 
-   if (flags & ANY_RENDER_FLAGS) {
-      if (flags & DD_FLATSHADE)
-        index |= FX_FLAT_BIT;
-      if (flags & DD_TRI_LIGHT_TWOSIDE)
-        index |= FX_TWOSIDE_BIT;
-      if (flags & DD_TRI_OFFSET)
-        index |= FX_OFFSET_BIT;
-      if (flags & DD_TRI_UNFILLED)
-        index |= FX_UNFILLED_BIT;
+   if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
+      return;
+       
+   if (fxMesa->raster_primitive != rprim) {
+      fxRasterPrimitive( ctx, rprim );
    }
+}
 
-   if (flags & (ANY_FALLBACK |
-               DD_LINE_WIDTH | DD_POINT_SIZE | DD_TRI_CULL_FRONT_BACK)) {
-
-      /* Hook in fallbacks for specific primitives.
-
-       * Set up a system to turn culling on/off for wide points and
-       * lines.  Alternately: figure out what tris to send so that
-       * culling isn't a problem.  
-       *
-       * This replaces the ReducedPrimitiveChange mechanism.
-       */
-      index |= FX_FALLBACK_BIT;
-      fxMesa->initial_point = fx_cull_draw_point;
-      fxMesa->initial_line = fx_cull_draw_line;
-      fxMesa->initial_tri = fx_cull_draw_tri;
-
-      fxMesa->subsequent_point = fx_draw_point;
-      fxMesa->subsequent_line = fx_draw_line;
-      fxMesa->subsequent_tri = fx_draw_tri;
-
-      if (flags & POINT_FALLBACK)
-        fxMesa->initial_point = fx_fallback_point;
-
-      if (flags & LINE_FALLBACK)
-        fxMesa->initial_line = fx_fallback_line;
 
-      if ((flags & DD_LINE_SMOOTH) && ctx->Line.Width != 1.0)
-        fxMesa->initial_line = fx_fallback_line;
 
-      if (flags & TRI_FALLBACK)
-        fxMesa->initial_tri = fx_fallback_tri;
+/**********************************************************************/
+/*               Manage total rasterization fallbacks                 */
+/**********************************************************************/
 
-      if (flags & DD_TRI_CULL_FRONT_BACK)
-        fxMesa->initial_tri = fx_null_tri;
 
-      fxMesa->draw_point = fxMesa->initial_point;
-      fxMesa->draw_line = fxMesa->initial_line;
-      fxMesa->draw_tri = fxMesa->initial_tri;
-   }
-   else if (fxMesa->render_index & FX_FALLBACK_BIT) {
-      FX_grCullMode(fxMesa->cullMode);
-   }
+void fxCheckIsInHardware( GLcontext *ctx )
+{
+   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   GLuint oldfallback = !fxMesa->is_in_hardware;
+   GLuint newfallback;
 
-   tnl->Driver.PointsFunc = rast_tab[index].points;
-   tnl->Driver.LineFunc = rast_tab[index].line;
-   tnl->Driver.TriangleFunc = rast_tab[index].triangle;
-   tnl->Driver.QuadFunc = rast_tab[index].quad;
-   fxMesa->render_index = index;
+   fxMesa->is_in_hardware = check_IsInHardware( ctx );
+   newfallback = !fxMesa->is_in_hardware;
 
-   if (fxMesa->render_index == 0) {
-      tnl->Driver.RenderTabVerts = fx_render_tab_verts;
-      tnl->Driver.RenderTabElts = fx_render_tab_elts;
+   if (newfallback) {
+      if (oldfallback == 0) {
+        _swsetup_Wakeup( ctx );
+      }
    }
    else {
-      tnl->Driver.RenderTabVerts = _tnl_render_tab_verts;
-      tnl->Driver.RenderTabElts = _tnl_render_tab_elts;
+      if (oldfallback) {
+        _swrast_flush( ctx );
+        tnl->Driver.Render.Start = fxCheckTexSizes;
+        tnl->Driver.Render.Finish = _swrast_flush;
+        tnl->Driver.Render.PrimitiveNotify = fxRenderPrimitive;
+        tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; 
+        tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine;
+        tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
+        tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
+        tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
+        tnl->Driver.Render.BuildVertices = fxBuildVertices;
+        tnl->Driver.Render.Multipass = 0;
+        fxDDChooseSetupState(ctx);
+        fxDDChooseRenderState(ctx);
+      }
    }
 }
 
+void fxDDInitTriFuncs( GLcontext *ctx )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   fxMesaContext fxMesa = FX_CONTEXT(ctx);
+   static int firsttime = 1;
 
+   if (firsttime) {
+      init_rast_tab();
+      firsttime = 0;
+   }
 
-
-#else
-
-
-/*
- * Need this to provide at least one external definition.
- */
-
-extern int gl_fx_dummy_function_trifuncs(void);
-int
-gl_fx_dummy_function_trifuncs(void)
-{
-   return 0;
+   tnl->Driver.Render.Start = fxCheckTexSizes;
+   tnl->Driver.Render.Finish = _swrast_flush;
+   tnl->Driver.Render.PrimitiveNotify = fxRenderPrimitive;
+   tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; 
+   tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine;
+   tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
+   tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
+   tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
+   tnl->Driver.Render.BuildVertices = fxBuildVertices;
+   tnl->Driver.Render.Multipass = 0;
+   
+   (void) fx_print_vertex;
 }
-
-#endif /* FX */
index e38d3c3cdd5cfddf977c942e67abde1cd24fd60a..9468d83e3b439d637bc2106e2e08d1f89b9038f6 100644 (file)
@@ -1,9 +1,6 @@
-
 /*
- * Mesa 3-D graphics library
- * Version:  3.3
- *
- * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * GLX Hardware Device Driver for Intel i810
+ * Copyright (C) 1999 Keith Whitwell
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (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.
- *
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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.
  *
- * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
- * terms stated above.
  *
- * Author:
- *   Keith Whitwell <keith@precisioninsight.com>
  */
-
-
-/* fxvsetup.c - 3Dfx VooDoo vertices setup functions */
-
-
-#ifdef HAVE_CONFIG_H
-#include "conf.h"
-#endif
-
-#if defined(FX)
-
-#include "fxdrv.h"
+/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfxvb.c,v 1.7 2000/11/08 05:02:43 dawes Exp $ */
+#include "glheader.h"
+#include "mtypes.h"
+#include "mem.h"
+#include "macros.h"
+#include "colormac.h"
 #include "mmath.h"
+
+#include "math/m_translate.h"
 #include "swrast_setup/swrast_setup.h"
 
+#include "tnl/tnl.h"
 #include "tnl/t_context.h"
-#include "tnl/t_pipeline.h"
+
+#include "fxdrv.h"
 
 
-void
-fxPrintSetupFlags(const char *msg, GLuint flags)
+static void copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc )
 {
-   fprintf(stderr, "%s: %d %s%s%s%s%s\n",
-          msg,
-          flags,
-          (flags & SETUP_XYZW) ? " xyzw," : "",
-          (flags & SETUP_SNAP) ? " snap," : "",
-          (flags & SETUP_RGBA) ? " rgba," : "",
-          (flags & SETUP_TMU0) ? " tmu0," : "",
-          (flags & SETUP_TMU1) ? " tmu1," : "");
+   fxMesaContext fxMesa = FX_CONTEXT( ctx );
+   GrVertex *dst = fxMesa->verts + edst;
+   GrVertex *src = fxMesa->verts + esrc;
+
+   dst->r = src->r;
+   dst->g = src->g;
+   dst->b = src->b;
+   dst->a = src->a;
 }
 
-static void
-project_texcoords(fxVertex * v,
-                 struct vertex_buffer *VB,
-                 GLuint tmu_nr, GLuint tc_nr, GLuint start, GLuint count)
+typedef void (*emit_func)( GLcontext *, GLuint, GLuint, void * );
+
+static struct {
+   emit_func           emit;
+   interp_func         interp;
+   GLboolean           (*check_tex_sizes)( GLcontext *ctx );
+   GLuint               vertex_format;
+} setup_tab[MAX_SETUP];
+
+
+static void import_float_colors( GLcontext *ctx )
 {
-   GrTmuVertex *tmu = &(v->v.tmuvtx[tmu_nr]);
-   GLvector4f *vec = VB->TexCoordPtr[tc_nr];
+   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+   struct gl_client_array *from = VB->ColorPtr[0];
+   struct gl_client_array *to = &FX_CONTEXT(ctx)->UbyteColor;
+   GLuint count = VB->Count;
 
-   GLuint i;
-   GLuint stride = vec->stride;
-   GLfloat *data = VEC_ELT(vec, GLfloat, start);
+   if (!to->Ptr) {
+      to->Ptr = ALIGN_MALLOC( VB->Size * 4 * sizeof(GLubyte), 32 );
+      to->Type = GL_UNSIGNED_BYTE;
+   }
 
-   for (i = start; i < count; i++, STRIDE_F(data, stride), v++) {
-      tmu->oow = v->v.oow * data[3];
-      tmu = (GrTmuVertex *) ((char *) tmu + sizeof(fxVertex));
+   /* No need to transform the same value 3000 times.
+    */
+   if (!from->StrideB) {
+      to->StrideB = 0;
+      count = 1;
    }
+   else
+      to->StrideB = 4 * sizeof(GLubyte);
+   
+   _math_trans_4ub( (GLubyte (*)[4]) to->Ptr,
+                   from->Ptr,
+                   from->StrideB,
+                   from->Type,
+                   from->Size,
+                   0,
+                   count);
+
+   VB->ColorPtr[0] = to;
 }
 
 
-static void
-copy_w(fxVertex * v,
-       struct vertex_buffer *VB, GLuint tmu_nr, GLuint start, GLuint count)
-{
-   GrTmuVertex *tmu = &(v->v.tmuvtx[tmu_nr]);
-   GLuint i;
+#define GET_COLOR(ptr, idx) (((GLfloat (*)[4])((ptr)->Ptr))[idx])
 
-   for (i = start; i < count; i++, v++) {
-      tmu->oow = v->v.oow;
-      tmu = (GrTmuVertex *) ((char *) tmu + sizeof(fxVertex));
-   }
-}
 
-/* need to compute W values for fogging purposes 
- */
-static void
-fx_fake_fog_w(GLcontext * ctx,
-             fxVertex * verts,
-             struct vertex_buffer *VB, GLuint start, GLuint end)
+static void interp_extras( GLcontext *ctx,
+                          GLfloat t,
+                          GLuint dst, GLuint out, GLuint in,
+                          GLboolean force_boundary )
 {
-   const GLfloat m10 = ctx->ProjectionMatrix.m[10];
-   const GLfloat m14 = ctx->ProjectionMatrix.m[14];
-   GLfloat(*clip)[4] = VB->ClipPtr->data;
-   GLubyte *clipmask = VB->ClipMask;
-   GLuint i;
-
-   for (i = start; i < end; i++) {
-      if (clipmask[i] == 0) {
-        verts[i].v.oow = -m10 / (clip[i][2] - m14);    /* -1/zEye */
+   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+
+   /*fprintf(stderr, "%s\n", __FUNCTION__);*/
+
+   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) );
       }
    }
-}
 
+   if (VB->EdgeFlag) {
+      VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
+   }
 
+   setup_tab[FX_CONTEXT(ctx)->SetupIndex].interp(ctx, t, dst, out, in,
+                                                  force_boundary);
+}
 
-static tfxSetupFunc setupfuncs[MAX_SETUP];
+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) );
 
-#define IND (SETUP_XYZW)
-#define INPUTS (VERT_CLIP)
-#define NAME fxsetupXYZW
-#include "fxvbtmp.h"
+        if (VB->SecondaryColorPtr[1]) {
+           COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst), 
+                     GET_COLOR(VB->SecondaryColorPtr[1], src) );
+        }
+   }
 
-#define IND (SETUP_XYZW|SETUP_RGBA)
-#define INPUTS (VERT_CLIP|VERT_RGBA)
-#define NAME fxsetupXYZWRGBA
-#include "fxvbtmp.h"
+   copy_pv(ctx, dst, src);
+}
 
-#define IND (SETUP_XYZW|SETUP_TMU0)
-#define INPUTS (VERT_CLIP|VERT_TEX_ANY)
-#define NAME fxsetupXYZWT0
-#include "fxvbtmp.h"
 
-#define IND (SETUP_XYZW|SETUP_TMU1)
-#define INPUTS (VERT_CLIP|VERT_TEX_ANY)
-#define NAME fxsetupXYZWT1
+#define IND (SETUP_XYZW|SETUP_RGBA)
+#define TAG(x) x##_wg
 #include "fxvbtmp.h"
 
-#define IND (SETUP_XYZW|SETUP_TMU1|SETUP_TMU0)
-#define INPUTS (VERT_CLIP|VERT_TEX_ANY)
-#define NAME fxsetupXYZWT0T1
+#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0)
+#define TAG(x) x##_wgt0
 #include "fxvbtmp.h"
 
-#define IND (SETUP_XYZW|SETUP_TMU0|SETUP_RGBA)
-#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
-#define NAME fxsetupXYZWRGBAT0
+#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1)
+#define TAG(x) x##_wgt0t1
 #include "fxvbtmp.h"
 
-#define IND (SETUP_XYZW|SETUP_TMU1|SETUP_RGBA)
-#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
-#define NAME fxsetupXYZWRGBAT1
+#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_PTEX)
+#define TAG(x) x##_wgpt0
 #include "fxvbtmp.h"
 
-#define IND (SETUP_XYZW|SETUP_TMU1|SETUP_TMU0|SETUP_RGBA)
-#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
-#define NAME fxsetupXYZWRGBAT0T1
+#define IND (SETUP_XYZW|SETUP_RGBA|SETUP_TMU0|SETUP_TMU1|\
+             SETUP_PTEX)
+#define TAG(x) x##_wgpt0t1
 #include "fxvbtmp.h"
 
 
-#define IND (SETUP_XYZW|SETUP_SNAP)
-#define INPUTS (VERT_CLIP)
-#define NAME fxsetupXYZW_SNAP
-#include "fxvbtmp.h"
-
+/* Snapping for voodoo-1
+ */
 #define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA)
-#define INPUTS (VERT_CLIP|VERT_RGBA)
-#define NAME fxsetupXYZW_SNAP_RGBA
-#include "fxvbtmp.h"
-
-#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU0)
-#define INPUTS (VERT_CLIP|VERT_TEX_ANY)
-#define NAME fxsetupXYZW_SNAP_T0
+#define TAG(x) x##_wsg
 #include "fxvbtmp.h"
 
-#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1)
-#define INPUTS (VERT_CLIP|VERT_TEX_ANY)
-#define NAME fxsetupXYZW_SNAP_T1
+#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0)
+#define TAG(x) x##_wsgt0
 #include "fxvbtmp.h"
 
-#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_TMU0)
-#define INPUTS (VERT_CLIP|VERT_TEX_ANY)
-#define NAME fxsetupXYZW_SNAP_T0T1
+#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
+             SETUP_TMU1)
+#define TAG(x) x##_wsgt0t1
 #include "fxvbtmp.h"
 
-#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU0|SETUP_RGBA)
-#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
-#define NAME fxsetupXYZW_SNAP_RGBAT0
+#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
+             SETUP_PTEX)
+#define TAG(x) x##_wsgpt0
 #include "fxvbtmp.h"
 
-#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_RGBA)
-#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
-#define NAME fxsetupXYZW_SNAP_RGBAT1
+#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_RGBA|SETUP_TMU0|\
+            SETUP_TMU1|SETUP_PTEX)
+#define TAG(x) x##_wsgpt0t1
 #include "fxvbtmp.h"
 
-#define IND (SETUP_XYZW|SETUP_SNAP|SETUP_TMU1|SETUP_TMU0|SETUP_RGBA)
-#define INPUTS (VERT_CLIP|VERT_RGBA|VERT_TEX_ANY)
-#define NAME fxsetupXYZW_SNAP_RGBAT0T1
-#include "fxvbtmp.h"
-
-
 
+/* Vertex repair (multipass rendering)
+ */
 #define IND (SETUP_RGBA)
-#define INPUTS (VERT_RGBA)
-#define NAME fxsetupRGBA
+#define TAG(x) x##_g
 #include "fxvbtmp.h"
 
 #define IND (SETUP_TMU0)
-#define INPUTS (VERT_TEX_ANY)
-#define NAME fxsetupT0
-#include "fxvbtmp.h"
-
-#define IND (SETUP_TMU1)
-#define INPUTS (VERT_TEX_ANY)
-#define NAME fxsetupT1
+#define TAG(x) x##_t0
 #include "fxvbtmp.h"
 
-#define IND (SETUP_TMU1|SETUP_TMU0)
-#define INPUTS (VERT_TEX_ANY)
-#define NAME fxsetupT0T1
+#define IND (SETUP_TMU0|SETUP_TMU1)
+#define TAG(x) x##_t0t1
 #include "fxvbtmp.h"
 
-#define IND (SETUP_TMU0|SETUP_RGBA)
-#define INPUTS (VERT_RGBA|VERT_TEX_ANY)
-#define NAME fxsetupRGBAT0
+#define IND (SETUP_RGBA|SETUP_TMU0)
+#define TAG(x) x##_gt0
 #include "fxvbtmp.h"
 
-#define IND (SETUP_TMU1|SETUP_RGBA)
-#define INPUTS (VERT_RGBA|VERT_TEX_ANY)
-#define NAME fxsetupRGBAT1
+#define IND (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1)
+#define TAG(x) x##_gt0t1
 #include "fxvbtmp.h"
 
-#define IND (SETUP_TMU1|SETUP_TMU0|SETUP_RGBA)
-#define INPUTS (VERT_RGBA|VERT_TEX_ANY)
-#define NAME fxsetupRGBAT0T1
-#include "fxvbtmp.h"
 
 
-static void
-fxsetup_invalid(GLcontext * ctx, GLuint start, GLuint end)
+static void init_setup_tab( void )
 {
-   fprintf(stderr, "fxMesa: invalid setup function\n");
-   (void) (ctx && start && end);
+   init_wg();
+   init_wgt0();
+   init_wgt0t1();
+   init_wgpt0();
+   init_wgpt0t1();
+
+   init_wsg();
+   init_wsgt0();
+   init_wsgt0t1();
+   init_wsgpt0();
+   init_wsgpt0t1();
+
+   init_g();
+   init_t0();
+   init_t0t1();
+   init_gt0();
+   init_gt0t1();
 }
 
 
-void
-fxDDSetupInit(void)
+void fxPrintSetupFlags(char *msg, GLuint flags )
 {
-   GLuint i;
-   for (i = 0; i < Elements(setupfuncs); i++)
-      setupfuncs[i] = fxsetup_invalid;
-
-   setupfuncs[SETUP_XYZW] = fxsetupXYZW;
-   setupfuncs[SETUP_XYZW | SETUP_RGBA] = fxsetupXYZWRGBA;
-   setupfuncs[SETUP_XYZW | SETUP_TMU0] = fxsetupXYZWT0;
-   setupfuncs[SETUP_XYZW | SETUP_TMU1] = fxsetupXYZWT1;
-   setupfuncs[SETUP_XYZW | SETUP_TMU0 | SETUP_RGBA] = fxsetupXYZWRGBAT0;
-   setupfuncs[SETUP_XYZW | SETUP_TMU1 | SETUP_RGBA] = fxsetupXYZWRGBAT1;
-   setupfuncs[SETUP_XYZW | SETUP_TMU1 | SETUP_TMU0] = fxsetupXYZWT0T1;
-   setupfuncs[SETUP_XYZW | SETUP_TMU1 | SETUP_TMU0 | SETUP_RGBA] =
-      fxsetupXYZWRGBAT0T1;
-
-   setupfuncs[SETUP_XYZW | SETUP_SNAP] = fxsetupXYZW_SNAP;
-   setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_RGBA] = fxsetupXYZW_SNAP_RGBA;
-   setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU0] = fxsetupXYZW_SNAP_T0;
-   setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU1] = fxsetupXYZW_SNAP_T1;
-   setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU0 | SETUP_RGBA] =
-      fxsetupXYZW_SNAP_RGBAT0;
-   setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU1 | SETUP_RGBA] =
-      fxsetupXYZW_SNAP_RGBAT1;
-   setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU1 | SETUP_TMU0] =
-      fxsetupXYZW_SNAP_T0T1;
-   setupfuncs[SETUP_XYZW | SETUP_SNAP | SETUP_TMU1 | SETUP_TMU0 | SETUP_RGBA]
-      = fxsetupXYZW_SNAP_RGBAT0T1;
-
-   setupfuncs[SETUP_RGBA] = fxsetupRGBA;
-   setupfuncs[SETUP_TMU0] = fxsetupT0;
-   setupfuncs[SETUP_TMU1] = fxsetupT1;
-   setupfuncs[SETUP_TMU1 | SETUP_TMU0] = fxsetupT0T1;
-   setupfuncs[SETUP_TMU0 | SETUP_RGBA] = fxsetupRGBAT0;
-   setupfuncs[SETUP_TMU1 | SETUP_RGBA] = fxsetupRGBAT1;
-   setupfuncs[SETUP_TMU1 | SETUP_TMU0 | SETUP_RGBA] = fxsetupRGBAT0T1;
+   fprintf(stderr, "%s(%x): %s%s%s%s\n",
+          msg,
+          (int)flags,
+          (flags & SETUP_XYZW)     ? " xyzw," : "", 
+          (flags & SETUP_SNAP)     ? " snap," : "", 
+          (flags & SETUP_RGBA)     ? " rgba," : "",
+          (flags & SETUP_TMU0)     ? " tex-0," : "",
+          (flags & SETUP_TMU1)     ? " tex-1," : "");
 }
 
 
 
-void
-fx_validate_BuildProjVerts(GLcontext * ctx, GLuint start, GLuint count,
-                          GLuint newinputs)
+void fxCheckTexSizes( GLcontext *ctx )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
-   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
-
-   if (!fxMesa->is_in_hardware)
-      tnl->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices;
-   else {
-      GLuint setupindex = SETUP_XYZW;
+   fxMesaContext fxMesa = FX_CONTEXT( ctx );
 
-      if (fxMesa->snapVertices)
-         setupindex |= SETUP_SNAP;
+   if (!setup_tab[fxMesa->SetupIndex].check_tex_sizes(ctx)) {
+      GLuint ind = fxMesa->SetupIndex |= (SETUP_PTEX|SETUP_RGBA);
 
-      fxMesa->tmu_source[0] = 0;
-      fxMesa->tmu_source[1] = 1;
-      fxMesa->tex_dest[0] = SETUP_TMU0;
-      fxMesa->tex_dest[1] = SETUP_TMU1;
-
-      /* For flat and two-side-lit triangles, colors will always be added
-       * to vertices in the triangle functions.  Vertices will *always*
-       * have rbga values, but only sometimes will they come from here.
+      /* Tdfx handles projective textures nicely; just have to change
+       * up to the new vertex format.
        */
-      if ((ctx->_TriangleCaps & (DD_FLATSHADE | DD_TRI_LIGHT_TWOSIDE)) == 0)
-        setupindex |= SETUP_RGBA;
-
-      if (ctx->Texture._ReallyEnabled & TEXTURE0_2D)
-        setupindex |= SETUP_TMU0;
-
-      if (ctx->Texture._ReallyEnabled & TEXTURE1_2D) {
-        if ((ctx->Texture._ReallyEnabled & TEXTURE0_2D) == 0) {
-           fxMesa->tmu_source[0] = 1;
-           fxMesa->tex_dest[0] = SETUP_TMU1;
-           fxMesa->tmu_source[1] = 0;
-           fxMesa->tex_dest[1] = SETUP_TMU0;
-           setupindex |= SETUP_TMU0;
-        }
-        else {
-           setupindex |= SETUP_TMU1;
+      if (setup_tab[ind].vertex_format != fxMesa->stw_hint_state) {
+
+        fxMesa->stw_hint_state = setup_tab[ind].vertex_format;
+        FX_grHints(GR_HINT_STWHINT, fxMesa->stw_hint_state);
+
+        /* This is required as we have just changed the vertex
+         * format, so the interp routines must also change.
+         * In the unfilled and twosided cases we are using the
+         * Extras ones anyway, so leave them in place.
+         */
+        if (!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
+           tnl->Driver.Render.Interp = setup_tab[fxMesa->SetupIndex].interp;
         }
       }
-
-      if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_PIPELINE | VERBOSE_STATE))
-        fxPrintSetupFlags("fxmesa: vertex setup function", setupindex);
-
-      fxMesa->setupindex = setupindex;
-      tnl->Driver.BuildProjectedVertices = fx_BuildProjVerts;
    }
-   tnl->Driver.BuildProjectedVertices(ctx, start, count, newinputs);
 }
 
 
-void
-fx_BuildProjVerts(GLcontext * ctx, GLuint start, GLuint count,
-                 GLuint newinputs)
+void fxBuildVertices( GLcontext *ctx, GLuint start, GLuint count,
+                       GLuint newinputs )
 {
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+   fxMesaContext fxMesa = FX_CONTEXT( ctx );
+   GrVertex *v = (fxMesa->verts + start);
 
-   if (newinputs == ~0) {
-      /* build interpolated vertices */
-      setupfuncs[fxMesa->setupindex] (ctx, start, count);
-   }
-   else {
-      GLuint ind = fxMesa->setup_gone;
-      fxMesa->setup_gone = 0;
-
-      if (newinputs & VERT_CLIP)
-        ind = fxMesa->setupindex;      /* clipmask has potentially changed */
-      else {
-        if (newinputs & VERT_TEX0)
-           ind |= fxMesa->tex_dest[0];
+   if (!newinputs)
+      return;
 
-        if (newinputs & VERT_TEX1)
-           ind |= fxMesa->tex_dest[1];
+   if (newinputs & VERT_CLIP) {
+      setup_tab[fxMesa->SetupIndex].emit( ctx, start, count, v );   
+   } else {
+      GLuint ind = 0;
 
-        if (newinputs & VERT_RGBA)
-           ind |= SETUP_RGBA;
+      if (newinputs & VERT_RGBA)
+        ind |= SETUP_RGBA;
+      
+      if (newinputs & VERT_TEX0) 
+        ind |= SETUP_TMU0;
 
-        ind &= fxMesa->setupindex;
-      }
+      if (newinputs & VERT_TEX1)
+        ind |= SETUP_TMU0|SETUP_TMU1;
 
-      if (ind) {
-        if (fxMesa->new_state)
-           fxSetupFXUnits(ctx);        /* why? */
+      if (fxMesa->SetupIndex & SETUP_PTEX)
+        ind = ~0;
 
-        if (VB->importable_data & newinputs)
-           VB->import_data(ctx, VB->importable_data & newinputs,
-                           VEC_BAD_STRIDE);
+      ind &= fxMesa->SetupIndex;
 
-        setupfuncs[ind] (ctx, start, count);
+      if (ind) {
+        setup_tab[ind].emit( ctx, start, count, v );   
       }
    }
 }
 
-void
-fxAllocVB(GLcontext * ctx)
+
+void fxChooseVertexState( GLcontext *ctx )
 {
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
    TNLcontext *tnl = TNL_CONTEXT(ctx);
-   fxMesa->verts = ALIGN_MALLOC(tnl->vb.Size * sizeof(fxMesa->verts[0]), 32);
-}
+   fxMesaContext fxMesa = FX_CONTEXT( ctx );
+   GLuint ind = SETUP_XYZW|SETUP_RGBA;
 
-void
-fxFreeVB(GLcontext * ctx)
-{
-   fxMesaContext fxMesa = FX_CONTEXT(ctx);
-   if (fxMesa->verts)
-      ALIGN_FREE(fxMesa->verts);
-   fxMesa->verts = 0;
-}
+   if (fxMesa->snapVertices)
+      ind |= SETUP_SNAP;
+
+   fxMesa->tmu_source[0] = 0;
+   fxMesa->tmu_source[1] = 1;
 
+   if (ctx->Texture._ReallyEnabled & 0xf0) {
+      if (ctx->Texture._ReallyEnabled & 0xf) {
+        ind |= SETUP_TMU1|SETUP_TMU0;
+      }
+      else {
+        fxMesa->tmu_source[0] = 1;
+        fxMesa->tmu_source[1] = 0;
+        ind |= SETUP_TMU0;
+      }
+   }
+   else if (ctx->Texture._ReallyEnabled & 0xf) {
+      ind |= SETUP_TMU0;
+   }
+   
+   fxMesa->SetupIndex = ind;
+
+   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 = setup_tab[ind].interp;
+      tnl->Driver.Render.CopyPV = copy_pv;
+   }
 
-#else
+   if (setup_tab[ind].vertex_format != fxMesa->stw_hint_state) {
+      fxMesa->stw_hint_state = setup_tab[ind].vertex_format;
+      FX_grHints(GR_HINT_STWHINT, fxMesa->stw_hint_state);
+   }
+}
 
 
-/*
- * Need this to provide at least one external definition.
- */
 
-extern int gl_fx_dummy_function_vsetup(void);
-int
-gl_fx_dummy_function_vsetup(void)
+void fxAllocVB( GLcontext *ctx )
 {
-   return 0;
+   fxMesaContext fxMesa = FX_CONTEXT(ctx);
+   GLuint size = TNL_CONTEXT(ctx)->vb.Size;
+   static int firsttime = 1;
+   if (firsttime) {
+      init_setup_tab();
+      firsttime = 0;
+   }
+
+   fxMesa->verts = (GrVertex *)ALIGN_MALLOC(size * sizeof(GrVertex), 32);
+   fxMesa->SetupIndex = SETUP_XYZW|SETUP_RGBA;
 }
 
-#endif /* FX */
+
+void fxFreeVB( GLcontext *ctx )
+{
+   fxMesaContext fxMesa = FX_CONTEXT(ctx);
+   if (fxMesa->verts) {
+      ALIGN_FREE(fxMesa->verts);
+      fxMesa->verts = 0;
+   }
+
+   if (fxMesa->UbyteColor.Ptr) {
+      ALIGN_FREE(fxMesa->UbyteColor.Ptr);
+      fxMesa->UbyteColor.Ptr = 0;
+   }
+}
index 24d5b521a0075df7c158e01031a1b20e2687e639..570e7adf16b124f7327f2185865e22f839208092 100644 (file)
 
-/*
- * Mesa 3-D graphics library
- * Version:  3.3
- *
- * Copyright (C) 1999-2000  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.
- *
- * Author:
- *   Keith Whitwell <keith@precisioninsight.com>
- */
-
-
-static void
-NAME(GLcontext * ctx, GLuint start, GLuint end)
+static void TAG(emit)( GLcontext *ctx,
+                      GLuint start, GLuint end,
+                      void *dest )
 {
-   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
-   fxVertex *verts = fxMesa->verts;
+   fxMesaContext fxMesa = FX_CONTEXT(ctx);
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
    GLuint tmu0_source = fxMesa->tmu_source[0];
    GLuint tmu1_source = fxMesa->tmu_source[1];
-   GLfloat (*tmu0_data)[4];
-   GLfloat (*tmu1_data)[4];
-   GLfloat (*color)[4];
-   GLfloat (*proj)[4] = VB->ProjectedClipPtr->data;
-   fxVertex *v = &verts[start];
-   GLfloat sscale0 = fxMesa->s0scale;
-   GLfloat tscale0 = fxMesa->t0scale;
-   GLfloat sscale1 = fxMesa->s1scale;
-   GLfloat tscale1 = fxMesa->t1scale;
-   GLubyte *clipmask = VB->ClipMask;
-   GLuint i;
+   GLfloat (*tc0)[4], (*tc1)[4];
+   GLubyte (*col)[4];
+   GLuint tc0_stride, tc1_stride, col_stride;
+   GLuint tc0_size, tc1_size;
+   GLfloat (*proj)[4] = VB->ProjectedClipPtr->data; 
+   GLuint proj_stride = VB->ProjectedClipPtr->stride;
+   GrVertex *v = (GrVertex *)dest;
+   GLfloat u0scale,v0scale,u1scale,v1scale;
    const GLfloat *const s = ctx->Viewport._WindowMap.m;
+   int i;
 
-   if (IND & SETUP_TMU0)
-      tmu0_data = VB->TexCoordPtr[tmu0_source]->data;
 
-   if (IND & SETUP_TMU1)
-      tmu1_data = VB->TexCoordPtr[tmu1_source]->data;
+   if (IND & SETUP_TMU0) {
+      tc0_stride = VB->TexCoordPtr[tmu0_source]->stride;
+      tc0 = VB->TexCoordPtr[tmu0_source]->data;
+      u0scale = fxMesa->s0scale;
+      v0scale = fxMesa->t0scale;
+      if (IND & SETUP_PTEX)
+        tc0_size = VB->TexCoordPtr[tmu0_source]->size;
+   }
+
+   if (IND & SETUP_TMU1) {
+      tc1 = VB->TexCoordPtr[tmu1_source]->data;
+      tc1_stride = VB->TexCoordPtr[tmu1_source]->stride;
+      u1scale = fxMesa->s1scale; /* wrong if tmu1_source == 0, possible? */
+      v1scale = fxMesa->t1scale;
+      if (IND & SETUP_PTEX)
+        tc1_size = VB->TexCoordPtr[tmu1_source]->size;
+   }
+   
+   if (IND & SETUP_RGBA) {
+      if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE)
+        import_float_colors( ctx );
+      col = VB->ColorPtr[0]->Ptr;
+      col_stride = VB->ColorPtr[0]->StrideB;
+   }
 
-   if (IND & SETUP_RGBA) 
-      color = VB->ColorPtr[0]->Ptr;
+   if (start) {
+      proj =  (GLfloat (*)[4])((GLubyte *)proj + start * proj_stride);
+      if (IND & SETUP_TMU0)
+        tc0 =  (GLfloat (*)[4])((GLubyte *)tc0 + start * tc0_stride);
+      if (IND & SETUP_TMU1) 
+        tc1 =  (GLfloat (*)[4])((GLubyte *)tc1 + start * tc1_stride);
+      if (IND & SETUP_RGBA) 
+        STRIDE_4UB(col, start * col_stride);
+   }
 
-   if (VB->ClipOrMask) {
-      for (i = start; i < end; i++, v++) {
-        if (!clipmask[i]) {
-           if (IND & SETUP_XYZW) {
-              v->v.x = s[0] * proj[i][0] + s[12];
-              v->v.y = s[5] * proj[i][1] + s[13];
-              v->v.ooz = s[10] * proj[i][2] + s[14];
-              v->v.oow = proj[i][3];
+   for (i=start; i < end; i++, v++) {
+      if (IND & SETUP_XYZW) {
+        /* unclipped */
+        v->x   = s[0]  * proj[0][0] + s[12];   
+        v->y   = s[5]  * proj[0][1] + s[13];   
+        v->ooz = s[10] * proj[0][2] + s[14];   
+        v->oow = proj[0][3];   
 
-              if (IND & SETUP_SNAP) {
+        if (IND & SETUP_SNAP) {
 #if defined(USE_IEEE)
-                 const float snapper = (3L << 18);
-                 v->v.x += snapper;
-                 v->v.x -= snapper;
-                 v->v.y += snapper;
-                 v->v.y -= snapper;
+           const float snapper = (3L << 18);
+           v->x += snapper;
+           v->x -= snapper;
+           v->y += snapper;
+           v->y -= snapper;
 #else
-                 v->v.x = ((int) (v->v.x * 16.0f)) * (1.0f / 16.0f);
-                 v->v.y = ((int) (v->v.y * 16.0f)) * (1.0f / 16.0f);
+           v->x = ((int) (v->x * 16.0f)) * (1.0f / 16.0f);
+           v->y = ((int) (v->y * 16.0f)) * (1.0f / 16.0f);
 #endif
-              }
-           }
-           if (IND & SETUP_RGBA) {
-               UNCLAMPED_FLOAT_TO_UBYTE(v->v.r, color[i][0]);
-               UNCLAMPED_FLOAT_TO_UBYTE(v->v.g, color[i][1]);
-               UNCLAMPED_FLOAT_TO_UBYTE(v->v.b, color[i][2]);
-               UNCLAMPED_FLOAT_TO_UBYTE(v->v.a, color[i][3]);
-           }
-           if (IND & SETUP_TMU0) {
-              v->v.tmuvtx[0].sow = sscale0 * tmu0_data[i][0] * v->v.oow;
-              v->v.tmuvtx[0].tow = tscale0 * tmu0_data[i][1] * v->v.oow;
-           }
-           if (IND & SETUP_TMU1) {
-              v->v.tmuvtx[1].sow = sscale1 * tmu1_data[i][0] * v->v.oow;
-              v->v.tmuvtx[1].tow = tscale1 * tmu1_data[i][1] * v->v.oow;
-           }
         }
+
+        proj =  (GLfloat (*)[4])((GLubyte *)proj +  proj_stride);
       }
+      if (IND & SETUP_RGBA) {
+        v->r = (GLfloat) col[0][0];
+        v->g = (GLfloat) col[0][1];
+        v->b = (GLfloat) col[0][2];
+        v->a = (GLfloat) col[0][3];
+        STRIDE_4UB(col, col_stride);
+      }
+      if (IND & SETUP_TMU0) {
+        GLfloat w = v->oow;
+        if (IND & SETUP_PTEX) {
+           v->tmuvtx[0].sow = tc0[0][0] * u0scale * w;
+           v->tmuvtx[0].tow = tc0[0][1] * v0scale * w;
+           v->tmuvtx[0].oow = w;
+           if (tc0_size == 4) 
+              v->tmuvtx[0].oow = tc0[0][3] * w;
+        } 
+        else {
+           v->tmuvtx[0].sow = tc0[0][0] * u0scale * w;
+           v->tmuvtx[0].tow = tc0[0][1] * v0scale * w;
+        } 
+        tc0 =  (GLfloat (*)[4])((GLubyte *)tc0 +  tc0_stride);
+      }
+      if (IND & SETUP_TMU1) {
+        GLfloat w = v->oow;
+        if (IND & SETUP_PTEX) {
+           v->tmuvtx[1].sow = tc1[0][0] * u1scale * w;
+           v->tmuvtx[1].tow = tc1[0][1] * v1scale * w;
+           v->tmuvtx[1].oow = w;
+           if (tc1_size == 4) 
+              v->tmuvtx[1].oow = tc1[0][3] * w;
+        } 
+        else {
+           v->tmuvtx[1].sow = tc1[0][0] * u1scale * w;
+           v->tmuvtx[1].tow = tc1[0][1] * v1scale * w;
+        }
+        tc1 =  (GLfloat (*)[4])((GLubyte *)tc1 +  tc1_stride);
+      } 
    }
-   else {
-      for (i = start; i < end; i++, v++) {
-        if (IND & SETUP_XYZW) {
-           v->v.x = s[0] * proj[i][0] + s[12];
-           v->v.y = s[5] * proj[i][1] + s[13];
-           v->v.ooz = s[10] * proj[i][2] + s[14];
-           v->v.oow = proj[i][3];
-
-           if (IND & SETUP_SNAP) {
+}
+
+#if (IND & SETUP_XYZW) && (IND & SETUP_RGBA)
+
+static GLboolean TAG(check_tex_sizes)( GLcontext *ctx )
+{
+/*     fprintf(stderr, "%s\n", __FUNCTION__); */
+
+   if (IND & SETUP_PTEX)
+      return GL_TRUE;
+   
+   if (IND & SETUP_TMU0) {
+      struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+
+      if (IND & SETUP_TMU1) {
+        if (VB->TexCoordPtr[0] == 0)
+           VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
+        
+        if (VB->TexCoordPtr[1]->size == 4)
+           return GL_FALSE;
+      }
+
+      if (VB->TexCoordPtr[0]->size == 4)
+        return GL_FALSE;
+   }
+
+   return GL_TRUE;
+}
+
+static void TAG(interp)( GLcontext *ctx,
+                        GLfloat t, 
+                        GLuint edst, GLuint eout, GLuint ein,
+                        GLboolean force_boundary )
+{
+   fxMesaContext fxMesa = FX_CONTEXT( ctx );
+   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+   const GLfloat *dstclip = VB->ClipPtr->data[edst];
+   const GLfloat oow = (dstclip[3] == 0.0F) ? 1.0F : (1.0F / dstclip[3]);
+   const GLfloat *const s = ctx->Viewport._WindowMap.m;
+   GrVertex *fxverts = fxMesa->verts;
+   GrVertex *dst = (GrVertex *) (fxverts + edst);
+   const GrVertex *out = (const GrVertex *) (fxverts + eout);
+   const GrVertex *in = (const GrVertex *) (fxverts + ein);
+   const GLfloat wout = 1.0F / out->oow;
+   const GLfloat win = 1.0F / in->oow;
+
+   dst->x   = s[0]  * dstclip[0] * oow + s[12];        
+   dst->y   = s[5]  * dstclip[1] * oow + s[13];        
+   dst->z   = s[10] * dstclip[2] * oow + s[14];        
+   dst->oow = oow;     
+   
+   if (IND & SETUP_SNAP) {
 #if defined(USE_IEEE)
-              const float snapper = (3L << 18);
-              v->v.x += snapper;
-              v->v.x -= snapper;
-              v->v.y += snapper;
-              v->v.y -= snapper;
+      const float snapper = (3L << 18);
+      dst->x += snapper;
+      dst->x -= snapper;
+      dst->y += snapper;
+      dst->y -= snapper;
 #else
-              v->v.x = ((int) (v->v.x * 16.0f)) * (1.0f / 16.0f);
-              v->v.y = ((int) (v->v.y * 16.0f)) * (1.0f / 16.0f);
+      dst->x = ((int) (dst->x * 16.0f)) * (1.0f / 16.0f);
+      dst->y = ((int) (dst->y * 16.0f)) * (1.0f / 16.0f);
 #endif
-           }
-        }
-        if (IND & SETUP_RGBA) {
-            UNCLAMPED_FLOAT_TO_UBYTE(v->v.r, color[i][0]);
-            UNCLAMPED_FLOAT_TO_UBYTE(v->v.g, color[i][1]);
-            UNCLAMPED_FLOAT_TO_UBYTE(v->v.b, color[i][2]);
-            UNCLAMPED_FLOAT_TO_UBYTE(v->v.a, color[i][3]);
-        }
-        if (IND & SETUP_TMU0) {
-           v->v.tmuvtx[0].sow = sscale0 * tmu0_data[i][0] * v->v.oow;
-           v->v.tmuvtx[0].tow = tscale0 * tmu0_data[i][1] * v->v.oow;
-        }
-        if (IND & SETUP_TMU1) {
-           v->v.tmuvtx[1].sow = sscale1 * tmu1_data[i][0] * v->v.oow;
-           v->v.tmuvtx[1].tow = tscale1 * tmu1_data[i][1] * v->v.oow;
-        }
-      }
    }
 
-   if ((IND & SETUP_XYZW) &&
-       ctx->ProjectionMatrix.m[15] != 0.0F && ctx->Fog.Enabled) {
-      fx_fake_fog_w(ctx, v, VB, start, end);
-   }
+   
+   INTERP_F( t, dst->r, out->r, in->r );
+   INTERP_F( t, dst->g, out->g, in->g );
+   INTERP_F( t, dst->b, out->b, in->b );
+   INTERP_F( t, dst->a, out->a, in->a );
 
-   /* Check for and enable projective texturing in each texture unit.
-    */
-   if (IND & (SETUP_TMU0 | SETUP_TMU1)) {
-      GLuint tmu0_sz = 2;
-      GLuint tmu1_sz = 2;
-      GLuint hs = fxMesa->stw_hint_state & ~(GR_STWHINT_W_DIFF_TMU0 |
-                                            GR_STWHINT_W_DIFF_TMU1);
-
-      if (VB->TexCoordPtr[tmu0_source])
-        tmu0_sz = VB->TexCoordPtr[tmu0_source]->size;
-
-      if (VB->TexCoordPtr[tmu1_source])
-        tmu1_sz = VB->TexCoordPtr[tmu1_source]->size;
-
-      if (tmu0_sz == 4) {
-        project_texcoords(v, VB, 0, tmu0_source, start, end);
-        if (tmu1_sz == 4)
-           project_texcoords(v, VB, 1, tmu1_source, start, end);
-        else
-           copy_w(v, VB, 1, start, end);
-        hs |= (GR_STWHINT_W_DIFF_TMU0 | GR_STWHINT_W_DIFF_TMU1);
-      }
-      else if (tmu1_sz == 4) {
-        project_texcoords(v, VB, 1, tmu1_source, start, end);
-        hs |= GR_STWHINT_W_DIFF_TMU1;
+   if (IND & SETUP_TMU0) {
+      if (IND & SETUP_PTEX) {
+        INTERP_F( t, 
+                  dst->tmuvtx[0].sow, 
+                  out->tmuvtx[0].sow * wout, 
+                  in->tmuvtx[0].sow * win );
+        INTERP_F( t,
+                  dst->tmuvtx[0].tow,
+                  out->tmuvtx[0].tow * wout, 
+                  in->tmuvtx[0].tow * win );
+        INTERP_F( t, 
+                  dst->tmuvtx[0].oow, 
+                  out->tmuvtx[0].oow * wout, 
+                  in->tmuvtx[0].oow * win );
+
+        dst->tmuvtx[0].sow *= oow;
+        dst->tmuvtx[0].tow *= oow;
+        dst->tmuvtx[0].oow *= oow;
+      } else {
+        INTERP_F( t, 
+                  dst->tmuvtx[0].sow, 
+                  out->tmuvtx[0].sow * wout, 
+                  in->tmuvtx[0].sow * win );
+        INTERP_F( t,
+                  dst->tmuvtx[0].tow,
+                  out->tmuvtx[0].tow * wout, 
+                  in->tmuvtx[0].tow * win );
+
+        dst->tmuvtx[0].sow *= oow;
+        dst->tmuvtx[0].tow *= oow;
       }
+   }
+
+   if (IND & SETUP_TMU1) {
+      if (IND & SETUP_PTEX) {
+        INTERP_F( t, 
+                  dst->tmuvtx[1].sow, 
+                  out->tmuvtx[1].sow * wout, 
+                  in->tmuvtx[1].sow * win );
+        INTERP_F( t,
+                  dst->tmuvtx[1].tow,
+                  out->tmuvtx[1].tow * wout, 
+                  in->tmuvtx[1].tow * win );
+        INTERP_F( t, 
+                  dst->tmuvtx[1].oow, 
+                  out->tmuvtx[1].oow * wout, 
+                  in->tmuvtx[1].oow * win );
+
+        dst->tmuvtx[1].sow *= oow;
+        dst->tmuvtx[1].tow *= oow;
+        dst->tmuvtx[1].oow *= oow;
+      } else {
+        INTERP_F( t, 
+                  dst->tmuvtx[1].sow, 
+                  out->tmuvtx[1].sow * wout, 
+                  in->tmuvtx[1].sow * win );
+        INTERP_F( t,
+                  dst->tmuvtx[1].tow,
+                  out->tmuvtx[1].tow * wout, 
+                  in->tmuvtx[1].tow * win );
 
-      if (hs != fxMesa->stw_hint_state) {
-        fxMesa->stw_hint_state = hs;
-        FX_grHints(GR_HINT_STWHINT, hs);
+        dst->tmuvtx[1].sow *= oow;
+        dst->tmuvtx[1].tow *= oow;
       }
    }
 }
+#endif
+
 
+static void TAG(init)( void )
+{
+   setup_tab[IND].emit = TAG(emit);
+   
+#if ((IND & SETUP_XYZW) && (IND & SETUP_RGBA))
+   setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes);
+   setup_tab[IND].interp = TAG(interp);
 
+   if (IND & SETUP_PTEX) {
+      setup_tab[IND].vertex_format = (GR_STWHINT_W_DIFF_TMU0 |
+                                     GR_STWHINT_W_DIFF_TMU1);
+   }
+   else {
+      setup_tab[IND].vertex_format = 0;
+   }
+#endif
+}
 
 
 #undef IND
-#undef NAME
-#undef INPUTS
+#undef TAG
index 85679d6a9287cdb3338a510d077b141ee1aadf52..a0f2823f1d97e959cf05661971ae0fc8852bb884 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: osmesa.c,v 1.60 2001/07/05 15:12:13 brianp Exp $ */
+/* $Id: osmesa.c,v 1.61 2001/07/12 22:09:21 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -346,6 +346,7 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
         _tnl_CreateContext( ctx );
         _swsetup_CreateContext( ctx );
        
+        _swsetup_Wakeup( ctx );
         osmesa_register_swrast_functions( ctx );
       }
    }
@@ -2072,20 +2073,6 @@ static void osmesa_update_state( GLcontext *ctx, GLuint new_state )
    swdd->SetReadBuffer = set_read_buffer;
 
    tnl->Driver.RunPipeline = _tnl_run_pipeline;
-   tnl->Driver.RenderStart = _swsetup_RenderStart;
-   tnl->Driver.RenderFinish = _swsetup_RenderFinish;
-   tnl->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices;
-   tnl->Driver.RenderPrimitive = _swsetup_RenderPrimitive;
-   tnl->Driver.PointsFunc = _swsetup_Points;
-   tnl->Driver.LineFunc = _swsetup_Line;
-   tnl->Driver.TriangleFunc = _swsetup_Triangle;
-   tnl->Driver.QuadFunc = _swsetup_Quad;
-   tnl->Driver.ResetLineStipple = _swrast_ResetLineStipple;
-   tnl->Driver.RenderInterp = _swsetup_RenderInterp;
-   tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
-   tnl->Driver.RenderClippedLine = _swsetup_RenderClippedLine;
-   tnl->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon;
-
 
    _swrast_InvalidateState( ctx, new_state );
    _swsetup_InvalidateState( ctx, new_state );
index dbb01f343eff917eb72c877cb3bd017d6a76cc25..768aa2f56bd48fdb0cddc54b748dd14e96c7ef14 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: xm_dd.c,v 1.24 2001/05/10 12:22:32 keithw Exp $ */
+/* $Id: xm_dd.c,v 1.25 2001/07/12 22:09:21 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -992,19 +992,10 @@ void xmesa_init_pointers( GLcontext *ctx )
     */
    tnl = TNL_CONTEXT(ctx);
    tnl->Driver.RunPipeline = _tnl_run_pipeline;
-   tnl->Driver.RenderStart = _swsetup_RenderStart;
-   tnl->Driver.RenderFinish = _swsetup_RenderFinish;
-   tnl->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices;
-   tnl->Driver.RenderPrimitive = _swsetup_RenderPrimitive;
-   tnl->Driver.PointsFunc = _swsetup_Points;
-   tnl->Driver.LineFunc = _swsetup_Line;
-   tnl->Driver.TriangleFunc = _swsetup_Triangle;
-   tnl->Driver.QuadFunc = _swsetup_Quad;
-   tnl->Driver.ResetLineStipple = _swrast_ResetLineStipple;
-   tnl->Driver.RenderInterp = _swsetup_RenderInterp;
-   tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
-   tnl->Driver.RenderClippedLine = _swsetup_RenderClippedLine;
-   tnl->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon;
+   
+   /* Install swsetup for tnl->Driver.Render.*:
+    */
+   _swsetup_Wakeup(ctx);
 
    (void) DitherValues;  /* silenced unused var warning */
 }
index 255ab695f44c80fa4a2c5581e82030f541686d42..28980575a530d4e1652ecc6c9ea42d487e66c531 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile.X11,v 1.55 2001/06/27 12:52:12 keithw Exp $
+# $Id: Makefile.X11,v 1.56 2001/07/12 22:09:21 keithw Exp $
 
 # Mesa 3-D graphics library
 # Version:  3.5
@@ -21,6 +21,9 @@ LIBDIR = ../lib
 
 
 CORE_SOURCES = \
+       swrast_setup/ss_context.c \
+       swrast_setup/ss_triangle.c \
+       swrast_setup/ss_vb.c \
        api_arrayelt.c \
        api_loopback.c \
        api_noop.c \
@@ -118,10 +121,6 @@ CORE_SOURCES = \
        swrast/s_texstore.c \
        swrast/s_triangle.c \
        swrast/s_zoom.c \
-       swrast_setup/ss_context.c \
-       swrast_setup/ss_triangle.c \
-       swrast_setup/ss_vb.c \
-       swrast_setup/ss_interp.c \
        tnl/t_array_api.c \
        tnl/t_array_import.c \
        tnl/t_context.c \
index 69e066097060428305366d387471fe2293f24024..354d809e08ddbc27e398068315e215ecbeea8154 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_context.c,v 1.21 2001/05/17 09:32:17 keithw Exp $ */
+/* $Id: s_context.c,v 1.22 2001/07/12 22:09:21 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -529,7 +529,7 @@ _swrast_GetDeviceDriverReference( GLcontext *ctx )
    return &swrast->Driver;
 }
 
-#define SWRAST_DEBUG_VERTICES 0
+#define SWRAST_DEBUG_VERTICES 1
 
 void
 _swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
@@ -540,6 +540,8 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
       fprintf(stderr, "win %f %f %f %f\n",
              v->win[0], v->win[1], v->win[2], v->win[3]);
 
+      return;
+
       for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
         fprintf(stderr, "texcoord[%d] %f %f %f %f\n", i,
                 v->texcoord[i][0], v->texcoord[i][1],
index 4445b332d967c766dfd2d1bef10750377ad591e3..c6cb4ab348428fe8bcd7f5d5e8adbde2fef9e5dc 100644 (file)
@@ -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
index def9e4f43c84dd4c0abce3137040d011d89405c2..2e92342e07959f4014c8daeef609339f0e8f69cc 100644 (file)
@@ -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
 #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|         \
 #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 );
 }
index 895fb1b03edea9341037b95b9489128c2dea142a..f477f850cd3c4213141c3454db86482b491218ba 100644 (file)
@@ -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
 
 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)
index a12429e26df40b093d2e5671321d77019b4a3414..7b2d638213df9d905b08c7fba999f98ab74d9fbf 100644 (file)
@@ -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;
 }
index 0db792ba2b5abf0aaf7f8f19a7376d1513d41cdd..49e92acf1c37c0457df5987005d9024922710fda 100644 (file)
@@ -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]);
index f9d1d019975a2d596d2b861f66210c9f35431b10..7afb646769ff11641bf64bdba0a62afb8bd255ab 100644 (file)
@@ -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;
 }
+   
index 9ef51a3c2059d699d5f5114d78bbd50fcbb89799..4a83cf23019277f998546083a1a64e2a8b9768ca 100644 (file)
@@ -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
  */
 
 
-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
index bec8d90c1f3ff8578b074ccefad60011c015ebd8..1a4b036442976c0c483ce9c3ed668efe4ab38bce 100644 (file)
@@ -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
 /* 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
index 0acb9f9db20bac2dbc460b5ff3554651afe4c3a6..76f4180b657859efc6281492293dff203626d211 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: t_context.c,v 1.20 2001/06/28 17:34:14 keithw Exp $ */
+/* $Id: t_context.c,v 1.21 2001/07/12 22:09:21 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -123,8 +123,8 @@ _tnl_CreateContext( GLcontext *ctx )
    ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
    ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
 
-   tnl->Driver.RenderTabElts = _tnl_render_tab_elts;
-   tnl->Driver.RenderTabVerts = _tnl_render_tab_verts;
+   tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
+   tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
 
    
    return GL_TRUE;
index a7ecb346b708ba9b3c1383d65c3a9eac50c6b445..7142f31616588d77ac48b4fdeb8b97fc97700dca 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: t_context.h,v 1.29 2001/06/28 17:34:14 keithw Exp $ */
+/* $Id: t_context.h,v 1.30 2001/07/12 22:09:22 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -376,6 +376,9 @@ typedef void (*interp_func)( GLcontext *ctx,
                             GLfloat t, GLuint dst, GLuint out, GLuint in,
                             GLboolean force_boundary );
 typedef void (*copy_pv_func)( GLcontext *ctx, GLuint dst, GLuint src );
+typedef void (*setup_func)( GLcontext *ctx,
+                           GLuint start, GLuint end,
+                           GLuint new_inputs);
 
 
 struct tnl_device_driver {
@@ -390,87 +393,86 @@ struct tnl_device_driver {
     */
 
    /***
-    *** Rendering
+    *** Rendering -- These functions called only from t_vb_render.c
     ***/
-
-   void (*RenderStart)(GLcontext *ctx);
-   void (*RenderFinish)(GLcontext *ctx);
-   /* Called before and after all rendering operations, including DrawPixels,
-    * ReadPixels, Bitmap, span functions, and CopyTexImage, etc commands.
-    * These are a suitable place for grabbing/releasing hardware locks.
-    */
-
-   void (*RenderPrimitive)(GLcontext *ctx, GLenum mode);
-   /* Called between RednerStart() and RenderFinish() to indicate the
-    * type of primitive we're about to draw.  Mode will be one of the
-    * modes accepted by glBegin().
-    */
-
-   interp_func RenderInterp;
-   /* The interp function is called by the clipping routines when we need
-    * to generate an interpolated vertex.  All pertinant vertex ancilliary
-    * data should be computed by interpolating between the 'in' and 'out'
-    * vertices.
-    */
-
-   copy_pv_func RenderCopyPV;
-   /* The copy function is used to make a copy of a vertex.  All pertinant
-    * vertex attributes should be copied.
-    */
-
-   void (*RenderClippedPolygon)( GLcontext *ctx, const GLuint *elts, GLuint n );
-   /* Render a polygon with <n> vertices whose indexes are in the <elts>
-    * array.
-    */
-
-   void (*RenderClippedLine)( GLcontext *ctx, GLuint v0, GLuint v1 );
-   /* Render a line between the two vertices given by indexes v0 and v1. */
-
-   points_func           PointsFunc; /* must now respect vb->elts */
-   line_func             LineFunc;
-   triangle_func         TriangleFunc;
-   quad_func             QuadFunc;
-   /* These functions are called in order to render points, lines,
-    * triangles and quads.  These are only called via the T&L module.
-    */
-
-   render_func          *RenderTabVerts;
-   render_func          *RenderTabElts;
-   /* Render whole unclipped primitives (points, lines, linestrips,
-    * lineloops, etc).  The tables are indexed by the GL enum of the
-    * primitive to be rendered.  RenderTabVerts is used for non-indexed
-    * arrays of vertices.  RenderTabElts is used for indexed arrays of
-    * vertices.
-    */
-
-   void (*ResetLineStipple)( GLcontext *ctx );
-   /* Reset the hardware's line stipple counter.
-    */
-
-   void (*BuildProjectedVertices)( GLcontext *ctx,
-                                  GLuint start, GLuint end,
-                                  GLuint new_inputs);
-   /* This function is called whenever new vertices are required for
-    * rendering.  The vertices in question are those n such that start
-    * <= n < end.  The new_inputs parameter indicates those fields of
-    * the vertex which need to be updated, if only a partial repair of
-    * the vertex is required.
-    *
-    * This function is called only from _tnl_render_stage in tnl/t_render.c.
-    */
-
-
-   GLboolean (*MultipassFunc)( GLcontext *ctx, GLuint passno );
-   /* Driver may request additional render passes by returning GL_TRUE
-    * when this function is called.  This function will be called
-    * after the first pass, and passes will be made until the function
-    * returns GL_FALSE.  If no function is registered, only one pass
-    * is made.
-    *
-    * This function will be first invoked with passno == 1.
-    */
+   struct {
+      void (*Start)(GLcontext *ctx);
+      void (*Finish)(GLcontext *ctx);
+      /* Called before and after all rendering operations, including DrawPixels,
+       * ReadPixels, Bitmap, span functions, and CopyTexImage, etc commands.
+       * These are a suitable place for grabbing/releasing hardware locks.
+       */
+
+      void (*PrimitiveNotify)(GLcontext *ctx, GLenum mode);
+      /* Called between RenderStart() and RenderFinish() to indicate the
+       * type of primitive we're about to draw.  Mode will be one of the
+       * modes accepted by glBegin().
+       */
+
+      interp_func Interp;
+      /* The interp function is called by the clipping routines when we need
+       * to generate an interpolated vertex.  All pertinant vertex ancilliary
+       * data should be computed by interpolating between the 'in' and 'out'
+       * vertices.
+       */
+
+      copy_pv_func CopyPV;
+      /* The copy function is used to make a copy of a vertex.  All pertinant
+       * vertex attributes should be copied.
+       */
+
+      void (*ClippedPolygon)( GLcontext *ctx, const GLuint *elts, GLuint n );
+      /* Render a polygon with <n> vertices whose indexes are in the <elts>
+       * array.
+       */
+
+      void (*ClippedLine)( GLcontext *ctx, GLuint v0, GLuint v1 );
+      /* Render a line between the two vertices given by indexes v0 and v1. */
+
+      points_func           Points; /* must now respect vb->elts */
+      line_func             Line;
+      triangle_func         Triangle;
+      quad_func             Quad;
+      /* These functions are called in order to render points, lines,
+       * triangles and quads.  These are only called via the T&L module.
+       */
+
+      render_func          *PrimTabVerts;
+      render_func          *PrimTabElts;
+      /* Render whole unclipped primitives (points, lines, linestrips,
+       * lineloops, etc).  The tables are indexed by the GL enum of the
+       * primitive to be rendered.  RenderTabVerts is used for non-indexed
+       * arrays of vertices.  RenderTabElts is used for indexed arrays of
+       * vertices.
+       */
+
+      void (*ResetLineStipple)( GLcontext *ctx );
+      /* Reset the hardware's line stipple counter.
+       */
+
+      setup_func BuildVertices;
+      /* This function is called whenever new vertices are required for
+       * rendering.  The vertices in question are those n such that start
+       * <= n < end.  The new_inputs parameter indicates those fields of
+       * the vertex which need to be updated, if only a partial repair of
+       * the vertex is required.
+       *
+       * This function is called only from _tnl_render_stage in tnl/t_render.c.
+       */
+      
+
+      GLboolean (*Multipass)( GLcontext *ctx, GLuint passno );
+      /* Driver may request additional render passes by returning GL_TRUE
+       * when this function is called.  This function will be called
+       * after the first pass, and passes will be made until the function
+       * returns GL_FALSE.  If no function is registered, only one pass
+       * is made.
+       *
+       * This function will be first invoked with passno == 1.
+       */
+   } Render;
 };
-
+   
 
 typedef struct {
 
index 60b349d0e01db3cfb1579d40aa69dd4ec9272239..cb057df8105f88c84604036363d21b280e826dea 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: t_pipeline.h,v 1.7 2001/03/12 00:48:43 gareth Exp $ */
+/* $Id: t_pipeline.h,v 1.8 2001/07/12 22:09:22 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -66,4 +66,10 @@ extern const struct gl_pipeline_stage *_tnl_default_pipeline[];
 extern render_func _tnl_render_tab_elts[];
 extern render_func _tnl_render_tab_verts[];
 
+extern void _tnl_RenderClippedPolygon( GLcontext *ctx, 
+                                      const GLuint *elts, GLuint n );
+
+extern void _tnl_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj );
+
+
 #endif
index 90b9b82f53a7cab34e34e6fb76581dc0e26b44b3..8a26ad2de7bcc71914e64d788b506bb288a66a3d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: t_vb_cliptmp.h,v 1.12 2001/05/09 12:25:40 keithw Exp $ */
+/* $Id: t_vb_cliptmp.h,v 1.13 2001/07/12 22:09:22 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -124,7 +124,7 @@ static __inline void TAG(clip_line)( GLcontext *ctx,
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb;
-   interp_func interp = tnl->Driver.RenderInterp;
+   interp_func interp = tnl->Driver.Render.Interp;
    GLfloat (*coord)[4] = VB->ClipPtr->data;
    GLuint ii = i, jj = j, p;
 
@@ -152,9 +152,9 @@ static __inline void TAG(clip_line)( GLcontext *ctx,
    }
 
    if ((ctx->_TriangleCaps & DD_FLATSHADE) && j != jj)
-      tnl->Driver.RenderCopyPV( ctx, jj, j );
+      tnl->Driver.Render.CopyPV( ctx, jj, j );
 
-   tnl->Driver.RenderClippedLine( ctx, ii, jj );
+   tnl->Driver.Render.ClippedLine( ctx, ii, jj );
 }
 
 
@@ -166,7 +166,7 @@ static __inline void TAG(clip_tri)( GLcontext *ctx,
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb;
-   interp_func interp = tnl->Driver.RenderInterp;
+   interp_func interp = tnl->Driver.Render.Interp;
    GLfloat (*coord)[4] = VB->ClipPtr->data;
    GLuint pv = v2;
    GLuint vlist[2][MAX_CLIPPED_VERTICES];
@@ -203,11 +203,11 @@ static __inline void TAG(clip_tri)( GLcontext *ctx,
    if (ctx->_TriangleCaps & DD_FLATSHADE) {
       if (pv != inlist[0]) {
         ASSERT( inlist[0] >= VB->FirstClipped );
-        tnl->Driver.RenderCopyPV( ctx, inlist[0], pv );
+        tnl->Driver.Render.CopyPV( ctx, inlist[0], pv );
       }
    }
 
-   tnl->Driver.RenderClippedPolygon( ctx, inlist, n );
+   tnl->Driver.Render.ClippedPolygon( ctx, inlist, n );
 }
 
 
@@ -219,7 +219,7 @@ static __inline void TAG(clip_quad)( GLcontext *ctx,
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb;
-   interp_func interp = tnl->Driver.RenderInterp;
+   interp_func interp = tnl->Driver.Render.Interp;
    GLfloat (*coord)[4] = VB->ClipPtr->data;
    GLuint pv = v3;
    GLuint vlist[2][MAX_CLIPPED_VERTICES];
@@ -256,11 +256,11 @@ static __inline void TAG(clip_quad)( GLcontext *ctx,
    if (ctx->_TriangleCaps & DD_FLATSHADE) {
       if (pv != inlist[0]) {
         ASSERT( inlist[0] >= VB->FirstClipped );
-        tnl->Driver.RenderCopyPV( ctx, inlist[0], pv );
+        tnl->Driver.Render.CopyPV( ctx, inlist[0], pv );
       }
    }
 
-   tnl->Driver.RenderClippedPolygon( ctx, inlist, n );
+   tnl->Driver.Render.ClippedPolygon( ctx, inlist, n );
 }
 
 #undef W
index ec3cb02bb66869dce05d1b7a8a45546f5f7d1831..5ad8c3e5be318c2dfff647586f80053fb8b1287d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: t_vb_render.c,v 1.21 2001/06/15 15:22:08 brianp Exp $ */
+/* $Id: t_vb_render.c,v 1.22 2001/07/12 22:09:22 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
  * This file makes calls to project vertices and to the point, line
  * and triangle rasterizers via the function pointers:
  *
- *    context->Driver.BuildProjectedVertices()
+ *    context->Driver.Render.*
  *
- *    context->Driver.PointsFunc()
- *    context->Driver.LineFunc()
- *    context->Driver.TriangleFunc()
- *    context->Driver.QuadFunc()
- *
- *    context->Driver.RenderTabVerts[]
- *    context->Driver.RenderTabElts[]
- *
- * None of these may be null.
  */
 
 
 /* Vertices, with the possibility of clipping.
  */
 #define RENDER_POINTS( start, count ) \
-   tnl->Driver.PointsFunc( ctx, start, count )
+   tnl->Driver.Render.Points( ctx, start, count )
 
 #define RENDER_LINE( v1, v2 )                  \
 do {                                           \
@@ -142,16 +133,16 @@ do {                                                      \
    const GLuint * const elt = VB->Elts;                                \
    const GLubyte *mask = VB->ClipMask;                         \
    const GLuint sz = VB->ClipPtr->size;                                \
-   const line_func LineFunc = tnl->Driver.LineFunc;            \
-   const triangle_func TriangleFunc = tnl->Driver.TriangleFunc;        \
-   const quad_func QuadFunc = tnl->Driver.QuadFunc;            \
+   const line_func LineFunc = tnl->Driver.Render.Line;         \
+   const triangle_func TriangleFunc = tnl->Driver.Render.Triangle;     \
+   const quad_func QuadFunc = tnl->Driver.Render.Quad;         \
    const GLboolean stipple = ctx->Line.StippleFlag;            \
    (void) (LineFunc && TriangleFunc && QuadFunc);              \
    (void) elt; (void) mask; (void) sz; (void) stipple;
 
 #define TAG(x) clip_##x##_verts
-#define INIT(x) tnl->Driver.RenderPrimitive( ctx, x )
-#define RESET_STIPPLE if (stipple) tnl->Driver.ResetLineStipple( ctx )
+#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x )
+#define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple( ctx )
 #define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE
 #define PRESERVE_VB_DEFS
 #include "t_vb_rendertmp.h"
@@ -174,7 +165,7 @@ static void clip_elt_triangles( GLcontext *ctx,
                                GLuint flags )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
-   render_func render_tris = tnl->Driver.RenderTabElts[GL_TRIANGLES];
+   render_func render_tris = tnl->Driver.Render.PrimTabElts[GL_TRIANGLES];
    struct vertex_buffer *VB = &tnl->vb;
    const GLuint * const elt = VB->Elts;
    GLubyte *mask = VB->ClipMask;
@@ -182,7 +173,7 @@ static void clip_elt_triangles( GLcontext *ctx,
    GLuint j;
    (void) flags;
 
-   tnl->Driver.RenderPrimitive( ctx, GL_TRIANGLES );
+   tnl->Driver.Render.PrimitiveNotify( ctx, GL_TRIANGLES );
 
    for (j=start; j < last; j+=3 ) {
       GLubyte c1 = mask[elt[j]];
@@ -214,7 +205,7 @@ static void clip_elt_triangles( GLcontext *ctx,
 /* Vertices, no clipping.
  */
 #define RENDER_POINTS( start, count ) \
-   tnl->Driver.PointsFunc( ctx, start, count )
+   tnl->Driver.Render.Points( ctx, start, count )
 
 #define RENDER_LINE( v1, v2 ) \
    LineFunc( ctx, v1, v2 )
@@ -231,15 +222,15 @@ static void clip_elt_triangles( GLcontext *ctx,
    TNLcontext *tnl = TNL_CONTEXT(ctx);                         \
    struct vertex_buffer *VB = &tnl->vb;                                \
    const GLuint * const elt = VB->Elts;                                \
-   const line_func LineFunc = tnl->Driver.LineFunc;            \
-   const triangle_func TriangleFunc = tnl->Driver.TriangleFunc;        \
-   const quad_func QuadFunc = tnl->Driver.QuadFunc;            \
+   const line_func LineFunc = tnl->Driver.Render.Line;         \
+   const triangle_func TriangleFunc = tnl->Driver.Render.Triangle;     \
+   const quad_func QuadFunc = tnl->Driver.Render.Quad;         \
    (void) (LineFunc && TriangleFunc && QuadFunc);              \
    (void) elt;
 
-#define RESET_STIPPLE tnl->Driver.ResetLineStipple( ctx )
+#define RESET_STIPPLE tnl->Driver.Render.ResetLineStipple( ctx )
 #define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE
-#define INIT(x) tnl->Driver.RenderPrimitive( ctx, x )
+#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x )
 #define RENDER_TAB_QUALIFIER
 #define PRESERVE_VB_DEFS
 #include "t_vb_rendertmp.h"
@@ -253,6 +244,27 @@ static void clip_elt_triangles( GLcontext *ctx,
 #include "t_vb_rendertmp.h"
 
 
+/**********************************************************************/
+/*              Helper functions for drivers                  */
+/**********************************************************************/
+
+void _tnl_RenderClippedPolygon( GLcontext *ctx, const GLuint *elts, GLuint n )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct vertex_buffer *VB = &tnl->vb;
+   GLuint *tmp = VB->Elts;
+
+   VB->Elts = (GLuint *)elts;
+   tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END );
+   VB->Elts = tmp;
+}
+
+void _tnl_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
+{
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   tnl->Driver.Render.Line( ctx, ii, jj );
+}
+
 
 
 /**********************************************************************/
@@ -274,31 +286,33 @@ static GLboolean run_render( GLcontext *ctx,
     * that window coordinates are guarenteed not to change before
     * rendering.
     */
-   ASSERT(tnl->Driver.RenderStart);
+   ASSERT(tnl->Driver.Render.Start);
 
-   tnl->Driver.RenderStart( ctx );
+   tnl->Driver.Render.Start( ctx );
 
-   ASSERT(tnl->Driver.BuildProjectedVertices);
-   ASSERT(tnl->Driver.RenderPrimitive);
-   ASSERT(tnl->Driver.PointsFunc);
-   ASSERT(tnl->Driver.LineFunc);
-   ASSERT(tnl->Driver.TriangleFunc);
-   ASSERT(tnl->Driver.QuadFunc);
-   ASSERT(tnl->Driver.ResetLineStipple);
-   ASSERT(tnl->Driver.RenderInterp);
-   ASSERT(tnl->Driver.RenderCopyPV);
-   ASSERT(tnl->Driver.RenderClippedLine);
-   ASSERT(tnl->Driver.RenderClippedPolygon);
-   ASSERT(tnl->Driver.RenderFinish);
+   ASSERT(tnl->Driver.Render.BuildVertices);
+   ASSERT(tnl->Driver.Render.PrimitiveNotify);
+   ASSERT(tnl->Driver.Render.Points);
+   ASSERT(tnl->Driver.Render.Line);
+   ASSERT(tnl->Driver.Render.Triangle);
+   ASSERT(tnl->Driver.Render.Quad);
+   ASSERT(tnl->Driver.Render.ResetLineStipple);
+   ASSERT(tnl->Driver.Render.Interp);
+   ASSERT(tnl->Driver.Render.CopyPV);
+   ASSERT(tnl->Driver.Render.ClippedLine);
+   ASSERT(tnl->Driver.Render.ClippedPolygon);
+   ASSERT(tnl->Driver.Render.Finish);
 
-   tnl->Driver.BuildProjectedVertices( ctx, 0, VB->Count, new_inputs );
+   tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, new_inputs );
 
    if (VB->ClipOrMask) {
       tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts;
       clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles;
    }
    else {
-      tab = VB->Elts ? tnl->Driver.RenderTabElts : tnl->Driver.RenderTabVerts;
+      tab = (VB->Elts ? 
+            tnl->Driver.Render.PrimTabElts : 
+            tnl->Driver.Render.PrimTabVerts);
    }
 
    do
@@ -313,11 +327,11 @@ static GLboolean run_render( GLcontext *ctx,
         if (length)
            tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags );
       }
-   } while (tnl->Driver.MultipassFunc &&
-           tnl->Driver.MultipassFunc( ctx, ++pass ));
+   } while (tnl->Driver.Render.Multipass &&
+           tnl->Driver.Render.Multipass( ctx, ++pass ));
 
 
-   tnl->Driver.RenderFinish( ctx );
+   tnl->Driver.Render.Finish( ctx );
 /*     _swrast_flush(ctx); */
 /*     usleep(1000000); */
    return GL_FALSE;            /* finished the pipe */