/* -*- 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/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
 *
 * Authors:
 *	Gareth Hughes <gareth@valinux.com>
 *	Brian Paul <brianp@valinux.com>
 *      Keith Whitwell <keith@tungstengraphics.com> (port to 3.5)
 *
 */

#include "mtypes.h"
#include "colormac.h"
#include "texformat.h"
#include "texstore.h"
#include "teximage.h"

#include "swrast/swrast.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 )
{
   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 ) {
      func = ctx->Color.AlphaFunc - GL_NEVER + GR_CMP_NEVER;
   } else {
      func = GR_CMP_ALWAYS;
   }

   if ( ctx->Color.BlendEnabled
        && (fxMesa->Fallback & TDFX_FALLBACK_BLEND) == 0 ) {
      switch ( ctx->Color.BlendSrcRGB ) {
      case GL_ZERO:
	 srcRGB = GR_BLEND_ZERO;
	 break;
      case GL_ONE:
	 srcRGB = GR_BLEND_ONE;
	 break;
      case GL_DST_COLOR:
	 srcRGB = GR_BLEND_DST_COLOR;
	 break;
      case GL_ONE_MINUS_DST_COLOR:
	 srcRGB = GR_BLEND_ONE_MINUS_DST_COLOR;
	 break;
      case GL_SRC_ALPHA:
	 srcRGB = GR_BLEND_SRC_ALPHA;
	 break;
      case GL_ONE_MINUS_SRC_ALPHA:
	 srcRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA;
	 break;
      case GL_DST_ALPHA:
	 srcRGB = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/;
	 break;
      case GL_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;
      }

      switch ( ctx->Color.BlendSrcA ) {
      case GL_ZERO:
	 srcA = GR_BLEND_ZERO;
	 break;
      case GL_ONE:
	 srcA = GR_BLEND_ONE;
	 break;
      case GL_SRC_COLOR:
      case GL_SRC_ALPHA:
	 srcA = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ONE/*JJJ*/;
	 break;
      case GL_ONE_MINUS_SRC_COLOR:
      case GL_ONE_MINUS_SRC_ALPHA:
	 srcA = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ONE/*JJJ*/;
	 break;
      case GL_DST_COLOR:
      case GL_DST_ALPHA:
	 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 = (have32bpp && haveAlpha) ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/;
	 break;
      case GL_SRC_ALPHA_SATURATE:
         srcA = GR_BLEND_ONE;
	 break;
      default:
	 srcA = GR_BLEND_ONE;
      }

      switch ( ctx->Color.BlendDstRGB ) {
      case GL_ZERO:
	 dstRGB = GR_BLEND_ZERO;
	 break;
      case GL_ONE:
	 dstRGB = GR_BLEND_ONE;
	 break;
      case GL_SRC_COLOR:
	 dstRGB = GR_BLEND_SRC_COLOR;
	 break;
      case GL_ONE_MINUS_SRC_COLOR:
	 dstRGB = GR_BLEND_ONE_MINUS_SRC_COLOR;
	 break;
      case GL_SRC_ALPHA:
	 dstRGB = GR_BLEND_SRC_ALPHA;
	 break;
      case GL_ONE_MINUS_SRC_ALPHA:
	 dstRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA;
	 break;
      case GL_DST_ALPHA:
	 dstRGB = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/;
	 break;
      case GL_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;
      }

      switch ( ctx->Color.BlendDstA ) {
      case GL_ZERO:
	 dstA = GR_BLEND_ZERO;
	 break;
      case GL_ONE:
	 dstA = GR_BLEND_ONE;
	 break;
      case GL_SRC_COLOR:
      case GL_SRC_ALPHA:
	 dstA = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ZERO/*JJJ*/;
	 break;
      case GL_ONE_MINUS_SRC_COLOR:
      case GL_ONE_MINUS_SRC_ALPHA:
	 dstA = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ZERO/*JJJ*/;
	 break;
      case GL_DST_COLOR:
      case GL_DST_ALPHA:
	 dstA = have32bpp ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/;
	 break;
      case GL_ONE_MINUS_DST_COLOR:
      case GL_ONE_MINUS_DST_ALPHA:
	 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 ) {
      fxMesa->Color.AlphaFunc = func;
      fxMesa->dirty |= TDFX_UPLOAD_ALPHA_TEST;
   }
   if ( fxMesa->Color.AlphaRef != ref ) {
      fxMesa->Color.AlphaRef = ref;
      fxMesa->dirty |= TDFX_UPLOAD_ALPHA_REF;
   }

   if ( 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->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 )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );

   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_ALPHA;
}

static void tdfxDDBlendEquationSeparate( GLcontext *ctx, 
					 GLenum modeRGB, GLenum modeA )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );

   assert( modeRGB == modeA );
   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_ALPHA;
}

static void tdfxDDBlendFuncSeparate( GLcontext *ctx,
				     GLenum sfactorRGB, GLenum dfactorRGB,
				     GLenum sfactorA, GLenum dfactorA )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );

   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_ALPHA;

   /*
    * XXX - Voodoo5 seems to suffer from precision problems in some
    * blend modes.  To pass all the conformance tests we'd have to
    * fall back to software for many modes.  Revisit someday.
    */
}

/* =============================================================
 * Stipple
 */

void tdfxUpdateStipple( GLcontext *ctx )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
   GrStippleMode_t mode = GR_STIPPLE_DISABLE;

   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
      fprintf( stderr, "%s()\n", __FUNCTION__ );
   }

   FLUSH_BATCH( fxMesa );

   if (ctx->Polygon.StippleFlag) {
      mode = GR_STIPPLE_PATTERN;
   }

   if ( fxMesa->Stipple.Mode != mode ) {
      fxMesa->Stipple.Mode = mode;
      fxMesa->dirty |= TDFX_UPLOAD_STIPPLE;
   }
}


/* =============================================================
 * Depth testing
 */

static void tdfxUpdateZMode( GLcontext *ctx )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
   GrCmpFnc_t func;
   FxI32 bias;
   FxBool mask;

   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) 
      fprintf( stderr, "%s()\n", __FUNCTION__ );


   bias = (FxI32) (ctx->Polygon.OffsetUnits * TDFX_DEPTH_BIAS_SCALE);

   if ( ctx->Depth.Test ) {
      func = ctx->Depth.Func - GL_NEVER + GR_CMP_NEVER;
      mask = ctx->Depth.Mask;
   }
   else {
      /* depth testing disabled */
      func = GR_CMP_ALWAYS;  /* fragments always pass */
      mask = FXFALSE;        /* zbuffer is not touched */
   }

   fxMesa->Depth.Clear = (FxU32) (ctx->DrawBuffer->_DepthMaxF * ctx->Depth.Clear);

   if ( fxMesa->Depth.Bias != bias ) {
      fxMesa->Depth.Bias = bias;
      fxMesa->dirty |= TDFX_UPLOAD_DEPTH_BIAS;
   }
   if ( fxMesa->Depth.Func != func ) {
      fxMesa->Depth.Func = func;
      fxMesa->dirty |= TDFX_UPLOAD_DEPTH_FUNC | TDFX_UPLOAD_DEPTH_MASK;
   }
   if ( fxMesa->Depth.Mask != mask ) {
      fxMesa->Depth.Mask = mask;
      fxMesa->dirty |= TDFX_UPLOAD_DEPTH_MASK;
   }
}

static void tdfxDDDepthFunc( GLcontext *ctx, GLenum func )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );

   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_DEPTH;
}

static void tdfxDDDepthMask( GLcontext *ctx, GLboolean flag )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );

   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_DEPTH;
}

static void tdfxDDClearDepth( GLcontext *ctx, GLclampd d )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );

   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_DEPTH;
}



/* =============================================================
 * Stencil
 */


/* Evaluate all stencil state and make the Glide calls.
 */
static GrStencil_t convertGLStencilOp( GLenum op )
{
   switch ( op ) {
   case GL_KEEP:
      return GR_STENCILOP_KEEP;
   case GL_ZERO:
      return GR_STENCILOP_ZERO;
   case GL_REPLACE:
      return GR_STENCILOP_REPLACE;
   case GL_INCR:
      return GR_STENCILOP_INCR_CLAMP;
   case GL_DECR:
      return GR_STENCILOP_DECR_CLAMP;
   case GL_INVERT:
      return GR_STENCILOP_INVERT;
   case GL_INCR_WRAP_EXT:
      return GR_STENCILOP_INCR_WRAP;
   case GL_DECR_WRAP_EXT:
      return GR_STENCILOP_DECR_WRAP;
   default:
      _mesa_problem( NULL, "bad stencil op in convertGLStencilOp" );
   }
   return GR_STENCILOP_KEEP;   /* never get, silence compiler warning */
}


static void tdfxUpdateStencil( GLcontext *ctx )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);

   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
      fprintf( stderr, "%s()\n", __FUNCTION__ );
   }

   if (fxMesa->haveHwStencil) {
      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]);
         fxMesa->Stencil.Clear = ctx->Stencil.Clear & 0xff;
      }
      fxMesa->dirty |= TDFX_UPLOAD_STENCIL;
   }
}


static void
tdfxDDStencilFuncSeparate( GLcontext *ctx, GLenum face, GLenum func,
                           GLint ref, GLuint mask )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);

   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_STENCIL;
}

static void
tdfxDDStencilMaskSeparate( GLcontext *ctx, GLenum face, GLuint mask )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);

   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_STENCIL;
}

static void
tdfxDDStencilOpSeparate( GLcontext *ctx, GLenum face, GLenum sfail,
                         GLenum zfail, GLenum zpass )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);

   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_STENCIL;
}


/* =============================================================
 * Fog - orthographic fog still not working
 */

static void tdfxUpdateFogAttrib( GLcontext *ctx )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
   GrFogMode_t mode;
   GrColor_t color;

   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
      fprintf( stderr, "%s()\n", __FUNCTION__ );
   }

   if ( ctx->Fog.Enabled ) {
      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;
   }

   color = TDFXPACKCOLOR888((GLubyte)(ctx->Fog.Color[0]*255.0F),
			    (GLubyte)(ctx->Fog.Color[1]*255.0F),
			    (GLubyte)(ctx->Fog.Color[2]*255.0F));

   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;
      fxMesa->dirty |= TDFX_UPLOAD_FOG_COLOR;
   }
   if ( fxMesa->Fog.TableMode != ctx->Fog.Mode ||
	fxMesa->Fog.Density != ctx->Fog.Density ||
	fxMesa->Fog.Near != ctx->Fog.Start ||
	fxMesa->Fog.Far != ctx->Fog.End )
   {
      switch( ctx->Fog.Mode ) {
      case GL_EXP:
	 fxMesa->Glide.guFogGenerateExp( fxMesa->Fog.Table, ctx->Fog.Density );
	 break;
      case GL_EXP2:
	 fxMesa->Glide.guFogGenerateExp2( fxMesa->Fog.Table, ctx->Fog.Density);
	 break;
      case GL_LINEAR:
	 fxMesa->Glide.guFogGenerateLinear( fxMesa->Fog.Table,
                                            ctx->Fog.Start, ctx->Fog.End );
	 break;
      }

      fxMesa->Fog.TableMode = ctx->Fog.Mode;
      fxMesa->Fog.Density = ctx->Fog.Density;
      fxMesa->Fog.Near = ctx->Fog.Start;
      fxMesa->Fog.Far = ctx->Fog.End;
      fxMesa->dirty |= TDFX_UPLOAD_FOG_TABLE;
   }
}

static void tdfxDDFogfv( GLcontext *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:
         ;
   }
}


/* =============================================================
 * Clipping
 */

static int intersect_rect( drm_clip_rect_t *out,
			   const drm_clip_rect_t *a,
			   const drm_clip_rect_t *b)
{
   *out = *a;
   if (b->x1 > out->x1) out->x1 = b->x1;
   if (b->y1 > out->y1) out->y1 = b->y1;
   if (b->x2 < out->x2) out->x2 = b->x2;
   if (b->y2 < out->y2) out->y2 = b->y2;
   if (out->x1 >= out->x2) return 0;
   if (out->y1 >= out->y2) return 0;
   return 1;
}


/*
 * Examine XF86 cliprect list and scissor state to recompute our
 * cliprect list.
 */
void tdfxUpdateClipping( GLcontext *ctx )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
   __DRIdrawablePrivate *dPriv = fxMesa->driDrawable;

   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
      fprintf( stderr, "%s()\n", __FUNCTION__ );
   }

   assert(ctx);
   assert(fxMesa);
   assert(dPriv);

   if ( dPriv->x != fxMesa->x_offset || dPriv->y != fxMesa->y_offset ||
	dPriv->w != fxMesa->width || dPriv->h != fxMesa->height ) {
      fxMesa->x_offset = dPriv->x;
      fxMesa->y_offset = dPriv->y;
      fxMesa->width = dPriv->w;
      fxMesa->height = dPriv->h;
      fxMesa->y_delta =
	 fxMesa->screen_height - fxMesa->y_offset - fxMesa->height;
      tdfxUpdateViewport( ctx );
   }

   if (fxMesa->scissoredClipRects && fxMesa->pClipRects) {
      free(fxMesa->pClipRects);
   }

   if (ctx->Scissor.Enabled) {
      /* intersect OpenGL scissor box with all cliprects to make a new
       * list of cliprects.
       */
      drm_clip_rect_t scissor;
      int x1 = ctx->Scissor.X + fxMesa->x_offset;
      int y1 = fxMesa->screen_height - fxMesa->y_delta
             - ctx->Scissor.Y - ctx->Scissor.Height;
      int x2 = x1 + ctx->Scissor.Width;
      int y2 = y1 + ctx->Scissor.Height;
      scissor.x1 = MAX2(x1, 0);
      scissor.y1 = MAX2(y1, 0);
      scissor.x2 = MAX2(x2, 0);
      scissor.y2 = MAX2(y2, 0);

      assert(scissor.x2 >= scissor.x1);
      assert(scissor.y2 >= scissor.y1);

      fxMesa->pClipRects = malloc(dPriv->numClipRects
                                  * sizeof(drm_clip_rect_t));
      if (fxMesa->pClipRects) {
         int i;
         fxMesa->numClipRects = 0;
         for (i = 0; i < dPriv->numClipRects; i++) {
            if (intersect_rect(&fxMesa->pClipRects[fxMesa->numClipRects],
                               &scissor, &dPriv->pClipRects[i])) {
               fxMesa->numClipRects++;
            }
         }
         fxMesa->scissoredClipRects = GL_TRUE;
      }
      else {
         /* out of memory, forgo scissor */
         fxMesa->numClipRects = dPriv->numClipRects;
         fxMesa->pClipRects = dPriv->pClipRects;
         fxMesa->scissoredClipRects = GL_FALSE;
      }
   }
   else {
      fxMesa->numClipRects = dPriv->numClipRects;
      fxMesa->pClipRects = dPriv->pClipRects;
      fxMesa->scissoredClipRects = GL_FALSE;
   }

   fxMesa->dirty |= TDFX_UPLOAD_CLIP;
}



/* =============================================================
 * Culling
 */

void tdfxUpdateCull( GLcontext *ctx )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
   GrCullMode_t mode = GR_CULL_DISABLE;

   /* KW: don't need to check raster_primitive here as we don't
    * attempt to draw lines or points with triangles.
    */
   if ( ctx->Polygon.CullFlag ) {
      switch ( ctx->Polygon.CullFaceMode ) {
      case GL_FRONT:
	 if ( ctx->Polygon.FrontFace == GL_CCW ) {
	    mode = GR_CULL_POSITIVE;
	 } else {
	    mode = GR_CULL_NEGATIVE;
	 }
	 break;

      case GL_BACK:
	 if ( ctx->Polygon.FrontFace == GL_CCW ) {
	    mode = GR_CULL_NEGATIVE;
	 } else {
	    mode = GR_CULL_POSITIVE;
	 }
	 break;

      case GL_FRONT_AND_BACK:
	 /* Handled as a fallback on triangles in tdfx_tris.c */
	 return;

      default:
	 ASSERT(0);
	 break;
      }
   }

   if ( fxMesa->CullMode != mode ) {
      fxMesa->CullMode = mode;
      fxMesa->dirty |= TDFX_UPLOAD_CULL;
   }
}

static void tdfxDDCullFace( GLcontext *ctx, GLenum mode )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );

   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_CULL;
}

static void tdfxDDFrontFace( GLcontext *ctx, GLenum mode )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );

   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_CULL;
}


/* =============================================================
 * Line drawing.
 */

static void tdfxUpdateLine( GLcontext *ctx )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );

   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
      fprintf( stderr, "%s()\n", __FUNCTION__ );
   }

   FLUSH_BATCH( fxMesa );
   fxMesa->dirty |= TDFX_UPLOAD_LINE;
}


static void tdfxDDLineWidth( GLcontext *ctx, GLfloat width )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );
   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_LINE;
}


/* =============================================================
 * Color Attributes
 */

static void tdfxDDColorMask( GLcontext *ctx,
			     GLboolean r, GLboolean g,
			     GLboolean b, GLboolean a )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);

   FLUSH_BATCH( fxMesa );

   if ( fxMesa->Color.ColorMask[RCOMP] != r ||
	fxMesa->Color.ColorMask[GCOMP] != g ||
	fxMesa->Color.ColorMask[BCOMP] != b ||
	fxMesa->Color.ColorMask[ACOMP] != a ) {
      fxMesa->Color.ColorMask[RCOMP] = r;
      fxMesa->Color.ColorMask[GCOMP] = g;
      fxMesa->Color.ColorMask[BCOMP] = b;
      fxMesa->Color.ColorMask[ACOMP] = a;
      fxMesa->dirty |= TDFX_UPLOAD_COLOR_MASK;

      if (ctx->Visual.redBits < 8) {
         /* Can't do RGB colormasking in 16bpp mode. */
         /* We can completely ignore the alpha mask. */
	 FALLBACK( fxMesa, TDFX_FALLBACK_COLORMASK, (r != g || g != b) );
      }
   }
}


static void tdfxDDClearColor( GLcontext *ctx,
			      const GLfloat color[4] )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
   GLubyte c[4];
   FLUSH_BATCH( fxMesa );
   CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
   CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
   CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
   CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
   fxMesa->Color.ClearColor = TDFXPACKCOLOR888( c[0], c[1], c[2] );
   fxMesa->Color.ClearAlpha = c[3];
}


/* =============================================================
 * Light Model
 */

static void tdfxDDLightModelfv( GLcontext *ctx, GLenum pname,
				const GLfloat *param )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);

   if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) {
      FALLBACK( fxMesa, TDFX_FALLBACK_SPECULAR,
		(ctx->Light.Enabled &&
		 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ));
   }
}

static void tdfxDDShadeModel( GLcontext *ctx, GLenum mode )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);

   /* FIXME: Can we implement native flat shading? */
   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_TEXTURE;
}


/* =============================================================
 * Scissor
 */

static void
tdfxDDScissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h)
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_CLIP;
}

/* =============================================================
 * Render
 */

static void tdfxUpdateRenderAttrib( GLcontext *ctx )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
   FLUSH_BATCH( fxMesa );
   fxMesa->dirty |= TDFX_UPLOAD_RENDER_BUFFER;
}

/* =============================================================
 * Viewport
 */

void tdfxUpdateViewport( GLcontext *ctx )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
   const GLfloat *v = ctx->Viewport._WindowMap.m;
   GLfloat *m = fxMesa->hw_viewport;

   m[MAT_SX] = v[MAT_SX];
   m[MAT_TX] = v[MAT_TX] + fxMesa->x_offset + TRI_X_OFFSET;
   m[MAT_SY] = v[MAT_SY];
   m[MAT_TY] = v[MAT_TY] + fxMesa->y_delta + TRI_Y_OFFSET;
   m[MAT_SZ] = v[MAT_SZ];
   m[MAT_TZ] = v[MAT_TZ];

   fxMesa->SetupNewInputs |= VERT_BIT_POS;
}


static void tdfxDDViewport( GLcontext *ctx, GLint x, GLint y,
			    GLsizei w, GLsizei h )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_VIEWPORT;
}


static void tdfxDDDepthRange( GLcontext *ctx, GLclampd nearVal, GLclampd farVal )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
   FLUSH_BATCH( fxMesa );
   fxMesa->new_state |= TDFX_NEW_VIEWPORT;
}


/* =============================================================
 * State enable/disable
 */

static void tdfxDDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx );

   switch ( cap ) {
   case GL_ALPHA_TEST:
      FLUSH_BATCH( fxMesa );
      fxMesa->new_state |= TDFX_NEW_ALPHA;
      break;

   case GL_BLEND:
      FLUSH_BATCH( fxMesa );
      fxMesa->new_state |= TDFX_NEW_ALPHA;
      FALLBACK( fxMesa, TDFX_FALLBACK_LOGICOP,
		(ctx->Color.ColorLogicOpEnabled &&
		 ctx->Color.LogicOp != GL_COPY)/*JJJ - more blending*/);
      break;

   case GL_CULL_FACE:
      FLUSH_BATCH( fxMesa );
      fxMesa->new_state |= TDFX_NEW_CULL;
      break;

   case GL_DEPTH_TEST:
      FLUSH_BATCH( fxMesa );
      fxMesa->new_state |= TDFX_NEW_DEPTH;
      break;

   case GL_DITHER:
      FLUSH_BATCH( fxMesa );
      if ( state ) {
	 fxMesa->Color.Dither = GR_DITHER_2x2;
      } else {
	 fxMesa->Color.Dither = GR_DITHER_DISABLE;
      }
      fxMesa->dirty |= TDFX_UPLOAD_DITHER;
      break;

   case GL_FOG:
      FLUSH_BATCH( fxMesa );
      fxMesa->new_state |= TDFX_NEW_FOG;
      break;

   case GL_COLOR_LOGIC_OP:
      FALLBACK( fxMesa, TDFX_FALLBACK_LOGICOP,
		(ctx->Color.ColorLogicOpEnabled &&
		 ctx->Color.LogicOp != GL_COPY));
      break;

   case GL_LIGHTING:
      FALLBACK( fxMesa, TDFX_FALLBACK_SPECULAR,
		(ctx->Light.Enabled &&
		 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ));
      break;

   case GL_LINE_SMOOTH:
      FLUSH_BATCH( fxMesa );
      fxMesa->new_state |= TDFX_NEW_LINE;
      break;

   case GL_LINE_STIPPLE:
      FALLBACK(fxMesa, TDFX_FALLBACK_LINE_STIPPLE, state);
      break;

   case GL_POLYGON_STIPPLE:
      FLUSH_BATCH(fxMesa);
      fxMesa->new_state |= TDFX_NEW_STIPPLE;
      break;

   case GL_SCISSOR_TEST:
      FLUSH_BATCH( fxMesa );
      fxMesa->new_state |= TDFX_NEW_CLIP;
      break;

   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_3D:
      FLUSH_BATCH( fxMesa );
      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;
      break;

   default:
      return;
   }
}



/* Set the buffer used for drawing */
/* XXX support for separate read/draw buffers hasn't been tested */
static void tdfxDDDrawBuffer( GLcontext *ctx, GLenum mode )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);

   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
      fprintf( stderr, "%s()\n", __FUNCTION__ );
   }

   FLUSH_BATCH( fxMesa );

   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 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 -1:
      FX_grColorMaskv( ctx, false4 );
      FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE );
      break;
   default:
      FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_TRUE );
      break;
   }
}


static void tdfxDDReadBuffer( GLcontext *ctx, GLenum mode )
{
   /* XXX ??? */
}


/* =============================================================
 * Polygon stipple
 */

static void tdfxDDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
   const GLubyte *m = mask;
   GLubyte q[4];
   int i,j,k;
   GLboolean allBitsSet;

/*     int active = (ctx->Polygon.StippleFlag &&  */
/*  		 fxMesa->reduced_prim == GL_TRIANGLES); */

   FLUSH_BATCH(fxMesa);
   fxMesa->Stipple.Pattern = 0xffffffff;
   fxMesa->dirty |= TDFX_UPLOAD_STIPPLE;
   fxMesa->new_state |= TDFX_NEW_STIPPLE;

   /* Check if the stipple pattern is fully opaque.  If so, use software
    * rendering.  This basically a trick to make sure the OpenGL conformance
    * test passes.
    */
   allBitsSet = GL_TRUE;
   for (i = 0; i < 32; i++) {
      if (((GLuint *) mask)[i] != 0xffffffff) {
         allBitsSet = GL_FALSE;
         break;
      }
   }
   if (allBitsSet) {
      fxMesa->haveHwStipple = GL_FALSE;
      return;
   }

   q[0] = mask[0];
   q[1] = mask[4];
   q[2] = mask[8];
   q[3] = mask[12];

   for (k = 0 ; k < 8 ; k++)
      for (j = 0 ; j < 4; j++)
	 for (i = 0 ; i < 4 ; i++,m++) {
	    if (*m != q[j]) {
	       fxMesa->haveHwStipple = GL_FALSE;
	       return;
	    }
         }

   fxMesa->haveHwStipple = GL_TRUE;
   fxMesa->Stipple.Pattern = ( (q[0] << 0) |
                               (q[1] << 8) |
                               (q[2] << 16) |
                               (q[3] << 24) );
}



static void tdfxDDRenderMode( GLcontext *ctx, GLenum mode )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
   FALLBACK( fxMesa, TDFX_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
}



static void tdfxDDPrintState( const char *msg, GLuint flags )
{
   fprintf( stderr,
	    "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s\n",
	    msg,
	    flags,
	    (flags & TDFX_NEW_COLOR) ? "color, " : "",
	    (flags & TDFX_NEW_ALPHA) ? "alpha, " : "",
	    (flags & TDFX_NEW_DEPTH) ? "depth, " : "",
	    (flags & TDFX_NEW_RENDER) ? "render, " : "",
	    (flags & TDFX_NEW_FOG) ? "fog, " : "",
	    (flags & TDFX_NEW_STENCIL) ? "stencil, " : "",
	    (flags & TDFX_NEW_STIPPLE) ? "stipple, " : "",
	    (flags & TDFX_NEW_CLIP) ? "clip, " : "",
	    (flags & TDFX_NEW_VIEWPORT) ? "viewport, " : "",
	    (flags & TDFX_NEW_CULL) ? "cull, " : "",
	    (flags & TDFX_NEW_GLIDE) ? "glide, " : "",
	    (flags & TDFX_NEW_TEXTURE) ? "texture, " : "",
	    (flags & TDFX_NEW_CONTEXT) ? "context, " : "");
}



void tdfxDDUpdateHwState( GLcontext *ctx )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
   int new_state = fxMesa->new_state;

   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
      fprintf( stderr, "%s()\n", __FUNCTION__ );
   }

   if ( new_state )
   {
      FLUSH_BATCH( fxMesa );

      fxMesa->new_state = 0;

      if ( 0 )
	 tdfxDDPrintState( "tdfxUpdateHwState", new_state );

      /* Update the various parts of the context's state.
       */
      if ( new_state & TDFX_NEW_ALPHA ) {
	 tdfxUpdateAlphaMode( ctx );
      }

      if ( new_state & TDFX_NEW_DEPTH )
	 tdfxUpdateZMode( ctx );

      if ( new_state & TDFX_NEW_FOG )
	 tdfxUpdateFogAttrib( ctx );

      if ( new_state & TDFX_NEW_CLIP )
	 tdfxUpdateClipping( ctx );

      if ( new_state & TDFX_NEW_STIPPLE )
	 tdfxUpdateStipple( ctx );

      if ( new_state & TDFX_NEW_CULL )
	 tdfxUpdateCull( ctx );

      if ( new_state & TDFX_NEW_LINE )
         tdfxUpdateLine( ctx );

      if ( new_state & TDFX_NEW_VIEWPORT )
	 tdfxUpdateViewport( ctx );

      if ( new_state & TDFX_NEW_RENDER )
	 tdfxUpdateRenderAttrib( ctx );

      if ( new_state & TDFX_NEW_STENCIL )
         tdfxUpdateStencil( ctx );

      if ( new_state & TDFX_NEW_TEXTURE ) {
	 tdfxUpdateTextureState( ctx );
      }
      else if ( new_state & TDFX_NEW_TEXTURE_BIND ) {
	 tdfxUpdateTextureBinding( ctx );
      }
   }

   if ( 0 ) {
      FxI32 bias = (FxI32) (ctx->Polygon.OffsetUnits * TDFX_DEPTH_BIAS_SCALE);

      if ( fxMesa->Depth.Bias != bias ) {
	 fxMesa->Depth.Bias = bias;
	 fxMesa->dirty |= TDFX_UPLOAD_DEPTH_BIAS;
      }
   }

   if ( fxMesa->dirty ) {
      LOCK_HARDWARE( fxMesa );
      tdfxEmitHwStateLocked( fxMesa );
      UNLOCK_HARDWARE( fxMesa );
   }
}


static void tdfxDDInvalidateState( GLcontext *ctx, GLuint new_state )
{
   _swrast_InvalidateState( ctx, new_state );
   _swsetup_InvalidateState( ctx, new_state );
   _vbo_InvalidateState( ctx, new_state );
   _tnl_InvalidateState( ctx, new_state );
   TDFX_CONTEXT(ctx)->new_gl_state |= new_state;
}



/* Initialize the context's Glide state mirror.  These values will be
 * used as Glide function call parameters when the time comes.
 */
void tdfxInitState( tdfxContextPtr fxMesa )
{
   GLcontext *ctx = fxMesa->glCtx;
   GLint i;

   fxMesa->ColorCombine.Function	= GR_COMBINE_FUNCTION_LOCAL;
   fxMesa->ColorCombine.Factor		= GR_COMBINE_FACTOR_NONE;
   fxMesa->ColorCombine.Local		= GR_COMBINE_LOCAL_ITERATED;
   fxMesa->ColorCombine.Other		= GR_COMBINE_OTHER_NONE;
   fxMesa->ColorCombine.Invert		= FXFALSE;
   fxMesa->AlphaCombine.Function	= GR_COMBINE_FUNCTION_LOCAL;
   fxMesa->AlphaCombine.Factor		= GR_COMBINE_FACTOR_NONE;
   fxMesa->AlphaCombine.Local		= GR_COMBINE_LOCAL_ITERATED;
   fxMesa->AlphaCombine.Other		= GR_COMBINE_OTHER_NONE;
   fxMesa->AlphaCombine.Invert		= FXFALSE;

   fxMesa->ColorCombineExt.SourceA	= GR_CMBX_ITRGB;
   fxMesa->ColorCombineExt.ModeA	= GR_FUNC_MODE_X;
   fxMesa->ColorCombineExt.SourceB	= GR_CMBX_ZERO;
   fxMesa->ColorCombineExt.ModeB	= GR_FUNC_MODE_ZERO;
   fxMesa->ColorCombineExt.SourceC	= GR_CMBX_ZERO;
   fxMesa->ColorCombineExt.InvertC	= FXTRUE;
   fxMesa->ColorCombineExt.SourceD	= GR_CMBX_ZERO;
   fxMesa->ColorCombineExt.InvertD	= FXFALSE;
   fxMesa->ColorCombineExt.Shift	= 0;
   fxMesa->ColorCombineExt.Invert	= FXFALSE;
   fxMesa->AlphaCombineExt.SourceA	= GR_CMBX_ITALPHA;
   fxMesa->AlphaCombineExt.ModeA	= GR_FUNC_MODE_X;
   fxMesa->AlphaCombineExt.SourceB	= GR_CMBX_ZERO;
   fxMesa->AlphaCombineExt.ModeB	= GR_FUNC_MODE_ZERO;
   fxMesa->AlphaCombineExt.SourceC	= GR_CMBX_ZERO;
   fxMesa->AlphaCombineExt.InvertC	= FXTRUE;
   fxMesa->AlphaCombineExt.SourceD	= GR_CMBX_ZERO;
   fxMesa->AlphaCombineExt.InvertD	= FXFALSE;
   fxMesa->AlphaCombineExt.Shift	= 0;
   fxMesa->AlphaCombineExt.Invert	= FXFALSE;

   fxMesa->sScale0 = fxMesa->tScale0 = 1.0;
   fxMesa->sScale1 = fxMesa->tScale1 = 1.0;

   fxMesa->TexPalette.Type = 0;
   fxMesa->TexPalette.Data = NULL;

   for ( i = 0 ; i < TDFX_NUM_TMU ; i++ ) {
      fxMesa->TexSource[i].StartAddress	= 0;
      fxMesa->TexSource[i].EvenOdd	= GR_MIPMAPLEVELMASK_EVEN;
      fxMesa->TexSource[i].Info		= NULL;

      fxMesa->TexCombine[i].FunctionRGB		= 0;
      fxMesa->TexCombine[i].FactorRGB		= 0;
      fxMesa->TexCombine[i].FunctionAlpha	= 0;
      fxMesa->TexCombine[i].FactorAlpha		= 0;
      fxMesa->TexCombine[i].InvertRGB		= FXFALSE;
      fxMesa->TexCombine[i].InvertAlpha		= FXFALSE;

      fxMesa->TexCombineExt[i].Alpha.SourceA	= 0;
      /* XXX more state to init here */
      fxMesa->TexCombineExt[i].Color.SourceA	= 0;
      fxMesa->TexCombineExt[i].EnvColor        = 0x0;

      fxMesa->TexParams[i].sClamp 	= GR_TEXTURECLAMP_WRAP;
      fxMesa->TexParams[i].tClamp	= GR_TEXTURECLAMP_WRAP;
      fxMesa->TexParams[i].minFilt	= GR_TEXTUREFILTER_POINT_SAMPLED;
      fxMesa->TexParams[i].magFilt	= GR_TEXTUREFILTER_BILINEAR;
      fxMesa->TexParams[i].mmMode	= GR_MIPMAP_DISABLE;
      fxMesa->TexParams[i].LODblend	= FXFALSE;
      fxMesa->TexParams[i].LodBias	= 0.0;

      fxMesa->TexState.EnvMode[i]	= ~0;
      fxMesa->TexState.TexFormat[i]	= ~0;
      fxMesa->TexState.Enabled[i]	= 0;
   }

   if ( ctx->Visual.doubleBufferMode) {
      fxMesa->DrawBuffer		= GR_BUFFER_BACKBUFFER;
      fxMesa->ReadBuffer		= GR_BUFFER_BACKBUFFER;
   } else {
      fxMesa->DrawBuffer		= GR_BUFFER_FRONTBUFFER;
      fxMesa->ReadBuffer		= GR_BUFFER_FRONTBUFFER;
   }

   fxMesa->Color.ClearColor		= 0x00000000;
   fxMesa->Color.ClearAlpha		= 0x00;
   fxMesa->Color.ColorMask[RCOMP]	= FXTRUE;
   fxMesa->Color.ColorMask[BCOMP]	= FXTRUE;
   fxMesa->Color.ColorMask[GCOMP]	= FXTRUE;
   fxMesa->Color.ColorMask[ACOMP]	= FXTRUE;
   fxMesa->Color.MonoColor		= 0xffffffff;

   fxMesa->Color.AlphaFunc		= GR_CMP_ALWAYS;
   fxMesa->Color.AlphaRef		= 0x00;
   fxMesa->Color.BlendSrcRGB		= GR_BLEND_ONE;
   fxMesa->Color.BlendDstRGB		= GR_BLEND_ZERO;
   fxMesa->Color.BlendSrcA		= GR_BLEND_ONE;
   fxMesa->Color.BlendSrcA		= GR_BLEND_ZERO;

   fxMesa->Color.Dither			= GR_DITHER_2x2;

   if ( fxMesa->glCtx->Visual.depthBits > 0 ) {
      fxMesa->Depth.Mode		= GR_DEPTHBUFFER_ZBUFFER;
   } else {
      fxMesa->Depth.Mode		= GR_DEPTHBUFFER_DISABLE;
   }
   fxMesa->Depth.Bias			= 0;
   fxMesa->Depth.Func			= GR_CMP_LESS;
   fxMesa->Depth.Clear			= 0; /* computed later */
   fxMesa->Depth.Mask			= FXTRUE;


   fxMesa->Fog.Mode			= GR_FOG_DISABLE;
   fxMesa->Fog.Color			= 0x00000000;
   fxMesa->Fog.Table			= NULL;
   fxMesa->Fog.Density			= 1.0;
   fxMesa->Fog.Near			= 1.0;
   fxMesa->Fog.Far			= 1.0;

   fxMesa->Stencil.Function		= GR_CMP_ALWAYS;
   fxMesa->Stencil.RefValue		= 0;
   fxMesa->Stencil.ValueMask		= 0xff;
   fxMesa->Stencil.WriteMask		= 0xff;
   fxMesa->Stencil.FailFunc		= 0;
   fxMesa->Stencil.ZFailFunc		= 0;
   fxMesa->Stencil.ZPassFunc		= 0;
   fxMesa->Stencil.Clear		= 0;

   fxMesa->Stipple.Mode                 = GR_STIPPLE_DISABLE;
   fxMesa->Stipple.Pattern              = 0xffffffff;

   fxMesa->Scissor.minX			= 0;
   fxMesa->Scissor.minY			= 0;
   fxMesa->Scissor.maxX			= 0;
   fxMesa->Scissor.maxY			= 0;

   fxMesa->Viewport.Mode		= GR_WINDOW_COORDS;
   fxMesa->Viewport.X			= 0;
   fxMesa->Viewport.Y			= 0;
   fxMesa->Viewport.Width		= 0;
   fxMesa->Viewport.Height		= 0;
   fxMesa->Viewport.Near		= 0.0;
   fxMesa->Viewport.Far			= 0.0;

   fxMesa->CullMode			= GR_CULL_DISABLE;

   fxMesa->Glide.ColorFormat		= GR_COLORFORMAT_ABGR;
   fxMesa->Glide.Origin			= GR_ORIGIN_LOWER_LEFT;
   fxMesa->Glide.Initialized		= FXFALSE;
}



void tdfxDDInitStateFuncs( GLcontext *ctx )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);

   ctx->Driver.UpdateState		= tdfxDDInvalidateState;

   ctx->Driver.ClearColor		= tdfxDDClearColor;
   ctx->Driver.DrawBuffer		= tdfxDDDrawBuffer;
   ctx->Driver.ReadBuffer		= tdfxDDReadBuffer;

   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;
   ctx->Driver.DepthMask		= tdfxDDDepthMask;
   ctx->Driver.DepthRange		= tdfxDDDepthRange;
   ctx->Driver.Enable			= tdfxDDEnable;
   ctx->Driver.Fogfv			= tdfxDDFogfv;
   ctx->Driver.LightModelfv		= tdfxDDLightModelfv;
   ctx->Driver.LineWidth		= tdfxDDLineWidth;
   ctx->Driver.PolygonStipple		= tdfxDDPolygonStipple;
   ctx->Driver.RenderMode               = tdfxDDRenderMode;
   ctx->Driver.Scissor			= tdfxDDScissor;
   ctx->Driver.ShadeModel		= tdfxDDShadeModel;

   if ( fxMesa->haveHwStencil ) {
      ctx->Driver.StencilFuncSeparate	= tdfxDDStencilFuncSeparate;
      ctx->Driver.StencilMaskSeparate	= tdfxDDStencilMaskSeparate;
      ctx->Driver.StencilOpSeparate	= tdfxDDStencilOpSeparate;
   }

   ctx->Driver.Viewport			= tdfxDDViewport;
}
