/* -*- 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_render.c,v 1.4 2002/02/22 21:45:03 dawes 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>
 *
 */

#include "tdfx_context.h"
#include "tdfx_render.h"
#include "tdfx_state.h"
#include "tdfx_texman.h"
#include "swrast/swrast.h"

/* Clear the color and/or depth buffers.
 */
static void tdfxClear( GLcontext *ctx, GLbitfield mask )
{
   tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx;
   GLbitfield softwareMask = mask & (BUFFER_BIT_ACCUM);
   const GLuint stencil_size =
      fxMesa->haveHwStencil ? fxMesa->glCtx->Visual.stencilBits : 0;

   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
      fprintf( stderr, "tdfxClear(0x%x)\n", mask);
   }

   /* Need this check to respond to glScissor and clipping updates */
   if ((fxMesa->new_state & (TDFX_NEW_CLIP | TDFX_NEW_DEPTH)) ||
       (fxMesa->dirty & TDFX_UPLOAD_COLOR_MASK)) {
      tdfxDDUpdateHwState(ctx);
   }

   /* we can't clear accum buffers */
   mask &= ~(BUFFER_BIT_ACCUM);

   if (mask & BUFFER_BIT_STENCIL) {
      if (!fxMesa->haveHwStencil || (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
         /* Napalm seems to have trouble with stencil write masks != 0xff */
         /* do stencil clear in software */
         mask &= ~(BUFFER_BIT_STENCIL);
         softwareMask |= BUFFER_BIT_STENCIL;
      }
   }

   if (fxMesa->glCtx->Visual.redBits != 8) {
      /* can only do color masking if running in 24/32bpp on Napalm */
      if (ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP] ||
          ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP]) {
         softwareMask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT));
         mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT);
      }
   }

   if (fxMesa->haveHwStencil) {
      /*
       * If we want to clear stencil, it must be enabled
       * in the HW, even if the stencil test is not enabled
       * in the OGL state.
       */
      LOCK_HARDWARE(fxMesa);
      if (mask & BUFFER_BIT_STENCIL) {
	 fxMesa->Glide.grStencilMask(/*ctx->Stencil.WriteMask*/ 0xff);
	 /* set stencil ref value = desired clear value */
	 fxMesa->Glide.grStencilFunc(GR_CMP_ALWAYS,
                                     (fxMesa->Stencil.Clear & 0xff), 0xff);
	 fxMesa->Glide.grStencilOp(GR_STENCILOP_REPLACE,
                                   GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE);
	 fxMesa->Glide.grEnable(GR_STENCIL_MODE_EXT);
      }
      else {
	 fxMesa->Glide.grDisable(GR_STENCIL_MODE_EXT);
      }
      UNLOCK_HARDWARE(fxMesa);
   }

   /*
    * This may be ugly, but it's needed in order to work around a number
    * of Glide bugs.
    */
   BEGIN_CLIP_LOOP(fxMesa);
   {
      /*
       * This could probably be done fancier but doing each possible case
       * explicitly is less error prone.
       */
      switch (mask & ~BUFFER_BIT_STENCIL) {
      case BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH:
	 /* back buffer & depth */
	 FX_grColorMaskv_NoLock(ctx, true4); /* work around Voodoo3 bug */
	 fxMesa->Glide.grDepthMask(FXTRUE);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
	 if (stencil_size > 0) {
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) (ctx->Stencil.Clear & 0xff));
         }
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 if (!ctx->Depth.Mask || !ctx->Depth.Test) {
            fxMesa->Glide.grDepthMask(FXFALSE);
	 }
	 break;
      case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_DEPTH:
	 /* XXX it appears that the depth buffer isn't cleared when
	  * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
	  * This is a work-around/
	  */
	 /* clear depth */
	 fxMesa->Glide.grDepthMask(FXTRUE);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
	 FX_grColorMaskv_NoLock(ctx, false4);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) (ctx->Stencil.Clear & 0xff));
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear & 0xff);
	 /* clear front */
	 FX_grColorMaskv_NoLock(ctx, true4);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) (ctx->Stencil.Clear & 0xff));
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 if (!ctx->Depth.Mask || !ctx->Depth.Test) {
            fxMesa->Glide.grDepthMask(FXFALSE);
	 }
	 break;
      case BUFFER_BIT_BACK_LEFT:
	 /* back buffer only */
	 fxMesa->Glide.grDepthMask(FXFALSE);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) (ctx->Stencil.Clear & 0xff));
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 if (ctx->Depth.Mask && ctx->Depth.Test) {
            fxMesa->Glide.grDepthMask(FXTRUE);
	 }
	 break;
      case BUFFER_BIT_FRONT_LEFT:
	 /* front buffer only */
	 fxMesa->Glide.grDepthMask(FXFALSE);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) (ctx->Stencil.Clear & 0xff));
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 if (ctx->Depth.Mask && ctx->Depth.Test) {
            fxMesa->Glide.grDepthMask(FXTRUE);
	 }
	 break;
      case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT:
	 /* front and back */
	 fxMesa->Glide.grDepthMask(FXFALSE);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) (ctx->Stencil.Clear & 0xff));
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) (ctx->Stencil.Clear & 0xff));
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 if (ctx->Depth.Mask && ctx->Depth.Test) {
            fxMesa->Glide.grDepthMask(FXTRUE);
	 }
	 break;
      case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH:
	 /* clear front */
	 fxMesa->Glide.grDepthMask(FXFALSE);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) (ctx->Stencil.Clear & 0xff));
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 /* clear back and depth */
	 fxMesa->Glide.grDepthMask(FXTRUE);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
         if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) (ctx->Stencil.Clear & 0xff));
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 if (!ctx->Depth.Mask || !ctx->Depth.Mask) {
            fxMesa->Glide.grDepthMask(FXFALSE);
	 }
	 break;
      case BUFFER_BIT_DEPTH:
	 /* just the depth buffer */
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
	 FX_grColorMaskv_NoLock(ctx, false4);
	 fxMesa->Glide.grDepthMask(FXTRUE);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) (ctx->Stencil.Clear & 0xff));
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 FX_grColorMaskv_NoLock(ctx, true4);
	 if (ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT)
            fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
	 if (!ctx->Depth.Test || !ctx->Depth.Mask)
	    fxMesa->Glide.grDepthMask(FXFALSE);
	 break;
      default:
         /* clear no color buffers or depth buffer but might clear stencil */
	 if (stencil_size > 0 && (mask & BUFFER_BIT_STENCIL)) {
            /* XXX need this RenderBuffer call to work around Glide bug */
            fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
            fxMesa->Glide.grDepthMask(FXFALSE);
            FX_grColorMaskv_NoLock(ctx, false4);
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) (ctx->Stencil.Clear & 0xff));
            if (ctx->Depth.Mask && ctx->Depth.Test) {
               fxMesa->Glide.grDepthMask(FXTRUE);
            }
            FX_grColorMaskv_NoLock(ctx, true4);
            if (ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT)
               fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
         }
      }
   }
   END_CLIP_LOOP(fxMesa);

   if (fxMesa->haveHwStencil && (mask & BUFFER_BIT_STENCIL)) {
      /* We changed the stencil state above.  Signal that we need to
       * upload it again.
       */
      fxMesa->dirty |= TDFX_UPLOAD_STENCIL;
   }

   if (softwareMask)
      _swrast_Clear(ctx, softwareMask);
}



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

   FLUSH_BATCH( fxMesa );

   LOCK_HARDWARE( fxMesa );
   fxMesa->Glide.grFinish();
   UNLOCK_HARDWARE( fxMesa );
}

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

   FLUSH_BATCH( fxMesa );

   LOCK_HARDWARE( fxMesa );
   fxMesa->Glide.grFlush();
   UNLOCK_HARDWARE( fxMesa );
}


#if 0
static const char *texSource(int k)
{
   switch (k) {
      case GR_CMBX_ZERO:
         return "GR_CMBX_ZERO";
      case GR_CMBX_TEXTURE_ALPHA:
         return "GR_CMBX_TEXTURE_ALPHA";
      case GR_CMBX_ALOCAL:
         return "GR_CMBX_ALOCAL";
      case GR_CMBX_AOTHER:
         return "GR_CMBX_AOTHER";
      case GR_CMBX_B:
         return "GR_CMBX_B";
      case GR_CMBX_CONSTANT_ALPHA:
         return "GR_CMBX_CONSTANT_ALPHA";
      case GR_CMBX_CONSTANT_COLOR:
         return "GR_CMBX_CONSTANT_COLOR";
      case GR_CMBX_DETAIL_FACTOR:
         return "GR_CMBX_DETAIL_FACTOR";
      case GR_CMBX_ITALPHA:
         return "GR_CMBX_ITALPHA";
      case GR_CMBX_ITRGB:
         return "GR_CMBX_ITRGB";
      case GR_CMBX_LOCAL_TEXTURE_ALPHA:
         return "GR_CMBX_LOCAL_TEXTURE_ALPHA";
      case GR_CMBX_LOCAL_TEXTURE_RGB:
         return "GR_CMBX_LOCAL_TEXTURE_RGB";
      case GR_CMBX_LOD_FRAC:
         return "GR_CMBX_LOD_FRAC";
      case GR_CMBX_OTHER_TEXTURE_ALPHA:
         return "GR_CMBX_OTHER_TEXTURE_ALPHA";
      case GR_CMBX_OTHER_TEXTURE_RGB:
         return "GR_CMBX_OTHER_TEXTURE_RGB";
      case GR_CMBX_TEXTURE_RGB:
         return "GR_CMBX_TEXTURE_RGB";
      case GR_CMBX_TMU_CALPHA:
         return "GR_CMBX_TMU_CALPHA";
      case GR_CMBX_TMU_CCOLOR:
         return "GR_CMBX_TMU_CCOLOR";
      default:
         return "";
   }
}
#endif

#if 0
static const char *texMode(int k)
{
   switch (k) {
      case GR_FUNC_MODE_ZERO:
         return "GR_FUNC_MODE_ZERO";
      case GR_FUNC_MODE_X:
         return "GR_FUNC_MODE_X";
      case GR_FUNC_MODE_ONE_MINUS_X:
         return "GR_FUNC_MODE_ONE_MINUS_X";
      case GR_FUNC_MODE_NEGATIVE_X:
         return "GR_FUNC_MODE_NEGATIVE_X";
      case GR_FUNC_MODE_X_MINUS_HALF:
         return "GR_FUNC_MODE_X_MINUS_HALF";
      default:
         return "";
   }
}
#endif

#if 0
static const char *texInvert(int k)
{
   return k ? "FXTRUE" : "FXFALSE";
}
#endif

static void uploadTextureEnv( tdfxContextPtr fxMesa )
{
   if (TDFX_IS_NAPALM(fxMesa)) {
      int unit;
      for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
#if 0
         printf("upload env %d\n", unit);
         printf("   cSourceA = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceA));
         printf("     cModeA = %s\n", texMode(fxMesa->TexCombineExt[unit].Color.ModeA));
         printf("   cSourceB = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceB));
         printf("     cModeB = %s\n", texMode(fxMesa->TexCombineExt[unit].Color.ModeB));
         printf("   cSourceC = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceC));
         printf("   cInvertC = %s\n", texInvert(fxMesa->TexCombineExt[unit].Color.InvertC));
         printf("   cSourceD = %s\t", texSource(fxMesa->TexCombineExt[unit].Color.SourceD));
         printf("   cInvertD = %s\n", texInvert(fxMesa->TexCombineExt[unit].Color.InvertD));
         printf("     cShift = %d\t", fxMesa->TexCombineExt[unit].Color.Shift);
         printf("    cInvert = %d\n", fxMesa->TexCombineExt[unit].Color.Invert);
         printf("   aSourceA = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceA));
         printf("     aModeA = %s\n", texMode(fxMesa->TexCombineExt[unit].Alpha.ModeA));
         printf("   aSourceB = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceB));
         printf("     aModeB = %s\n", texMode(fxMesa->TexCombineExt[unit].Alpha.ModeB));
         printf("   aSourceC = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceC));
         printf("   aInvertC = %s\n", texInvert(fxMesa->TexCombineExt[unit].Alpha.InvertC));
         printf("   aSourceD = %s\t", texSource(fxMesa->TexCombineExt[unit].Alpha.SourceD));
         printf("   aInvertD = %s\n", texInvert(fxMesa->TexCombineExt[unit].Alpha.InvertD));
         printf("     aShift = %d\t", fxMesa->TexCombineExt[unit].Alpha.Shift);
         printf("    aInvert = %d\n", fxMesa->TexCombineExt[unit].Alpha.Invert);
         printf("      Color = 0x%08x\n", fxMesa->TexCombineExt[unit].EnvColor);
#endif
         fxMesa->Glide.grTexColorCombineExt(TDFX_TMU0 + unit,
                                     fxMesa->TexCombineExt[unit].Color.SourceA,
                                     fxMesa->TexCombineExt[unit].Color.ModeA,
                                     fxMesa->TexCombineExt[unit].Color.SourceB,
                                     fxMesa->TexCombineExt[unit].Color.ModeB,
                                     fxMesa->TexCombineExt[unit].Color.SourceC,
                                     fxMesa->TexCombineExt[unit].Color.InvertC,
                                     fxMesa->TexCombineExt[unit].Color.SourceD,
                                     fxMesa->TexCombineExt[unit].Color.InvertD,
                                     fxMesa->TexCombineExt[unit].Color.Shift,
                                     fxMesa->TexCombineExt[unit].Color.Invert);
         fxMesa->Glide.grTexAlphaCombineExt(TDFX_TMU0 + unit,
                                     fxMesa->TexCombineExt[unit].Alpha.SourceA,
                                     fxMesa->TexCombineExt[unit].Alpha.ModeA,
                                     fxMesa->TexCombineExt[unit].Alpha.SourceB,
                                     fxMesa->TexCombineExt[unit].Alpha.ModeB,
                                     fxMesa->TexCombineExt[unit].Alpha.SourceC,
                                     fxMesa->TexCombineExt[unit].Alpha.InvertC,
                                     fxMesa->TexCombineExt[unit].Alpha.SourceD,
                                     fxMesa->TexCombineExt[unit].Alpha.InvertD,
                                     fxMesa->TexCombineExt[unit].Alpha.Shift,
                                     fxMesa->TexCombineExt[unit].Alpha.Invert);
         fxMesa->Glide.grConstantColorValueExt(TDFX_TMU0 + unit,
                                        fxMesa->TexCombineExt[unit].EnvColor);
      }
   }
   else {
      /* Voodoo3 */
      int unit;
      for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
         struct tdfx_texcombine *comb = &fxMesa->TexCombine[unit];
         fxMesa->Glide.grTexCombine(TDFX_TMU0 + unit,
                                    comb->FunctionRGB,
                                    comb->FactorRGB,
                                    comb->FunctionAlpha,
                                    comb->FactorAlpha,
                                    comb->InvertRGB,
                                    comb->InvertAlpha);
      }
   }
}


static void uploadTextureParams( tdfxContextPtr fxMesa )
{
   int unit;
   for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
      const struct tdfx_texparams *p = &fxMesa->TexParams[unit];
      /*
      printf("upload params %d\n", unit);
      printf("   clamp %x %x\n", env->sClamp, env->tClamp);
      printf("   filter %x %x\n", env->minFilt, env->magFilt);
      printf("   mipmap %x %x\n", env->mmMode, env->LODblend);
      printf("   lod bias %f\n", env->LodBias);
      */
      fxMesa->Glide.grTexClampMode(GR_TMU0 + unit, p->sClamp, p->tClamp);
      fxMesa->Glide.grTexFilterMode(GR_TMU0 + unit, p->minFilt, p->magFilt);
      fxMesa->Glide.grTexMipMapMode(GR_TMU0 + unit, p->mmMode, p->LODblend);
      fxMesa->Glide.grTexLodBiasValue(GR_TMU0 + unit, CLAMP(p->LodBias, -8, 7.75));
   }
}


static void uploadTextureSource( tdfxContextPtr fxMesa )
{
   int unit;
   for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
      const struct tdfx_texsource *src = &fxMesa->TexSource[unit];
      /*
      printf("upload source %d @ %d %p\n", unit, src->StartAddress, src->Info);
      */
      if (src->Info) {
         /*
         printf("  smallLodLog2=%d largeLodLog2=%d ar=%d format=%d data=%p\n",
                src->Info->smallLodLog2, src->Info->largeLodLog2,
                src->Info->aspectRatioLog2, src->Info->format,
                src->Info->data);
         */
         fxMesa->Glide.grTexSource(GR_TMU0 + unit,
                                   src->StartAddress,
                                   src->EvenOdd,
                                   src->Info);
      }
   }
}


static void uploadTextureImages( tdfxContextPtr fxMesa )
{
   GLcontext *ctx = fxMesa->glCtx;
   int unit;
   for (unit = 0; unit < TDFX_NUM_TMU; unit++) {
      if (ctx->Texture.Unit[unit]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) {
         struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
         tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
         if (ti && ti->reloadImages && ti->whichTMU != TDFX_TMU_NONE) {
            /*
            printf("download texture image on unit %d\n", unit);
            */
            tdfxTMDownloadTexture(fxMesa, tObj);
            ti->reloadImages = GL_FALSE;
         }
      }
   }
}



/*
 * If scissoring is enabled, compute intersection of scissor region
 * with all X clip rects, resulting in new cliprect list.
 * If number of cliprects is zero or one, call grClipWindow to setup
 * the clip region.  Otherwise we'll call grClipWindow inside the
 * BEGIN_CLIP_LOOP macro.
 */
void tdfxUploadClipping( tdfxContextPtr fxMesa )
{
   __DRIdrawablePrivate *dPriv = fxMesa->driDrawable;

   assert(dPriv);

   if (fxMesa->numClipRects == 0) {
      /* all drawing clipped away */
      fxMesa->Glide.grClipWindow(0, 0, 0, 0);
   }
   else if (fxMesa->numClipRects == 1) {
      fxMesa->Glide.grClipWindow(fxMesa->pClipRects[0].x1,
                            fxMesa->screen_height - fxMesa->pClipRects[0].y2,
                            fxMesa->pClipRects[0].x2,
                            fxMesa->screen_height - fxMesa->pClipRects[0].y1);
   }
   /* else, we'll do a cliprect loop around all drawing */

   fxMesa->Glide.grDRIPosition( dPriv->x, dPriv->y, dPriv->w, dPriv->h,
                                fxMesa->numClipRects, fxMesa->pClipRects );
}


void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa )
{
   if ( !fxMesa->dirty )
      return;

   if ( fxMesa->dirty & TDFX_UPLOAD_COLOR_COMBINE ) {
      if (TDFX_IS_NAPALM(fxMesa)) {
         fxMesa->Glide.grColorCombineExt(fxMesa->ColorCombineExt.SourceA,
                                         fxMesa->ColorCombineExt.ModeA,
                                         fxMesa->ColorCombineExt.SourceB,
                                         fxMesa->ColorCombineExt.ModeB,
                                         fxMesa->ColorCombineExt.SourceC,
                                         fxMesa->ColorCombineExt.InvertC,
                                         fxMesa->ColorCombineExt.SourceD,
                                         fxMesa->ColorCombineExt.InvertD,
                                         fxMesa->ColorCombineExt.Shift,
                                         fxMesa->ColorCombineExt.Invert);
      }
      else {
         /* Voodoo 3 */
         fxMesa->Glide.grColorCombine( fxMesa->ColorCombine.Function,
                                       fxMesa->ColorCombine.Factor,
                                       fxMesa->ColorCombine.Local,
                                       fxMesa->ColorCombine.Other,
                                       fxMesa->ColorCombine.Invert );
      }
      fxMesa->dirty &= ~TDFX_UPLOAD_COLOR_COMBINE;
   }
   if ( fxMesa->dirty & TDFX_UPLOAD_ALPHA_COMBINE ) {
      if (TDFX_IS_NAPALM(fxMesa)) {
         fxMesa->Glide.grAlphaCombineExt(fxMesa->AlphaCombineExt.SourceA,
                                         fxMesa->AlphaCombineExt.ModeA,
                                         fxMesa->AlphaCombineExt.SourceB,
                                         fxMesa->AlphaCombineExt.ModeB,
                                         fxMesa->AlphaCombineExt.SourceC,
                                         fxMesa->AlphaCombineExt.InvertC,
                                         fxMesa->AlphaCombineExt.SourceD,
                                         fxMesa->AlphaCombineExt.InvertD,
                                         fxMesa->AlphaCombineExt.Shift,
                                         fxMesa->AlphaCombineExt.Invert);
      }
      else {
         /* Voodoo 3 */
         fxMesa->Glide.grAlphaCombine( fxMesa->AlphaCombine.Function,
                                       fxMesa->AlphaCombine.Factor,
                                       fxMesa->AlphaCombine.Local,
                                       fxMesa->AlphaCombine.Other,
                                       fxMesa->AlphaCombine.Invert );
      }
      fxMesa->dirty &= ~TDFX_UPLOAD_ALPHA_COMBINE;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_RENDER_BUFFER ) {
      fxMesa->Glide.grRenderBuffer( fxMesa->DrawBuffer );
      fxMesa->dirty &= ~TDFX_UPLOAD_RENDER_BUFFER;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_STIPPLE) {
      fxMesa->Glide.grStipplePattern( fxMesa->Stipple.Pattern );
      fxMesa->Glide.grStippleMode( fxMesa->Stipple.Mode );
      fxMesa->dirty &= ~TDFX_UPLOAD_STIPPLE;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_ALPHA_TEST ) {
      fxMesa->Glide.grAlphaTestFunction( fxMesa->Color.AlphaFunc );
      fxMesa->dirty &= ~TDFX_UPLOAD_ALPHA_TEST;
   }
   if ( fxMesa->dirty & TDFX_UPLOAD_ALPHA_REF ) {
      fxMesa->Glide.grAlphaTestReferenceValue( fxMesa->Color.AlphaRef );
      fxMesa->dirty &= ~TDFX_UPLOAD_ALPHA_REF;
   }
   if ( fxMesa->dirty & TDFX_UPLOAD_BLEND_FUNC ) {
      if (fxMesa->Glide.grAlphaBlendFunctionExt) {
         fxMesa->Glide.grAlphaBlendFunctionExt( fxMesa->Color.BlendSrcRGB,
                                                fxMesa->Color.BlendDstRGB,
                                                fxMesa->Color.BlendEqRGB,
                                                fxMesa->Color.BlendSrcA,
                                                fxMesa->Color.BlendDstA,
                                                fxMesa->Color.BlendEqA );
      }
      else {
         fxMesa->Glide.grAlphaBlendFunction( fxMesa->Color.BlendSrcRGB,
                                             fxMesa->Color.BlendDstRGB,
                                             fxMesa->Color.BlendSrcA,
                                             fxMesa->Color.BlendDstA );
      }
      fxMesa->dirty &= ~TDFX_UPLOAD_BLEND_FUNC;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_MODE ) {
      fxMesa->Glide.grDepthBufferMode( fxMesa->Depth.Mode );
      fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_MODE;
   }
   if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_BIAS ) {
      fxMesa->Glide.grDepthBiasLevel( fxMesa->Depth.Bias );
      fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_BIAS;
   }
   if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_FUNC ) {
      fxMesa->Glide.grDepthBufferFunction( fxMesa->Depth.Func );
      fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_FUNC;
   }
   if ( fxMesa->dirty & TDFX_UPLOAD_DEPTH_MASK ) {
      fxMesa->Glide.grDepthMask( fxMesa->Depth.Mask );
      fxMesa->dirty &= ~TDFX_UPLOAD_DEPTH_MASK;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_DITHER) {
      fxMesa->Glide.grDitherMode( fxMesa->Color.Dither );
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_FOG_MODE ) {
      fxMesa->Glide.grFogMode( fxMesa->Fog.Mode );
      fxMesa->dirty &= ~TDFX_UPLOAD_FOG_MODE;
   }
   if ( fxMesa->dirty & TDFX_UPLOAD_FOG_COLOR ) {
      fxMesa->Glide.grFogColorValue( fxMesa->Fog.Color );
      fxMesa->dirty &= ~TDFX_UPLOAD_FOG_COLOR;
   }
   if ( fxMesa->dirty & TDFX_UPLOAD_FOG_TABLE ) {
      fxMesa->Glide.grFogTable( fxMesa->Fog.Table );
      fxMesa->dirty &= ~TDFX_UPLOAD_FOG_TABLE;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_CULL ) {
      fxMesa->Glide.grCullMode( fxMesa->CullMode );
      fxMesa->dirty &= ~TDFX_UPLOAD_CULL;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_CLIP ) {
      tdfxUploadClipping( fxMesa );
      fxMesa->dirty &= ~TDFX_UPLOAD_CLIP;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_COLOR_MASK ) {
      if ( fxMesa->Glide.grColorMaskExt
           && fxMesa->glCtx->Visual.redBits == 8) {
	 fxMesa->Glide.grColorMaskExt( fxMesa->Color.ColorMask[RCOMP],
                                       fxMesa->Color.ColorMask[GCOMP],
                                       fxMesa->Color.ColorMask[BCOMP],
                                       fxMesa->Color.ColorMask[ACOMP] );
      } else {
	 fxMesa->Glide.grColorMask( fxMesa->Color.ColorMask[RCOMP] ||
                                    fxMesa->Color.ColorMask[GCOMP] ||
                                    fxMesa->Color.ColorMask[BCOMP],
                                    /*fxMesa->Color.ColorMask[ACOMP]*/GL_FALSE/*[dBorca] no-no*/ );
      }
      fxMesa->dirty &= ~TDFX_UPLOAD_COLOR_MASK;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_CONSTANT_COLOR ) {
      fxMesa->Glide.grConstantColorValue( fxMesa->Color.MonoColor );
      fxMesa->dirty &= ~TDFX_UPLOAD_CONSTANT_COLOR;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_LINE ) {
      if (fxMesa->glCtx->Line.SmoothFlag && fxMesa->glCtx->Line.Width == 1.0)
         fxMesa->Glide.grEnable(GR_AA_ORDERED);
      else
         fxMesa->Glide.grDisable(GR_AA_ORDERED);
      fxMesa->dirty &= ~TDFX_UPLOAD_LINE;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_STENCIL ) {
      if (fxMesa->glCtx->Stencil.Enabled) {
         fxMesa->Glide.grEnable(GR_STENCIL_MODE_EXT);
         fxMesa->Glide.grStencilOp(fxMesa->Stencil.FailFunc,
                                   fxMesa->Stencil.ZFailFunc,
                                   fxMesa->Stencil.ZPassFunc);
         fxMesa->Glide.grStencilFunc(fxMesa->Stencil.Function,
                                     fxMesa->Stencil.RefValue,
                                     fxMesa->Stencil.ValueMask);
         fxMesa->Glide.grStencilMask(fxMesa->Stencil.WriteMask);
      }
      else {
         fxMesa->Glide.grDisable(GR_STENCIL_MODE_EXT);
      }
      fxMesa->dirty &= ~TDFX_UPLOAD_STENCIL;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_VERTEX_LAYOUT ) {
      fxMesa->Glide.grGlideSetVertexLayout( fxMesa->layout[fxMesa->vertexFormat] );
      /* [dborca] enable fogcoord */
      fxMesa->Glide.grVertexLayout(GR_PARAM_FOG_EXT, TDFX_FOG_OFFSET,
	 fxMesa->Fog.Mode == GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
      fxMesa->dirty &= ~TDFX_UPLOAD_VERTEX_LAYOUT;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_ENV ) {
      uploadTextureEnv(fxMesa);
      fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_ENV;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_PARAMS ) {
      uploadTextureParams(fxMesa);
      fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_PARAMS;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_PALETTE ) {
      if (fxMesa->TexPalette.Data) {
         fxMesa->Glide.grTexDownloadTable(fxMesa->TexPalette.Type, fxMesa->TexPalette.Data);
      }
      fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_PALETTE;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_SOURCE ) {
      uploadTextureSource(fxMesa);
      fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_SOURCE;
   }

   if ( fxMesa->dirty & TDFX_UPLOAD_TEXTURE_IMAGES ) {
      uploadTextureImages(fxMesa);
      fxMesa->dirty &= ~TDFX_UPLOAD_TEXTURE_IMAGES;
   }

   fxMesa->dirty = 0;
}



void tdfxInitRenderFuncs( struct dd_function_table *functions )
{
   functions->Clear	= tdfxClear;
   functions->Finish	= tdfxFinish;
   functions->Flush	= tdfxFlush;
}
