/*
 * 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 <stdlib.h>
#include <stdio.h>

#include <GL/gl.h>

#include "mm.h"
#include "savagecontext.h"
#include "savagetex.h"
#include "savagetris.h"
#include "savageioctl.h"
#include "simple_list.h"
#include "enums.h"
#include "savage_bci.h"

#include "macros.h"
#include "texformat.h"
#include "texstore.h"
#include "texobj.h"

#include "convolve.h"
#include "colormac.h"

#include "swrast/swrast.h"

#include "xmlpool.h"

#define TILE_INDEX_DXT1 0
#define TILE_INDEX_8    1
#define TILE_INDEX_16   2
#define TILE_INDEX_DXTn 3
#define TILE_INDEX_32   4

/* On Savage4 the texure LOD-bias needs an offset of ~ 0.3 to get
 * somewhere close to software rendering.
 */
#define SAVAGE4_LOD_OFFSET 10

/* Tile info for S3TC formats counts in 4x4 blocks instead of texels.
 * In DXT1 each block is encoded in 64 bits. In DXT3 and 5 each block is
 * encoded in 128 bits. */

/* Size 1, 2 and 4 images are packed into the last subtile. Each image
 * is repeated to fill a 4x4 pixel area. The figure below shows the
 * layout of those 4x4 pixel areas in the 8x8 subtile.
 *
 *    4 2
 *    x 1
 *
 * Yuck! 8-bit texture formats use 4x8 subtiles. See below.
 */
static const savageTileInfo tileInfo_pro[5] = {
    {16, 16, 16, 8, 1, 2, {0x18, 0x10}}, /* DXT1 */
    {64, 32, 16, 4, 4, 8, {0x30, 0x20}}, /* 8-bit */
    {64, 16,  8, 2, 8, 8, {0x48, 0x08}}, /* 16-bit */
    {16,  8, 16, 4, 1, 2, {0x30, 0x20}}, /* DXT3, DXT5 */
    {32, 16,  4, 2, 8, 8, {0x90, 0x10}}, /* 32-bit */
};

/* Size 1, 2 and 4 images are packed into the last two subtiles. Each
 * image is repeated to fill a 4x4 pixel area. The figures below show
 * the layout of those 4x4 pixel areas in the two 4x8 subtiles.
 *
 * second last subtile: 4   last subtile: 2
 *                      x                 1
 */
static const savageTileInfo tileInfo_s3d_s4[5] = {
    {16, 16, 16, 8, 1, 2, {0x18, 0x10}}, /* DXT1 */
    {64, 32, 16, 4, 4, 8, {0x30, 0x20}}, /* 8-bit */
    {64, 16, 16, 2, 4, 8, {0x60, 0x40}}, /* 16-bit */
    {16,  8, 16, 4, 1, 2, {0x30, 0x20}}, /* DXT3, DXT5 */
    {32, 16,  8, 2, 4, 8, {0xc0, 0x80}}, /* 32-bit */
};

/** \brief Template for subtile uploads.
 * \param h   height in pixels
 * \param w   width in bytes
 */
#define SUBTILE_FUNC(w,h)					\
static INLINE GLubyte *savageUploadSubtile_##w##x##h		\
(GLubyte *dest, GLubyte *src, GLuint srcStride)			\
{								\
    GLuint y;							\
    for (y = 0; y < h; ++y) {					\
	memcpy (dest, src, w);					\
	src += srcStride;					\
	dest += w;						\
    }								\
    return dest;						\
}

SUBTILE_FUNC(2, 8) /* 4 bits per pixel, 4 pixels wide */
SUBTILE_FUNC(4, 8)
SUBTILE_FUNC(8, 8)
SUBTILE_FUNC(16, 8)
SUBTILE_FUNC(32, 8) /* 4 bytes per pixel, 8 pixels wide */

SUBTILE_FUNC(8, 2) /* DXT1 */
SUBTILE_FUNC(16, 2) /* DXT3 and DXT5 */

/** \brief Upload a complete tile from src (srcStride) to dest
 *
 * \param tileInfo     Pointer to tiling information
 * \param wInSub       Width of source/dest image in subtiles
 * \param hInSub       Height of source/dest image in subtiles
 * \param bpp          Bytes per pixel
 * \param src          Pointer to source data
 * \param srcStride    Byte stride of rows in the source data
 * \param dest         Pointer to destination
 *
 * Writes linearly to the destination memory in order to exploit write
 * combining.
 *
 * For a complete tile wInSub and hInSub are set to the same values as
 * in tileInfo. If the source image is smaller than a whole tile in
 * one or both dimensions then they are set to the values of the
 * source image. This only works as long as the source image is bigger
 * than 8x8 pixels.
 */
static void savageUploadTile (const savageTileInfo *tileInfo,
			      GLuint wInSub, GLuint hInSub, GLuint bpp,
			      GLubyte *src, GLuint srcStride, GLubyte *dest) {
    GLuint subStride = tileInfo->subWidth * bpp;
    GLubyte *srcSRow = src, *srcSTile = src;
    GLubyte *(*subtileFunc) (GLubyte *, GLubyte *, GLuint);
    GLuint sx, sy;
    switch (subStride) {
    case  2: subtileFunc = savageUploadSubtile_2x8; break;
    case  4: subtileFunc = savageUploadSubtile_4x8; break;
    case  8: subtileFunc = tileInfo->subHeight == 8 ?
		 savageUploadSubtile_8x8 : savageUploadSubtile_8x2; break;
    case 16: subtileFunc = tileInfo->subHeight == 8 ?
		 savageUploadSubtile_16x8 : savageUploadSubtile_16x2; break;
    case 32: subtileFunc = savageUploadSubtile_32x8; break;
    default: assert(0);
    }
    for (sy = 0; sy < hInSub; ++sy) {
	srcSTile = srcSRow;
	for (sx = 0; sx < wInSub; ++sx) {
	    src = srcSTile;
	    dest = subtileFunc (dest, src, srcStride);
	    srcSTile += subStride;
	}
	srcSRow += srcStride * tileInfo->subHeight;
    }
}

/** \brief Upload a image that is smaller than 8 pixels in either dimension.
 *
 * \param tileInfo    Pointer to tiling information
 * \param width       Width of the image
 * \param height      Height of the image
 * \param bpp         Bytes per pixel
 * \param src         Pointer to source data
 * \param dest        Pointer to destination
 *
 * This function handles all the special cases that need to be taken
 * care off. The caller may need to call this function multiple times
 * with the destination offset in different ways since small texture
 * images must be repeated in order to fill a whole tile (or 4x4 for
 * the last 3 levels).
 *
 * FIXME: Repeating inside this function would be more efficient.
 */
static void savageUploadTiny (const savageTileInfo *tileInfo,
			      GLuint pixWidth, GLuint pixHeight,
			      GLuint width, GLuint height, GLuint bpp,
			      GLubyte *src, GLubyte *dest) {
    GLuint size = MAX2(pixWidth, pixHeight);

    if (width > tileInfo->subWidth) { /* assert: height <= subtile height */
	GLuint wInSub = width / tileInfo->subWidth;
	GLuint srcStride = width * bpp;
	GLuint subStride = tileInfo->subWidth * bpp;
	GLuint subSkip = (tileInfo->subHeight - height) * subStride;
	GLubyte *srcSTile = src;
	GLuint sx, y;
	for (sx = 0; sx < wInSub; ++sx) {
	    src = srcSTile;
	    for (y = 0; y < height; ++y) {
		memcpy (dest, src, subStride);
		src += srcStride;
		dest += subStride;
	    }
	    dest += subSkip;
	    srcSTile += subStride;
	}
    } else if (size > 4) { /* a tile or less wide, except the last 3 levels */
	GLuint srcStride = width * bpp;
	GLuint subStride = tileInfo->subWidth * bpp;
	/* if the subtile width is 4 we have to skip every other subtile */
	GLuint subSkip = tileInfo->subWidth <= 4 ?
	    subStride * tileInfo->subHeight : 0;
	GLuint skipRemainder = tileInfo->subHeight - 1;
	GLuint y;
	for (y = 0; y < height; ++y) {
	    memcpy (dest, src, srcStride);
	    src += srcStride;
	    dest += subStride;
	    if ((y & skipRemainder) == skipRemainder)
		dest += subSkip;
	}
    } else { /* the last 3 mipmap levels */
	GLuint offset = (size <= 2 ? tileInfo->tinyOffset[size-1] : 0);
	GLuint subStride = tileInfo->subWidth * bpp;
	GLuint y;
	dest += offset;
	for (y = 0; y < height; ++y) {
	    memcpy (dest, src, bpp*width);
	    src += width * bpp;
	    dest += subStride;
	}
    }
}

/** \brief Upload an image from mesa's internal copy.
 */
static void savageUploadTexLevel( savageTexObjPtr t, int level )
{
    const struct gl_texture_image *image = t->base.tObj->Image[0][level];
    const savageTileInfo *tileInfo = t->tileInfo;
    GLuint pixWidth = image->Width2, pixHeight = image->Height2;
    GLuint bpp = t->texelBytes;
    GLuint width, height;

    /* FIXME: Need triangle (rather than pixel) fallbacks to simulate
     * this using normal textured triangles.
     *
     * DO THIS IN DRIVER STATE MANAGMENT, not hardware state.
     */
    if(image->Border != 0) 
	fprintf (stderr, "Not supported texture border %d.\n",
		 (int) image->Border);

    if (t->hwFormat == TFT_S3TC4A4Bit || t->hwFormat == TFT_S3TC4CA4Bit ||
	t->hwFormat == TFT_S3TC4Bit) {
	width = (pixWidth+3) / 4;
	height = (pixHeight+3) / 4;
    } else {
	width = pixWidth;
	height = pixHeight;
    }

    if (pixWidth >= 8 && pixHeight >= 8) {
	GLuint *dirtyPtr = t->image[level].dirtyTiles;
	GLuint dirtyMask = 1;

	if (width >= tileInfo->width && height >= tileInfo->height) {
	    GLuint wInTiles = width / tileInfo->width;
	    GLuint hInTiles = height / tileInfo->height;
	    GLubyte *srcTRow = image->Data, *src;
	    GLubyte *dest = (GLubyte *)(t->bufAddr + t->image[level].offset);
	    GLuint x, y;
	    for (y = 0; y < hInTiles; ++y) {
		src = srcTRow;
		for (x = 0; x < wInTiles; ++x) {
		    if (*dirtyPtr & dirtyMask) {
			savageUploadTile (tileInfo,
					  tileInfo->wInSub, tileInfo->hInSub,
					  bpp, src, width * bpp, dest);
		    }
		    src += tileInfo->width * bpp;
		    dest += 2048; /* tile size is always 2k */
		    if (dirtyMask == 1<<31) {
			dirtyMask = 1;
			dirtyPtr++;
		    } else
			dirtyMask <<= 1;
		}
		srcTRow += width * tileInfo->height * bpp;
	    }
	} else if (width >= tileInfo->width) {
	    GLuint wInTiles = width / tileInfo->width;
	    GLubyte *src = image->Data;
	    GLubyte *dest = (GLubyte *)(t->bufAddr + t->image[level].offset);
	    GLuint tileStride = tileInfo->width * bpp * height;
	    savageContextPtr imesa = (savageContextPtr)t->base.heap->driverContext;
	    GLuint x;
	    /* Savage3D-based chips seem so use a constant tile stride
	     * of 2048 for vertically incomplete tiles, but only if
	     * the color depth is 32bpp. Nobody said this was supposed
	     * to be logical!
	     */
	    if (bpp == 4 && imesa->savageScreen->chipset < S3_SAVAGE4)
		tileStride = 2048;
	    for (x = 0; x < wInTiles; ++x) {
		if (*dirtyPtr & dirtyMask) {
		    savageUploadTile (tileInfo,
				      tileInfo->wInSub,
				      height / tileInfo->subHeight,
				      bpp, src, width * bpp, dest);
		}
		src += tileInfo->width * bpp;
		dest += tileStride;
		if (dirtyMask == 1<<31) {
		    dirtyMask = 1;
		    dirtyPtr++;
		} else
		    dirtyMask <<= 1;
	    }
	} else {
	    savageUploadTile (tileInfo, width / tileInfo->subWidth,
			      height / tileInfo->subHeight, bpp,
			      image->Data, width * bpp,
			      (GLubyte *)(t->bufAddr+t->image[level].offset));
	}
    } else {
	GLuint minHeight, minWidth, hRepeat, vRepeat, x, y;
	if (t->hwFormat == TFT_S3TC4A4Bit || t->hwFormat == TFT_S3TC4CA4Bit ||
	    t->hwFormat == TFT_S3TC4Bit)
	    minWidth = minHeight = 1;
	else
	    minWidth = minHeight = 4;
	if (width > minWidth || height > minHeight) {
	    minWidth = tileInfo->subWidth;
	    minHeight = tileInfo->subHeight;
	}
	hRepeat = width  >= minWidth  ? 1 : minWidth  / width;
	vRepeat = height >= minHeight ? 1 : minHeight / height;
	for (y = 0; y < vRepeat; ++y) {
	    GLuint offset = y * tileInfo->subWidth*height * bpp;
	    for (x = 0; x < hRepeat; ++x) {
		savageUploadTiny (tileInfo, pixWidth, pixHeight,
				  width, height, bpp, image->Data,
				  (GLubyte *)(t->bufAddr +
					      t->image[level].offset+offset));
		offset += width * bpp;
	    }
	}
    }
}

/** \brief Compute the destination size of a texture image
 */
static GLuint savageTexImageSize (GLuint width, GLuint height, GLuint bpp) {
    /* full subtiles */
    if (width >= 8 && height >= 8)
	return width * height * bpp;
    /* special case for the last three mipmap levels: the hardware computes
     * the offset internally */
    else if (width <= 4 && height <= 4)
	return 0;
    /* partially filled sub tiles waste memory
     * on Savage3D and Savage4 with subtile width 4 every other subtile is
     * skipped if width < 8 so we can assume a uniform subtile width of 8 */
    else if (width >= 8)
	return width * 8 * bpp;
    else if (height >= 8)
	return 8 * height * bpp;
    else
	return 64 * bpp;
}

/** \brief Compute the destination size of a compressed texture image
 */
static GLuint savageCompressedTexImageSize (GLuint width, GLuint height,
					    GLuint bpp) {
    width = (width+3) / 4;
    height = (height+3) / 4;
    /* full subtiles */
    if (width >= 2 && height >= 2)
	return width * height * bpp;
    /* special case for the last three mipmap levels: the hardware computes
     * the offset internally */
    else if (width <= 1 && height <= 1)
	return 0;
    /* partially filled sub tiles waste memory
     * on Savage3D and Savage4 with subtile width 4 every other subtile is
     * skipped if width < 8 so we can assume a uniform subtile width of 8 */
    else if (width >= 2)
	return width * 2 * bpp;
    else if (height >= 2)
	return 2 * height * bpp;
    else
	return 4 * bpp;
}

/** \brief Compute the number of (partial) tiles of a texture image
 */
static GLuint savageTexImageTiles (GLuint width, GLuint height,
				   const savageTileInfo *tileInfo)
{
   return (width + tileInfo->width - 1) / tileInfo->width *
      (height + tileInfo->height - 1) / tileInfo->height;
}

/** \brief Mark dirty tiles
 *
 * Some care must be taken because tileInfo may not be set or not
 * up-to-date. So we check if tileInfo is initialized and if the number
 * of tiles in the bit vector matches the number of tiles computed from
 * the current tileInfo.
 */
static void savageMarkDirtyTiles (savageTexObjPtr t, GLuint level,
				  GLuint totalWidth, GLuint totalHeight,
				  GLint xoffset, GLint yoffset,
				  GLsizei width, GLsizei height)
{
   GLuint wInTiles, hInTiles;
   GLuint x0, y0, x1, y1;
   GLuint x, y;
   if (!t->tileInfo)
      return;
   wInTiles = (totalWidth + t->tileInfo->width - 1) / t->tileInfo->width;
   hInTiles = (totalHeight + t->tileInfo->height - 1) / t->tileInfo->height;
   if (wInTiles * hInTiles != t->image[level].nTiles)
      return;

   x0 = xoffset / t->tileInfo->width;
   y0 = yoffset / t->tileInfo->height;
   x1 = (xoffset + width - 1) / t->tileInfo->width;
   y1 = (yoffset + height - 1) / t->tileInfo->height;

   for (y = y0; y <= y1; ++y) {
      GLuint *ptr = t->image[level].dirtyTiles + (y * wInTiles + x0) / 32;
      GLuint mask = 1 << (y * wInTiles + x0) % 32;
      for (x = x0; x <= x1; ++x) {
	 *ptr |= mask;
	 if (mask == (1<<31)) {
	    ptr++;
	    mask = 1;
	 } else {
	    mask <<= 1;
	 }
      }
   }
}

/** \brief Mark all tiles as dirty
 */
static void savageMarkAllTiles (savageTexObjPtr t, GLuint level)
{
   GLuint words = (t->image[level].nTiles + 31) / 32;
   if (words)
      memset(t->image[level].dirtyTiles, ~0, words*sizeof(GLuint));
}


static void savageSetTexWrapping(savageTexObjPtr tex, GLenum s, GLenum t)
{
    tex->setup.sWrapMode = s;
    tex->setup.tWrapMode = t;
}

static void savageSetTexFilter(savageTexObjPtr t, GLenum minf, GLenum magf)
{
   t->setup.minFilter = minf;
   t->setup.magFilter = magf;
}


/* Need a fallback ?
 */
static void savageSetTexBorderColor(savageTexObjPtr t, GLubyte color[4])
{
/*    t->Setup[SAVAGE_TEXREG_TEXBORDERCOL] =  */
    /*t->setup.borderColor = SAVAGEPACKCOLOR8888(color[0],color[1],color[2],color[3]); */
}



static savageTexObjPtr
savageAllocTexObj( struct gl_texture_object *texObj ) 
{
   savageTexObjPtr t;

   t = (savageTexObjPtr) calloc(1,sizeof(*t));
   texObj->DriverData = t;
   if ( t != NULL ) {
      GLuint i;

      /* Initialize non-image-dependent parts of the state:
       */
      t->base.tObj = texObj;
      t->base.dirty_images[0] = 0;
      t->dirtySubImages = 0;
      t->tileInfo = NULL;

      /* Initialize dirty tiles bit vectors
       */
      for (i = 0; i < SAVAGE_TEX_MAXLEVELS; ++i)
	 t->image[i].nTiles = 0;

      /* FIXME Something here to set initial values for other parts of
       * FIXME t->setup?
       */
  
      make_empty_list( &t->base );

      savageSetTexWrapping(t,texObj->WrapS,texObj->WrapT);
      savageSetTexFilter(t,texObj->MinFilter,texObj->MagFilter);
      savageSetTexBorderColor(t,texObj->_BorderChan);
   }

   return t;
}

/* Mesa texture formats for alpha-images on Savage3D/IX/MX
 *
 * Promoting texture images to ARGB888 or ARGB4444 doesn't work
 * because we can't tell the hardware to ignore the color components
 * and only use the alpha component. So we define our own texture
 * formats that promote to ARGB8888 or ARGB4444 and set the color
 * components to white. This way we get the correct result.
 */

static GLboolean
_savage_texstore_a1114444(TEXSTORE_PARAMS);

static GLboolean
_savage_texstore_a1118888(TEXSTORE_PARAMS);

static struct gl_texture_format _savage_texformat_a1114444 = {
    MESA_FORMAT_ARGB4444,		/* MesaFormat */
    GL_RGBA,				/* BaseFormat */
    GL_UNSIGNED_NORMALIZED_ARB,		/* DataType */
    4,					/* RedBits */
    4,					/* GreenBits */
    4,					/* BlueBits */
    4,					/* AlphaBits */
    0,					/* LuminanceBits */
    0,					/* IntensityBits */
    0,					/* IndexBits */
    0,					/* DepthBits */
    0,					/* StencilBits */
    2,					/* TexelBytes */
    _savage_texstore_a1114444,		/* StoreTexImageFunc */
    NULL, NULL, NULL, NULL, NULL, NULL  /* FetchTexel* filled in by 
					 * savageDDInitTextureFuncs */
};
static struct gl_texture_format _savage_texformat_a1118888 = {
    MESA_FORMAT_ARGB8888,		/* MesaFormat */
    GL_RGBA,				/* BaseFormat */
    GL_UNSIGNED_NORMALIZED_ARB,		/* DataType */
    8,					/* RedBits */
    8,					/* GreenBits */
    8,					/* BlueBits */
    8,					/* AlphaBits */
    0,					/* LuminanceBits */
    0,					/* IntensityBits */
    0,					/* IndexBits */
    0,					/* DepthBits */
    0,					/* StencilBits */
    4,					/* TexelBytes */
    _savage_texstore_a1118888,		/* StoreTexImageFunc */
    NULL, NULL, NULL, NULL, NULL, NULL  /* FetchTexel* filled in by 
					 * savageDDInitTextureFuncs */
};


static GLboolean
_savage_texstore_a1114444(TEXSTORE_PARAMS)
{
    const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                 baseInternalFormat,
                                                 baseInternalFormat,
                                                 srcWidth, srcHeight, srcDepth,
                                                 srcFormat, srcType, srcAddr,
                                                 srcPacking);
    const GLchan *src = tempImage;
    GLint img, row, col;

    ASSERT(dstFormat == &_savage_texformat_a1114444);
    ASSERT(baseInternalFormat == GL_ALPHA);

    if (!tempImage)
	return GL_FALSE;
    _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
    for (img = 0; img < srcDepth; img++) {
        GLubyte *dstRow = (GLubyte *) dstAddr
           + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
           + dstYoffset * dstRowStride
           + dstXoffset * dstFormat->TexelBytes;
	for (row = 0; row < srcHeight; row++) {
            GLushort *dstUI = (GLushort *) dstRow;
	    for (col = 0; col < srcWidth; col++) {
		dstUI[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[0]),
					      255, 255, 255 );
		src += 1;
            }
            dstRow += dstRowStride;
	}
    }
    _mesa_free((void *) tempImage);

    return GL_TRUE;
}


static GLboolean
_savage_texstore_a1118888(TEXSTORE_PARAMS)
{
    const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
                                                 baseInternalFormat,
                                                 baseInternalFormat,
                                                 srcWidth, srcHeight, srcDepth,
                                                 srcFormat, srcType, srcAddr,
                                                 srcPacking);
    const GLchan *src = tempImage;
    GLint img, row, col;

    ASSERT(dstFormat == &_savage_texformat_a1118888);
    ASSERT(baseInternalFormat == GL_ALPHA);

    if (!tempImage)
	return GL_FALSE;
    _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
    for (img = 0; img < srcDepth; img++) {
        GLubyte *dstRow = (GLubyte *) dstAddr
           + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
           + dstYoffset * dstRowStride
           + dstXoffset * dstFormat->TexelBytes;
	for (row = 0; row < srcHeight; row++) {
            GLuint *dstUI = (GLuint *) dstRow;
	    for (col = 0; col < srcWidth; col++) {
		dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[0]),
					      255, 255, 255 );
		src += 1;
            }
            dstRow += dstRowStride;
	}
    }
    _mesa_free((void *) tempImage);

    return GL_TRUE;
}


/* Called by the _mesa_store_teximage[123]d() functions. */
static const struct gl_texture_format *
savageChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
			   GLenum format, GLenum type )
{
   savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
   const GLboolean do32bpt =
       ( imesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32 );
   const GLboolean force16bpt =
       ( imesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16 );
   const GLboolean isSavage4 = (imesa->savageScreen->chipset >= S3_SAVAGE4);
   (void) format;

   switch ( internalFormat ) {
   case 4:
   case GL_RGBA:
   case GL_COMPRESSED_RGBA:
      switch ( type ) {
      case GL_UNSIGNED_INT_10_10_10_2:
      case GL_UNSIGNED_INT_2_10_10_10_REV:
	 return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555;
      case GL_UNSIGNED_SHORT_4_4_4_4:
      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
	 return &_mesa_texformat_argb4444;
      case GL_UNSIGNED_SHORT_5_5_5_1:
      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
	 return &_mesa_texformat_argb1555;
      default:
         return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
      }

   case 3:
   case GL_RGB:
   case GL_COMPRESSED_RGB:
      switch ( type ) {
      case GL_UNSIGNED_SHORT_4_4_4_4:
      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
	 return &_mesa_texformat_argb4444;
      case GL_UNSIGNED_SHORT_5_5_5_1:
      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
	 return &_mesa_texformat_argb1555;
      case GL_UNSIGNED_SHORT_5_6_5:
      case GL_UNSIGNED_SHORT_5_6_5_REV:
	 return &_mesa_texformat_rgb565;
      default:
         return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
      }

   case GL_RGBA8:
   case GL_RGBA12:
   case GL_RGBA16:
      return !force16bpt ?
	  &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;

   case GL_RGB10_A2:
      return !force16bpt ?
	  &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555;

   case GL_RGBA4:
   case GL_RGBA2:
      return &_mesa_texformat_argb4444;

   case GL_RGB5_A1:
      return &_mesa_texformat_argb1555;

   case GL_RGB8:
   case GL_RGB10:
   case GL_RGB12:
   case GL_RGB16:
      return !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;

   case GL_RGB5:
   case GL_RGB4:
   case GL_R3_G3_B2:
      return &_mesa_texformat_rgb565;

   case GL_ALPHA:
   case GL_COMPRESSED_ALPHA:
      return isSavage4 ? &_mesa_texformat_a8 : (
	 do32bpt ? &_savage_texformat_a1118888 : &_savage_texformat_a1114444);
   case GL_ALPHA4:
      return isSavage4 ? &_mesa_texformat_a8 : &_savage_texformat_a1114444;
   case GL_ALPHA8:
   case GL_ALPHA12:
   case GL_ALPHA16:
      return isSavage4 ? &_mesa_texformat_a8 : (
	 !force16bpt ? &_savage_texformat_a1118888 : &_savage_texformat_a1114444);

   case 1:
   case GL_LUMINANCE:
   case GL_COMPRESSED_LUMINANCE:
      /* no alpha, but use argb1555 in 16bit case to get pure grey values */
      return isSavage4 ? &_mesa_texformat_l8 : (
	 do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555);
   case GL_LUMINANCE4:
      return isSavage4 ? &_mesa_texformat_l8 : &_mesa_texformat_argb1555;
   case GL_LUMINANCE8:
   case GL_LUMINANCE12:
   case GL_LUMINANCE16:
      return isSavage4 ? &_mesa_texformat_l8 : (
	 !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555);

   case 2:
   case GL_LUMINANCE_ALPHA:
   case GL_COMPRESSED_LUMINANCE_ALPHA:
      /* Savage4 has a al44 texture format. But it's not supported by Mesa. */
      return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
   case GL_LUMINANCE4_ALPHA4:
   case GL_LUMINANCE6_ALPHA2:
      return &_mesa_texformat_argb4444;
   case GL_LUMINANCE8_ALPHA8:
   case GL_LUMINANCE12_ALPHA4:
   case GL_LUMINANCE12_ALPHA12:
   case GL_LUMINANCE16_ALPHA16:
      return !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
#if 0
   /* TFT_I8 produces garbage on ProSavageDDR and subsequent texture
    * disable keeps rendering garbage. Disabled for now. */
   case GL_INTENSITY:
   case GL_COMPRESSED_INTENSITY:
      return isSavage4 ? &_mesa_texformat_i8 : (
	 do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444);
   case GL_INTENSITY4:
      return isSavage4 ? &_mesa_texformat_i8 : &_mesa_texformat_argb4444;
   case GL_INTENSITY8:
   case GL_INTENSITY12:
   case GL_INTENSITY16:
      return isSavage4 ? &_mesa_texformat_i8 : (
	 !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444);
#else
   case GL_INTENSITY:
   case GL_COMPRESSED_INTENSITY:
      return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
   case GL_INTENSITY4:
      return &_mesa_texformat_argb4444;
   case GL_INTENSITY8:
   case GL_INTENSITY12:
   case GL_INTENSITY16:
      return !force16bpt ? &_mesa_texformat_argb8888 :
	  &_mesa_texformat_argb4444;
#endif

   case GL_RGB_S3TC:
   case GL_RGB4_S3TC:
   case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
      return &_mesa_texformat_rgb_dxt1;
   case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
      return &_mesa_texformat_rgba_dxt1;

   case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
      return &_mesa_texformat_rgba_dxt3;

   case GL_RGBA_S3TC:
   case GL_RGBA4_S3TC:
      if (!isSavage4)
	 /* Not the best choice but Savage3D/MX/IX don't support DXT3 or DXT5. */
	 return &_mesa_texformat_rgba_dxt1;
      /* fall through */
   case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
      return &_mesa_texformat_rgba_dxt5;

/*
   case GL_COLOR_INDEX:
   case GL_COLOR_INDEX1_EXT:
   case GL_COLOR_INDEX2_EXT:
   case GL_COLOR_INDEX4_EXT:
   case GL_COLOR_INDEX8_EXT:
   case GL_COLOR_INDEX12_EXT:
   case GL_COLOR_INDEX16_EXT:
      return &_mesa_texformat_ci8;
*/
   default:
      _mesa_problem(ctx, "unexpected texture format in %s", __FUNCTION__);
      return NULL;
   }
}

static void savageSetTexImages( savageContextPtr imesa,
				const struct gl_texture_object *tObj )
{
   savageTexObjPtr t = (savageTexObjPtr) tObj->DriverData;
   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
   GLuint offset, i, textureFormat, tileIndex, size;
   GLint firstLevel, lastLevel;

   assert(t);
   assert(image);

   switch (image->TexFormat->MesaFormat) {
   case MESA_FORMAT_ARGB8888:
      textureFormat = TFT_ARGB8888;
      t->texelBytes = tileIndex = 4;
      break;
   case MESA_FORMAT_ARGB1555:
      textureFormat = TFT_ARGB1555;
      t->texelBytes = tileIndex = 2;
      break;
   case MESA_FORMAT_ARGB4444:
      textureFormat = TFT_ARGB4444;
      t->texelBytes = tileIndex = 2;
      break;
   case MESA_FORMAT_RGB565:
      textureFormat = TFT_RGB565;
      t->texelBytes = tileIndex = 2;
      break;
   case MESA_FORMAT_L8:
      textureFormat = TFT_L8;
      t->texelBytes = tileIndex = 1;
      break;
   case MESA_FORMAT_I8:
      textureFormat = TFT_I8;
      t->texelBytes = tileIndex = 1;
      break;
   case MESA_FORMAT_A8:
      textureFormat = TFT_A8;
      t->texelBytes = tileIndex = 1;
      break;
   case MESA_FORMAT_RGB_DXT1:
      textureFormat = TFT_S3TC4Bit;
      tileIndex = TILE_INDEX_DXT1;
      t->texelBytes = 8;
      break;
   case MESA_FORMAT_RGBA_DXT1:
      textureFormat = TFT_S3TC4Bit;
      tileIndex = TILE_INDEX_DXT1;
      t->texelBytes = 8;
      break;
   case MESA_FORMAT_RGBA_DXT3:
      textureFormat =  TFT_S3TC4A4Bit;
      tileIndex = TILE_INDEX_DXTn;
      t->texelBytes = 16;
      break;
   case MESA_FORMAT_RGBA_DXT5:
      textureFormat = TFT_S3TC4CA4Bit;
      tileIndex = TILE_INDEX_DXTn;
      t->texelBytes = 16;
      break;
   default:
      _mesa_problem(imesa->glCtx, "Bad texture format in %s", __FUNCTION__);
      return;
   }
   t->hwFormat = textureFormat;

   /* Select tiling format depending on the chipset and texture format */
   if (imesa->savageScreen->chipset <= S3_SAVAGE4)
       t->tileInfo = &tileInfo_s3d_s4[tileIndex];
   else
       t->tileInfo = &tileInfo_pro[tileIndex];

   /* Compute which mipmap levels we really want to send to the hardware.
    */
   driCalculateTextureFirstLastLevel( &t->base );
   firstLevel = t->base.firstLevel;
   lastLevel  = t->base.lastLevel;

   /* Figure out the size now (and count the levels).  Upload won't be
    * done until later. If the number of tiles changes, it means that
    * this function is called for the first time on this tex object or
    * the image or the destination color format changed. So all tiles
    * are marked as dirty.
    */ 
   offset = 0;
   size = 1;
   for ( i = firstLevel ; i <= lastLevel && tObj->Image[0][i] ; i++ ) {
      GLuint nTiles;
      nTiles = savageTexImageTiles (image->Width2, image->Height2, t->tileInfo);
      if (t->image[i].nTiles != nTiles) {
	 GLuint words = (nTiles + 31) / 32;
	 if (t->image[i].nTiles != 0) {
	    free(t->image[i].dirtyTiles);
	 }
	 t->image[i].dirtyTiles = malloc(words*sizeof(GLuint));
	 memset(t->image[i].dirtyTiles, ~0, words*sizeof(GLuint));
      }
      t->image[i].nTiles = nTiles;

      t->image[i].offset = offset;

      image = tObj->Image[0][i];
      if (t->texelBytes >= 8)
	 size = savageCompressedTexImageSize (image->Width2, image->Height2,
					      t->texelBytes);
      else
	 size = savageTexImageSize (image->Width2, image->Height2,
				    t->texelBytes);
      offset += size;
   }

   t->base.lastLevel = i-1;
   t->base.totalSize = offset;
   /* the last three mipmap levels don't add to the offset. They are packed
    * into 64 pixels. */
   if (size == 0)
       t->base.totalSize += (t->texelBytes >= 8 ? 4 : 64) * t->texelBytes;
   /* 2k-aligned (really needed?) */
   t->base.totalSize = (t->base.totalSize + 2047UL) & ~2047UL;
}

void savageDestroyTexObj(savageContextPtr imesa, savageTexObjPtr t)
{
    GLuint i;

    /* Free dirty tiles bit vectors */
    for (i = 0; i < SAVAGE_TEX_MAXLEVELS; ++i) {
	if (t->image[i].nTiles)
	    free (t->image[i].dirtyTiles);
    }

    /* See if it was the driver's current object.
     */
    if ( imesa != NULL )
    { 
	for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ )
	{
	    if ( &t->base == imesa->CurrentTexObj[ i ] ) {
		assert( t->base.bound & (1 << i) );
		imesa->CurrentTexObj[ i ] = NULL;
	    }
	}
    }
}

/* Upload a texture's images to one of the texture heaps. May have to
 * eject our own and/or other client's texture objects to make room
 * for the upload.
 */
static void savageUploadTexImages( savageContextPtr imesa, savageTexObjPtr t )
{
   const GLint numLevels = t->base.lastLevel - t->base.firstLevel + 1;
   GLuint i;

   assert(t);

   LOCK_HARDWARE(imesa);
   
   /* Do we need to eject LRU texture objects?
    */
   if (!t->base.memBlock) {
      GLint heap;
      GLuint ofs;

      heap = driAllocateTexture(imesa->textureHeaps, imesa->lastTexHeap,
				(driTextureObject *)t);
      if (heap == -1) {
	  UNLOCK_HARDWARE(imesa);
	  return;
      }

      ofs = t->base.memBlock->ofs;
      t->setup.physAddr = imesa->savageScreen->textureOffset[heap] + ofs;
      t->bufAddr = (GLubyte *)imesa->savageScreen->texVirtual[heap] + ofs;
      imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; /* FIXME: really needed? */
   }

   /* Let the world know we've used this memory recently.
    */
   driUpdateTextureLRU( &t->base );
   UNLOCK_HARDWARE(imesa);

   if (t->base.dirty_images[0] || t->dirtySubImages) {
      if (SAVAGE_DEBUG & DEBUG_VERBOSE_TEX)
	 fprintf(stderr, "Texture upload: |");

      /* Heap timestamps are only reliable with Savage DRM 2.3.x or
       * later. Earlier versions had only 16 bit time stamps which
       * would wrap too frequently. */
      if (imesa->savageScreen->driScrnPriv->drm_version.minor >= 3) {
	  unsigned int heap = t->base.heap->heapId;
	  LOCK_HARDWARE(imesa);
	  savageWaitEvent (imesa, imesa->textureHeaps[heap]->timestamp);
      } else {
	  savageFlushVertices (imesa);
	  LOCK_HARDWARE(imesa);
	  savageFlushCmdBufLocked (imesa, GL_FALSE);
	  WAIT_IDLE_EMPTY_LOCKED(imesa);
      }

      for (i = 0 ; i < numLevels ; i++) {
         const GLint j = t->base.firstLevel + i;  /* the texObj's level */
	 if (t->base.dirty_images[0] & (1 << j)) {
	    savageMarkAllTiles(t, j);
	    if (SAVAGE_DEBUG & DEBUG_VERBOSE_TEX)
		fprintf (stderr, "*");
	 } else if (SAVAGE_DEBUG & DEBUG_VERBOSE_TEX) {
	    if (t->dirtySubImages & (1 << j))
	       fprintf (stderr, ".");
	    else
	       fprintf (stderr, " ");
	 }
	 if ((t->base.dirty_images[0] | t->dirtySubImages) & (1 << j))
	    savageUploadTexLevel( t, j );
      }

      UNLOCK_HARDWARE(imesa);
      t->base.dirty_images[0] = 0;
      t->dirtySubImages = 0;

      if (SAVAGE_DEBUG & DEBUG_VERBOSE_TEX)
	 fprintf(stderr, "|\n");
   }
}


static void
savage4_set_wrap_mode( savageContextPtr imesa, unsigned unit,
		      GLenum s_mode, GLenum t_mode )
{
    switch( s_mode ) {
    case GL_REPEAT:
	imesa->regs.s4.texCtrl[ unit ].ni.uMode = TAM_Wrap;
	break;
    case GL_CLAMP:
    case GL_CLAMP_TO_EDGE:
	imesa->regs.s4.texCtrl[ unit ].ni.uMode = TAM_Clamp;
	break;
    case GL_MIRRORED_REPEAT:
	imesa->regs.s4.texCtrl[ unit ].ni.uMode = TAM_Mirror;
	break;
    }

    switch( t_mode ) {
    case GL_REPEAT:
	imesa->regs.s4.texCtrl[ unit ].ni.vMode = TAM_Wrap;
	break;
    case GL_CLAMP:
    case GL_CLAMP_TO_EDGE:
	imesa->regs.s4.texCtrl[ unit ].ni.vMode = TAM_Clamp;
	break;
    case GL_MIRRORED_REPEAT:
	imesa->regs.s4.texCtrl[ unit ].ni.vMode = TAM_Mirror;
	break;
    }
}


/**
 * Sets the hardware bits for the specified GL texture filter modes.
 * 
 * \todo
 * Does the Savage4 have the ability to select the magnification filter?
 */
static void
savage4_set_filter_mode( savageContextPtr imesa, unsigned unit,
			 GLenum minFilter, GLenum magFilter )
{
    (void) magFilter;

    switch (minFilter) {
    case GL_NEAREST:
	imesa->regs.s4.texCtrl[ unit ].ni.filterMode   = TFM_Point;
	imesa->regs.s4.texCtrl[ unit ].ni.mipmapEnable = GL_FALSE;
	break;

    case GL_LINEAR:
	imesa->regs.s4.texCtrl[ unit ].ni.filterMode   = TFM_Bilin;
	imesa->regs.s4.texCtrl[ unit ].ni.mipmapEnable = GL_FALSE;
	break;

    case GL_NEAREST_MIPMAP_NEAREST:
	imesa->regs.s4.texCtrl[ unit ].ni.filterMode   = TFM_Point;
	imesa->regs.s4.texCtrl[ unit ].ni.mipmapEnable = GL_TRUE;
	break;

    case GL_LINEAR_MIPMAP_NEAREST:
	imesa->regs.s4.texCtrl[ unit ].ni.filterMode   = TFM_Bilin;
	imesa->regs.s4.texCtrl[ unit ].ni.mipmapEnable = GL_TRUE;
	break;

    case GL_NEAREST_MIPMAP_LINEAR:
    case GL_LINEAR_MIPMAP_LINEAR:
	imesa->regs.s4.texCtrl[ unit ].ni.filterMode   = TFM_Trilin;
	imesa->regs.s4.texCtrl[ unit ].ni.mipmapEnable = GL_TRUE;
	break;
    }
}


static void savageUpdateTex0State_s4( GLcontext *ctx )
{
   savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
   struct gl_texture_object	*tObj;
   struct gl_texture_image *image;
   savageTexObjPtr t;
   GLuint format;

   /* disable */
   imesa->regs.s4.texDescr.ni.tex0En = GL_FALSE;
   imesa->regs.s4.texBlendCtrl[0].ui = TBC_NoTexMap;
   imesa->regs.s4.texCtrl[0].ui = 0x20f040;
   if (ctx->Texture.Unit[0]._ReallyEnabled == 0)
      return;

   tObj = ctx->Texture.Unit[0]._Current;
   if ((ctx->Texture.Unit[0]._ReallyEnabled & ~(TEXTURE_1D_BIT|TEXTURE_2D_BIT))
       || tObj->Image[0][tObj->BaseLevel]->Border > 0) {
      /* 3D texturing enabled, or texture border - fallback */
      FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE);
      return;
   }

   /* Do 2D texture setup */

   t = tObj->DriverData;
   if (!t) {
      t = savageAllocTexObj( tObj );
      if (!t)
         return;
   }

   imesa->CurrentTexObj[0] = &t->base;
   t->base.bound |= 1;

   if (t->base.dirty_images[0] || t->dirtySubImages) {
       savageSetTexImages(imesa, tObj);
       savageUploadTexImages(imesa, t); 
   }
   
   driUpdateTextureLRU( &t->base );

   format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;

   switch (ctx->Texture.Unit[0].EnvMode) {
   case GL_REPLACE:
      imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE;
      switch(format)
      {
          case GL_LUMINANCE:
          case GL_RGB:
               imesa->regs.s4.texBlendCtrl[0].ui = TBC_Decal;
               break;

          case GL_LUMINANCE_ALPHA:
          case GL_RGBA:
          case GL_INTENSITY:
               imesa->regs.s4.texBlendCtrl[0].ui = TBC_Copy;
               break;

          case GL_ALPHA:
               imesa->regs.s4.texBlendCtrl[0].ui = TBC_CopyAlpha;
               break;
      }
       __HWEnvCombineSingleUnitScale(imesa, 0, 0,
				     &imesa->regs.s4.texBlendCtrl[0]);
      break;

    case GL_DECAL:
        imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE;
        switch (format)
        {
            case GL_RGB:
            case GL_LUMINANCE:
                imesa->regs.s4.texBlendCtrl[0].ui = TBC_Decal;
                break;

            case GL_RGBA:
            case GL_INTENSITY:
            case GL_LUMINANCE_ALPHA:
                imesa->regs.s4.texBlendCtrl[0].ui = TBC_DecalAlpha;
                break;

            /*
             GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_INTENSITY
             are undefined with GL_DECAL
            */

            case GL_ALPHA:
                imesa->regs.s4.texBlendCtrl[0].ui = TBC_CopyAlpha;
                break;
        }
        __HWEnvCombineSingleUnitScale(imesa, 0, 0,
				      &imesa->regs.s4.texBlendCtrl[0]);
        break;

    case GL_MODULATE:
        imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE;
        imesa->regs.s4.texBlendCtrl[0].ui = TBC_ModulAlpha;
        __HWEnvCombineSingleUnitScale(imesa, 0, 0,
				      &imesa->regs.s4.texBlendCtrl[0]);
        break;

    case GL_BLEND:
	imesa->regs.s4.texBlendColor.ui = imesa->texEnvColor;

        switch (format)
        {
            case GL_ALPHA:
                imesa->regs.s4.texBlendCtrl[0].ui = TBC_ModulAlpha;
                imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE;
                break;

            case GL_LUMINANCE:
            case GL_RGB:
                imesa->regs.s4.texBlendCtrl[0].ui = TBC_Blend0;
                imesa->regs.s4.texDescr.ni.tex1En = GL_TRUE;
                imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE;
                imesa->regs.s4.texDescr.ni.tex1Width  =
		    imesa->regs.s4.texDescr.ni.tex0Width;
                imesa->regs.s4.texDescr.ni.tex1Height =
		    imesa->regs.s4.texDescr.ni.tex0Height;
                imesa->regs.s4.texDescr.ni.tex1Fmt =
		    imesa->regs.s4.texDescr.ni.tex0Fmt;

		imesa->regs.s4.texAddr[1].ui = imesa->regs.s4.texAddr[0].ui;
		imesa->regs.s4.texBlendCtrl[1].ui = TBC_Blend1;

                imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_TRUE;
                imesa->bTexEn1 = GL_TRUE;
                break;

            case GL_LUMINANCE_ALPHA:
            case GL_RGBA:
                imesa->regs.s4.texBlendCtrl[0].ui = TBC_BlendAlpha0;
                imesa->regs.s4.texDescr.ni.tex1En = GL_TRUE;
                imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE;
                imesa->regs.s4.texDescr.ni.tex1Width  =
		    imesa->regs.s4.texDescr.ni.tex0Width;
                imesa->regs.s4.texDescr.ni.tex1Height =
		    imesa->regs.s4.texDescr.ni.tex0Height;
                imesa->regs.s4.texDescr.ni.tex1Fmt =
		    imesa->regs.s4.texDescr.ni.tex0Fmt;

		imesa->regs.s4.texAddr[1].ui = imesa->regs.s4.texAddr[0].ui;
		imesa->regs.s4.texBlendCtrl[1].ui = TBC_BlendAlpha1;

                imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_TRUE;
                imesa->bTexEn1 = GL_TRUE;
                break;

            case GL_INTENSITY:
                imesa->regs.s4.texBlendCtrl[0].ui = TBC_BlendInt0;
                imesa->regs.s4.texDescr.ni.tex1En = GL_TRUE;
                imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE;
                imesa->regs.s4.texDescr.ni.tex1Width  =
		    imesa->regs.s4.texDescr.ni.tex0Width;
                imesa->regs.s4.texDescr.ni.tex1Height =
		    imesa->regs.s4.texDescr.ni.tex0Height;
                imesa->regs.s4.texDescr.ni.tex1Fmt =
		    imesa->regs.s4.texDescr.ni.tex0Fmt;

		imesa->regs.s4.texAddr[1].ui = imesa->regs.s4.texAddr[0].ui;
		imesa->regs.s4.texBlendCtrl[1].ui = TBC_BlendInt1;

                imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_TRUE;
                imesa->regs.s4.texCtrl[0].ni.alphaArg1Invert = GL_TRUE;
                imesa->bTexEn1 = GL_TRUE;
                break;
        }
        __HWEnvCombineSingleUnitScale(imesa, 0, 0,
				      &imesa->regs.s4.texBlendCtrl[0]);
        break;

    case GL_ADD:
        imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE;
        switch (format)
        {
            case GL_ALPHA:
                imesa->regs.s4.texBlendCtrl[0].ui = TBC_ModulAlpha;
		break;

            case GL_LUMINANCE:
            case GL_RGB:
		imesa->regs.s4.texBlendCtrl[0].ui = TBC_Add;
		break;

            case GL_LUMINANCE_ALPHA:
            case GL_RGBA:
		imesa->regs.s4.texBlendCtrl[0].ui = TBC_Add;
		break;

            case GL_INTENSITY:
		imesa->regs.s4.texBlendCtrl[0].ui = TBC_AddAlpha;
		break;
	}
        __HWEnvCombineSingleUnitScale(imesa, 0, 0,
				      &imesa->regs.s4.texBlendCtrl[0]);
        break;

#if GL_ARB_texture_env_combine
    case GL_COMBINE_ARB:
        __HWParseTexEnvCombine(imesa, 0, &imesa->regs.s4.texCtrl[0],
			       &imesa->regs.s4.texBlendCtrl[0]);
        break;
#endif

   default:
      fprintf(stderr, "unknown tex env mode");
      exit(1);
      break;			
   }

    savage4_set_wrap_mode( imesa, 0, t->setup.sWrapMode, t->setup.tWrapMode );
    savage4_set_filter_mode( imesa, 0, t->setup.minFilter, t->setup.magFilter );

    if((ctx->Texture.Unit[0].LodBias !=0.0F) ||
       (imesa->regs.s4.texCtrl[0].ni.dBias != 0))
    {
	int bias = (int)(ctx->Texture.Unit[0].LodBias * 32.0) +
	    SAVAGE4_LOD_OFFSET;
	if (bias < -256)
	    bias = -256;
	else if (bias > 255)
	    bias = 255;
	imesa->regs.s4.texCtrl[0].ni.dBias = bias & 0x1ff;
    }

    image = tObj->Image[0][tObj->BaseLevel];
    imesa->regs.s4.texDescr.ni.tex0En = GL_TRUE;
    imesa->regs.s4.texDescr.ni.tex0Width  = image->WidthLog2;
    imesa->regs.s4.texDescr.ni.tex0Height = image->HeightLog2;
    imesa->regs.s4.texDescr.ni.tex0Fmt = t->hwFormat;
    imesa->regs.s4.texCtrl[0].ni.dMax = t->base.lastLevel - t->base.firstLevel;

    if (imesa->regs.s4.texDescr.ni.tex1En)
        imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE;

    imesa->regs.s4.texAddr[0].ui = (u_int32_t) t->setup.physAddr | 0x2;
    if(t->base.heap->heapId == SAVAGE_AGP_HEAP)
	imesa->regs.s4.texAddr[0].ui |= 0x1;
    
    return;
}
static void savageUpdateTex1State_s4( GLcontext *ctx )
{
   savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
   struct gl_texture_object	*tObj;
   struct gl_texture_image *image;
   savageTexObjPtr t;
   GLuint format;

   /* disable */
   if(imesa->bTexEn1)
   {
       imesa->bTexEn1 = GL_FALSE;
       return;
   }

   imesa->regs.s4.texDescr.ni.tex1En = GL_FALSE;
   imesa->regs.s4.texBlendCtrl[1].ui = TBC_NoTexMap1;
   imesa->regs.s4.texCtrl[1].ui = 0x20f040;
   imesa->regs.s4.texDescr.ni.texBLoopEn = GL_FALSE;
   if (ctx->Texture.Unit[1]._ReallyEnabled == 0)
      return;

   tObj = ctx->Texture.Unit[1]._Current;

   if ((ctx->Texture.Unit[1]._ReallyEnabled & ~(TEXTURE_1D_BIT|TEXTURE_2D_BIT))
       || tObj->Image[0][tObj->BaseLevel]->Border > 0) {
      /* 3D texturing enabled, or texture border - fallback */
      FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE);
      return;
   }

   /* Do 2D texture setup */

   t = tObj->DriverData;
   if (!t) {
      t = savageAllocTexObj( tObj );
      if (!t)
         return;
   }
    
   imesa->CurrentTexObj[1] = &t->base;

   t->base.bound |= 2;

   if (t->base.dirty_images[0] || t->dirtySubImages) {
       savageSetTexImages(imesa, tObj);
       savageUploadTexImages(imesa, t);
   }
   
   driUpdateTextureLRU( &t->base );

   format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;

   switch (ctx->Texture.Unit[1].EnvMode) {
   case GL_REPLACE:
        imesa->regs.s4.texCtrl[1].ni.clrArg1Invert = GL_FALSE;
        switch (format)
        {
            case GL_LUMINANCE:
            case GL_RGB:
                imesa->regs.s4.texBlendCtrl[1].ui = TBC_Decal;
                break;

            case GL_LUMINANCE_ALPHA:
            case GL_INTENSITY:
            case GL_RGBA:
                imesa->regs.s4.texBlendCtrl[1].ui = TBC_Copy;
                break;

            case GL_ALPHA:
                imesa->regs.s4.texBlendCtrl[1].ui = TBC_CopyAlpha1;
                break;
        }
        __HWEnvCombineSingleUnitScale(imesa, 0, 1, &imesa->regs.s4.texBlendCtrl);
      break;
   case GL_MODULATE:
       imesa->regs.s4.texCtrl[1].ni.clrArg1Invert = GL_FALSE;
       imesa->regs.s4.texBlendCtrl[1].ui = TBC_ModulAlpha1;
       __HWEnvCombineSingleUnitScale(imesa, 0, 1, &imesa->regs.s4.texBlendCtrl);
       break;

    case GL_ADD:
        imesa->regs.s4.texCtrl[1].ni.clrArg1Invert = GL_FALSE;
        switch (format)
        {
            case GL_ALPHA:
                imesa->regs.s4.texBlendCtrl[1].ui = TBC_ModulAlpha1;
		break;

            case GL_LUMINANCE:
            case GL_RGB:
		imesa->regs.s4.texBlendCtrl[1].ui = TBC_Add1;
		break;

            case GL_LUMINANCE_ALPHA:
            case GL_RGBA:
		imesa->regs.s4.texBlendCtrl[1].ui = TBC_Add1;
		break;

            case GL_INTENSITY:
		imesa->regs.s4.texBlendCtrl[1].ui = TBC_AddAlpha1;
		break;
	}
        __HWEnvCombineSingleUnitScale(imesa, 0, 1, &imesa->regs.s4.texBlendCtrl);
        break;

#if GL_ARB_texture_env_combine
    case GL_COMBINE_ARB:
        __HWParseTexEnvCombine(imesa, 1, &texCtrl, &imesa->regs.s4.texBlendCtrl);
        break;
#endif

   case GL_DECAL:
        imesa->regs.s4.texCtrl[1].ni.clrArg1Invert = GL_FALSE;

        switch (format)
        {
            case GL_LUMINANCE:
            case GL_RGB:
                imesa->regs.s4.texBlendCtrl[1].ui = TBC_Decal1;
                break;
            case GL_LUMINANCE_ALPHA:
            case GL_INTENSITY:
            case GL_RGBA:
                imesa->regs.s4.texBlendCtrl[1].ui = TBC_DecalAlpha1;
                break;

                /*
                // GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_INTENSITY
                // are undefined with GL_DECAL
                */
            case GL_ALPHA:
                imesa->regs.s4.texBlendCtrl[1].ui = TBC_CopyAlpha1;
                break;
        }
        __HWEnvCombineSingleUnitScale(imesa, 0, 1, &imesa->regs.s4.texBlendCtrl);
        break;

   case GL_BLEND:
        if (format == GL_LUMINANCE)
        {
            /*
            // This is a hack for GLQuake, invert.
            */
            imesa->regs.s4.texCtrl[1].ni.clrArg1Invert = GL_TRUE;
            imesa->regs.s4.texBlendCtrl[1].ui = 0;
        }
        __HWEnvCombineSingleUnitScale(imesa, 0, 1, &imesa->regs.s4.texBlendCtrl);
      break;

   default:
      fprintf(stderr, "unknown tex 1 env mode\n");
      exit(1);
      break;			
   }

    savage4_set_wrap_mode( imesa, 1, t->setup.sWrapMode, t->setup.tWrapMode );
    savage4_set_filter_mode( imesa, 1, t->setup.minFilter, t->setup.magFilter );

    if((ctx->Texture.Unit[1].LodBias !=0.0F) ||
       (imesa->regs.s4.texCtrl[1].ni.dBias != 0))
    {
	int bias = (int)(ctx->Texture.Unit[1].LodBias * 32.0) +
	    SAVAGE4_LOD_OFFSET;
	if (bias < -256)
	    bias = -256;
	else if (bias > 255)
	    bias = 255;
	imesa->regs.s4.texCtrl[1].ni.dBias = bias & 0x1ff;
    }

    image = tObj->Image[0][tObj->BaseLevel];
    imesa->regs.s4.texDescr.ni.tex1En = GL_TRUE;
    imesa->regs.s4.texDescr.ni.tex1Width  = image->WidthLog2;
    imesa->regs.s4.texDescr.ni.tex1Height = image->HeightLog2;
    imesa->regs.s4.texDescr.ni.tex1Fmt = t->hwFormat;
    imesa->regs.s4.texCtrl[1].ni.dMax = t->base.lastLevel - t->base.firstLevel;
    imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE;

    imesa->regs.s4.texAddr[1].ui = (u_int32_t) t->setup.physAddr | 2;
    if(t->base.heap->heapId == SAVAGE_AGP_HEAP)
	imesa->regs.s4.texAddr[1].ui |= 0x1;
}
static void savageUpdateTexState_s3d( GLcontext *ctx )
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    struct gl_texture_object *tObj;
    struct gl_texture_image *image;
    savageTexObjPtr t;
    GLuint format;

    /* disable */
    imesa->regs.s3d.texCtrl.ui = 0;
    imesa->regs.s3d.texCtrl.ni.texEn = GL_FALSE;
    imesa->regs.s3d.texCtrl.ni.dBias = 0x08;
    imesa->regs.s3d.texCtrl.ni.texXprEn = GL_TRUE;
    if (ctx->Texture.Unit[0]._ReallyEnabled == 0)
	return;

    tObj = ctx->Texture.Unit[0]._Current;
    if ((ctx->Texture.Unit[0]._ReallyEnabled & ~(TEXTURE_1D_BIT|TEXTURE_2D_BIT))
	|| tObj->Image[0][tObj->BaseLevel]->Border > 0) {
	/* 3D texturing enabled, or texture border - fallback */
	FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE);
	return;
    }

    /* Do 2D texture setup */
    t = tObj->DriverData;
    if (!t) {
	t = savageAllocTexObj( tObj );
	if (!t)
	    return;
    }

    imesa->CurrentTexObj[0] = &t->base;
    t->base.bound |= 1;

    if (t->base.dirty_images[0] || t->dirtySubImages) {
	savageSetTexImages(imesa, tObj);
	savageUploadTexImages(imesa, t);
    }

    driUpdateTextureLRU( &t->base );

    format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;

    /* FIXME: copied from utah-glx, probably needs some tuning */
    switch (ctx->Texture.Unit[0].EnvMode) {
    case GL_DECAL:
	imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_DECALALPHA_S3D;
	break;
    case GL_REPLACE:
	switch (format) {
	case GL_ALPHA: /* FIXME */
	    imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = 1;
	    break;
	case GL_LUMINANCE_ALPHA:
	case GL_RGBA:
	    imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = 4;
	    break;
	case GL_RGB:
	case GL_LUMINANCE:
	    imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_DECAL_S3D;
	    break;
	case GL_INTENSITY:
	    imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_COPY_S3D;
	}
	break;
    case GL_BLEND: /* hardware can't do GL_BLEND */
	FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE);
	return;
    case GL_MODULATE:
	imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_MODULATEALPHA_S3D;
	break;
    default:
	fprintf(stderr, "unknown tex env mode\n");
	/*exit(1);*/
	break;			
    }

    /* The Savage3D can't handle different wrapping modes in s and t.
     * If they are not the same, fall back to software. */
    if (t->setup.sWrapMode != t->setup.tWrapMode) {
	FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE);
	return;
    }
    imesa->regs.s3d.texCtrl.ni.uWrapEn = 0;
    imesa->regs.s3d.texCtrl.ni.vWrapEn = 0;
    imesa->regs.s3d.texCtrl.ni.wrapMode =
	(t->setup.sWrapMode == GL_REPEAT) ? TAM_Wrap : TAM_Clamp;

    switch (t->setup.minFilter) {
    case GL_NEAREST:
	imesa->regs.s3d.texCtrl.ni.filterMode    = TFM_Point;
	imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_TRUE;
	break;

    case GL_LINEAR:
	imesa->regs.s3d.texCtrl.ni.filterMode    = TFM_Bilin;
	imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_TRUE;
	break;

    case GL_NEAREST_MIPMAP_NEAREST:
	imesa->regs.s3d.texCtrl.ni.filterMode    = TFM_Point;
	imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_FALSE;
	break;

    case GL_LINEAR_MIPMAP_NEAREST:
	imesa->regs.s3d.texCtrl.ni.filterMode    = TFM_Bilin;
	imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_FALSE;
	break;

    case GL_NEAREST_MIPMAP_LINEAR:
    case GL_LINEAR_MIPMAP_LINEAR:
	imesa->regs.s3d.texCtrl.ni.filterMode    = TFM_Trilin;
	imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_FALSE;
	break;
    }

    /* There is no way to specify a maximum mipmap level. We may have to
       disable mipmapping completely. */
    /*
    if (t->max_level < t->image[0].image->WidthLog2 ||
	t->max_level < t->image[0].image->HeightLog2) {
	texCtrl.ni.mipmapEnable = GL_TRUE;
	if (texCtrl.ni.filterMode == TFM_Trilin)
	    texCtrl.ni.filterMode = TFM_Bilin;
	texCtrl.ni.filterMode = TFM_Point;
    }
    */

    if((ctx->Texture.Unit[0].LodBias !=0.0F) ||
       (imesa->regs.s3d.texCtrl.ni.dBias != 0))
    {
	int bias = (int)(ctx->Texture.Unit[0].LodBias * 16.0);
	if (bias < -256)
	    bias = -256;
	else if (bias > 255)
	    bias = 255;
	imesa->regs.s3d.texCtrl.ni.dBias = bias & 0x1ff;
    }

    image = tObj->Image[0][tObj->BaseLevel];
    imesa->regs.s3d.texCtrl.ni.texEn = GL_TRUE;
    imesa->regs.s3d.texDescr.ni.texWidth  = image->WidthLog2;
    imesa->regs.s3d.texDescr.ni.texHeight = image->HeightLog2;
    assert (t->hwFormat <= 7);
    imesa->regs.s3d.texDescr.ni.texFmt = t->hwFormat;

    imesa->regs.s3d.texAddr.ui = (u_int32_t) t->setup.physAddr | 2;
    if(t->base.heap->heapId == SAVAGE_AGP_HEAP)
	imesa->regs.s3d.texAddr.ui |= 0x1;
}


static void savageTimestampTextures( savageContextPtr imesa )
{
   /* Timestamp current texture objects for texture heap aging.
    * Only useful with long-lived 32-bit event tags available
    * with Savage DRM 2.3.x or later. */
   if ((imesa->CurrentTexObj[0] || imesa->CurrentTexObj[1]) &&
       imesa->savageScreen->driScrnPriv->drm_version.minor >= 3) {
       unsigned int e;
       FLUSH_BATCH(imesa);
       e = savageEmitEvent(imesa, SAVAGE_WAIT_3D);
       if (imesa->CurrentTexObj[0])
	   imesa->CurrentTexObj[0]->timestamp = e;
       if (imesa->CurrentTexObj[1])
	   imesa->CurrentTexObj[1]->timestamp = e;
   }
}


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

   /* When a texture is about to change or be disabled, timestamp the
    * old texture(s). We'll have to wait for this time stamp before
    * uploading anything to the same texture heap.
    */
   if ((imesa->CurrentTexObj[0] && ctx->Texture.Unit[0]._ReallyEnabled &&
	ctx->Texture.Unit[0]._Current->DriverData != imesa->CurrentTexObj[0]) ||
       (imesa->CurrentTexObj[1] && ctx->Texture.Unit[1]._ReallyEnabled &&
	ctx->Texture.Unit[1]._Current->DriverData != imesa->CurrentTexObj[1]) ||
       (imesa->CurrentTexObj[0] && !ctx->Texture.Unit[0]._ReallyEnabled) ||
       (imesa->CurrentTexObj[1] && !ctx->Texture.Unit[1]._ReallyEnabled))
       savageTimestampTextures(imesa);

   if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->bound &= ~1;
   if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->bound &= ~2;
   imesa->CurrentTexObj[0] = 0;
   imesa->CurrentTexObj[1] = 0;   
   savageUpdateTex0State_s4( ctx );
   savageUpdateTex1State_s4( ctx );
   imesa->dirty |= (SAVAGE_UPLOAD_TEX0 | 
		    SAVAGE_UPLOAD_TEX1);
}
static void savageUpdateTextureState_s3d( GLcontext *ctx )
{
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);

   /* When a texture is about to change or be disabled, timestamp the
    * old texture(s). We'll have to wait for this time stamp before
    * uploading anything to the same texture heap.
    */
    if ((imesa->CurrentTexObj[0] && ctx->Texture.Unit[0]._ReallyEnabled &&
	 ctx->Texture.Unit[0]._Current->DriverData != imesa->CurrentTexObj[0]) ||
	(imesa->CurrentTexObj[0] && !ctx->Texture.Unit[0]._ReallyEnabled))
	savageTimestampTextures(imesa);

    if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->bound &= ~1;
    imesa->CurrentTexObj[0] = 0;
    savageUpdateTexState_s3d( ctx );
    imesa->dirty |= (SAVAGE_UPLOAD_TEX0);
}
void savageUpdateTextureState( GLcontext *ctx)
{
    savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
    FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_FALSE);
    FALLBACK(ctx, SAVAGE_FALLBACK_PROJ_TEXTURE, GL_FALSE);
    if (imesa->savageScreen->chipset >= S3_SAVAGE4)
	savageUpdateTextureState_s4 (ctx);
    else
	savageUpdateTextureState_s3d (ctx);
}



/*****************************************
 * DRIVER functions
 *****************************************/

static void savageTexEnv( GLcontext *ctx, GLenum target, 
			GLenum pname, const GLfloat *param )
{
   savageContextPtr imesa = SAVAGE_CONTEXT( ctx );

   if (pname == GL_TEXTURE_ENV_MODE) {

      imesa->new_state |= SAVAGE_NEW_TEXTURE;

   } else if (pname == GL_TEXTURE_ENV_COLOR) {

      struct gl_texture_unit *texUnit = 
	 &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
      const GLfloat *fc = texUnit->EnvColor;
      GLuint r, g, b, a;
      CLAMPED_FLOAT_TO_UBYTE(r, fc[0]);
      CLAMPED_FLOAT_TO_UBYTE(g, fc[1]);
      CLAMPED_FLOAT_TO_UBYTE(b, fc[2]);
      CLAMPED_FLOAT_TO_UBYTE(a, fc[3]);

      imesa->texEnvColor = ((a << 24) | (r << 16) | 
			    (g <<  8) | (b <<  0));
    

   } 
}

/* Update the heap's time stamp, so the new image is not uploaded
 * while the old one is still in use. If the texture that is going to
 * be changed is currently bound, we need to timestamp the texture
 * first. */
static void savageTexImageChanged (savageTexObjPtr t) {
    if (t->base.heap) {
	if (t->base.bound)
	    savageTimestampTextures(
		(savageContextPtr)t->base.heap->driverContext);
	if (t->base.timestamp > t->base.heap->timestamp)
	    t->base.heap->timestamp = t->base.timestamp;
    }
}

static void savageTexImage1D( GLcontext *ctx, GLenum target, GLint level,
			      GLint internalFormat,
			      GLint width, GLint border,
			      GLenum format, GLenum type, const GLvoid *pixels,
			      const struct gl_pixelstore_attrib *packing,
			      struct gl_texture_object *texObj,
			      struct gl_texture_image *texImage )
{
   savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData;
   if (t) {
      savageTexImageChanged (t);
   } else {
      t = savageAllocTexObj(texObj);
      if (!t) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
         return;
      }
   }
   _mesa_store_teximage1d( ctx, target, level, internalFormat,
			   width, border, format, type,
			   pixels, packing, texObj, texImage );
   t->base.dirty_images[0] |= (1 << level);
   SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE;
}

static void savageTexSubImage1D( GLcontext *ctx, 
				 GLenum target,
				 GLint level,	
				 GLint xoffset,
				 GLsizei width,
				 GLenum format, GLenum type,
				 const GLvoid *pixels,
				 const struct gl_pixelstore_attrib *packing,
				 struct gl_texture_object *texObj,
				 struct gl_texture_image *texImage )
{
   savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData;
   assert( t ); /* this _should_ be true */
   if (t) {
      savageTexImageChanged (t);
      savageMarkDirtyTiles(t, level, texImage->Width2, 1,
			   xoffset, 0, width, 1);
   } else {
      t = savageAllocTexObj(texObj);
      if (!t) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
         return;
      }
      t->base.dirty_images[0] |= (1 << level);
   }
   _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, 
			     format, type, pixels, packing, texObj,
			     texImage);
   t->dirtySubImages |= (1 << level);
   SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE;
}

static void savageTexImage2D( GLcontext *ctx, GLenum target, GLint level,
			      GLint internalFormat,
			      GLint width, GLint height, GLint border,
			      GLenum format, GLenum type, const GLvoid *pixels,
			      const struct gl_pixelstore_attrib *packing,
			      struct gl_texture_object *texObj,
			      struct gl_texture_image *texImage )
{
   savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData;
   if (t) {
      savageTexImageChanged (t);
   } else {
      t = savageAllocTexObj(texObj);
      if (!t) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
         return;
      }
   }
   _mesa_store_teximage2d( ctx, target, level, internalFormat,
			   width, height, border, format, type,
			   pixels, packing, texObj, texImage );
   t->base.dirty_images[0] |= (1 << level);
   SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE;
}

static void savageTexSubImage2D( GLcontext *ctx, 
				 GLenum target,
				 GLint level,	
				 GLint xoffset, GLint yoffset,
				 GLsizei width, GLsizei height,
				 GLenum format, GLenum type,
				 const GLvoid *pixels,
				 const struct gl_pixelstore_attrib *packing,
				 struct gl_texture_object *texObj,
				 struct gl_texture_image *texImage )
{
   savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData;
   assert( t ); /* this _should_ be true */
   if (t) {
      savageTexImageChanged (t);
      savageMarkDirtyTiles(t, level, texImage->Width2, texImage->Height2,
			   xoffset, yoffset, width, height);
   } else {
      t = savageAllocTexObj(texObj);
      if (!t) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
         return;
      }
      t->base.dirty_images[0] |= (1 << level);
   }
   _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, 
			     height, format, type, pixels, packing, texObj,
			     texImage);
   t->dirtySubImages |= (1 << level);
   SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE;
}

static void
savageCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
			    GLint internalFormat,
			    GLint width, GLint height, GLint border,
			    GLsizei imageSize, const GLvoid *data,
			    struct gl_texture_object *texObj,
			    struct gl_texture_image *texImage )
{
   savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData;
   if (t) {
      savageTexImageChanged (t);
   } else {
      t = savageAllocTexObj(texObj);
      if (!t) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
         return;
      }
   }
   _mesa_store_compressed_teximage2d( ctx, target, level, internalFormat,
				      width, height, border, imageSize,
				      data, texObj, texImage );
   t->base.dirty_images[0] |= (1 << level);
   SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE;
}

static void
savageCompressedTexSubImage2D( GLcontext *ctx, 
			       GLenum target,
			       GLint level,	
			       GLint xoffset, GLint yoffset,
			       GLsizei width, GLsizei height,
			       GLenum format, GLsizei imageSize,
			       const GLvoid *data,
			       struct gl_texture_object *texObj,
			       struct gl_texture_image *texImage )
{
   savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData;
   assert( t ); /* this _should_ be true */
   if (t) {
      savageTexImageChanged (t);
      savageMarkDirtyTiles(t, level, texImage->Width2, texImage->Height2,
			   xoffset, yoffset, width, height);
   } else {
      t = savageAllocTexObj(texObj);
      if (!t) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
         return;
      }
      t->base.dirty_images[0] |= (1 << level);
   }
   _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, yoffset,
					width, height, format, imageSize,
					data, texObj, texImage);
   t->dirtySubImages |= (1 << level);
   SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE;
}

static void savageTexParameter( GLcontext *ctx, GLenum target,
			      struct gl_texture_object *tObj,
			      GLenum pname, const GLfloat *params )
{
   savageTexObjPtr t = (savageTexObjPtr) tObj->DriverData;
   savageContextPtr imesa = SAVAGE_CONTEXT( ctx );

   if (!t || (target != GL_TEXTURE_1D && target != GL_TEXTURE_2D))
      return;

   switch (pname) {
   case GL_TEXTURE_MIN_FILTER:
   case GL_TEXTURE_MAG_FILTER:
      savageSetTexFilter(t,tObj->MinFilter,tObj->MagFilter);
      break;

   case GL_TEXTURE_WRAP_S:
   case GL_TEXTURE_WRAP_T:
      savageSetTexWrapping(t,tObj->WrapS,tObj->WrapT);
      break;
  
   case GL_TEXTURE_BORDER_COLOR:
      savageSetTexBorderColor(t,tObj->_BorderChan);
      break;

   default:
      return;
   }

   imesa->new_state |= SAVAGE_NEW_TEXTURE;
}

static void savageBindTexture( GLcontext *ctx, GLenum target,
			       struct gl_texture_object *tObj )
{
   savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
   
   assert( (target != GL_TEXTURE_1D && target != GL_TEXTURE_2D) ||
	   (tObj->DriverData != NULL) );

   imesa->new_state |= SAVAGE_NEW_TEXTURE;
}

static void savageDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
{
   driTextureObject *t = (driTextureObject *)tObj->DriverData;
   savageContextPtr imesa = SAVAGE_CONTEXT( ctx );

   if (t) {
      if (t->bound)
	 savageTimestampTextures(imesa);

      driDestroyTextureObject(t);
   }
   /* Free mipmap images and the texture object itself */
   _mesa_delete_texture_object(ctx, tObj);
}


static struct gl_texture_object *
savageNewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
{
    struct gl_texture_object *obj;
    obj = _mesa_new_texture_object(ctx, name, target);
    savageAllocTexObj( obj );

    return obj;
}

void savageDDInitTextureFuncs( struct dd_function_table *functions )
{
   functions->TexEnv = savageTexEnv;
   functions->ChooseTextureFormat = savageChooseTextureFormat;
   functions->TexImage1D = savageTexImage1D;
   functions->TexSubImage1D = savageTexSubImage1D;
   functions->TexImage2D = savageTexImage2D;
   functions->TexSubImage2D = savageTexSubImage2D;
   functions->CompressedTexImage2D = savageCompressedTexImage2D;
   functions->CompressedTexSubImage2D = savageCompressedTexSubImage2D;
   functions->BindTexture = savageBindTexture;
   functions->NewTextureObject = savageNewTextureObject;
   functions->DeleteTexture = savageDeleteTexture;
   functions->IsTextureResident = driIsTextureResident;
   functions->TexParameter = savageTexParameter;

   /* Texel fetching with our custom texture formats works just like
    * the standard argb formats. */
   _savage_texformat_a1114444.FetchTexel1D = _mesa_texformat_argb4444.FetchTexel1D;
   _savage_texformat_a1114444.FetchTexel2D = _mesa_texformat_argb4444.FetchTexel2D;
   _savage_texformat_a1114444.FetchTexel3D = _mesa_texformat_argb4444.FetchTexel3D;
   _savage_texformat_a1114444.FetchTexel1Df= _mesa_texformat_argb4444.FetchTexel1Df;
   _savage_texformat_a1114444.FetchTexel2Df= _mesa_texformat_argb4444.FetchTexel2Df;
   _savage_texformat_a1114444.FetchTexel3Df= _mesa_texformat_argb4444.FetchTexel3Df;

   _savage_texformat_a1118888.FetchTexel1D = _mesa_texformat_argb8888.FetchTexel1D;
   _savage_texformat_a1118888.FetchTexel2D = _mesa_texformat_argb8888.FetchTexel2D;
   _savage_texformat_a1118888.FetchTexel3D = _mesa_texformat_argb8888.FetchTexel3D;
   _savage_texformat_a1118888.FetchTexel1Df= _mesa_texformat_argb8888.FetchTexel1Df;
   _savage_texformat_a1118888.FetchTexel2Df= _mesa_texformat_argb8888.FetchTexel2Df;
   _savage_texformat_a1118888.FetchTexel3Df= _mesa_texformat_argb8888.FetchTexel3Df;
}
