/* -*- 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_tex.c,v 1.7 2002/11/05 17:46:10 tsi 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 "enums.h"
#include "image.h"
#include "mipmap.h"
#include "texcompress.h"
#include "texformat.h"
#include "teximage.h"
#include "texstore.h"
#include "texobj.h"
#include "tdfx_context.h"
#include "tdfx_tex.h"
#include "tdfx_texman.h"


/* no borders! can't halve 1x1! (stride > width * comp) not allowed */
static void
_mesa_halve2x2_teximage2d ( GLcontext *ctx,
			    struct gl_texture_image *texImage,
			    GLuint bytesPerPixel,
			    GLint srcWidth, GLint srcHeight,
			    const GLvoid *srcImage, GLvoid *dstImage )
{
   GLint i, j, k;
   GLint dstWidth = srcWidth / 2;
   GLint dstHeight = srcHeight / 2;
   GLint srcRowStride = srcWidth * bytesPerPixel;
   GLubyte *src = (GLubyte *)srcImage;
   GLubyte *dst = dstImage;
   GLuint dstImageOffsets = 0;

   GLuint bpt = 0;
   GLubyte *_s = NULL;
   GLubyte *_d = NULL;
   GLenum _t = 0;

   if (texImage->TexFormat->MesaFormat == MESA_FORMAT_RGB565) {
      _t = GL_UNSIGNED_SHORT_5_6_5_REV;
      bpt = bytesPerPixel;
   } else if (texImage->TexFormat->MesaFormat == MESA_FORMAT_ARGB4444) {
      _t = GL_UNSIGNED_SHORT_4_4_4_4_REV;
      bpt = bytesPerPixel;
   } else if (texImage->TexFormat->MesaFormat == MESA_FORMAT_ARGB1555) {
      _t = GL_UNSIGNED_SHORT_1_5_5_5_REV;
      bpt = bytesPerPixel;
   }
   if (bpt) {
      bytesPerPixel = 4;
      srcRowStride = srcWidth * bytesPerPixel;
      if (dstWidth == 0) {
         dstWidth = 1;
      }
      if (dstHeight == 0) {
         dstHeight = 1;
      }
      _s = src = MALLOC(srcRowStride * srcHeight);
      _d = dst = MALLOC(dstWidth * bytesPerPixel * dstHeight);
      _mesa_texstore_rgba8888(ctx, 2, GL_RGBA,
                              &_mesa_texformat_rgba8888_rev, src,
                              0, 0, 0, /* dstX/Y/Zoffset */
                              srcRowStride, /* dstRowStride */
                              &dstImageOffsets,
                              srcWidth, srcHeight, 1,
                              texImage->_BaseFormat, _t, srcImage, &ctx->DefaultPacking);
   }

   if (srcHeight == 1) {
      for (i = 0; i < dstWidth; i++) {
         for (k = 0; k < bytesPerPixel; k++) {
            dst[0] = (src[0] + src[bytesPerPixel] + 1) / 2;
            src++;
            dst++;
         }
         src += bytesPerPixel;
      }
   } else if (srcWidth == 1) {
      for (j = 0; j < dstHeight; j++) {
         for (k = 0; k < bytesPerPixel; k++) {
            dst[0] = (src[0] + src[srcRowStride] + 1) / 2;
            src++;
            dst++;
         }
         src += srcRowStride;
      }
   } else {
      for (j = 0; j < dstHeight; j++) {
         for (i = 0; i < dstWidth; i++) {
            for (k = 0; k < bytesPerPixel; k++) {
               dst[0] = (src[0] +
                         src[bytesPerPixel] +
                         src[srcRowStride] +
                         src[srcRowStride + bytesPerPixel] + 2) / 4;
               src++;
               dst++;
            }
            src += bytesPerPixel;
         }
         src += srcRowStride;
      }
   }

   if (bpt) {
      src = _s;
      dst = _d;
      texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
                                      texImage->TexFormat, dstImage,
                                      0, 0, 0, /* dstX/Y/Zoffset */
                                      dstWidth * bpt,
                                      &dstImageOffsets,
                                      dstWidth, dstHeight, 1,
                                      GL_BGRA, CHAN_TYPE, dst, &ctx->DefaultPacking);
      FREE(dst);
      FREE(src);
   }
}


static int
logbase2(int n)
{
    GLint i = 1;
    GLint log2 = 0;

    if (n < 0) {
        return -1;
    }

    while (n > i) {
        i *= 2;
        log2++;
    }
    if (i != n) {
        return -1;
    }
    else {
        return log2;
    }
}


/*
 * Compute various texture image parameters.
 * Input:  w, h - source texture width and height
 * Output:  lodlevel - Glide lod level token for the larger texture dimension
 *          aspectratio - Glide aspect ratio token
 *          sscale - S scale factor used during triangle setup
 *          tscale - T scale factor used during triangle setup
 *          wscale - OpenGL -> Glide image width scale factor
 *          hscale - OpenGL -> Glide image height scale factor
 *
 * Sample results:
 *      w    h       lodlevel               aspectRatio
 *     128  128  GR_LOD_LOG2_128 (=7)  GR_ASPECT_LOG2_1x1 (=0)
 *      64   64  GR_LOD_LOG2_64 (=6)   GR_ASPECT_LOG2_1x1 (=0)
 *      64   32  GR_LOD_LOG2_64 (=6)   GR_ASPECT_LOG2_2x1 (=1)
 *      32   64  GR_LOD_LOG2_64 (=6)   GR_ASPECT_LOG2_1x2 (=-1)
 *      32   32  GR_LOD_LOG2_32 (=5)   GR_ASPECT_LOG2_1x1 (=0)
 */
static void
tdfxTexGetInfo(const GLcontext *ctx, int w, int h,
               GrLOD_t *lodlevel, GrAspectRatio_t *aspectratio,
               float *sscale, float *tscale,
               int *wscale, int *hscale)
{
    int logw, logh, ar, lod, ws, hs;
    float s, t;

    ASSERT(w >= 1);
    ASSERT(h >= 1);

    logw = logbase2(w);
    logh = logbase2(h);
    ar = logw - logh;  /* aspect ratio = difference in log dimensions */
    s = t = 256.0;
    ws = hs = 1;

    /* Hardware only allows a maximum aspect ratio of 8x1, so handle
       |ar| > 3 by scaling the image and using an 8x1 aspect ratio */
    if (ar >= 0) {
        ASSERT(w >= h);
        lod = logw;
        if (ar <= GR_ASPECT_LOG2_8x1) {
            t = 256 >> ar;
        }
        else {
            /* have to stretch image height */
            t = 32.0;
            hs = 1 << (ar - 3);
            ar = GR_ASPECT_LOG2_8x1;
        }
    }
    else {
        ASSERT(w < h);
        lod = logh;
        if (ar >= GR_ASPECT_LOG2_1x8) {
            s = 256 >> -ar;
        }
        else {
            /* have to stretch image width */
            s = 32.0;
            ws = 1 << (-ar - 3);
            ar = GR_ASPECT_LOG2_1x8;
        }
    }

    if (lodlevel)
        *lodlevel = (GrLOD_t) lod;
    if (aspectratio)
        *aspectratio = (GrAspectRatio_t) ar;
    if (sscale)
        *sscale = s;
    if (tscale)
        *tscale = t;
    if (wscale)
        *wscale = ws;
    if (hscale)
        *hscale = hs;
}


/*
 * We need to call this when a texture object's minification filter
 * or texture image sizes change.
 */
static void RevalidateTexture(GLcontext *ctx, struct gl_texture_object *tObj)
{
    tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
    GLint minl, maxl;

    if (!ti)
       return;

    minl = maxl = tObj->BaseLevel;

    if (tObj->Image[0][minl]) {
       maxl = MIN2(tObj->MaxLevel, tObj->Image[0][minl]->MaxLog2);

       /* compute largeLodLog2, aspect ratio and texcoord scale factors */
       tdfxTexGetInfo(ctx, tObj->Image[0][minl]->Width, tObj->Image[0][minl]->Height,
                      &ti->info.largeLodLog2,
                      &ti->info.aspectRatioLog2,
                      &(ti->sScale), &(ti->tScale), NULL, NULL);
    }

    if (tObj->Image[0][maxl] && (tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR)) {
        /* mipmapping: need to compute smallLodLog2 */
        tdfxTexGetInfo(ctx, tObj->Image[0][maxl]->Width,
                       tObj->Image[0][maxl]->Height,
                       &ti->info.smallLodLog2, NULL,
                       NULL, NULL, NULL, NULL);
    }
    else {
        /* not mipmapping: smallLodLog2 = largeLodLog2 */
        ti->info.smallLodLog2 = ti->info.largeLodLog2;
        maxl = minl;
    }

    ti->minLevel = minl;
    ti->maxLevel = maxl;
    ti->info.data = NULL;

   /* this is necessary because of fxDDCompressedTexImage2D */
   if (ti->padded) {
      struct gl_texture_image *texImage = tObj->Image[0][minl];
      tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
      if (mml->wScale != 1 || mml->hScale != 1) {
         ti->sScale /= mml->wScale;
         ti->tScale /= mml->hScale;
      }
   }
}


static tdfxTexInfo *
fxAllocTexObjData(tdfxContextPtr fxMesa)
{
    tdfxTexInfo *ti;

    if (!(ti = CALLOC(sizeof(tdfxTexInfo)))) {
        _mesa_problem(NULL, "tdfx driver: out of memory");
        return NULL;
    }

    ti->isInTM = GL_FALSE;

    ti->whichTMU = TDFX_TMU_NONE;

    ti->tm[TDFX_TMU0] = NULL;
    ti->tm[TDFX_TMU1] = NULL;

    ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
    ti->magFilt = GR_TEXTUREFILTER_BILINEAR;

    ti->sClamp = GR_TEXTURECLAMP_WRAP;
    ti->tClamp = GR_TEXTURECLAMP_WRAP;

    ti->mmMode = GR_MIPMAP_NEAREST;
    ti->LODblend = FXFALSE;

    return ti;
}


/*
 * Called via glBindTexture.
 */
static void
tdfxBindTexture(GLcontext * ctx, GLenum target,
                  struct gl_texture_object *tObj)
{
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    tdfxTexInfo *ti;

    if (MESA_VERBOSE & VERBOSE_DRIVER) {
        fprintf(stderr, "fxmesa: fxDDTexBind(%d,%p)\n", tObj->Name,
                tObj->DriverData);
    }

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

    if (!tObj->DriverData) {
        tObj->DriverData = fxAllocTexObjData(fxMesa);
    }

    ti = TDFX_TEXTURE_DATA(tObj);
    ti->lastTimeUsed = fxMesa->texBindNumber++;

    fxMesa->new_state |= TDFX_NEW_TEXTURE;
}


/*
 * Called via glTexEnv.
 */
static void
tdfxTexEnv(GLcontext * ctx, GLenum target, GLenum pname,
             const GLfloat * param)
{
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);

    if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
        if (param)
            fprintf(stderr, "fxmesa: texenv(%x,%x)\n", pname,
                    (GLint) (*param));
        else
            fprintf(stderr, "fxmesa: texenv(%x)\n", pname);
    }

    /* XXX this is a bit of a hack to force the Glide texture
     * state to be updated.
     */
    fxMesa->TexState.EnvMode[ctx->Texture.CurrentUnit]  = 0;

    fxMesa->new_state |= TDFX_NEW_TEXTURE;
}


/*
 * Called via glTexParameter.
 */
static void
tdfxTexParameter(GLcontext * ctx, GLenum target,
                   struct gl_texture_object *tObj,
                   GLenum pname, const GLfloat * params)
{
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    GLenum param = (GLenum) (GLint) params[0];
    tdfxTexInfo *ti;

    if (MESA_VERBOSE & VERBOSE_DRIVER) {
        fprintf(stderr, "fxmesa: fxDDTexParam(%d,%p,%x,%x)\n", tObj->Name,
                tObj->DriverData, pname, param);
    }

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

    if (!tObj->DriverData)
        tObj->DriverData = fxAllocTexObjData(fxMesa);

    ti = TDFX_TEXTURE_DATA(tObj);

    switch (pname) {
    case GL_TEXTURE_MIN_FILTER:
        switch (param) {
        case GL_NEAREST:
            ti->mmMode = GR_MIPMAP_DISABLE;
            ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
            ti->LODblend = FXFALSE;
            break;
        case GL_LINEAR:
            ti->mmMode = GR_MIPMAP_DISABLE;
            ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
            ti->LODblend = FXFALSE;
            break;
        case GL_NEAREST_MIPMAP_LINEAR:
            if (!fxMesa->Glide.HaveCombineExt) {
                 if (fxMesa->haveTwoTMUs) {
                     ti->mmMode = GR_MIPMAP_NEAREST;
                     ti->LODblend = FXTRUE;
                 }
                 else {
                     ti->mmMode = GR_MIPMAP_NEAREST_DITHER;
                     ti->LODblend = FXFALSE;
                 }
                 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
                 break;
            }
            /* XXX Voodoo3/Banshee mipmap blending seems to produce
             * incorrectly filtered colors for the smallest mipmap levels.
             * To work-around we fall-through here and use a different filter.
             */
        case GL_NEAREST_MIPMAP_NEAREST:
            ti->mmMode = GR_MIPMAP_NEAREST;
            ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
            ti->LODblend = FXFALSE;
            break;
        case GL_LINEAR_MIPMAP_LINEAR:
            if (!fxMesa->Glide.HaveCombineExt) {
                if (fxMesa->haveTwoTMUs) {
                    ti->mmMode = GR_MIPMAP_NEAREST;
                    ti->LODblend = FXTRUE;
                }
                else {
                    ti->mmMode = GR_MIPMAP_NEAREST_DITHER;
                    ti->LODblend = FXFALSE;
                }
                ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
                break;
            }
            /* XXX Voodoo3/Banshee mipmap blending seems to produce
             * incorrectly filtered colors for the smallest mipmap levels.
             * To work-around we fall-through here and use a different filter.
             */
        case GL_LINEAR_MIPMAP_NEAREST:
            ti->mmMode = GR_MIPMAP_NEAREST;
            ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
            ti->LODblend = FXFALSE;
            break;
        default:
            break;
        }
        ti->reloadImages = GL_TRUE;
        RevalidateTexture(ctx, tObj);
        fxMesa->new_state |= TDFX_NEW_TEXTURE;
        break;

    case GL_TEXTURE_MAG_FILTER:
        switch (param) {
        case GL_NEAREST:
            ti->magFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
            break;
        case GL_LINEAR:
            ti->magFilt = GR_TEXTUREFILTER_BILINEAR;
            break;
        default:
            break;
        }
        fxMesa->new_state |= TDFX_NEW_TEXTURE;
        break;

    case GL_TEXTURE_WRAP_S:
        switch (param) {
        case GL_CLAMP_TO_BORDER:
        case GL_CLAMP_TO_EDGE:
        case GL_CLAMP:
            ti->sClamp = GR_TEXTURECLAMP_CLAMP;
            break;
        case GL_REPEAT:
            ti->sClamp = GR_TEXTURECLAMP_WRAP;
            break;
        case GL_MIRRORED_REPEAT:
            ti->sClamp = GR_TEXTURECLAMP_MIRROR_EXT;
            break;
        default:
            break;
        }
        fxMesa->new_state |= TDFX_NEW_TEXTURE;
        break;

    case GL_TEXTURE_WRAP_T:
        switch (param) {
        case GL_CLAMP_TO_BORDER:
        case GL_CLAMP_TO_EDGE:
        case GL_CLAMP:
            ti->tClamp = GR_TEXTURECLAMP_CLAMP;
            break;
        case GL_REPEAT:
            ti->tClamp = GR_TEXTURECLAMP_WRAP;
            break;
        case GL_MIRRORED_REPEAT:
            ti->tClamp = GR_TEXTURECLAMP_MIRROR_EXT;
            break;
        default:
            break;
        }
        fxMesa->new_state |= TDFX_NEW_TEXTURE;
        break;

    case GL_TEXTURE_BORDER_COLOR:
        /* TO DO */
        break;
    case GL_TEXTURE_MIN_LOD:
        /* TO DO */
        break;
    case GL_TEXTURE_MAX_LOD:
        /* TO DO */
        break;
    case GL_TEXTURE_BASE_LEVEL:
        RevalidateTexture(ctx, tObj);
        break;
    case GL_TEXTURE_MAX_LEVEL:
        RevalidateTexture(ctx, tObj);
        break;

    default:
        break;
    }
}


/*
 * Called via glDeleteTextures to delete a texture object.
 * Here, we delete the Glide data associated with the texture.
 */
static void
tdfxDeleteTexture(GLcontext * ctx, struct gl_texture_object *tObj)
{
    if (ctx && ctx->DriverCtx) {
        tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
        tdfxTMFreeTexture(fxMesa, tObj);
        fxMesa->new_state |= TDFX_NEW_TEXTURE;
        /* Free mipmap images and the texture object itself */
        _mesa_delete_texture_object(ctx, tObj);
    }
}


/*
 * Return true if texture is resident, false otherwise.
 */
static GLboolean
tdfxIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj)
{
    tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj);
    return (GLboolean) (ti && ti->isInTM);
}



/*
 * Convert a gl_color_table texture palette to Glide's format.
 */
static GrTexTable_t
convertPalette(FxU32 data[256], const struct gl_color_table *table)
{
    const GLubyte *tableUB = table->TableUB;
    GLint width = table->Size;
    FxU32 r, g, b, a;
    GLint i;

    switch (table->_BaseFormat) {
    case GL_INTENSITY:
        for (i = 0; i < width; i++) {
            r = tableUB[i];
            g = tableUB[i];
            b = tableUB[i];
            a = tableUB[i];
            data[i] = (a << 24) | (r << 16) | (g << 8) | b;
        }
        return GR_TEXTABLE_PALETTE_6666_EXT;
    case GL_LUMINANCE:
        for (i = 0; i < width; i++) {
            r = tableUB[i];
            g = tableUB[i];
            b = tableUB[i];
            a = 255;
            data[i] = (a << 24) | (r << 16) | (g << 8) | b;
        }
        return GR_TEXTABLE_PALETTE;
    case GL_ALPHA:
        for (i = 0; i < width; i++) {
            r = g = b = 255;
            a = tableUB[i];
            data[i] = (a << 24) | (r << 16) | (g << 8) | b;
        }
        return GR_TEXTABLE_PALETTE_6666_EXT;
    case GL_LUMINANCE_ALPHA:
        for (i = 0; i < width; i++) {
            r = g = b = tableUB[i * 2 + 0];
            a = tableUB[i * 2 + 1];
            data[i] = (a << 24) | (r << 16) | (g << 8) | b;
        }
        return GR_TEXTABLE_PALETTE_6666_EXT;
    case GL_RGB:
        for (i = 0; i < width; i++) {
            r = tableUB[i * 3 + 0];
            g = tableUB[i * 3 + 1];
            b = tableUB[i * 3 + 2];
            a = 255;
            data[i] = (a << 24) | (r << 16) | (g << 8) | b;
        }
        return GR_TEXTABLE_PALETTE;
    case GL_RGBA:
        for (i = 0; i < width; i++) {
            r = tableUB[i * 4 + 0];
            g = tableUB[i * 4 + 1];
            b = tableUB[i * 4 + 2];
            a = tableUB[i * 4 + 3];
            data[i] = (a << 24) | (r << 16) | (g << 8) | b;
        }
        return GR_TEXTABLE_PALETTE_6666_EXT;
    default:
        /* XXX fixme: how can this happen? */
        _mesa_error(NULL, GL_INVALID_ENUM, "convertPalette: table->Format == %s",
                                           _mesa_lookup_enum_by_nr(table->Format));
        return GR_TEXTABLE_PALETTE;
    }
}



static void
tdfxUpdateTexturePalette(GLcontext * ctx, struct gl_texture_object *tObj)
{
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);

    if (tObj) {
        /* per-texture palette */
        tdfxTexInfo *ti;
        
        /* This might be a proxy texture. */
        if (!tObj->Palette.TableUB)
            return;
            
        if (!tObj->DriverData)
            tObj->DriverData = fxAllocTexObjData(fxMesa);
        ti = TDFX_TEXTURE_DATA(tObj);
        assert(ti);
        ti->paltype = convertPalette(ti->palette.data, &tObj->Palette);
        /*tdfxTexInvalidate(ctx, tObj);*/
    }
    else {
        /* global texture palette */
        fxMesa->TexPalette.Type = convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette);
	fxMesa->TexPalette.Data = &(fxMesa->glbPalette.data);
	fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE;
    }
    fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX too heavy-handed */
}


/**********************************************************************/
/**** NEW TEXTURE IMAGE FUNCTIONS                                  ****/
/**********************************************************************/

#if 000
static FxBool TexusFatalError = FXFALSE;
static FxBool TexusError = FXFALSE;

#define TX_DITHER_NONE                                  0x00000000

static void
fxTexusError(const char *string, FxBool fatal)
{
    _mesa_problem(NULL, string);
   /*
    * Just propagate the fatal value up.
    */
    TexusError = FXTRUE;
    TexusFatalError = fatal;
}
#endif


static const struct gl_texture_format *
tdfxChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
                           GLenum srcFormat, GLenum srcType )
{
   tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
   const GLboolean allow32bpt = TDFX_IS_NAPALM(fxMesa);

   switch (internalFormat) {
   case GL_ALPHA:
   case GL_ALPHA4:
   case GL_ALPHA8:
   case GL_ALPHA12:
   case GL_ALPHA16:
   case GL_COMPRESSED_ALPHA:
      return &_mesa_texformat_a8;
   case 1:
   case GL_LUMINANCE:
   case GL_LUMINANCE4:
   case GL_LUMINANCE8:
   case GL_LUMINANCE12:
   case GL_LUMINANCE16:
   case GL_COMPRESSED_LUMINANCE:
      return &_mesa_texformat_l8;
   case 2:
   case GL_LUMINANCE_ALPHA:
   case GL_LUMINANCE4_ALPHA4:
   case GL_LUMINANCE6_ALPHA2:
   case GL_LUMINANCE8_ALPHA8:
   case GL_LUMINANCE12_ALPHA4:
   case GL_LUMINANCE12_ALPHA12:
   case GL_LUMINANCE16_ALPHA16:
   case GL_COMPRESSED_LUMINANCE_ALPHA:
      return &_mesa_texformat_al88;
   case GL_INTENSITY:
   case GL_INTENSITY4:
   case GL_INTENSITY8:
   case GL_INTENSITY12:
   case GL_INTENSITY16:
   case GL_COMPRESSED_INTENSITY:
      return &_mesa_texformat_i8;
   case GL_R3_G3_B2:
   case GL_RGB4:
   case GL_RGB5:
      return &_mesa_texformat_rgb565;
   case GL_COMPRESSED_RGB:
      /* intentional fall-through */
   case 3:
   case GL_RGB:
     if ( srcFormat == GL_RGB && srcType == GL_UNSIGNED_SHORT_5_6_5 ) {
       return &_mesa_texformat_rgb565;
     }
     /* intentional fall through */
   case GL_RGB8:
   case GL_RGB10:
   case GL_RGB12:
   case GL_RGB16:
      return (allow32bpt) ? &_mesa_texformat_argb8888
                          : &_mesa_texformat_rgb565;
   case GL_RGBA2:
   case GL_RGBA4:
      return &_mesa_texformat_argb4444;
   case GL_COMPRESSED_RGBA:
      /* intentional fall-through */
   case 4:
   case GL_RGBA:
     if ( srcFormat == GL_BGRA ) {
       if ( srcType == GL_UNSIGNED_INT_8_8_8_8_REV ) {
         return &_mesa_texformat_argb8888;
       }
       else if ( srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
         return &_mesa_texformat_argb4444;
       }
       else if ( srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
         return &_mesa_texformat_argb1555;
       }
     }
     /* intentional fall through */
   case GL_RGBA8:
   case GL_RGB10_A2:
   case GL_RGBA12:
   case GL_RGBA16:
      return allow32bpt ? &_mesa_texformat_argb8888
                        : &_mesa_texformat_argb4444;
   case GL_RGB5_A1:
      return &_mesa_texformat_argb1555;
   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;
   /* GL_EXT_texture_compression_s3tc */
   /* GL_S3_s3tc */
   case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
   case GL_RGB_S3TC:
   case GL_RGB4_S3TC:
      return &_mesa_texformat_rgb_dxt1;
   case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
      return &_mesa_texformat_rgba_dxt1;
   case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
   case GL_RGBA_S3TC:
   case GL_RGBA4_S3TC:
      return &_mesa_texformat_rgba_dxt3;
   case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
      return &_mesa_texformat_rgba_dxt5;
   /* GL_3DFX_texture_compression_FXT1 */
   case GL_COMPRESSED_RGB_FXT1_3DFX:
      return &_mesa_texformat_rgb_fxt1;
   case GL_COMPRESSED_RGBA_FXT1_3DFX:
      return &_mesa_texformat_rgba_fxt1;
   default:
      _mesa_problem(ctx, "unexpected format in tdfxChooseTextureFormat");
      return NULL;
   }
}


/*
 * Return the Glide format for the given mesa texture format.
 */
static GrTextureFormat_t
fxGlideFormat(GLint mesaFormat)
{
   switch (mesaFormat) {
   case MESA_FORMAT_I8:
      return GR_TEXFMT_ALPHA_8;
   case MESA_FORMAT_A8:
      return GR_TEXFMT_ALPHA_8;
   case MESA_FORMAT_L8:
      return GR_TEXFMT_INTENSITY_8;
   case MESA_FORMAT_CI8:
      return GR_TEXFMT_P_8;
   case MESA_FORMAT_AL88:
      return GR_TEXFMT_ALPHA_INTENSITY_88;
   case MESA_FORMAT_RGB565:
      return GR_TEXFMT_RGB_565;
   case MESA_FORMAT_ARGB4444:
      return GR_TEXFMT_ARGB_4444;
   case MESA_FORMAT_ARGB1555:
      return GR_TEXFMT_ARGB_1555;
   case MESA_FORMAT_ARGB8888:
      return GR_TEXFMT_ARGB_8888;
   case MESA_FORMAT_RGB_FXT1:
   case MESA_FORMAT_RGBA_FXT1:
     return GR_TEXFMT_ARGB_CMP_FXT1;
   case MESA_FORMAT_RGB_DXT1:
   case MESA_FORMAT_RGBA_DXT1:
     return GR_TEXFMT_ARGB_CMP_DXT1;
   case MESA_FORMAT_RGBA_DXT3:
     return GR_TEXFMT_ARGB_CMP_DXT3;
   case MESA_FORMAT_RGBA_DXT5:
     return GR_TEXFMT_ARGB_CMP_DXT5;
   default:
      _mesa_problem(NULL, "Unexpected format in fxGlideFormat");
      return 0;
   }
}


/* Texel-fetch functions for software texturing and glGetTexImage().
 * We should have been able to use some "standard" fetch functions (which
 * may get defined in texutil.c) but we have to account for scaled texture
 * images on tdfx hardware (the 8:1 aspect ratio limit).
 * Hence, we need special functions here.
 */
extern void
fxt1_decode_1 (const void *texture, int width,
               int i, int j, unsigned char *rgba);

static void
fetch_intensity8(const struct gl_texture_image *texImage,
		 GLint i, GLint j, GLint k, GLchan * rgba)
{
    const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
    const GLubyte *texel;

    i = i * mml->wScale;
    j = j * mml->hScale;

    texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
    rgba[RCOMP] = *texel;
    rgba[GCOMP] = *texel;
    rgba[BCOMP] = *texel;
    rgba[ACOMP] = *texel;
}


static void
fetch_luminance8(const struct gl_texture_image *texImage,
		 GLint i, GLint j, GLint k, GLchan * rgba)
{
    const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
    const GLubyte *texel;

    i = i * mml->wScale;
    j = j * mml->hScale;

    texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
    rgba[RCOMP] = *texel;
    rgba[GCOMP] = *texel;
    rgba[BCOMP] = *texel;
    rgba[ACOMP] = 255;
}


static void
fetch_alpha8(const struct gl_texture_image *texImage,
	     GLint i, GLint j, GLint k, GLchan * rgba)
{
    const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
    const GLubyte *texel;

    i = i * mml->wScale;
    j = j * mml->hScale;

    texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
    rgba[RCOMP] = 255;
    rgba[GCOMP] = 255;
    rgba[BCOMP] = 255;
    rgba[ACOMP] = *texel;
}


static void
fetch_index8(const struct gl_texture_image *texImage,
	     GLint i, GLint j, GLint k, GLchan * indexOut)
{
    const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
    const GLubyte *texel;

    i = i * mml->wScale;
    j = j * mml->hScale;

    texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
    *indexOut = *texel;
}


static void
fetch_luminance8_alpha8(const struct gl_texture_image *texImage,
			GLint i, GLint j, GLint k, GLchan * rgba)
{
    const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
    const GLubyte *texel;

    i = i * mml->wScale;
    j = j * mml->hScale;

    texel = ((GLubyte *) texImage->Data) + (j * mml->width + i) * 2;
    rgba[RCOMP] = texel[0];
    rgba[GCOMP] = texel[0];
    rgba[BCOMP] = texel[0];
    rgba[ACOMP] = texel[1];
}


static void
fetch_r5g6b5(const struct gl_texture_image *texImage,
	     GLint i, GLint j, GLint k, GLchan * rgba)
{
    const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
    const GLushort *texel;

    i = i * mml->wScale;
    j = j * mml->hScale;

    texel = ((GLushort *) texImage->Data) + j * mml->width + i;
    rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31;
    rgba[GCOMP] = (((*texel) >> 5) & 0x3f) * 255 / 63;
    rgba[BCOMP] = (((*texel) >> 0) & 0x1f) * 255 / 31;
    rgba[ACOMP] = 255;
}


static void
fetch_r4g4b4a4(const struct gl_texture_image *texImage,
	       GLint i, GLint j, GLint k, GLchan * rgba)
{
    const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
    const GLushort *texel;

    i = i * mml->wScale;
    j = j * mml->hScale;

    texel = ((GLushort *) texImage->Data) + j * mml->width + i;
    rgba[RCOMP] = (((*texel) >> 12) & 0xf) * 255 / 15;
    rgba[GCOMP] = (((*texel) >> 8) & 0xf) * 255 / 15;
    rgba[BCOMP] = (((*texel) >> 4) & 0xf) * 255 / 15;
    rgba[ACOMP] = (((*texel) >> 0) & 0xf) * 255 / 15;
}


static void
fetch_r5g5b5a1(const struct gl_texture_image *texImage,
	       GLint i, GLint j, GLint k, GLchan * rgba)
{
    const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
    const GLushort *texel;

    i = i * mml->wScale;
    j = j * mml->hScale;

    texel = ((GLushort *) texImage->Data) + j * mml->width + i;
    rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31;
    rgba[GCOMP] = (((*texel) >> 6) & 0x1f) * 255 / 31;
    rgba[BCOMP] = (((*texel) >> 1) & 0x1f) * 255 / 31;
    rgba[ACOMP] = (((*texel) >> 0) & 0x01) * 255;
}


static void
fetch_a8r8g8b8(const struct gl_texture_image *texImage,
	       GLint i, GLint j, GLint k, GLchan * rgba)
{
    const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);
    const GLuint *texel;

    i = i * mml->wScale;
    j = j * mml->hScale;

    texel = ((GLuint *) texImage->Data) + j * mml->width + i;
    rgba[RCOMP] = (((*texel) >> 16) & 0xff);
    rgba[GCOMP] = (((*texel) >>  8) & 0xff);
    rgba[BCOMP] = (((*texel)      ) & 0xff);
    rgba[ACOMP] = (((*texel) >> 24) & 0xff);
}


static void
fetch_rgb_fxt1(const struct gl_texture_image *texImage,
	       GLint i, GLint j, GLint k, GLchan *rgba)
{
    const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);

    i = i * mml->wScale;
    j = j * mml->hScale;

    fxt1_decode_1(texImage->Data, mml->width, i, j, rgba);
    rgba[ACOMP] = 255;
}


static void
fetch_rgba_fxt1(const struct gl_texture_image *texImage,
		GLint i, GLint j, GLint k, GLchan *rgba)
{
    const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);

    i = i * mml->wScale;
    j = j * mml->hScale;

    fxt1_decode_1(texImage->Data, mml->width, i, j, rgba);
}


static void
fetch_rgb_dxt1(const struct gl_texture_image *texImage,
	       GLint i, GLint j, GLint k, GLchan *rgba)
{
    const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);

    i = i * mml->wScale;
    j = j * mml->hScale;

    _mesa_texformat_rgb_dxt1.FetchTexel2D(texImage, i, j, k, rgba);
}


static void
fetch_rgba_dxt1(const struct gl_texture_image *texImage,
		GLint i, GLint j, GLint k, GLchan *rgba)
{
    const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);

    i = i * mml->wScale;
    j = j * mml->hScale;

    _mesa_texformat_rgba_dxt1.FetchTexel2D(texImage, i, j, k, rgba);
}


static void
fetch_rgba_dxt3(const struct gl_texture_image *texImage,
		GLint i, GLint j, GLint k, GLchan *rgba)
{
    const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);

    i = i * mml->wScale;
    j = j * mml->hScale;

    _mesa_texformat_rgba_dxt3.FetchTexel2D(texImage, i, j, k, rgba);
}


static void
fetch_rgba_dxt5(const struct gl_texture_image *texImage,
		GLint i, GLint j, GLint k, GLchan *rgba)
{
    const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage);

    i = i * mml->wScale;
    j = j * mml->hScale;

    _mesa_texformat_rgba_dxt5.FetchTexel2D(texImage, i, j, k, rgba);
}


static FetchTexelFuncC
fxFetchFunction(GLint mesaFormat)
{
   switch (mesaFormat) {
   case MESA_FORMAT_I8:
      return &fetch_intensity8;
   case MESA_FORMAT_A8:
      return &fetch_alpha8;
   case MESA_FORMAT_L8:
      return &fetch_luminance8;
   case MESA_FORMAT_CI8:
      return &fetch_index8;
   case MESA_FORMAT_AL88:
      return &fetch_luminance8_alpha8;
   case MESA_FORMAT_RGB565:
      return &fetch_r5g6b5;
   case MESA_FORMAT_ARGB4444:
      return &fetch_r4g4b4a4;
   case MESA_FORMAT_ARGB1555:
      return &fetch_r5g5b5a1;
   case MESA_FORMAT_ARGB8888:
      return &fetch_a8r8g8b8;
   case MESA_FORMAT_RGB_FXT1:
      return &fetch_rgb_fxt1;
   case MESA_FORMAT_RGBA_FXT1:
      return &fetch_rgba_fxt1;
   case MESA_FORMAT_RGB_DXT1:
      return &fetch_rgb_dxt1;
   case MESA_FORMAT_RGBA_DXT1:
      return &fetch_rgba_dxt1;
   case MESA_FORMAT_RGBA_DXT3:
      return &fetch_rgba_dxt3;
   case MESA_FORMAT_RGBA_DXT5:
      return &fetch_rgba_dxt5;
   default:
      _mesa_problem(NULL, "Unexpected format in fxFetchFunction");
      return NULL;
   }
}


static GLboolean
adjust2DRatio (GLcontext *ctx,
	       GLint xoffset, GLint yoffset,
	       GLint width, GLint height,
	       GLenum format, GLenum type, const GLvoid *pixels,
	       const struct gl_pixelstore_attrib *packing,
	       tdfxMipMapLevel *mml,
	       struct gl_texture_image *texImage,
	       GLint texelBytes,
	       GLint dstRowStride)
{
   const GLint newWidth = width * mml->wScale;
   const GLint newHeight = height * mml->hScale;
   GLvoid *tempImage;
   GLuint dstImageOffsets = 0;

   if (!texImage->IsCompressed) {
      GLubyte *destAddr;
      tempImage = MALLOC(width * height * texelBytes);
      if (!tempImage) {
         return GL_FALSE;
      }

      texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
                                      texImage->TexFormat, tempImage,
                                      0, 0, 0, /* dstX/Y/Zoffset */
                                      width * texelBytes, /* dstRowStride */
                                      &dstImageOffsets,
                                      width, height, 1,
                                      format, type, pixels, packing);

      /* now rescale */
      /* compute address of dest subimage within the overal tex image */
      destAddr = (GLubyte *) texImage->Data
         + (yoffset * mml->hScale * mml->width
            + xoffset * mml->wScale) * texelBytes;

      _mesa_rescale_teximage2d(texelBytes,
                               width,
                               dstRowStride, /* dst stride */
                               width, height,
                               newWidth, newHeight,
                               tempImage, destAddr);
   } else {
      const GLint rawBytes = 4;
      GLvoid *rawImage = MALLOC(width * height * rawBytes);
      if (!rawImage) {
         return GL_FALSE;
      }
      tempImage = MALLOC(newWidth * newHeight * rawBytes);
      if (!tempImage) {
	 FREE(rawImage);
         return GL_FALSE;
      }
      /* unpack image, apply transfer ops and store in rawImage */
      _mesa_texstore_rgba8888(ctx, 2, GL_RGBA,
                              &_mesa_texformat_rgba8888_rev, rawImage,
                              0, 0, 0, /* dstX/Y/Zoffset */
                              width * rawBytes, /* dstRowStride */
                              &dstImageOffsets,
                              width, height, 1,
                              format, type, pixels, packing);
      _mesa_rescale_teximage2d(rawBytes,
                               width,
                               newWidth * rawBytes, /* dst stride */
                               width, height, /* src */
                               newWidth, newHeight, /* dst */
                               rawImage /*src*/, tempImage /*dst*/ );
      texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
                                      texImage->TexFormat, texImage->Data,
                                      xoffset * mml->wScale, yoffset * mml->hScale, 0, /* dstX/Y/Zoffset */
                                      dstRowStride,
                                      &dstImageOffsets,
                                      newWidth, newHeight, 1,
                                      GL_RGBA, CHAN_TYPE, tempImage, &ctx->DefaultPacking);
      FREE(rawImage);
   }

   FREE(tempImage);

   return GL_TRUE;
}


static void
tdfxTexImage2D(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)
{
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    tdfxTexInfo *ti;
    tdfxMipMapLevel *mml;
    GLint texelBytes, dstRowStride;
    GLuint mesaFormat;

    /*
    printf("TexImage id=%d int 0x%x  format 0x%x  type 0x%x  %dx%d\n",
           texObj->Name, texImage->InternalFormat, format, type,
           texImage->Width, texImage->Height);
    */

    ti = TDFX_TEXTURE_DATA(texObj);
    if (!ti) {
        texObj->DriverData = fxAllocTexObjData(fxMesa);
        if (!texObj->DriverData) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
            return;
        }
        ti = TDFX_TEXTURE_DATA(texObj);
    }
    assert(ti);

    mml = TDFX_TEXIMAGE_DATA(texImage);
    if (!mml) {
        texImage->DriverData = CALLOC(sizeof(tdfxMipMapLevel));
        if (!texImage->DriverData) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
            return;
        }
        mml = TDFX_TEXIMAGE_DATA(texImage);
    }

    /* Determine width and height scale factors for texture.
     * Remember, Glide is limited to 8:1 aspect ratios.
     */
    tdfxTexGetInfo(ctx,
                   texImage->Width, texImage->Height,
                   NULL,       /* lod level          */
                   NULL,       /* aspect ratio       */
                   NULL, NULL, /* sscale, tscale     */
                   &mml->wScale, &mml->hScale);

    /* rescaled size: */
    mml->width = width * mml->wScale;
    mml->height = height * mml->hScale;

#if FX_COMPRESS_S3TC_AS_FXT1_HACK
    /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */
    /* [dBorca] we should update texture's attribute, then,
     * because if the application asks us to decompress, we
     * have to know the REAL format! Also, DXT3/5 might not
     * be correct, since it would mess with "compressedSize".
     * Ditto for GL_RGBA[4]_S3TC, which is always mapped to DXT3.
     */
    if (texImage->IsCompressed) {
      switch (internalFormat) {
      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
      case GL_RGB_S3TC:
      case GL_RGB4_S3TC:
        internalFormat = GL_COMPRESSED_RGB_FXT1_3DFX;
        break;
      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
      case GL_RGBA_S3TC:
      case GL_RGBA4_S3TC:
        internalFormat = GL_COMPRESSED_RGBA_FXT1_3DFX;
      }
      texImage->InternalFormat = internalFormat;
    }
#endif
#if FX_TC_NAPALM
    if (fxMesa->type >= GR_SSTTYPE_Voodoo4) {
       GLenum texNapalm = 0;
       if (internalFormat == GL_COMPRESSED_RGB) {
          texNapalm = GL_COMPRESSED_RGB_FXT1_3DFX;
       } else if (internalFormat == GL_COMPRESSED_RGBA) {
          texNapalm = GL_COMPRESSED_RGBA_FXT1_3DFX;
       }
       if (texNapalm) {
          texImage->InternalFormat = internalFormat = texNapalm;
          texImage->IsCompressed = GL_TRUE;
       }
    }
#endif

    /* choose the texture format */
    assert(ctx->Driver.ChooseTextureFormat);
    texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
                                     internalFormat, format, type);
    assert(texImage->TexFormat);
    mesaFormat = texImage->TexFormat->MesaFormat;
    mml->glideFormat = fxGlideFormat(mesaFormat);
    ti->info.format = mml->glideFormat;
    texImage->FetchTexelc = fxFetchFunction(mesaFormat);
    texelBytes = texImage->TexFormat->TexelBytes;

    if (texImage->IsCompressed) {
       texImage->CompressedSize = _mesa_compressed_texture_size(ctx,
                                                        	mml->width,
                                                        	mml->height,
                                                        	1,
                                                        	mesaFormat);
       dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, mml->width);
       texImage->Data = _mesa_alloc_texmemory(texImage->CompressedSize);
    } else {
       dstRowStride = mml->width * texelBytes;
       texImage->Data = _mesa_alloc_texmemory(mml->width * mml->height * texelBytes);
    }
    if (!texImage->Data) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
       return;
    }

    if (pixels != NULL) {
       if (mml->wScale != 1 || mml->hScale != 1) {
	  /* rescale image to overcome 1:8 aspect limitation */
	  if (!adjust2DRatio(ctx,
			    0, 0,
			    width, height,
			    format, type, pixels,
			    packing,
			    mml,
			    texImage,
			    texelBytes,
			    dstRowStride)
	     ) {
	     _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
	     return;
	  }
       }
       else {
          /* no rescaling needed */
          /* unpack image, apply transfer ops and store in texImage->Data */
          texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
                                          texImage->TexFormat, texImage->Data,
                                          0, 0, 0, /* dstX/Y/Zoffset */
                                          dstRowStride,
                                          texImage->ImageOffsets,
                                          width, height, 1,
                                          format, type, pixels, packing);
       }

      /* GL_SGIS_generate_mipmap */
      if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
         GLint mipWidth, mipHeight;
         tdfxMipMapLevel *mip;
         struct gl_texture_image *mipImage;
         const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
   
         assert(!texImage->IsCompressed);
   
         while (level < texObj->MaxLevel && level < maxLevels - 1) {
            mipWidth = width / 2;
            if (!mipWidth) {
               mipWidth = 1;
            }
            mipHeight = height / 2;
            if (!mipHeight) {
               mipHeight = 1;
            }
            if ((mipWidth == width) && (mipHeight == height)) {
               break;
            }
            _mesa_TexImage2D(target, ++level, internalFormat,
                             mipWidth, mipHeight, border,
                             format, type,
                             NULL);
            mipImage = _mesa_select_tex_image(ctx, texObj, target, level);
            mip = TDFX_TEXIMAGE_DATA(mipImage);
            _mesa_halve2x2_teximage2d(ctx,
                                      texImage,
                                      texelBytes,
                                      mml->width, mml->height,
                                      texImage->Data, mipImage->Data);
            texImage = mipImage;
            mml = mip;
            width = mipWidth;
            height = mipHeight;
         }
      }
    }

    RevalidateTexture(ctx, texObj);

    ti->reloadImages = GL_TRUE;
    fxMesa->new_state |= TDFX_NEW_TEXTURE;
}


static void
tdfxTexSubImage2D(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 )
{
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    tdfxTexInfo *ti;
    tdfxMipMapLevel *mml;
    GLint texelBytes, dstRowStride;

    if (!texObj->DriverData) {
        _mesa_problem(ctx, "problem in fxDDTexSubImage2D");
        return;
    }

    ti = TDFX_TEXTURE_DATA(texObj);
    assert(ti);
    mml = TDFX_TEXIMAGE_DATA(texImage);
    assert(mml);

    assert(texImage->Data);	/* must have an existing texture image! */
    assert(texImage->_BaseFormat);

    texelBytes = texImage->TexFormat->TexelBytes;
    if (texImage->IsCompressed) {
       dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, mml->width);
    } else {
       dstRowStride = mml->width * texelBytes;
    }

    if (mml->wScale != 1 || mml->hScale != 1) {
	/* need to rescale subimage to match mipmap level's rescale factors */
	if (!adjust2DRatio(ctx,
			    xoffset, yoffset,
			    width, height,
			    format, type, pixels,
			    packing,
			    mml,
			    texImage,
			    texelBytes,
			    dstRowStride)
           ) {
           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
           return;
	}
    }
    else {
        /* no rescaling needed */
        texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
                                        texImage->TexFormat, texImage->Data,
                                        xoffset, yoffset, 0,
                                        dstRowStride,
                                        texImage->ImageOffsets,
                                        width, height, 1,
                                        format, type, pixels, packing);
    }

   /* GL_SGIS_generate_mipmap */
   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
      GLint mipWidth, mipHeight;
      tdfxMipMapLevel *mip;
      struct gl_texture_image *mipImage;
      const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);

      assert(!texImage->IsCompressed);

      width = texImage->Width;
      height = texImage->Height;
      while (level < texObj->MaxLevel && level < maxLevels - 1) {
         mipWidth = width / 2;
         if (!mipWidth) {
            mipWidth = 1;
         }
         mipHeight = height / 2;
         if (!mipHeight) {
            mipHeight = 1;
         }
         if ((mipWidth == width) && (mipHeight == height)) {
            break;
         }
         ++level;
         mipImage = _mesa_select_tex_image(ctx, texObj, target, level);
         mip = TDFX_TEXIMAGE_DATA(mipImage);
         _mesa_halve2x2_teximage2d(ctx,
                                   texImage,
                                   texelBytes,
                                   mml->width, mml->height,
                                   texImage->Data, mipImage->Data);
         texImage = mipImage;
         mml = mip;
         width = mipWidth;
         height = mipHeight;
      }
   }

    ti->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */
    fxMesa->new_state |= TDFX_NEW_TEXTURE;  /* XXX this might be a bit much */
}


static void
tdfxTexImage1D(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)
{
 tdfxTexImage2D(ctx, target, level,
                internalFormat, width, 1, border,
                format, type, pixels,
                packing,
                texObj,
                texImage);
}

static void
tdfxTexSubImage1D(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 )
{
 tdfxTexSubImage2D(ctx, target, level,
                    xoffset, 0,
                    width, 1,
                    format, type,
                    pixels,
                    packing,
                    texObj,
                    texImage);
}

/**********************************************************************/
/**** COMPRESSED TEXTURE IMAGE FUNCTIONS                           ****/
/**********************************************************************/

static void
tdfxCompressedTexImage2D (GLcontext *ctx, GLenum target,
                          GLint level, GLint internalFormat,
                          GLsizei width, GLsizei height, GLint border,
                          GLsizei imageSize, const GLvoid *data,
                          struct gl_texture_object *texObj,
                          struct gl_texture_image *texImage)
{
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    tdfxTexInfo *ti;
    tdfxMipMapLevel *mml;
    GLuint mesaFormat;

    if (TDFX_DEBUG & DEBUG_VERBOSE_DRI) {
        fprintf(stderr, "tdfxCompressedTexImage2D: id=%d int 0x%x  %dx%d\n",
                        texObj->Name, internalFormat,
                        width, height);
    }

    if ((target != GL_TEXTURE_1D && target != GL_TEXTURE_2D) || texImage->Border > 0) {
       _mesa_problem(NULL, "tdfx: unsupported texture in tdfxCompressedTexImg()\n");
       return;
    }

    assert(texImage->IsCompressed);

    ti = TDFX_TEXTURE_DATA(texObj);
    if (!ti) {
        texObj->DriverData = fxAllocTexObjData(fxMesa);
        if (!texObj->DriverData) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
            return;
        }
        ti = TDFX_TEXTURE_DATA(texObj);
    }
    assert(ti);

    mml = TDFX_TEXIMAGE_DATA(texImage);
    if (!mml) {
        texImage->DriverData = CALLOC(sizeof(tdfxMipMapLevel));
        if (!texImage->DriverData) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
            return;
        }
        mml = TDFX_TEXIMAGE_DATA(texImage);
    }

    tdfxTexGetInfo(ctx, width, height, NULL, NULL, NULL, NULL,
		&mml->wScale, &mml->hScale);

    mml->width = width * mml->wScale;
    mml->height = height * mml->hScale;


    /* choose the texture format */
    assert(ctx->Driver.ChooseTextureFormat);
    texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
                                           internalFormat, -1/*format*/, -1/*type*/);
    assert(texImage->TexFormat);

    /* Determine the appropriate Glide texel format,
     * given the user's internal texture format hint.
     */
    mesaFormat = texImage->TexFormat->MesaFormat;
    mml->glideFormat = fxGlideFormat(mesaFormat);
    ti->info.format = mml->glideFormat;
    texImage->FetchTexelc = fxFetchFunction(mesaFormat);

    /* allocate new storage for texture image, if needed */
    if (!texImage->Data) {
       texImage->CompressedSize = _mesa_compressed_texture_size(ctx,
                                                                mml->width,
                                                                mml->height,
                                                                1,
                                                                mesaFormat);
       texImage->Data = _mesa_alloc_texmemory(texImage->CompressedSize);
       if (!texImage->Data) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
          return;
       }
    }

    /* save the texture data */
    if (mml->wScale != 1 || mml->hScale != 1) {
       /* [dBorca] Hack alert:
        * now we're screwed. We can't decompress,
        * unless we do it in HW (via textureBuffer).
        * We still have some chances:
        * 1) we got FXT1 textures - we CAN decompress, rescale for
        *    aspectratio, then compress back.
        * 2) there is a chance that MIN("s", "t") won't be overflowed.
        *    Thus, we don't care about textureclamp and we could lower
        *    MIN("uscale", "vscale") below 32. We still have to have
        *    our data aligned inside a 8:1 rectangle.
        * 3) just in case if MIN("s", "t") gets overflowed with GL_REPEAT,
        *    we replicate the data over the padded area.
        * For now, we take 2) + 3) but texelfetchers will be wrong!
        */
       const GLuint mesaFormat = texImage->TexFormat->MesaFormat;
       GLuint srcRowStride = _mesa_compressed_row_stride(mesaFormat, width);
 
       GLuint destRowStride = _mesa_compressed_row_stride(mesaFormat,
                                                   mml->width);
 
       _mesa_upscale_teximage2d(srcRowStride, (height+3) / 4,
                                destRowStride, (mml->height+3) / 4,
                                1, data, srcRowStride,
                                texImage->Data);
       ti->padded = GL_TRUE;
    } else {
       MEMCPY(texImage->Data, data, texImage->CompressedSize);
    }

    /* GL_SGIS_generate_mipmap */
    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
       assert(!texImage->IsCompressed);
    }

    RevalidateTexture(ctx, texObj);

    ti->reloadImages = GL_TRUE;
    fxMesa->new_state |= TDFX_NEW_TEXTURE;
}


static void
tdfxCompressedTexSubImage2D( GLcontext *ctx, GLenum target,
                             GLint level, GLint xoffset,
                             GLint yoffset, GLsizei width,
                             GLint height, GLenum format,
                             GLsizei imageSize, const GLvoid *data,
                             struct gl_texture_object *texObj,
                             struct gl_texture_image *texImage )
{
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    tdfxTexInfo *ti;
    tdfxMipMapLevel *mml;
    GLint destRowStride, srcRowStride;
    GLint i, rows;
    GLubyte *dest;
    const GLuint mesaFormat = texImage->TexFormat->MesaFormat;

    if (TDFX_DEBUG & DEBUG_VERBOSE_DRI) {
        fprintf(stderr, "tdfxCompressedTexSubImage2D: id=%d\n", texObj->Name);
    }

    ti = TDFX_TEXTURE_DATA(texObj);
    assert(ti);
    mml = TDFX_TEXIMAGE_DATA(texImage);
    assert(mml);

    srcRowStride = _mesa_compressed_row_stride(mesaFormat, width);

    destRowStride = _mesa_compressed_row_stride(mesaFormat, mml->width);
    dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
                                          mesaFormat,
                                          mml->width,
                               (GLubyte*) texImage->Data);

    rows = height / 4; /* [dBorca] hardcoded 4, but works for FXT1/DXTC */

    for (i = 0; i < rows; i++) {
       MEMCPY(dest, data, srcRowStride);
       dest += destRowStride;
       data = (GLvoid *)((intptr_t)data + (intptr_t)srcRowStride);
    }

    /* [dBorca] Hack alert:
     * see fxDDCompressedTexImage2D for caveats
     */
    if (mml->wScale != 1 || mml->hScale != 1) {
       srcRowStride = _mesa_compressed_row_stride(mesaFormat, texImage->Width);
 
       destRowStride = _mesa_compressed_row_stride(mesaFormat, mml->width);
       _mesa_upscale_teximage2d(srcRowStride, texImage->Height / 4,
                                destRowStride, mml->height / 4,
                                1, texImage->Data, destRowStride,
                                texImage->Data);
    }

    /* GL_SGIS_generate_mipmap */
    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
       assert(!texImage->IsCompressed);
    }

    RevalidateTexture(ctx, texObj);

    ti->reloadImages = GL_TRUE;
    fxMesa->new_state |= TDFX_NEW_TEXTURE;
}


#if	0
static void
PrintTexture(int w, int h, int c, const GLubyte * data)
{
    int i, j;
    for (i = 0; i < h; i++) {
        for (j = 0; j < w; j++) {
            if (c == 2)
                printf("%02x %02x  ", data[0], data[1]);
            else if (c == 3)
                printf("%02x %02x %02x  ", data[0], data[1], data[2]);
            data += c;
        }
        printf("\n");
    }
}
#endif


GLboolean
tdfxTestProxyTexImage(GLcontext *ctx, GLenum target,
                        GLint level, GLint internalFormat,
                        GLenum format, GLenum type,
                        GLint width, GLint height,
                        GLint depth, GLint border)
{
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
    struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared;
    struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData;

    switch (target) {
    case GL_PROXY_TEXTURE_1D:
	/*JJJ wrong*/
    case GL_PROXY_TEXTURE_2D:
        {
            struct gl_texture_object *tObj;
            tdfxTexInfo *ti;
            int memNeeded;

            tObj = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
            if (!tObj->DriverData)
                tObj->DriverData = fxAllocTexObjData(fxMesa);
            ti = TDFX_TEXTURE_DATA(tObj);
            assert(ti);

            /* assign the parameters to test against */
            tObj->Image[0][level]->Width = width;
            tObj->Image[0][level]->Height = height;
            tObj->Image[0][level]->Border = border;
#if 0
            tObj->Image[0][level]->InternalFormat = internalFormat;
#endif
            if (level == 0) {
               /* don't use mipmap levels > 0 */
               tObj->MinFilter = tObj->MagFilter = GL_NEAREST;
            }
            else {
               /* test with all mipmap levels */
               tObj->MinFilter = GL_LINEAR_MIPMAP_LINEAR;
               tObj->MagFilter = GL_NEAREST;
            }
            RevalidateTexture(ctx, tObj);

            /*
            printf("small lodlog2 0x%x\n", ti->info.smallLodLog2);
            printf("large lodlog2 0x%x\n", ti->info.largeLodLog2);
            printf("aspect ratio 0x%x\n", ti->info.aspectRatioLog2);
            printf("glide format 0x%x\n", ti->info.format);
            printf("data %p\n", ti->info.data);
            printf("lodblend %d\n", (int) ti->LODblend);
            */

            /* determine where texture will reside */
            if (ti->LODblend && !shared->umaTexMemory) {
                /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
                memNeeded = fxMesa->Glide.grTexTextureMemRequired(
                                        GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
            }
            else {
                /* XXX GR_MIPMAPLEVELMASK_BOTH might not be right, but works */
                memNeeded = fxMesa->Glide.grTexTextureMemRequired(
                                        GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
            }
            /*
            printf("Proxy test %d > %d\n", memNeeded, shared->totalTexMem[0]);
            */
            if (memNeeded > shared->totalTexMem[0])
                return GL_FALSE;
            else
                return GL_TRUE;
        }
    case GL_PROXY_TEXTURE_3D:
        return GL_TRUE;  /* software rendering */
    default:
        return GL_TRUE;  /* never happens, silence compiler */
    }
}


/**
 * Allocate a new texture object.
 * Called via ctx->Driver.NewTextureObject.
 * Note: this function will be called during context creation to
 * allocate the default texture objects.
 * Note: we could use containment here to 'derive' the driver-specific
 * texture object from the core mesa gl_texture_object.  Not done at this time.
 */
static struct gl_texture_object *
tdfxNewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
{
   struct gl_texture_object *obj;
   obj = _mesa_new_texture_object(ctx, name, target);
   return obj;
}


void tdfxInitTextureFuncs( struct dd_function_table *functions )
{
   functions->BindTexture		= tdfxBindTexture;
   functions->NewTextureObject		= tdfxNewTextureObject;
   functions->DeleteTexture		= tdfxDeleteTexture;
   functions->TexEnv			= tdfxTexEnv;
   functions->TexParameter		= tdfxTexParameter;
   functions->ChooseTextureFormat       = tdfxChooseTextureFormat;
   functions->TexImage1D		= tdfxTexImage1D;
   functions->TexSubImage1D		= tdfxTexSubImage1D;
   functions->TexImage2D		= tdfxTexImage2D;
   functions->TexSubImage2D		= tdfxTexSubImage2D;
   functions->IsTextureResident		= tdfxIsTextureResident;
   functions->CompressedTexImage2D	= tdfxCompressedTexImage2D;
   functions->CompressedTexSubImage2D	= tdfxCompressedTexSubImage2D;
   functions->UpdateTexturePalette      = tdfxUpdateTexturePalette;
}
