Merge branch 'llvm-cliptest-viewport'
[mesa.git] / src / mesa / drivers / dri / tdfx / tdfx_state.c
index 5e59b91f80d67eeac9ff0c42fb8fd7fd38c4f0a9..3f6822d4574d31d2ad448256c8cf161400c29b61 100644 (file)
  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c,v 1.7 2002/10/30 12:52:00 alanh Exp $ */
 
 /*
+ * New fixes:
+ *     Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004
+ *
  * Original rewrite:
  *     Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
  *
  *
  */
 
-#include "mtypes.h"
-#include "colormac.h"
-#include "texformat.h"
-#include "texstore.h"
-#include "teximage.h"
+#include "main/mtypes.h"
+#include "main/colormac.h"
 
 #include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
 #include "tnl/tnl.h"
 #include "tnl/t_pipeline.h"
 #include "swrast_setup/swrast_setup.h"
 
 #include "tdfx_context.h"
 #include "tdfx_state.h"
-#include "tdfx_vb.h"
 #include "tdfx_tex.h"
 #include "tdfx_texman.h"
 #include "tdfx_texstate.h"
-#include "tdfx_tris.h"
 #include "tdfx_render.h"
 
 
  * Alpha blending
  */
 
-static void tdfxUpdateAlphaMode( GLcontext *ctx )
+static void tdfxUpdateAlphaMode( struct gl_context *ctx )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    GrCmpFnc_t func;
    GrAlphaBlendFnc_t srcRGB, dstRGB, srcA, dstA;
+   GrAlphaBlendOp_t eqRGB, eqA;
    GrAlpha_t ref = (GLint) (ctx->Color.AlphaRef * 255.0);
+   
+   GLboolean isNapalm = TDFX_IS_NAPALM(fxMesa);
+   GLboolean have32bpp = (ctx->Visual.greenBits == 8);
+   GLboolean haveAlpha = fxMesa->haveHwAlpha;
 
    if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
       fprintf( stderr, "%s()\n", __FUNCTION__ );
    }
 
    if ( ctx->Color.AlphaEnabled ) {
-      switch ( ctx->Color.AlphaFunc ) {
-      case GL_NEVER:
-        func = GR_CMP_NEVER;
-        break;
-      case GL_LESS:
-        func = GR_CMP_LESS;
-         break;
-      case GL_LEQUAL:
-        func = GR_CMP_LEQUAL;
-        break;
-      case GL_EQUAL:
-        func = GR_CMP_EQUAL;
-        break;
-      case GL_GEQUAL:
-        func = GR_CMP_GEQUAL;
-        break;
-      case GL_GREATER:
-        func = GR_CMP_GREATER;
-        break;
-      case GL_NOTEQUAL:
-        func = GR_CMP_NOTEQUAL;
-        break;
-      case GL_ALWAYS:
-      default:
-        func = GR_CMP_ALWAYS;
-        break;
-      }
+      func = ctx->Color.AlphaFunc - GL_NEVER + GR_CMP_NEVER;
    } else {
       func = GR_CMP_ALWAYS;
    }
@@ -128,14 +104,24 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx )
         srcRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA;
         break;
       case GL_DST_ALPHA:
-        srcRGB = GR_BLEND_DST_ALPHA;
+        srcRGB = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/;
         break;
       case GL_ONE_MINUS_DST_ALPHA:
-        srcRGB = GR_BLEND_ONE_MINUS_DST_ALPHA;
+        srcRGB = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/;
         break;
       case GL_SRC_ALPHA_SATURATE:
         srcRGB = GR_BLEND_ALPHA_SATURATE;
         break;
+      case GL_SRC_COLOR:
+         if (isNapalm) {
+           srcRGB = GR_BLEND_SAME_COLOR_EXT;
+           break;
+         }
+      case GL_ONE_MINUS_SRC_COLOR:
+         if (isNapalm) {
+           srcRGB = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT;
+           break;
+         }
       default:
         srcRGB = GR_BLEND_ONE;
       }
@@ -147,23 +133,21 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx )
       case GL_ONE:
         srcA = GR_BLEND_ONE;
         break;
-      case GL_DST_COLOR:
-        srcA = GR_BLEND_DST_ALPHA;  /* Napalm only */
-        break;
-      case GL_ONE_MINUS_DST_COLOR:
-        srcA = GR_BLEND_ONE_MINUS_DST_ALPHA;  /* Napalm only */
-        break;
+      case GL_SRC_COLOR:
       case GL_SRC_ALPHA:
-        srcA = GR_BLEND_SRC_ALPHA;  /* Napalm only */
+        srcA = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ONE/*JJJ*/;
         break;
+      case GL_ONE_MINUS_SRC_COLOR:
       case GL_ONE_MINUS_SRC_ALPHA:
-        srcA = GR_BLEND_ONE_MINUS_SRC_ALPHA;  /* Napalm only */
+        srcA = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ONE/*JJJ*/;
         break;
+      case GL_DST_COLOR:
       case GL_DST_ALPHA:
-        srcA = GR_BLEND_DST_ALPHA;  /* Napalm only */
+        srcA = (have32bpp && haveAlpha) ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/;
         break;
+      case GL_ONE_MINUS_DST_COLOR:
       case GL_ONE_MINUS_DST_ALPHA:
-        srcA = GR_BLEND_ONE_MINUS_DST_ALPHA;  /* Napalm only */
+        srcA = (have32bpp && haveAlpha) ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/;
         break;
       case GL_SRC_ALPHA_SATURATE:
          srcA = GR_BLEND_ONE;
@@ -192,11 +176,21 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx )
         dstRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA;
         break;
       case GL_DST_ALPHA:
-        dstRGB = GR_BLEND_DST_ALPHA;
+        dstRGB = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/;
         break;
       case GL_ONE_MINUS_DST_ALPHA:
-        dstRGB = GR_BLEND_ONE_MINUS_DST_ALPHA;
+        dstRGB = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/;
         break;
+      case GL_DST_COLOR:
+         if (isNapalm) {
+           dstRGB = GR_BLEND_SAME_COLOR_EXT;
+           break;
+         }
+      case GL_ONE_MINUS_DST_COLOR:
+         if (isNapalm) {
+           dstRGB = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT;
+           break;
+         }
       default:
         dstRGB = GR_BLEND_ZERO;
       }
@@ -209,32 +203,58 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx )
         dstA = GR_BLEND_ONE;
         break;
       case GL_SRC_COLOR:
-        dstA = GR_BLEND_SRC_ALPHA;  /* Napalm only */
-        break;
-      case GL_ONE_MINUS_SRC_COLOR:
-        dstA = GR_BLEND_ONE_MINUS_SRC_ALPHA;  /* Napalm only */
-        break;
       case GL_SRC_ALPHA:
-        dstA = GR_BLEND_SRC_ALPHA;  /* Napalm only */
+        dstA = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ZERO/*JJJ*/;
         break;
+      case GL_ONE_MINUS_SRC_COLOR:
       case GL_ONE_MINUS_SRC_ALPHA:
-        dstA = GR_BLEND_ONE_MINUS_SRC_ALPHA;  /* Napalm only */
+        dstA = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ZERO/*JJJ*/;
         break;
+      case GL_DST_COLOR:
       case GL_DST_ALPHA:
-        dstA = GR_BLEND_DST_ALPHA;  /* Napalm only */
+        dstA = have32bpp ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/;
         break;
+      case GL_ONE_MINUS_DST_COLOR:
       case GL_ONE_MINUS_DST_ALPHA:
-        dstA = GR_BLEND_ONE_MINUS_DST_ALPHA;  /* Napalm only */
+        dstA = have32bpp ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/;
         break;
       default:
         dstA = GR_BLEND_ZERO;
       }
+
+      switch ( ctx->Color.BlendEquationRGB ) {
+      case GL_FUNC_SUBTRACT:
+        eqRGB = GR_BLEND_OP_SUB;
+        break;
+      case GL_FUNC_REVERSE_SUBTRACT:
+        eqRGB = GR_BLEND_OP_REVSUB;
+        break;
+      case GL_FUNC_ADD:
+      default:
+        eqRGB = GR_BLEND_OP_ADD;
+        break;
+      }
+
+      switch ( ctx->Color.BlendEquationA ) {
+      case GL_FUNC_SUBTRACT:
+        eqA = GR_BLEND_OP_SUB;
+        break;
+      case GL_FUNC_REVERSE_SUBTRACT:
+        eqA = GR_BLEND_OP_REVSUB;
+        break;
+      case GL_FUNC_ADD:
+      default:
+        eqA = GR_BLEND_OP_ADD;
+        break;
+      }
    } else {
       /* blend disabled */
       srcRGB = GR_BLEND_ONE;
       dstRGB = GR_BLEND_ZERO;
+      eqRGB = GR_BLEND_OP_ADD;
       srcA = GR_BLEND_ONE;
       dstA = GR_BLEND_ZERO;
+      eqA = GR_BLEND_OP_ADD;
    }
 
    if ( fxMesa->Color.AlphaFunc != func ) {
@@ -248,18 +268,22 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx )
 
    if ( fxMesa->Color.BlendSrcRGB != srcRGB ||
        fxMesa->Color.BlendDstRGB != dstRGB ||
+       fxMesa->Color.BlendEqRGB != eqRGB ||
        fxMesa->Color.BlendSrcA != srcA ||
-       fxMesa->Color.BlendDstA != dstA )
+       fxMesa->Color.BlendDstA != dstA ||
+       fxMesa->Color.BlendEqA != eqA )
    {
       fxMesa->Color.BlendSrcRGB = srcRGB;
       fxMesa->Color.BlendDstRGB = dstRGB;
+      fxMesa->Color.BlendEqRGB = eqRGB;
       fxMesa->Color.BlendSrcA = srcA;
       fxMesa->Color.BlendDstA = dstA;
+      fxMesa->Color.BlendEqA = eqA;
       fxMesa->dirty |= TDFX_UPLOAD_BLEND_FUNC;
    }
 }
 
-static void tdfxDDAlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref )
+static void tdfxDDAlphaFunc( struct gl_context *ctx, GLenum func, GLfloat ref )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
@@ -267,7 +291,7 @@ static void tdfxDDAlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref )
    fxMesa->new_state |= TDFX_NEW_ALPHA;
 }
 
-static void tdfxDDBlendEquationSeparate( GLcontext *ctx, 
+static void tdfxDDBlendEquationSeparate( struct gl_context *ctx, 
                                         GLenum modeRGB, GLenum modeA )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
@@ -277,7 +301,7 @@ static void tdfxDDBlendEquationSeparate( GLcontext *ctx,
    fxMesa->new_state |= TDFX_NEW_ALPHA;
 }
 
-static void tdfxDDBlendFuncSeparate( GLcontext *ctx,
+static void tdfxDDBlendFuncSeparate( struct gl_context *ctx,
                                     GLenum sfactorRGB, GLenum dfactorRGB,
                                     GLenum sfactorA, GLenum dfactorA )
 {
@@ -297,7 +321,7 @@ static void tdfxDDBlendFuncSeparate( GLcontext *ctx,
  * Stipple
  */
 
-void tdfxUpdateStipple( GLcontext *ctx )
+void tdfxUpdateStipple( struct gl_context *ctx )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
    GrStippleMode_t mode = GR_STIPPLE_DISABLE;
@@ -323,7 +347,7 @@ void tdfxUpdateStipple( GLcontext *ctx )
  * Depth testing
  */
 
-static void tdfxUpdateZMode( GLcontext *ctx )
+static void tdfxUpdateZMode( struct gl_context *ctx )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
    GrCmpFnc_t func;
@@ -337,40 +361,8 @@ static void tdfxUpdateZMode( GLcontext *ctx )
    bias = (FxI32) (ctx->Polygon.OffsetUnits * TDFX_DEPTH_BIAS_SCALE);
 
    if ( ctx->Depth.Test ) {
-      switch ( ctx->Depth.Func ) {
-      case GL_NEVER:
-        func = GR_CMP_NEVER;
-        break;
-      case GL_LESS:
-        func = GR_CMP_LESS;
-         break;
-      case GL_LEQUAL:
-        func = GR_CMP_LEQUAL;
-        break;
-      case GL_EQUAL:
-        func = GR_CMP_EQUAL;
-        break;
-      case GL_GEQUAL:
-        func = GR_CMP_GEQUAL;
-        break;
-      case GL_GREATER:
-        func = GR_CMP_GREATER;
-        break;
-      case GL_NOTEQUAL:
-        func = GR_CMP_NOTEQUAL;
-        break;
-      case GL_ALWAYS:
-      default:
-        func = GR_CMP_ALWAYS;
-        break;
-      }
-
-      if ( ctx->Depth.Mask ) {
-         mask = FXTRUE;
-      }
-      else {
-         mask = FXFALSE;
-      }
+      func = ctx->Depth.Func - GL_NEVER + GR_CMP_NEVER;
+      mask = ctx->Depth.Mask;
    }
    else {
       /* depth testing disabled */
@@ -378,8 +370,7 @@ static void tdfxUpdateZMode( GLcontext *ctx )
       mask = FXFALSE;        /* zbuffer is not touched */
    }
 
-   fxMesa->Depth.Clear = (FxU32) (((1 << fxMesa->glCtx->Visual.depthBits) - 1)
-                                  * ctx->Depth.Clear);
+   fxMesa->Depth.Clear = (FxU32) (ctx->DrawBuffer->_DepthMaxF * ctx->Depth.Clear);
 
    if ( fxMesa->Depth.Bias != bias ) {
       fxMesa->Depth.Bias = bias;
@@ -395,7 +386,7 @@ static void tdfxUpdateZMode( GLcontext *ctx )
    }
 }
 
-static void tdfxDDDepthFunc( GLcontext *ctx, GLenum func )
+static void tdfxDDDepthFunc( struct gl_context *ctx, GLenum func )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
@@ -403,7 +394,7 @@ static void tdfxDDDepthFunc( GLcontext *ctx, GLenum func )
    fxMesa->new_state |= TDFX_NEW_DEPTH;
 }
 
-static void tdfxDDDepthMask( GLcontext *ctx, GLboolean flag )
+static void tdfxDDDepthMask( struct gl_context *ctx, GLboolean flag )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
@@ -411,7 +402,7 @@ static void tdfxDDDepthMask( GLcontext *ctx, GLboolean flag )
    fxMesa->new_state |= TDFX_NEW_DEPTH;
 }
 
-static void tdfxDDClearDepth( GLcontext *ctx, GLclampd d )
+static void tdfxDDClearDepth( struct gl_context *ctx, GLclampd d )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
@@ -454,7 +445,7 @@ static GrStencil_t convertGLStencilOp( GLenum op )
 }
 
 
-static void tdfxUpdateStencil( GLcontext *ctx )
+static void tdfxUpdateStencil( struct gl_context *ctx )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
@@ -463,11 +454,11 @@ static void tdfxUpdateStencil( GLcontext *ctx )
    }
 
    if (fxMesa->haveHwStencil) {
-      if (ctx->Stencil.Enabled) {
-         fxMesa->Stencil.Function = ctx->Stencil.Function[0] - GL_NEVER;
-         fxMesa->Stencil.RefValue = ctx->Stencil.Ref[0];
-         fxMesa->Stencil.ValueMask = ctx->Stencil.ValueMask[0];
-         fxMesa->Stencil.WriteMask = ctx->Stencil.WriteMask[0];
+      if (ctx->Stencil._Enabled) {
+         fxMesa->Stencil.Function = ctx->Stencil.Function[0] - GL_NEVER + GR_CMP_NEVER;
+         fxMesa->Stencil.RefValue = ctx->Stencil.Ref[0] & 0xff;
+         fxMesa->Stencil.ValueMask = ctx->Stencil.ValueMask[0] & 0xff;
+         fxMesa->Stencil.WriteMask = ctx->Stencil.WriteMask[0] & 0xff;
          fxMesa->Stencil.FailFunc = convertGLStencilOp(ctx->Stencil.FailFunc[0]);
          fxMesa->Stencil.ZFailFunc = convertGLStencilOp(ctx->Stencil.ZFailFunc[0]);
          fxMesa->Stencil.ZPassFunc = convertGLStencilOp(ctx->Stencil.ZPassFunc[0]);
@@ -478,8 +469,9 @@ static void tdfxUpdateStencil( GLcontext *ctx )
 }
 
 
-static void tdfxDDStencilFunc( GLcontext *ctx, GLenum func,
-                              GLint ref, GLuint mask )
+static void
+tdfxDDStencilFuncSeparate( struct gl_context *ctx, GLenum face, GLenum func,
+                           GLint ref, GLuint mask )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
@@ -487,7 +479,8 @@ static void tdfxDDStencilFunc( GLcontext *ctx, GLenum func,
    fxMesa->new_state |= TDFX_NEW_STENCIL;
 }
 
-static void tdfxDDStencilMask( GLcontext *ctx, GLuint mask )
+static void
+tdfxDDStencilMaskSeparate( struct gl_context *ctx, GLenum face, GLuint mask )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
@@ -495,8 +488,9 @@ static void tdfxDDStencilMask( GLcontext *ctx, GLuint mask )
    fxMesa->new_state |= TDFX_NEW_STENCIL;
 }
 
-static void tdfxDDStencilOp( GLcontext *ctx, GLenum sfail,
-                            GLenum zfail, GLenum zpass )
+static void
+tdfxDDStencilOpSeparate( struct gl_context *ctx, GLenum face, GLenum sfail,
+                         GLenum zfail, GLenum zpass )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
@@ -509,7 +503,7 @@ static void tdfxDDStencilOp( GLcontext *ctx, GLenum sfail,
  * Fog - orthographic fog still not working
  */
 
-static void tdfxUpdateFogAttrib( GLcontext *ctx )
+static void tdfxUpdateFogAttrib( struct gl_context *ctx )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    GrFogMode_t mode;
@@ -520,7 +514,11 @@ static void tdfxUpdateFogAttrib( GLcontext *ctx )
    }
 
    if ( ctx->Fog.Enabled ) {
-      mode = GR_FOG_WITH_TABLE_ON_Q;
+      if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) {
+         mode = GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT;
+      } else {
+         mode = GR_FOG_WITH_TABLE_ON_Q;
+      }
    } else {
       mode = GR_FOG_DISABLE;
    }
@@ -532,6 +530,7 @@ static void tdfxUpdateFogAttrib( GLcontext *ctx )
    if ( fxMesa->Fog.Mode != mode ) {
       fxMesa->Fog.Mode = mode;
       fxMesa->dirty |= TDFX_UPLOAD_FOG_MODE;
+      fxMesa->dirty |= TDFX_UPLOAD_VERTEX_LAYOUT;/*JJJ*/
    }
    if ( fxMesa->Fog.Color != color ) {
       fxMesa->Fog.Color = color;
@@ -563,12 +562,32 @@ static void tdfxUpdateFogAttrib( GLcontext *ctx )
    }
 }
 
-static void tdfxDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
+static void tdfxDDFogfv( struct gl_context *ctx, GLenum pname, const GLfloat *param )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
    FLUSH_BATCH( fxMesa );
    fxMesa->new_state |= TDFX_NEW_FOG;
+
+   switch (pname) {
+      case GL_FOG_COORDINATE_SOURCE_EXT: {
+         GLenum p = (GLenum)*param;
+         if (p == GL_FOG_COORDINATE_EXT) {
+            _swrast_allow_vertex_fog(ctx, GL_TRUE);
+            _swrast_allow_pixel_fog(ctx, GL_FALSE);
+            _tnl_allow_vertex_fog( ctx, GL_TRUE);
+            _tnl_allow_pixel_fog( ctx, GL_FALSE);
+         } else {
+            _swrast_allow_vertex_fog(ctx, GL_FALSE);
+            _swrast_allow_pixel_fog(ctx, GL_TRUE);
+            _tnl_allow_vertex_fog( ctx, GL_FALSE);
+            _tnl_allow_pixel_fog( ctx, GL_TRUE);
+         }
+         break;
+      }
+      default:
+         ;
+   }
 }
 
 
@@ -595,10 +614,10 @@ static int intersect_rect( drm_clip_rect_t *out,
  * Examine XF86 cliprect list and scissor state to recompute our
  * cliprect list.
  */
-void tdfxUpdateClipping( GLcontext *ctx )
+void tdfxUpdateClipping( struct gl_context *ctx )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = fxMesa->driDrawable;
+   __DRIdrawable *dPriv = fxMesa->driDrawable;
 
    if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
       fprintf( stderr, "%s()\n", __FUNCTION__ );
@@ -676,7 +695,7 @@ void tdfxUpdateClipping( GLcontext *ctx )
  * Culling
  */
 
-void tdfxUpdateCull( GLcontext *ctx )
+void tdfxUpdateCull( struct gl_context *ctx )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    GrCullMode_t mode = GR_CULL_DISABLE;
@@ -718,7 +737,7 @@ void tdfxUpdateCull( GLcontext *ctx )
    }
 }
 
-static void tdfxDDCullFace( GLcontext *ctx, GLenum mode )
+static void tdfxDDCullFace( struct gl_context *ctx, GLenum mode )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
@@ -726,7 +745,7 @@ static void tdfxDDCullFace( GLcontext *ctx, GLenum mode )
    fxMesa->new_state |= TDFX_NEW_CULL;
 }
 
-static void tdfxDDFrontFace( GLcontext *ctx, GLenum mode )
+static void tdfxDDFrontFace( struct gl_context *ctx, GLenum mode )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
@@ -739,7 +758,7 @@ static void tdfxDDFrontFace( GLcontext *ctx, GLenum mode )
  * Line drawing.
  */
 
-static void tdfxUpdateLine( GLcontext *ctx )
+static void tdfxUpdateLine( struct gl_context *ctx )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
@@ -752,7 +771,7 @@ static void tdfxUpdateLine( GLcontext *ctx )
 }
 
 
-static void tdfxDDLineWidth( GLcontext *ctx, GLfloat width )
+static void tdfxDDLineWidth( struct gl_context *ctx, GLfloat width )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
    FLUSH_BATCH( fxMesa );
@@ -764,7 +783,7 @@ static void tdfxDDLineWidth( GLcontext *ctx, GLfloat width )
  * Color Attributes
  */
 
-static void tdfxDDColorMask( GLcontext *ctx,
+static void tdfxDDColorMask( struct gl_context *ctx,
                             GLboolean r, GLboolean g,
                             GLboolean b, GLboolean a )
 {
@@ -791,7 +810,7 @@ static void tdfxDDColorMask( GLcontext *ctx,
 }
 
 
-static void tdfxDDClearColor( GLcontext *ctx,
+static void tdfxDDClearColor( struct gl_context *ctx,
                              const GLfloat color[4] )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
@@ -810,7 +829,7 @@ static void tdfxDDClearColor( GLcontext *ctx,
  * Light Model
  */
 
-static void tdfxDDLightModelfv( GLcontext *ctx, GLenum pname,
+static void tdfxDDLightModelfv( struct gl_context *ctx, GLenum pname,
                                const GLfloat *param )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
@@ -822,7 +841,7 @@ static void tdfxDDLightModelfv( GLcontext *ctx, GLenum pname,
    }
 }
 
-static void tdfxDDShadeModel( GLcontext *ctx, GLenum mode )
+static void tdfxDDShadeModel( struct gl_context *ctx, GLenum mode )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
@@ -837,7 +856,7 @@ static void tdfxDDShadeModel( GLcontext *ctx, GLenum mode )
  */
 
 static void
-tdfxDDScissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+tdfxDDScissor(struct gl_context * ctx, GLint x, GLint y, GLsizei w, GLsizei h)
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    FLUSH_BATCH( fxMesa );
@@ -848,7 +867,7 @@ tdfxDDScissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h)
  * Render
  */
 
-static void tdfxUpdateRenderAttrib( GLcontext *ctx )
+static void tdfxUpdateRenderAttrib( struct gl_context *ctx )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    FLUSH_BATCH( fxMesa );
@@ -859,7 +878,7 @@ static void tdfxUpdateRenderAttrib( GLcontext *ctx )
  * Viewport
  */
 
-void tdfxUpdateViewport( GLcontext *ctx )
+void tdfxUpdateViewport( struct gl_context *ctx )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -876,7 +895,7 @@ void tdfxUpdateViewport( GLcontext *ctx )
 }
 
 
-static void tdfxDDViewport( GLcontext *ctx, GLint x, GLint y,
+static void tdfxDDViewport( struct gl_context *ctx, GLint x, GLint y,
                            GLsizei w, GLsizei h )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
@@ -885,7 +904,7 @@ static void tdfxDDViewport( GLcontext *ctx, GLint x, GLint y,
 }
 
 
-static void tdfxDDDepthRange( GLcontext *ctx, GLclampd nearVal, GLclampd farVal )
+static void tdfxDDDepthRange( struct gl_context *ctx, GLclampd nearVal, GLclampd farVal )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    FLUSH_BATCH( fxMesa );
@@ -897,7 +916,7 @@ static void tdfxDDDepthRange( GLcontext *ctx, GLclampd nearVal, GLclampd farVal
  * State enable/disable
  */
 
-static void tdfxDDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
+static void tdfxDDEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
 
@@ -912,7 +931,7 @@ static void tdfxDDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
       fxMesa->new_state |= TDFX_NEW_ALPHA;
       FALLBACK( fxMesa, TDFX_FALLBACK_LOGICOP,
                (ctx->Color.ColorLogicOpEnabled &&
-                ctx->Color.LogicOp != GL_COPY));
+                ctx->Color.LogicOp != GL_COPY)/*JJJ - more blending*/);
       break;
 
    case GL_CULL_FACE:
@@ -974,15 +993,16 @@ static void tdfxDDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
    case GL_STENCIL_TEST:
       FLUSH_BATCH( fxMesa );
       FALLBACK( fxMesa, TDFX_FALLBACK_STENCIL, state && !fxMesa->haveHwStencil);
+      fxMesa->new_state |= TDFX_NEW_STENCIL;
       break;
 
-   case GL_TEXTURE_1D:
    case GL_TEXTURE_3D:
       FLUSH_BATCH( fxMesa );
-      FALLBACK( fxMesa, TDFX_FALLBACK_TEXTURE_1D_3D, state); /* wrong */
+      FALLBACK( fxMesa, TDFX_FALLBACK_TEXTURE_MAP, state); /* wrong */
       fxMesa->new_state |= TDFX_NEW_TEXTURE;
       break;
 
+   case GL_TEXTURE_1D:
    case GL_TEXTURE_2D:
       FLUSH_BATCH( fxMesa );
       fxMesa->new_state |= TDFX_NEW_TEXTURE;
@@ -997,7 +1017,7 @@ static void tdfxDDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
 
 /* Set the buffer used for drawing */
 /* XXX support for separate read/draw buffers hasn't been tested */
-static void tdfxDDDrawBuffer( GLcontext *ctx, GLenum mode )
+static void tdfxDDDrawBuffer( struct gl_context *ctx, GLenum mode )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
@@ -1007,21 +1027,23 @@ static void tdfxDDDrawBuffer( GLcontext *ctx, GLenum mode )
 
    FLUSH_BATCH( fxMesa );
 
-   /*
-    * _DrawDestMask is easier to cope with than <mode>.
-    */
-   switch ( ctx->Color._DrawDestMask ) {
-   case FRONT_LEFT_BIT:
+   if (ctx->DrawBuffer->_NumColorDrawBuffers > 1) {
+      FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_TRUE );
+      return;
+   }
+
+   switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) {
+   case BUFFER_FRONT_LEFT:
       fxMesa->DrawBuffer = fxMesa->ReadBuffer = GR_BUFFER_FRONTBUFFER;
       fxMesa->new_state |= TDFX_NEW_RENDER;
       FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE );
       break;
-   case BACK_LEFT_BIT:
+   case BUFFER_BACK_LEFT:
       fxMesa->DrawBuffer = fxMesa->ReadBuffer = GR_BUFFER_BACKBUFFER;
       fxMesa->new_state |= TDFX_NEW_RENDER;
       FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE );
       break;
-   case 0:
+   case -1:
       FX_grColorMaskv( ctx, false4 );
       FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE );
       break;
@@ -1029,15 +1051,10 @@ static void tdfxDDDrawBuffer( GLcontext *ctx, GLenum mode )
       FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_TRUE );
       break;
    }
-
-   /* We want to update the s/w rast state too so that tdfxDDSetBuffer()
-    * gets called.
-    */
-   _swrast_DrawBuffer(ctx, mode);
 }
 
 
-static void tdfxDDReadBuffer( GLcontext *ctx, GLenum mode )
+static void tdfxDDReadBuffer( struct gl_context *ctx, GLenum mode )
 {
    /* XXX ??? */
 }
@@ -1047,7 +1064,7 @@ static void tdfxDDReadBuffer( GLcontext *ctx, GLenum mode )
  * Polygon stipple
  */
 
-static void tdfxDDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
+static void tdfxDDPolygonStipple( struct gl_context *ctx, const GLubyte *mask )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    const GLubyte *m = mask;
@@ -1102,7 +1119,7 @@ static void tdfxDDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
 
 
 
-static void tdfxDDRenderMode( GLcontext *ctx, GLenum mode )
+static void tdfxDDRenderMode( struct gl_context *ctx, GLenum mode )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    FALLBACK( fxMesa, TDFX_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
@@ -1133,7 +1150,7 @@ static void tdfxDDPrintState( const char *msg, GLuint flags )
 
 
 
-void tdfxDDUpdateHwState( GLcontext *ctx )
+void tdfxDDUpdateHwState( struct gl_context *ctx )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    int new_state = fxMesa->new_state;
@@ -1209,11 +1226,11 @@ void tdfxDDUpdateHwState( GLcontext *ctx )
 }
 
 
-static void tdfxDDInvalidateState( GLcontext *ctx, GLuint new_state )
+static void tdfxDDInvalidateState( struct gl_context *ctx, GLuint new_state )
 {
    _swrast_InvalidateState( ctx, new_state );
    _swsetup_InvalidateState( ctx, new_state );
-   _ac_InvalidateState( ctx, new_state );
+   _vbo_InvalidateState( ctx, new_state );
    _tnl_InvalidateState( ctx, new_state );
    TDFX_CONTEXT(ctx)->new_gl_state |= new_state;
 }
@@ -1225,7 +1242,7 @@ static void tdfxDDInvalidateState( GLcontext *ctx, GLuint new_state )
  */
 void tdfxInitState( tdfxContextPtr fxMesa )
 {
-   GLcontext *ctx = fxMesa->glCtx;
+   struct gl_context *ctx = fxMesa->glCtx;
    GLint i;
 
    fxMesa->ColorCombine.Function       = GR_COMBINE_FUNCTION_LOCAL;
@@ -1373,25 +1390,21 @@ void tdfxInitState( tdfxContextPtr fxMesa )
 
 
 
-void tdfxDDInitStateFuncs( GLcontext *ctx )
+void tdfxDDInitStateFuncs( struct gl_context *ctx )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
 
    ctx->Driver.UpdateState             = tdfxDDInvalidateState;
 
-
-   /* State notification callbacks:
-    */
    ctx->Driver.ClearColor              = tdfxDDClearColor;
    ctx->Driver.DrawBuffer              = tdfxDDDrawBuffer;
    ctx->Driver.ReadBuffer              = tdfxDDReadBuffer;
 
-   ctx->Driver.ColorMask               = tdfxDDColorMask;
-
    ctx->Driver.AlphaFunc               = tdfxDDAlphaFunc;
    ctx->Driver.BlendEquationSeparate   = tdfxDDBlendEquationSeparate;
    ctx->Driver.BlendFuncSeparate       = tdfxDDBlendFuncSeparate;
    ctx->Driver.ClearDepth              = tdfxDDClearDepth;
+   ctx->Driver.ColorMask               = tdfxDDColorMask;
    ctx->Driver.CullFace                        = tdfxDDCullFace;
    ctx->Driver.FrontFace               = tdfxDDFrontFace;
    ctx->Driver.DepthFunc               = tdfxDDDepthFunc;
@@ -1407,17 +1420,10 @@ void tdfxDDInitStateFuncs( GLcontext *ctx )
    ctx->Driver.ShadeModel              = tdfxDDShadeModel;
 
    if ( fxMesa->haveHwStencil ) {
-      ctx->Driver.StencilFunc          = tdfxDDStencilFunc;
-      ctx->Driver.StencilMask          = tdfxDDStencilMask;
-      ctx->Driver.StencilOp            = tdfxDDStencilOp;
+      ctx->Driver.StencilFuncSeparate  = tdfxDDStencilFuncSeparate;
+      ctx->Driver.StencilMaskSeparate  = tdfxDDStencilMaskSeparate;
+      ctx->Driver.StencilOpSeparate    = tdfxDDStencilOpSeparate;
    }
 
    ctx->Driver.Viewport                        = tdfxDDViewport;
-
-   /* Swrast hooks for imaging extensions:
-    */
-   ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
-   ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
-   ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
-   ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
 }