/*
 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
 * Copyright 2001-2003 S3 Graphics, Inc. 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, sub license,
 * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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.
 */


#include <stdio.h>

#include "mtypes.h"
#include "enums.h"
#include "macros.h"
#include "dd.h"

#include "mm.h"
#include "savagedd.h"
#include "savagecontext.h"

#include "savagestate.h"
#include "savagetex.h"
#include "savagetris.h"
#include "savageioctl.h"
#include "savage_bci.h"

#include "swrast/swrast.h"
#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "swrast_setup/swrast_setup.h"

#include "xmlpool.h"

/* Savage4, ProSavage[DDR], SuperSavage watermarks */
#define S4_ZRLO 24
#define S4_ZRHI 24
#define S4_ZWLO 0
#define S4_ZWHI 0

#define S4_DRLO 0
#define S4_DRHI 0
#define S4_DWLO 0
#define S4_DWHI 0

#define S4_TR   15

/* Savage3D/MX/IX watermarks */
#define S3D_ZRLO 8
#define S3D_ZRHI 24
#define S3D_ZWLO 0
#define S3D_ZWHI 24

#define S3D_DRLO 0
#define S3D_DRHI 0
#define S3D_DWLO 0
#define S3D_DWHI 0

#define S3D_TR   15

static void savageBlendFunc_s4(GLcontext *);
static void savageBlendFunc_s3d(GLcontext *);

static INLINE GLuint savagePackColor(GLuint format, 
                                         GLubyte r, GLubyte g, 
                                         GLubyte b, GLubyte a)
{
    switch (format) {
        case DV_PF_8888:
            return SAVAGEPACKCOLOR8888(r,g,b,a);
        case DV_PF_565:
            return SAVAGEPACKCOLOR565(r,g,b);
        default:
            
            return 0;
    }
}


static void savageDDAlphaFunc_s4(GLcontext *ctx, GLenum func, GLfloat ref)
{
    savageBlendFunc_s4(ctx);
}
static void savageDDAlphaFunc_s3d(GLcontext *ctx, GLenum func, GLfloat ref)
{
    savageBlendFunc_s3d(ctx);
}

static void savageDDBlendEquationSeparate(GLcontext *ctx,
					  GLenum modeRGB, GLenum modeA)
{
    assert( modeRGB == modeA );

    /* BlendEquation sets ColorLogicOpEnabled in an unexpected 
     * manner.  
     */
    FALLBACK( ctx, SAVAGE_FALLBACK_LOGICOP,
	      (ctx->Color.ColorLogicOpEnabled && 
	       ctx->Color.LogicOp != GL_COPY));

   /* Can only do blend addition, not min, max, subtract, etc. */
   FALLBACK( ctx, SAVAGE_FALLBACK_BLEND_EQ,
	     modeRGB != GL_FUNC_ADD);
}


static void savageBlendFunc_s4(GLcontext *ctx)
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
    u_int32_t drawCtrl0 = imesa->regs.s4.drawCtrl0.ui;
    u_int32_t drawCtrl1 = imesa->regs.s4.drawCtrl1.ui;

    /* set up draw control register (including blending, alpha
     * test, and shading model)
     */

    imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_FALSE;

    /*
     * blend modes
     */
    if(ctx->Color.BlendEnabled){
        switch (ctx->Color.BlendDstRGB)
        {
            case GL_ZERO:
                imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_Zero;
                break;

            case GL_ONE:
                imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_One;
                imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_SRC_COLOR:
                imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_SrcClr;
                imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_ONE_MINUS_SRC_COLOR:
                imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_1SrcClr;
                imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_SRC_ALPHA:
                imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_SrcAlpha;
                imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_ONE_MINUS_SRC_ALPHA:
                imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_1SrcAlpha;
                imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_DST_ALPHA:
                if (imesa->glCtx->Visual.alphaBits == 0)
                {
                    imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_One;
                }
                else
                {
                    imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode= DAM_DstAlpha;
                }
                imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_ONE_MINUS_DST_ALPHA:
                if (imesa->glCtx->Visual.alphaBits == 0)
                {
                    imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_Zero;
                }
                else
                {
                    imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode=DAM_1DstAlpha;
                    imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites= GL_TRUE;
                }
                break;
        }

        switch (ctx->Color.BlendSrcRGB)
        {
            case GL_ZERO:
                imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_Zero;
                break;

            case GL_ONE:
                imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_One;
                break;

            case GL_DST_COLOR:
                imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_DstClr;
                imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_ONE_MINUS_DST_COLOR:
                imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_1DstClr;
                imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_SRC_ALPHA:
                imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_SrcAlpha;
                break;

            case GL_ONE_MINUS_SRC_ALPHA:
                imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_1SrcAlpha;
                break;

            case GL_DST_ALPHA:
                if (imesa->glCtx->Visual.alphaBits == 0)
                {
                    imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_One;
                }
                else
                {
                    imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode= SAM_DstAlpha;
                    imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites= GL_TRUE;
                }
                break;

            case GL_ONE_MINUS_DST_ALPHA:
                if (imesa->glCtx->Visual.alphaBits == 0)          
                {
                    imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_Zero;
                }
                else
                {
                    imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode=SAM_1DstAlpha;
                    imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites= GL_TRUE;
                }
                break;
        }
    }
    else
    {
        imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_Zero;
        imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_One;
    }

    /* alpha test*/

    if(ctx->Color.AlphaEnabled) 
    {
        ACmpFunc a;
	GLubyte alphaRef;

	CLAMPED_FLOAT_TO_UBYTE(alphaRef,ctx->Color.AlphaRef);
         
        switch(ctx->Color.AlphaFunc)  { 
	case GL_NEVER: a = CF_Never; break;
	case GL_ALWAYS: a = CF_Always; break;
	case GL_LESS: a = CF_Less; break; 
	case GL_LEQUAL: a = CF_LessEqual; break;
	case GL_EQUAL: a = CF_Equal; break;
	case GL_GREATER: a = CF_Greater; break;
	case GL_GEQUAL: a = CF_GreaterEqual; break;
	case GL_NOTEQUAL: a = CF_NotEqual; break;
	default:return;
        }   
      
	imesa->regs.s4.drawCtrl1.ni.alphaTestEn = GL_TRUE;
	imesa->regs.s4.drawCtrl1.ni.alphaTestCmpFunc = a;
	imesa->regs.s4.drawCtrl0.ni.alphaRefVal = alphaRef;
    }
    else
    {
	imesa->regs.s4.drawCtrl1.ni.alphaTestEn      = GL_FALSE;
    }

    /* Set/Reset Z-after-alpha*/

    imesa->regs.s4.drawLocalCtrl.ni.wrZafterAlphaTst =
	imesa->regs.s4.drawCtrl1.ni.alphaTestEn;
    /*imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn =
        ~drawLocalCtrl.ni.wrZafterAlphaTst;*/

    if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
	imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
    if (drawCtrl0 != imesa->regs.s4.drawCtrl0.ui ||
	drawCtrl1 != imesa->regs.s4.drawCtrl1.ui)
	imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
}
static void savageBlendFunc_s3d(GLcontext *ctx)
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
    u_int32_t zBufCtrl = imesa->regs.s3d.zBufCtrl.ui;

    /* set up draw control register (including blending, alpha
     * test, dithering, and shading model)
     */

    imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = 0;

    /*
     * blend modes
     */
    if(ctx->Color.BlendEnabled){
        switch (ctx->Color.BlendDstRGB)
        {
            case GL_ZERO:
                imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_Zero;
                break;

            case GL_ONE:
                imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_One;
                imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_SRC_COLOR:
                imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_SrcClr;
                imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_ONE_MINUS_SRC_COLOR:
                imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_1SrcClr;
                imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_SRC_ALPHA:
                imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_SrcAlpha;
                imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_ONE_MINUS_SRC_ALPHA:
                imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_1SrcAlpha;
                imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_DST_ALPHA:
                if (imesa->glCtx->Visual.alphaBits == 0)
                {
                    imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_One;
                }
                else
                {
                    imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_DstAlpha;
                }
                imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_ONE_MINUS_DST_ALPHA:
                if (imesa->glCtx->Visual.alphaBits == 0)
                {
                    imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_Zero;
                }
                else
                {
                    imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_1DstAlpha;
                    imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
                }
                break;
        }

        switch (ctx->Color.BlendSrcRGB)
        {
            case GL_ZERO:
                imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_Zero;
                break;

            case GL_ONE:
                imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_One;
                break;

            case GL_DST_COLOR:
                imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_DstClr;
                imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_ONE_MINUS_DST_COLOR:
                imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_1DstClr;
                imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
                break;

            case GL_SRC_ALPHA:
                imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_SrcAlpha;
                break;

            case GL_ONE_MINUS_SRC_ALPHA:
                imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_1SrcAlpha;
                break;

            case GL_DST_ALPHA:
                if (imesa->glCtx->Visual.alphaBits == 0)
                {
                    imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_One;
                }
                else
                {
                    imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_DstAlpha;
                    imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
                }
                break;

            case GL_ONE_MINUS_DST_ALPHA:
                if (imesa->glCtx->Visual.alphaBits == 0)          
                {
                    imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_Zero;
                }
                else
                {
                    imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_1DstAlpha;
                    imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
                }
                break;
        }
    }
    else
    {
        imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_Zero;
        imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_One;
    }

    /* alpha test*/

    if(ctx->Color.AlphaEnabled) 
    {
        ACmpFunc a;
	GLubyte alphaRef;

	CLAMPED_FLOAT_TO_UBYTE(alphaRef,ctx->Color.AlphaRef);
         
        switch(ctx->Color.AlphaFunc)  { 
	case GL_NEVER: a = CF_Never; break;
	case GL_ALWAYS: a = CF_Always; break;
	case GL_LESS: a = CF_Less; break; 
	case GL_LEQUAL: a = CF_LessEqual; break;
	case GL_EQUAL: a = CF_Equal; break;
	case GL_GREATER: a = CF_Greater; break;
	case GL_GEQUAL: a = CF_GreaterEqual; break;
	case GL_NOTEQUAL: a = CF_NotEqual; break;
	default:return;
        }   

	imesa->regs.s3d.drawCtrl.ni.alphaTestEn = GL_TRUE;
	imesa->regs.s3d.drawCtrl.ni.alphaTestCmpFunc = a;
	imesa->regs.s3d.drawCtrl.ni.alphaRefVal = alphaRef;
    }
    else
    {
	imesa->regs.s3d.drawCtrl.ni.alphaTestEn = GL_FALSE;
    }

    /* Set/Reset Z-after-alpha*/

    imesa->regs.s3d.zBufCtrl.ni.wrZafterAlphaTst =
	imesa->regs.s3d.drawCtrl.ni.alphaTestEn;

    if (drawCtrl != imesa->regs.s3d.drawCtrl.ui ||
	zBufCtrl != imesa->regs.s3d.zBufCtrl.ui)
	imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
}

static void savageDDBlendFuncSeparate_s4( GLcontext *ctx, GLenum sfactorRGB, 
					  GLenum dfactorRGB, GLenum sfactorA,
					  GLenum dfactorA )
{
    assert (dfactorRGB == dfactorA && sfactorRGB == sfactorA);
    savageBlendFunc_s4( ctx );
}
static void savageDDBlendFuncSeparate_s3d( GLcontext *ctx, GLenum sfactorRGB, 
					   GLenum dfactorRGB, GLenum sfactorA,
					   GLenum dfactorA )
{
    assert (dfactorRGB == dfactorA && sfactorRGB == sfactorA);
    savageBlendFunc_s3d( ctx );
}



static void savageDDDepthFunc_s4(GLcontext *ctx, GLenum func)
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    ZCmpFunc zmode;
    u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
    u_int32_t zBufCtrl = imesa->regs.s4.zBufCtrl.ui;
    u_int32_t zWatermarks = imesa->regs.s4.zWatermarks.ui; /* FIXME: in DRM */

    /* set up z-buffer control register (global)
     * set up z-buffer offset register (global)
     * set up z read/write watermarks register (global)
     */

    switch(func)  { /* reversed (see savageCalcViewport) */
    case GL_NEVER: zmode = CF_Never; break;
    case GL_ALWAYS: zmode = CF_Always; break;
    case GL_LESS: zmode = CF_Greater; break; 
    case GL_LEQUAL: zmode = CF_GreaterEqual; break;
    case GL_EQUAL: zmode = CF_Equal; break;
    case GL_GREATER: zmode = CF_Less; break;
    case GL_GEQUAL: zmode = CF_LessEqual; break;
    case GL_NOTEQUAL: zmode = CF_NotEqual; break;
    default:return;
    } 
    if (ctx->Depth.Test)
    {

	imesa->regs.s4.zBufCtrl.ni.zCmpFunc = zmode;
	imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = ctx->Depth.Mask;
	imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_TRUE;
	imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
    }
    else if (imesa->glCtx->Stencil.Enabled && imesa->hw_stencil)
    {
        /* Need to keep Z on for Stencil. */
	imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Always;
	imesa->regs.s4.zBufCtrl.ni.zBufEn   = GL_TRUE;
	imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE;
	imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;
    }
    else
    {

        if (imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn == GL_FALSE)
        {
            imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Always;
            imesa->regs.s4.zBufCtrl.ni.zBufEn   = GL_TRUE;
        }
        else

            /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
        {
	    imesa->regs.s4.zBufCtrl.ni.zBufEn         = GL_FALSE;
        }
	imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE;
	imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;
    }

    if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
	imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
    if (zBufCtrl != imesa->regs.s4.zBufCtrl.ui ||
	zWatermarks != imesa->regs.s4.zWatermarks.ui)
	imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
}
static void savageDDDepthFunc_s3d(GLcontext *ctx, GLenum func)
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    ZCmpFunc zmode;
    u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
    u_int32_t zBufCtrl = imesa->regs.s3d.zBufCtrl.ui;
    u_int32_t zWatermarks = imesa->regs.s3d.zWatermarks.ui; /* FIXME: in DRM */

    /* set up z-buffer control register (global)
     * set up z-buffer offset register (global)
     * set up z read/write watermarks register (global)
     */
    switch(func)  { /* reversed (see savageCalcViewport) */
    case GL_NEVER: zmode = CF_Never; break;
    case GL_ALWAYS: zmode = CF_Always; break;
    case GL_LESS: zmode = CF_Greater; break; 
    case GL_LEQUAL: zmode = CF_GreaterEqual; break;
    case GL_EQUAL: zmode = CF_Equal; break;
    case GL_GREATER: zmode = CF_Less; break;
    case GL_GEQUAL: zmode = CF_LessEqual; break;
    case GL_NOTEQUAL: zmode = CF_NotEqual; break;
    default:return;
    } 
    if (ctx->Depth.Test)
    {
	imesa->regs.s3d.zBufCtrl.ni.zBufEn = GL_TRUE;
	imesa->regs.s3d.zBufCtrl.ni.zCmpFunc = zmode;
	imesa->regs.s3d.zBufCtrl.ni.zUpdateEn = ctx->Depth.Mask;
	
	imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
    }
    else
    {
	if (imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn == GL_FALSE) {
	    imesa->regs.s3d.zBufCtrl.ni.zCmpFunc = CF_Always;
            imesa->regs.s3d.zBufCtrl.ni.zBufEn = GL_TRUE;
	}
        else

            /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
        {
	    imesa->regs.s3d.zBufCtrl.ni.zBufEn = GL_FALSE;
        }
	imesa->regs.s3d.zBufCtrl.ni.zUpdateEn = GL_FALSE;
	imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_FALSE;
    }
  
    if (drawCtrl != imesa->regs.s3d.drawCtrl.ui ||
	zBufCtrl != imesa->regs.s3d.zBufCtrl.ui)
	imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
    if (zWatermarks != imesa->regs.s3d.zWatermarks.ui)
	imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
}

static void savageDDDepthMask_s4(GLcontext *ctx, GLboolean flag)
{
    savageDDDepthFunc_s4(ctx,ctx->Depth.Func);
}
static void savageDDDepthMask_s3d(GLcontext *ctx, GLboolean flag)
{
    savageDDDepthFunc_s3d(ctx,ctx->Depth.Func);
}




/* =============================================================
 * Hardware clipping
 */


static void savageDDScissor( GLcontext *ctx, GLint x, GLint y, 
                             GLsizei w, GLsizei h )
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);

    /* Emit buffered commands with old scissor state. */
    FLUSH_BATCH(imesa);

    /* Mirror scissors in private context. */
    imesa->scissor.enabled = ctx->Scissor.Enabled;
    imesa->scissor.x = x;
    imesa->scissor.y = y;
    imesa->scissor.w = w;
    imesa->scissor.h = h;
}



static void savageDDDrawBuffer(GLcontext *ctx, GLenum mode )
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    u_int32_t destCtrl = imesa->regs.s4.destCtrl.ui;

    if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
	FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_TRUE );
        return;
    }

    switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) {
    case BUFFER_FRONT_LEFT:
        imesa->IsDouble = GL_FALSE;
	imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->frontOffset>>11;
	break;
    case BUFFER_BACK_LEFT:
        imesa->IsDouble = GL_TRUE;
	imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->backOffset>>11;
	break;
    default:
	FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_TRUE );
	return;
    }
    
    imesa->NotFirstFrame = GL_FALSE;
    savageXMesaSetClipRects(imesa);
    FALLBACK(ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE);

    if (destCtrl != imesa->regs.s4.destCtrl.ui)
        imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
}

static void savageDDReadBuffer(GLcontext *ctx, GLenum mode )
{
   /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
}

#if 0
static void savageDDSetColor(GLcontext *ctx, 
                             GLubyte r, GLubyte g,
                             GLubyte b, GLubyte a )
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    imesa->MonoColor = savagePackColor( imesa->savageScreen->frontFormat, r, g, b, a );
}
#endif

/* =============================================================
 * Window position and viewport transformation
 */

void savageCalcViewport( GLcontext *ctx )
{
   savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
   const GLfloat *v = ctx->Viewport._WindowMap.m;
   GLfloat *m = imesa->hw_viewport;

   m[MAT_SX] =   v[MAT_SX];
   m[MAT_TX] =   v[MAT_TX] + imesa->drawX + SUBPIXEL_X;
   m[MAT_SY] = - v[MAT_SY];
   m[MAT_TY] = - v[MAT_TY] + imesa->driDrawable->h + imesa->drawY + SUBPIXEL_Y;
   /* Depth range is reversed (far: 0, near: 1) so that float depth
    * compensates for loss of accuracy of far coordinates. */
   if (imesa->float_depth && imesa->savageScreen->zpp == 2) {
       /* The Savage 16-bit floating point depth format can't encode
	* numbers < 2^-16. Make sure all depth values stay greater
	* than that. */
       m[MAT_SZ] = - v[MAT_SZ] * imesa->depth_scale * (65535.0/65536.0);
       m[MAT_TZ] = 1.0 - v[MAT_TZ] * imesa->depth_scale * (65535.0/65536.0);
   } else {
       m[MAT_SZ] = - v[MAT_SZ] * imesa->depth_scale;
       m[MAT_TZ] = 1.0 - v[MAT_TZ] * imesa->depth_scale;
   }

   imesa->SetupNewInputs = ~0;
}

static void savageViewport( GLcontext *ctx, 
			    GLint x, GLint y, 
			    GLsizei width, GLsizei height )
{
   savageCalcViewport( ctx );
}

static void savageDepthRange( GLcontext *ctx, 
			      GLclampd nearval, GLclampd farval )
{
   savageCalcViewport( ctx );
}


/* =============================================================
 * Miscellaneous
 */

static void savageDDClearColor(GLcontext *ctx, 
			       const GLfloat color[4] )
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    GLubyte c[4];
    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]);

    imesa->ClearColor = savagePackColor( imesa->savageScreen->frontFormat,
					 c[0], c[1], c[2], c[3] );
}

/* Fallback to swrast for select and feedback.
 */
static void savageRenderMode( GLcontext *ctx, GLenum mode )
{
   FALLBACK( ctx, SAVAGE_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
}


#if HW_CULL

/* =============================================================
 * Culling - the savage isn't quite as clean here as the rest of
 *           its interfaces, but it's not bad.
 */
static void savageDDCullFaceFrontFace(GLcontext *ctx, GLenum unused)
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    GLuint cullMode=imesa->LcsCullMode;        
    switch (ctx->Polygon.CullFaceMode)
    {
        case GL_FRONT:
            switch (ctx->Polygon.FrontFace)
            {
                case GL_CW:
                    cullMode = BCM_CW;
                    break;
                case GL_CCW:
                    cullMode = BCM_CCW;
                    break;
            }
            break;

        case GL_BACK:
            switch (ctx->Polygon.FrontFace)
            {
                case GL_CW:
                    cullMode = BCM_CCW;
                    break;
                case GL_CCW:
                    cullMode = BCM_CW;
                    break;
            }
            break;
    }
    imesa->LcsCullMode = cullMode;    
    imesa->new_state |= SAVAGE_NEW_CULL;
}
#endif /* end #if HW_CULL */

static void savageUpdateCull( GLcontext *ctx )
{
#if HW_CULL
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    GLuint cullMode;
    if (ctx->Polygon.CullFlag &&
	imesa->raster_primitive >= GL_TRIANGLES &&
	ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK)
	cullMode = imesa->LcsCullMode;
    else
	cullMode = BCM_None;
    if (imesa->savageScreen->chipset >= S3_SAVAGE4) {
	if (imesa->regs.s4.drawCtrl1.ni.cullMode != cullMode) {
	    imesa->regs.s4.drawCtrl1.ni.cullMode = cullMode;
	    imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
	}
    } else {
	if (imesa->regs.s3d.drawCtrl.ni.cullMode != cullMode) {
	    imesa->regs.s3d.drawCtrl.ni.cullMode = cullMode;
	    imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
	}
    }
#endif /* end  #if HW_CULL */
}



/* =============================================================
 * Color masks
 */

/* Savage4 can disable draw updates when all channels are
 * masked. Savage3D has a bit called drawUpdateEn, but it doesn't seem
 * to have any effect. If only some channels are masked we need a
 * software fallback on all chips.
 */
static void savageDDColorMask_s4(GLcontext *ctx, 
				 GLboolean r, GLboolean g, 
				 GLboolean b, GLboolean a )
{
    savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
    GLboolean passAny, passAll;

    if (ctx->Visual.alphaBits) {
	passAny = b || g || r || a;
	passAll = r && g && b && a;
    } else {
	passAny = b || g || r;
	passAll = r && g && b;
    }

    if (passAny) {
	if (!imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn) {
	    imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_TRUE;
	    imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
	}
	FALLBACK (ctx, SAVAGE_FALLBACK_COLORMASK, !passAll);
    } else if (imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn) {
	imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_FALSE;
	imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
    }
}
static void savageDDColorMask_s3d(GLcontext *ctx, 
				  GLboolean r, GLboolean g, 
				  GLboolean b, GLboolean a )
{
    if (ctx->Visual.alphaBits)
	FALLBACK (ctx, SAVAGE_FALLBACK_COLORMASK, !(r && g && b && a));
    else
	FALLBACK (ctx, SAVAGE_FALLBACK_COLORMASK, !(r && g && b));
}

static void savageUpdateSpecular_s4(GLcontext *ctx) {
    savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
    u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;

    if (NEED_SECONDARY_COLOR(ctx)) {
	imesa->regs.s4.drawLocalCtrl.ni.specShadeEn = GL_TRUE;
    } else {
	imesa->regs.s4.drawLocalCtrl.ni.specShadeEn = GL_FALSE;
    }

    if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
	imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
}

static void savageUpdateSpecular_s3d(GLcontext *ctx) {
    savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
    u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;

    if (NEED_SECONDARY_COLOR(ctx)) {
	imesa->regs.s3d.drawCtrl.ni.specShadeEn = GL_TRUE;
    } else {
	imesa->regs.s3d.drawCtrl.ni.specShadeEn = GL_FALSE;
    }

    if (drawCtrl != imesa->regs.s3d.drawCtrl.ui)
	imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
}

static void savageDDLightModelfv_s4(GLcontext *ctx, GLenum pname, 
				    const GLfloat *param)
{
    savageUpdateSpecular_s4 (ctx);
}
static void savageDDLightModelfv_s3d(GLcontext *ctx, GLenum pname, 
				     const GLfloat *param)
{
    savageUpdateSpecular_s3d (ctx);
}

static void savageDDShadeModel_s4(GLcontext *ctx, GLuint mod)
{
    savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
    u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;

    if (mod == GL_SMOOTH)  
    {    
	imesa->regs.s4.drawLocalCtrl.ni.flatShadeEn = GL_FALSE;
    }
    else
    {
	imesa->regs.s4.drawLocalCtrl.ni.flatShadeEn = GL_TRUE;
    }

    if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
	imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
}
static void savageDDShadeModel_s3d(GLcontext *ctx, GLuint mod)
{
    savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
    u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;

    if (mod == GL_SMOOTH)  
    {    
	imesa->regs.s3d.drawCtrl.ni.flatShadeEn = GL_FALSE;
    }
    else
    {
	imesa->regs.s3d.drawCtrl.ni.flatShadeEn = GL_TRUE;
    }

    if (drawCtrl != imesa->regs.s3d.drawCtrl.ui)
	imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
}


/* =============================================================
 * Fog
 * The fogCtrl register has the same position and the same layout
 * on savage3d and savage4. No need for two separate functions.
 */

static void savageDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    GLuint  fogClr;
    u_int32_t fogCtrl = imesa->regs.s4.fogCtrl.ui;

    /*if ((ctx->Fog.Enabled) &&(pname == GL_FOG_COLOR))*/
    if (ctx->Fog.Enabled)
    {
        fogClr = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) |
                  ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) |
                  ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0));
	imesa->regs.s4.fogCtrl.ni.fogEn  = GL_TRUE;
        /*cheap fog*/
	imesa->regs.s4.fogCtrl.ni.fogMode  = GL_TRUE;
	imesa->regs.s4.fogCtrl.ni.fogClr = fogClr;    
    }    
    else
    {
        /*No fog*/
        
	imesa->regs.s4.fogCtrl.ni.fogEn     = 0;
	imesa->regs.s4.fogCtrl.ni.fogMode   = 0;
    }

    if (fogCtrl != imesa->regs.s4.fogCtrl.ui)
	imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
}


static void
savageDDStencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
                            GLint ref, GLuint mask)
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    unsigned a=0;
    const u_int32_t zBufCtrl = imesa->regs.s4.zBufCtrl.ui;
    const u_int32_t stencilCtrl = imesa->regs.s4.stencilCtrl.ui;

    imesa->regs.s4.zBufCtrl.ni.stencilRefVal = ctx->Stencil.Ref[0] & 0xff;
    imesa->regs.s4.stencilCtrl.ni.readMask  = ctx->Stencil.ValueMask[0] & 0xff;

    switch (ctx->Stencil.Function[0])
    {
    case GL_NEVER: a = CF_Never; break;
    case GL_ALWAYS: a = CF_Always; break;
    case GL_LESS: a = CF_Less; break; 
    case GL_LEQUAL: a = CF_LessEqual; break;
    case GL_EQUAL: a = CF_Equal; break;
    case GL_GREATER: a = CF_Greater; break;
    case GL_GEQUAL: a = CF_GreaterEqual; break;
    case GL_NOTEQUAL: a = CF_NotEqual; break;
    default:
        break;
    }

    imesa->regs.s4.stencilCtrl.ni.cmpFunc = a;

    if (zBufCtrl != imesa->regs.s4.zBufCtrl.ui ||
	stencilCtrl != imesa->regs.s4.stencilCtrl.ui)
	imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
}

static void
savageDDStencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);

    if (imesa->regs.s4.stencilCtrl.ni.writeMask != (ctx->Stencil.WriteMask[0] & 0xff)) {
	imesa->regs.s4.stencilCtrl.ni.writeMask = (ctx->Stencil.WriteMask[0] & 0xff);
	imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
    }
}

static unsigned get_stencil_op_value( GLenum op )
{
    switch (op)
    {
    case GL_KEEP:      return STENCIL_Keep;
    case GL_ZERO:      return STENCIL_Zero;
    case GL_REPLACE:   return STENCIL_Equal;
    case GL_INCR:      return STENCIL_IncClamp;
    case GL_DECR:      return STENCIL_DecClamp;
    case GL_INVERT:    return STENCIL_Invert;
    case GL_INCR_WRAP: return STENCIL_Inc;
    case GL_DECR_WRAP: return STENCIL_Dec;
    }

    /* Should *never* get here. */
    return STENCIL_Keep;
}

static void
savageDDStencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
                          GLenum zfail, GLenum zpass)
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    const u_int32_t stencilCtrl = imesa->regs.s4.stencilCtrl.ui;

    imesa->regs.s4.stencilCtrl.ni.failOp = get_stencil_op_value( ctx->Stencil.FailFunc[0] );
    imesa->regs.s4.stencilCtrl.ni.passZfailOp = get_stencil_op_value( ctx->Stencil.ZFailFunc[0] );
    imesa->regs.s4.stencilCtrl.ni.passZpassOp = get_stencil_op_value( ctx->Stencil.ZPassFunc[0] );

    if (stencilCtrl != imesa->regs.s4.stencilCtrl.ui)
	imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
}


/* =============================================================
 */

static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state)
{
   
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    switch(cap) {
        case GL_ALPHA_TEST:
            /* we should consider the disable case*/
            savageBlendFunc_s4(ctx);
            break;
        case GL_BLEND:
            /*add the savageBlendFunc 2001/11/25
             * if call no such function, then glDisable(GL_BLEND) will do noting,
             *our chip has no disable bit
             */ 
            savageBlendFunc_s4(ctx);
        case GL_COLOR_LOGIC_OP:
            /* Fall through: 
	     * For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
             */
	    FALLBACK (ctx, SAVAGE_FALLBACK_LOGICOP,
		      (ctx->Color.ColorLogicOpEnabled &&
		       ctx->Color.LogicOp != GL_COPY));
            break;
        case GL_DEPTH_TEST:
            savageDDDepthFunc_s4(ctx,ctx->Depth.Func);
            break;
        case GL_SCISSOR_TEST:
	    savageDDScissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
			    ctx->Scissor.Width, ctx->Scissor.Height);
            break;
        case GL_STENCIL_TEST:
	    if (!imesa->hw_stencil)
		FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, state);
	    else {
		imesa->regs.s4.stencilCtrl.ni.stencilEn = state;
		if (ctx->Stencil.Enabled &&
		    imesa->regs.s4.zBufCtrl.ni.zBufEn != GL_TRUE)
		{
		    /* Stencil buffer requires Z enabled. */
		    imesa->regs.s4.zBufCtrl.ni.zCmpFunc       = CF_Always;
		    imesa->regs.s4.zBufCtrl.ni.zBufEn         = GL_TRUE;
		    imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE;
		}
		imesa->dirty |= SAVAGE_UPLOAD_GLOBAL | SAVAGE_UPLOAD_LOCAL;
	    }
            break;
        case GL_FOG:
            savageDDFogfv(ctx,0,0);	
            break;
        case GL_CULL_FACE:
#if HW_CULL
            if (state)
            {
                savageDDCullFaceFrontFace(ctx,0);
            }
            else
            {
		imesa->LcsCullMode = BCM_None;
		imesa->new_state |= SAVAGE_NEW_CULL;
            }
#endif
            break;
        case GL_DITHER:
            if (state)
            {
                if ( ctx->Color.DitherFlag )
                {
                    imesa->regs.s4.drawCtrl1.ni.ditherEn=GL_TRUE;
                }
            }   
            if (!ctx->Color.DitherFlag )
            {
                imesa->regs.s4.drawCtrl1.ni.ditherEn=GL_FALSE;
            }
            imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
            break;
 
        case GL_LIGHTING:
	    savageUpdateSpecular_s4 (ctx);
            break;
        case GL_TEXTURE_1D:      
        case GL_TEXTURE_3D:      
            imesa->new_state |= SAVAGE_NEW_TEXTURE;
            break;
        case GL_TEXTURE_2D:      
            imesa->new_state |= SAVAGE_NEW_TEXTURE;
            break;
        default:
            ; 
    }    
}
static void savageDDEnable_s3d(GLcontext *ctx, GLenum cap, GLboolean state)
{
   
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    switch(cap) {
        case GL_ALPHA_TEST:
            /* we should consider the disable case*/
            savageBlendFunc_s3d(ctx);
            break;
        case GL_BLEND:
            /*add the savageBlendFunc 2001/11/25
             * if call no such function, then glDisable(GL_BLEND) will do noting,
             *our chip has no disable bit
             */ 
            savageBlendFunc_s3d(ctx);
        case GL_COLOR_LOGIC_OP:
            /* Fall through: 
	     * For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
             */
	    FALLBACK (ctx, SAVAGE_FALLBACK_LOGICOP,
		      (ctx->Color.ColorLogicOpEnabled &&
		       ctx->Color.LogicOp != GL_COPY));
            break;
        case GL_DEPTH_TEST:
            savageDDDepthFunc_s3d(ctx,ctx->Depth.Func);
            break;
        case GL_SCISSOR_TEST:
	    savageDDScissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
			    ctx->Scissor.Width, ctx->Scissor.Height);
            break;
        case GL_STENCIL_TEST:
	    FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, state);
	    break;
        case GL_FOG:
            savageDDFogfv(ctx,0,0);	
            break;
        case GL_CULL_FACE:
#if HW_CULL
            if (state)
            {
                savageDDCullFaceFrontFace(ctx,0);
            }
            else
            {
                imesa->LcsCullMode = BCM_None;
		imesa->new_state |= SAVAGE_NEW_CULL;
            }
#endif
            break;
        case GL_DITHER:
            if (state)
            {
                if ( ctx->Color.DitherFlag )
                {
                    imesa->regs.s3d.drawCtrl.ni.ditherEn=GL_TRUE;
                }
            }
            if (!ctx->Color.DitherFlag )
            {
                imesa->regs.s3d.drawCtrl.ni.ditherEn=GL_FALSE;
            }
            imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
            break;
 
        case GL_LIGHTING:
	    savageUpdateSpecular_s3d (ctx);
            break;
        case GL_TEXTURE_1D:      
        case GL_TEXTURE_3D:      
            imesa->new_state |= SAVAGE_NEW_TEXTURE;
            break;
        case GL_TEXTURE_2D:      
            imesa->new_state |= SAVAGE_NEW_TEXTURE;
            break;
        default:
            ; 
    }    
}

void savageDDUpdateHwState( GLcontext *ctx )
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);

    if (imesa->new_state) {
	savageFlushVertices(imesa);
	if (imesa->new_state & SAVAGE_NEW_TEXTURE) {
	    savageUpdateTextureState( ctx );
	}
	if ((imesa->new_state & SAVAGE_NEW_CULL)) {
	    savageUpdateCull(ctx);
	}
	imesa->new_state = 0;
    }
}


static void savageDDPrintDirty( const char *msg, GLuint state )
{
    fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s\n",	   
            msg,
            (unsigned int) state,
            (state & SAVAGE_UPLOAD_LOCAL)      ? "upload-local, " : "",
            (state & SAVAGE_UPLOAD_TEX0)       ? "upload-tex0, " : "",
            (state & SAVAGE_UPLOAD_TEX1)       ? "upload-tex1, " : "",
            (state & SAVAGE_UPLOAD_FOGTBL)     ? "upload-fogtbl, " : "",
            (state & SAVAGE_UPLOAD_GLOBAL)     ? "upload-global, " : "",
            (state & SAVAGE_UPLOAD_TEXGLOBAL)  ? "upload-texglobal, " : ""
            );
}


/**
 * Check if global registers were changed
 */
static GLboolean savageGlobalRegChanged (savageContextPtr imesa,
					 GLuint first, GLuint last) {
    GLuint i;
    for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) {
	if (((imesa->oldRegs.ui[i] ^ imesa->regs.ui[i]) &
	     imesa->globalRegMask.ui[i]) != 0)
	    return GL_TRUE;
    }
    return GL_FALSE;
}
static void savageEmitOldRegs (savageContextPtr imesa,
			       GLuint first, GLuint last, GLboolean global) {
    GLuint n = last-first+1;
    drm_savage_cmd_header_t *cmd = savageAllocCmdBuf(imesa, n*4);
    cmd->state.cmd = SAVAGE_CMD_STATE;
    cmd->state.global = global;
    cmd->state.count = n;
    cmd->state.start = first;
    memcpy(cmd+1, &imesa->oldRegs.ui[first-SAVAGE_FIRST_REG], n*4);
}
static void savageEmitContiguousRegs (savageContextPtr imesa,
				      GLuint first, GLuint last) {
    GLuint i;
    GLuint n = last-first+1;
    drm_savage_cmd_header_t *cmd = savageAllocCmdBuf(imesa, n*4);
    cmd->state.cmd = SAVAGE_CMD_STATE;
    cmd->state.global = savageGlobalRegChanged(imesa, first, last);
    cmd->state.count = n;
    cmd->state.start = first;
    memcpy(cmd+1, &imesa->regs.ui[first-SAVAGE_FIRST_REG], n*4);
    /* savageAllocCmdBuf may need to flush the cmd buffer and backup
     * the current hardware state. It should see the "old" (current)
     * state that has actually been emitted to the hardware. Therefore
     * this update is done *after* savageAllocCmdBuf. */
    for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i)
	imesa->oldRegs.ui[i] = imesa->regs.ui[i];
    if (SAVAGE_DEBUG & DEBUG_STATE)
	fprintf (stderr, "Emitting regs 0x%02x-0x%02x\n", first, last);
}
static void savageEmitChangedRegs (savageContextPtr imesa,
				   GLuint first, GLuint last) {
    GLuint i, firstChanged;
    firstChanged = SAVAGE_NR_REGS;
    for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) {
	if (imesa->oldRegs.ui[i] != imesa->regs.ui[i]) {
	    if (firstChanged == SAVAGE_NR_REGS)
		firstChanged = i;
	} else {
	    if (firstChanged != SAVAGE_NR_REGS) {
		savageEmitContiguousRegs (imesa, firstChanged+SAVAGE_FIRST_REG,
					  i-1+SAVAGE_FIRST_REG);
		firstChanged = SAVAGE_NR_REGS;
	    }
	}
    }
    if (firstChanged != SAVAGE_NR_REGS)
	savageEmitContiguousRegs (imesa, firstChanged+SAVAGE_FIRST_REG,
				  last);
}
static void savageEmitChangedRegChunk (savageContextPtr imesa,
				       GLuint first, GLuint last) {
    GLuint i;
    for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) {
	if (imesa->oldRegs.ui[i] != imesa->regs.ui[i]) {
	    savageEmitContiguousRegs (imesa, first, last);
	    break;
	}
    }
}
static void savageUpdateRegister_s4(savageContextPtr imesa)
{
    /* In case the texture image was changed without changing the
     * texture address as well, we need to force emitting the texture
     * address in order to flush texture cashes. */
    if ((imesa->dirty & SAVAGE_UPLOAD_TEX0) &&
	imesa->oldRegs.s4.texAddr[0].ui == imesa->regs.s4.texAddr[0].ui)
	imesa->oldRegs.s4.texAddr[0].ui = 0xffffffff;
    if ((imesa->dirty & SAVAGE_UPLOAD_TEX1) &&
	imesa->oldRegs.s4.texAddr[1].ui == imesa->regs.s4.texAddr[1].ui)
	imesa->oldRegs.s4.texAddr[1].ui = 0xffffffff;

    /* Fix up watermarks */
    if (imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites) {
	imesa->regs.s4.destTexWatermarks.ni.destWriteLow = 0;
	imesa->regs.s4.destTexWatermarks.ni.destFlush = 1;
    } else
	imesa->regs.s4.destTexWatermarks.ni.destWriteLow = S4_DWLO;
    if (imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites)
	imesa->regs.s4.zWatermarks.ni.wLow = 0;
    else
	imesa->regs.s4.zWatermarks.ni.wLow = S4_ZWLO;

    savageEmitChangedRegs (imesa, 0x1e, 0x39);

    imesa->dirty=0;
}
static void savageUpdateRegister_s3d(savageContextPtr imesa)
{
    /* In case the texture image was changed without changing the
     * texture address as well, we need to force emitting the texture
     * address in order to flush texture cashes. */
    if ((imesa->dirty & SAVAGE_UPLOAD_TEX0) &&
	imesa->oldRegs.s3d.texAddr.ui == imesa->regs.s3d.texAddr.ui)
	imesa->oldRegs.s3d.texAddr.ui = 0xffffffff;

    /* Fix up watermarks */
    if (imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites) {
	imesa->regs.s3d.destTexWatermarks.ni.destWriteLow = 0;
	imesa->regs.s3d.destTexWatermarks.ni.destFlush = 1;
    } else
	imesa->regs.s3d.destTexWatermarks.ni.destWriteLow = S3D_DWLO;
    if (imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites)
	imesa->regs.s3d.zWatermarks.ni.wLow = 0;
    else
	imesa->regs.s3d.zWatermarks.ni.wLow = S3D_ZWLO;


    /* the savage3d uses two contiguous ranges of BCI registers:
     * 0x18-0x1c and 0x20-0x38. Some texture registers need to be
     * emitted in one chunk or we get some funky rendering errors. */
    savageEmitChangedRegs (imesa, 0x18, 0x19);
    savageEmitChangedRegChunk (imesa, 0x1a, 0x1c);
    savageEmitChangedRegs (imesa, 0x20, 0x38);

    imesa->dirty=0;
}


void savageEmitOldState( savageContextPtr imesa )
{
    assert(imesa->cmdBuf.write == imesa->cmdBuf.base);
    if (imesa->savageScreen->chipset >= S3_SAVAGE4) {
	savageEmitOldRegs (imesa, 0x1e, 0x39, GL_TRUE);
    } else {
	savageEmitOldRegs (imesa, 0x18, 0x1c, GL_TRUE);
	savageEmitOldRegs (imesa, 0x20, 0x38, GL_FALSE);
    }
}


/* Push the state into the sarea and/or texture memory.
 */
void savageEmitChangedState( savageContextPtr imesa )
{
    if (SAVAGE_DEBUG & DEBUG_VERBOSE_API)
        savageDDPrintDirty( "\n\n\nsavageEmitHwStateLocked", imesa->dirty );

    if (imesa->dirty)
    {
	if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
	    fprintf (stderr, "... emitting state\n");
	if (imesa->savageScreen->chipset >= S3_SAVAGE4)
	    savageUpdateRegister_s4(imesa);
	else
	    savageUpdateRegister_s3d(imesa);
     }

    imesa->dirty = 0;
}


static void savageDDInitState_s4( savageContextPtr imesa )
{
#if 1
    imesa->regs.s4.destCtrl.ui          = 1<<7;
#endif

    imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Less;
    imesa->regs.s4.zBufCtrl.ni.wToZEn               = GL_TRUE;
    if (imesa->float_depth) {
	imesa->regs.s4.zBufCtrl.ni.zExpOffset =
	    imesa->savageScreen->zpp == 2 ? 16 : 32;
	imesa->regs.s4.zBufCtrl.ni.floatZEn = GL_TRUE;
    } else {
	imesa->regs.s4.zBufCtrl.ni.zExpOffset = 0;
	imesa->regs.s4.zBufCtrl.ni.floatZEn = GL_FALSE;
    }
    imesa->regs.s4.texBlendCtrl[0].ui            = TBC_NoTexMap;
    imesa->regs.s4.texBlendCtrl[1].ui            = TBC_NoTexMap1;
    imesa->regs.s4.drawCtrl0.ui         = 0;
#if 0
    imesa->regs.s4.drawCtrl1.ni.xyOffsetEn = 1;
#endif

    /* Set DestTexWatermarks_31,30 to 01 always.
     *Has no effect if dest. flush is disabled.
     */
#if 0
    imesa->regs.s4.zWatermarks.ui       = 0x12000C04;
    imesa->regs.s4.destTexWatermarks.ui = 0x40200400;
#else
    /*imesa->regs.s4.zWatermarks.ui       = 0x16001808;*/
    imesa->regs.s4.zWatermarks.ni.rLow  = S4_ZRLO;
    imesa->regs.s4.zWatermarks.ni.rHigh = S4_ZRHI;
    imesa->regs.s4.zWatermarks.ni.wLow  = S4_ZWLO;
    imesa->regs.s4.zWatermarks.ni.wHigh = S4_ZWHI;
    /*imesa->regs.s4.destTexWatermarks.ui = 0x4f000000;*/
    imesa->regs.s4.destTexWatermarks.ni.destReadLow   = S4_DRLO;
    imesa->regs.s4.destTexWatermarks.ni.destReadHigh  = S4_DRHI;
    imesa->regs.s4.destTexWatermarks.ni.destWriteLow  = S4_DWLO;
    imesa->regs.s4.destTexWatermarks.ni.destWriteHigh = S4_DWHI;
    imesa->regs.s4.destTexWatermarks.ni.texRead       = S4_TR;
    imesa->regs.s4.destTexWatermarks.ni.destFlush     = 1;
#endif
    imesa->regs.s4.drawCtrl0.ni.dPerfAccelEn = GL_TRUE;

    /* clrCmpAlphaBlendCtrl is needed to get alphatest and
     * alpha blending working properly
     */

    imesa->regs.s4.texCtrl[0].ni.dBias                 = 0x08;
    imesa->regs.s4.texCtrl[1].ni.dBias                 = 0x08;
    imesa->regs.s4.texCtrl[0].ni.texXprEn              = GL_TRUE;
    imesa->regs.s4.texCtrl[1].ni.texXprEn              = GL_TRUE;
    imesa->regs.s4.texCtrl[0].ni.dMax                  = 0x0f;
    imesa->regs.s4.texCtrl[1].ni.dMax                  = 0x0f;
    /* programm a valid tex address, in case texture state is emitted
     * in wrong order. */
    if (imesa->lastTexHeap == 2 && imesa->savageScreen->textureSize[1]) {
	/* AGP textures available */
	imesa->regs.s4.texAddr[0].ui = imesa->savageScreen->textureOffset[1]|3;
	imesa->regs.s4.texAddr[1].ui = imesa->savageScreen->textureOffset[1]|3;
    } else {
	/* no AGP textures available, use local */
	imesa->regs.s4.texAddr[0].ui = imesa->savageScreen->textureOffset[0]|2;
	imesa->regs.s4.texAddr[1].ui = imesa->savageScreen->textureOffset[0]|2;
    }
    imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn     = GL_TRUE;
    imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode    = SAM_One;
    imesa->regs.s4.drawLocalCtrl.ni.wrZafterAlphaTst = GL_FALSE;
    imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites= GL_TRUE;
    imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites= GL_TRUE;

    imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn= GL_TRUE;
    imesa->regs.s4.drawCtrl1.ni.ditherEn = (
	driQueryOptioni(&imesa->optionCache, "color_reduction") ==
	DRI_CONF_COLOR_REDUCTION_DITHER) ? GL_TRUE : GL_FALSE;
    imesa->regs.s4.drawCtrl1.ni.cullMode             = BCM_None;

    imesa->regs.s4.zBufCtrl.ni.stencilRefVal      = 0x00;

    imesa->regs.s4.stencilCtrl.ni.stencilEn       = GL_FALSE;
    imesa->regs.s4.stencilCtrl.ni.cmpFunc         = CF_Always;
    imesa->regs.s4.stencilCtrl.ni.failOp          = STENCIL_Keep;
    imesa->regs.s4.stencilCtrl.ni.passZfailOp     = STENCIL_Keep;
    imesa->regs.s4.stencilCtrl.ni.passZpassOp     = STENCIL_Keep;
    imesa->regs.s4.stencilCtrl.ni.writeMask       = 0xff;
    imesa->regs.s4.stencilCtrl.ni.readMask        = 0xff;

    imesa->LcsCullMode=BCM_None;
    imesa->regs.s4.texDescr.ni.palSize               = TPS_256;

    /* clear the local registers in the global reg mask */
    imesa->globalRegMask.s4.drawLocalCtrl.ui   = 0;
    imesa->globalRegMask.s4.texPalAddr.ui      = 0;
    imesa->globalRegMask.s4.texCtrl[0].ui      = 0;
    imesa->globalRegMask.s4.texCtrl[1].ui      = 0;
    imesa->globalRegMask.s4.texAddr[0].ui      = 0;
    imesa->globalRegMask.s4.texAddr[1].ui      = 0;
    imesa->globalRegMask.s4.texBlendCtrl[0].ui = 0;
    imesa->globalRegMask.s4.texBlendCtrl[1].ui = 0;
    imesa->globalRegMask.s4.texXprClr.ui       = 0;
    imesa->globalRegMask.s4.texDescr.ui        = 0;
}
static void savageDDInitState_s3d( savageContextPtr imesa )
{
#if 1
    imesa->regs.s3d.destCtrl.ui           = 1<<7;
#endif

    imesa->regs.s3d.zBufCtrl.ni.zCmpFunc  = CF_Less;
#if 0
    imesa->regs.s3d.drawCtrl.ni.xyOffsetEn = 1;
#endif

    /* Set DestTexWatermarks_31,30 to 01 always.
     *Has no effect if dest. flush is disabled.
     */
#if 0
    imesa->regs.s3d.zWatermarks.ui       = 0x12000C04;
    imesa->regs.s3d.destTexWatermarks.ui = 0x40200400;
#else
    /*imesa->regs.s3d.zWatermarks.ui       = 0x16001808;*/
    imesa->regs.s3d.zWatermarks.ni.rLow  = S3D_ZRLO;
    imesa->regs.s3d.zWatermarks.ni.rHigh = S3D_ZRHI;
    imesa->regs.s3d.zWatermarks.ni.wLow  = S3D_ZWLO;
    imesa->regs.s3d.zWatermarks.ni.wHigh = S3D_ZWHI;
    /*imesa->regs.s3d.destTexWatermarks.ui = 0x4f000000;*/
    imesa->regs.s3d.destTexWatermarks.ni.destReadLow   = S3D_DRLO;
    imesa->regs.s3d.destTexWatermarks.ni.destReadHigh  = S3D_DRHI;
    imesa->regs.s3d.destTexWatermarks.ni.destWriteLow  = S3D_DWLO;
    imesa->regs.s3d.destTexWatermarks.ni.destWriteHigh = S3D_DWHI;
    imesa->regs.s3d.destTexWatermarks.ni.texRead       = S3D_TR;
    imesa->regs.s3d.destTexWatermarks.ni.destFlush     = 1;
#endif

    imesa->regs.s3d.texCtrl.ni.dBias          = 0x08;
    imesa->regs.s3d.texCtrl.ni.texXprEn       = GL_TRUE;
    /* texXprEn is needed to get alphatest and alpha blending working
     * properly. However, this makes texels with color texXprClr
     * completely transparent in some texture environment modes. I
     * couldn't find a way to disable this. So choose an arbitrary and
     * improbable color. (0 is a bad choice, makes all black texels
     * transparent.) */
    imesa->regs.s3d.texXprClr.ui              = 0x26ae26ae;
    /* programm a valid tex address, in case texture state is emitted
     * in wrong order. */
    if (imesa->lastTexHeap == 2 && imesa->savageScreen->textureSize[1]) {
	/* AGP textures available */
	imesa->regs.s3d.texAddr.ui = imesa->savageScreen->textureOffset[1]|3;
    } else {
	/* no AGP textures available, use local */
	imesa->regs.s3d.texAddr.ui = imesa->savageScreen->textureOffset[0]|2;
    }

    imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn     = GL_TRUE;
    imesa->regs.s3d.zBufCtrl.ni.wrZafterAlphaTst = GL_FALSE;
    imesa->regs.s3d.zBufCtrl.ni.zUpdateEn        = GL_TRUE;

    imesa->regs.s3d.drawCtrl.ni.srcAlphaMode      = SAM_One;
    imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
    imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;

    imesa->regs.s3d.drawCtrl.ni.ditherEn =  (
	driQueryOptioni(&imesa->optionCache, "color_reduction") ==
	DRI_CONF_COLOR_REDUCTION_DITHER) ? GL_TRUE : GL_FALSE;
    imesa->regs.s3d.drawCtrl.ni.cullMode          = BCM_None;

    imesa->LcsCullMode = BCM_None;
    imesa->regs.s3d.texDescr.ni.palSize          = TPS_256;

    /* clear the local registers in the global reg mask */
    imesa->globalRegMask.s3d.texPalAddr.ui = 0;
    imesa->globalRegMask.s3d.texXprClr.ui  = 0;
    imesa->globalRegMask.s3d.texAddr.ui    = 0;
    imesa->globalRegMask.s3d.texDescr.ui   = 0;
    imesa->globalRegMask.s3d.texCtrl.ui    = 0;

    imesa->globalRegMask.s3d.fogCtrl.ui = 0;

    /* drawCtrl is local with some exceptions */
    imesa->globalRegMask.s3d.drawCtrl.ui = 0;
    imesa->globalRegMask.s3d.drawCtrl.ni.cullMode = 0x3;
    imesa->globalRegMask.s3d.drawCtrl.ni.alphaTestCmpFunc = 0x7;
    imesa->globalRegMask.s3d.drawCtrl.ni.alphaTestEn = 0x1;
    imesa->globalRegMask.s3d.drawCtrl.ni.alphaRefVal = 0xff;

    /* zBufCtrl is local with some exceptions */
    imesa->globalRegMask.s3d.zBufCtrl.ui = 0;
    imesa->globalRegMask.s3d.zBufCtrl.ni.zCmpFunc = 0x7;
    imesa->globalRegMask.s3d.zBufCtrl.ni.zBufEn = 0x1;
}
void savageDDInitState( savageContextPtr imesa ) {
    memset (imesa->regs.ui, 0, SAVAGE_NR_REGS*sizeof(u_int32_t));
    memset (imesa->globalRegMask.ui, 0xff, SAVAGE_NR_REGS*sizeof(u_int32_t));
    if (imesa->savageScreen->chipset >= S3_SAVAGE4)
	savageDDInitState_s4 (imesa);
    else
	savageDDInitState_s3d (imesa);

    /*fprintf(stderr,"DBflag:%d\n",imesa->glCtx->Visual->DBflag);*/
    /* zbufoffset and destctrl have the same position and layout on
     * savage4 and savage3d. */
    if (imesa->glCtx->Visual.doubleBufferMode) {
	imesa->IsDouble = GL_TRUE;
	imesa->toggle = TARGET_BACK;
	imesa->regs.s4.destCtrl.ni.offset =
	    imesa->savageScreen->backOffset>>11;
    } else {
	imesa->IsDouble = GL_FALSE;
	imesa->toggle = TARGET_FRONT;
	imesa->regs.s4.destCtrl.ni.offset =
	    imesa->savageScreen->frontOffset>>11;
    }
    if(imesa->savageScreen->cpp == 2) {
        imesa->regs.s4.destCtrl.ni.dstPixFmt = 0;
        imesa->regs.s4.destCtrl.ni.dstWidthInTile =
            (imesa->savageScreen->width+63)>>6;
    } else {
        imesa->regs.s4.destCtrl.ni.dstPixFmt = 1;
        imesa->regs.s4.destCtrl.ni.dstWidthInTile =
            (imesa->savageScreen->width+31)>>5;
    }
    imesa->NotFirstFrame = GL_FALSE;

    imesa->regs.s4.zBufOffset.ni.offset=imesa->savageScreen->depthOffset>>11;
    if(imesa->savageScreen->zpp == 2) {
        imesa->regs.s4.zBufOffset.ni.zBufWidthInTiles = 
            (imesa->savageScreen->width+63)>>6;
        imesa->regs.s4.zBufOffset.ni.zDepthSelect = 0;
    } else {   
        imesa->regs.s4.zBufOffset.ni.zBufWidthInTiles = 
            (imesa->savageScreen->width+31)>>5;
        imesa->regs.s4.zBufOffset.ni.zDepthSelect = 1;      
    }

    memcpy (imesa->oldRegs.ui, imesa->regs.ui, SAVAGE_NR_REGS*sizeof(u_int32_t));

    /* Emit the initial state to the (empty) command buffer. */
    assert (imesa->cmdBuf.write == imesa->cmdBuf.base);
    savageEmitOldState(imesa);
    imesa->cmdBuf.start = imesa->cmdBuf.write;
}


#define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\
                      NEW_TEXTURE_MATRIX|\
                      NEW_USER_CLIP|NEW_CLIENT_STATE))

static void savageDDInvalidateState( 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 );
   SAVAGE_CONTEXT(ctx)->new_gl_state |= new_state;
}


void savageDDInitStateFuncs(GLcontext *ctx)
{
    ctx->Driver.UpdateState = savageDDInvalidateState;
    ctx->Driver.BlendEquationSeparate = savageDDBlendEquationSeparate;
    ctx->Driver.Fogfv = savageDDFogfv;
    ctx->Driver.Scissor = savageDDScissor;
#if HW_CULL
    ctx->Driver.CullFace = savageDDCullFaceFrontFace;
    ctx->Driver.FrontFace = savageDDCullFaceFrontFace;
#else
    ctx->Driver.CullFace = 0;
    ctx->Driver.FrontFace = 0;
#endif /* end #if HW_CULL */
    ctx->Driver.DrawBuffer = savageDDDrawBuffer;
    ctx->Driver.ReadBuffer = savageDDReadBuffer;
    ctx->Driver.ClearColor = savageDDClearColor;

    ctx->Driver.DepthRange = savageDepthRange;
    ctx->Driver.Viewport = savageViewport;
    ctx->Driver.RenderMode = savageRenderMode;

    if (SAVAGE_CONTEXT( ctx )->savageScreen->chipset >= S3_SAVAGE4) {
	ctx->Driver.Enable = savageDDEnable_s4;
	ctx->Driver.AlphaFunc = savageDDAlphaFunc_s4;
	ctx->Driver.DepthFunc = savageDDDepthFunc_s4;
	ctx->Driver.DepthMask = savageDDDepthMask_s4;
	ctx->Driver.BlendFuncSeparate = savageDDBlendFuncSeparate_s4;
	ctx->Driver.ColorMask = savageDDColorMask_s4;
	ctx->Driver.ShadeModel = savageDDShadeModel_s4;
	ctx->Driver.LightModelfv = savageDDLightModelfv_s4;
	ctx->Driver.StencilFuncSeparate = savageDDStencilFuncSeparate;
	ctx->Driver.StencilMaskSeparate = savageDDStencilMaskSeparate;
	ctx->Driver.StencilOpSeparate = savageDDStencilOpSeparate;
    } else {
	ctx->Driver.Enable = savageDDEnable_s3d;
	ctx->Driver.AlphaFunc = savageDDAlphaFunc_s3d;
	ctx->Driver.DepthFunc = savageDDDepthFunc_s3d;
	ctx->Driver.DepthMask = savageDDDepthMask_s3d;
	ctx->Driver.BlendFuncSeparate = savageDDBlendFuncSeparate_s3d;
	ctx->Driver.ColorMask = savageDDColorMask_s3d;
	ctx->Driver.ShadeModel = savageDDShadeModel_s3d;
	ctx->Driver.LightModelfv = savageDDLightModelfv_s3d;
	ctx->Driver.StencilFuncSeparate = NULL;
	ctx->Driver.StencilMaskSeparate = NULL;
	ctx->Driver.StencilOpSeparate = NULL;
    }
}
