fixed a bunch of g++ warnings/errors. Compiling with g++ can help find lots of poten...
[mesa.git] / src / mesa / drivers / glide / fxddtex.c
index 05ef77570c1e0aaf4033a5cc31934bc5be37eeec..a88ac0b2d052118423f48dcfe8f86b8aba34a450 100644 (file)
@@ -1,27 +1,47 @@
-/* -*- mode: C; tab-width:8;  -*-
-
-             fxddtex.c - 3Dfx VooDoo Texture mapping functions
-*/
 
 /*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Mesa 3-D graphics library
+ * Version:  3.5
+ *
+ * Copyright (C) 1999-2001  Brian Paul   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 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
+ * BRIAN PAUL 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.
+ *
+ *
+ * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
+ * terms stated above.
  *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
+ * Thank you for your contribution, David!
  *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Please make note of the above copyright/license statement.  If you
+ * contributed code or bug fixes to this code under the previous (GNU
+ * Library) license and object to the new license, your code will be
+ * removed at your request.  Please see the Mesa docs/COPYRIGHT file
+ * for more information.
  *
- * See the file fxapi.c for more informations about authors
+ * Additional Mesa/3Dfx driver developers:
+ *   Daryll Strauss <daryll@precisioninsight.com>
+ *   Keith Whitwell <keith@precisioninsight.com>
  *
+ * See fxapi.h for more revision/author details.
  */
 
+
 #ifdef HAVE_CONFIG_H
 #include "conf.h"
 #endif
 #if defined(FX)
 
 #include "fxdrv.h"
+#include "image.h"
+#include "teximage.h"
+#include "texstore.h"
+#include "texutil.h"
+
+
+void
+fxPrintTextureData(tfxTexInfo * ti)
+{
+   fprintf(stderr, "Texture Data:\n");
+   if (ti->tObj) {
+      fprintf(stderr, "\tName: %d\n", ti->tObj->Name);
+      fprintf(stderr, "\tBaseLevel: %d\n", ti->tObj->BaseLevel);
+      fprintf(stderr, "\tSize: %d x %d\n",
+             ti->tObj->Image[ti->tObj->BaseLevel]->Width,
+             ti->tObj->Image[ti->tObj->BaseLevel]->Height);
+   }
+   else
+      fprintf(stderr, "\tName: UNNAMED\n");
+   fprintf(stderr, "\tLast used: %d\n", ti->lastTimeUsed);
+   fprintf(stderr, "\tTMU: %ld\n", ti->whichTMU);
+   fprintf(stderr, "\t%s\n", (ti->isInTM) ? "In TMU" : "Not in TMU");
+   if (ti->tm[0])
+      fprintf(stderr, "\tMem0: %x-%x\n", (unsigned) ti->tm[0]->startAddr,
+             (unsigned) ti->tm[0]->endAddr);
+   if (ti->tm[1])
+      fprintf(stderr, "\tMem1: %x-%x\n", (unsigned) ti->tm[1]->startAddr,
+             (unsigned) ti->tm[1]->endAddr);
+   fprintf(stderr, "\tMipmaps: %d-%d\n", ti->minLevel, ti->maxLevel);
+   fprintf(stderr, "\tFilters: min %d min %d\n",
+          (int) ti->minFilt, (int) ti->maxFilt);
+   fprintf(stderr, "\tClamps: s %d t %d\n", (int) ti->sClamp,
+          (int) ti->tClamp);
+   fprintf(stderr, "\tScales: s %f t %f\n", ti->sScale, ti->tScale);
+   fprintf(stderr, "\tInt Scales: s %d t %d\n",
+          ti->int_sScale / 0x800000, ti->int_tScale / 0x800000);
+   fprintf(stderr, "\t%s\n",
+          (ti->fixedPalette) ? "Fixed palette" : "Non fixed palette");
+   fprintf(stderr, "\t%s\n", (ti->validated) ? "Validated" : "Not validated");
+}
+
 
 /************************************************************************/
 /*************************** Texture Mapping ****************************/
 /************************************************************************/
 
-static void fxTexInvalidate(GLcontext *ctx, struct gl_texture_object *tObj)
+static void
+fxTexInvalidate(GLcontext * ctx, struct gl_texture_object *tObj)
 {
-  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
-  tfxTexInfo *ti;
+   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+   tfxTexInfo *ti;
 
-  fxTMMoveOutTM(fxMesa,tObj); /* TO DO: SLOW but easy to write */
+   ti = fxTMGetTexInfo(tObj);
+   if (ti->isInTM)
+      fxTMMoveOutTM(fxMesa, tObj);     /* TO DO: SLOW but easy to write */
 
-  ti=(tfxTexInfo *)tObj->DriverData;
-  ti->validated=GL_FALSE;
-  fxMesa->new_state|=FX_NEW_TEXTURING;
-  ctx->Driver.RenderStart = fxSetupFXUnits;
+   ti->validated = GL_FALSE;
+   fxMesa->new_state |= FX_NEW_TEXTURING;
 }
 
-static tfxTexInfo *fxAllocTexObjData(fxMesaContext fxMesa)
+static tfxTexInfo *
+fxAllocTexObjData(fxMesaContext fxMesa)
 {
-  tfxTexInfo *ti;
-  int i;
+   tfxTexInfo *ti;
 
-  if(!(ti=malloc(sizeof(tfxTexInfo)))) {
-    fprintf(stderr,"fx Driver: out of memory !\n");
-    fxCloseHardware();
-    exit(-1);
-  }
-
-  ti->validated=GL_FALSE;
-  ti->tmi.isInTM=GL_FALSE;
+   if (!(ti = CALLOC(sizeof(tfxTexInfo)))) {
+      fprintf(stderr, "fx Driver: out of memory !\n");
+      fxCloseHardware();
+      exit(-1);
+   }
 
-  ti->tmi.whichTMU=FX_TMU_NONE;
+   ti->validated = GL_FALSE;
+   ti->isInTM = GL_FALSE;
 
-  ti->tmi.tm[FX_TMU0]=NULL;
-  ti->tmi.tm[FX_TMU1]=NULL;
+   ti->whichTMU = FX_TMU_NONE;
 
-  ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
-  ti->maxFilt=GR_TEXTUREFILTER_BILINEAR;
+   ti->tm[FX_TMU0] = NULL;
+   ti->tm[FX_TMU1] = NULL;
 
-  ti->sClamp=GR_TEXTURECLAMP_WRAP;
-  ti->tClamp=GR_TEXTURECLAMP_WRAP;
+   ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
+   ti->maxFilt = GR_TEXTUREFILTER_BILINEAR;
 
-  if(fxMesa->haveTwoTMUs) {
-    ti->mmMode=GR_MIPMAP_NEAREST;
-    ti->LODblend=FXTRUE;
-  } else {
-    ti->mmMode=GR_MIPMAP_NEAREST_DITHER;
-    ti->LODblend=FXFALSE;
-  }
+   ti->sClamp = GR_TEXTURECLAMP_WRAP;
+   ti->tClamp = GR_TEXTURECLAMP_WRAP;
 
-  for(i=0;i<MAX_TEXTURE_LEVELS;i++) {
-    ti->tmi.mipmapLevel[i].used=GL_FALSE;
-    ti->tmi.mipmapLevel[i].data=NULL;
-  }
+   ti->mmMode = GR_MIPMAP_NEAREST;
+   ti->LODblend = FXFALSE;
 
-  return ti;
+   return ti;
 }
 
-void fxDDTexBind(GLcontext *ctx, GLenum target, struct gl_texture_object *tObj)
+void
+fxDDTexBind(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj)
 {
-  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
-  tfxTexInfo *ti;
+   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+   tfxTexInfo *ti;
 
-  if (MESA_VERBOSE&VERBOSE_DRIVER) {
-     fprintf(stderr,"fxmesa: fxDDTexBind(%d,%x)\n",tObj->Name,(GLuint)tObj->DriverData);
-  }
+   if (MESA_VERBOSE & VERBOSE_DRIVER) {
+      fprintf(stderr, "fxmesa: fxDDTexBind(%d,%x)\n", tObj->Name,
+             (GLuint) tObj->DriverData);
+   }
 
-  if(target!=GL_TEXTURE_2D)
-    return;
+   if (target != GL_TEXTURE_2D)
+      return;
 
-  if(!tObj->DriverData)
-    tObj->DriverData=fxAllocTexObjData(fxMesa);
+   if (!tObj->DriverData) {
+      tObj->DriverData = fxAllocTexObjData(fxMesa);
+   }
 
-  ti=(tfxTexInfo *)tObj->DriverData;
+   ti = fxTMGetTexInfo(tObj);
 
-  fxMesa->texBindNumber++;
-  ti->tmi.lastTimeUsed=fxMesa->texBindNumber;
+   fxMesa->texBindNumber++;
+   ti->lastTimeUsed = fxMesa->texBindNumber;
 
-  fxMesa->new_state|=FX_NEW_TEXTURING;
-  ctx->Driver.RenderStart = fxSetupFXUnits;
+   fxMesa->new_state |= FX_NEW_TEXTURING;
 }
 
-void fxDDTexEnv(GLcontext *ctx, GLenum pname, const GLfloat *param)
+void
+fxDDTexEnv(GLcontext * ctx, GLenum target, GLenum pname,
+          const GLfloat * param)
 {
-  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
 
-   if (MESA_VERBOSE&VERBOSE_DRIVER) {
-      if(param)
-        fprintf(stderr,"fxmesa: texenv(%x,%x)\n",pname,(GLint)(*param));
+   if (MESA_VERBOSE & VERBOSE_DRIVER) {
+      if (param)
+        fprintf(stderr, "fxmesa: texenv(%x,%x)\n", pname, (GLint) (*param));
       else
-        fprintf(stderr,"fxmesa: texenv(%x)\n",pname);
+        fprintf(stderr, "fxmesa: texenv(%x)\n", pname);
    }
 
-   fxMesa->new_state|=FX_NEW_TEXTURING;
-   ctx->Driver.RenderStart = fxSetupFXUnits;
-}
+   /* apply any lod biasing right now */
+   if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
+      FX_grTexLodBiasValue(GR_TMU0, *param);
 
-void fxDDTexParam(GLcontext *ctx, GLenum target, struct gl_texture_object *tObj,
-                  GLenum pname, const GLfloat *params)
-{
-  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
-  GLenum param=(GLenum)(GLint)params[0];
-  tfxTexInfo *ti;
+      if (fxMesa->haveTwoTMUs) {
+        FX_grTexLodBiasValue(GR_TMU1, *param);
+      }
 
-  if (MESA_VERBOSE&VERBOSE_DRIVER) {
-     fprintf(stderr,"fxmesa: fxDDTexParam(%d,%x,%x,%x)\n",tObj->Name,(GLuint)tObj->DriverData,pname,param);
-  }
+   }
 
-  if(target!=GL_TEXTURE_2D)
-    return;
+   fxMesa->new_state |= FX_NEW_TEXTURING;
+}
 
-  if(!tObj->DriverData)
-    tObj->DriverData=fxAllocTexObjData(fxMesa);
+void
+fxDDTexParam(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj,
+            GLenum pname, const GLfloat * params)
+{
+   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+   GLenum param = (GLenum) (GLint) params[0];
+   tfxTexInfo *ti;
 
-  ti=(tfxTexInfo *)tObj->DriverData;
+   if (MESA_VERBOSE & VERBOSE_DRIVER) {
+      fprintf(stderr, "fxmesa: fxDDTexParam(%d,%x,%x,%x)\n", tObj->Name,
+             (GLuint) tObj->DriverData, pname, param);
+   }
 
-  switch(pname) {
+   if (target != GL_TEXTURE_2D)
+      return;
 
-  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_NEAREST:
-      ti->mmMode=GR_MIPMAP_NEAREST;
-      ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
-      ti->LODblend=FXFALSE;
+   if (!tObj->DriverData)
+      tObj->DriverData = fxAllocTexObjData(fxMesa);
+
+   ti = fxTMGetTexInfo(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_NEAREST:
+        ti->mmMode = GR_MIPMAP_NEAREST;
+        ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
+        ti->LODblend = FXFALSE;
+        break;
+      case GL_LINEAR_MIPMAP_NEAREST:
+        ti->mmMode = GR_MIPMAP_NEAREST;
+        ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
+        ti->LODblend = FXFALSE;
+        break;
+      case GL_NEAREST_MIPMAP_LINEAR:
+        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;
+      case GL_LINEAR_MIPMAP_LINEAR:
+        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;
+      default:
+        break;
+      }
+      fxTexInvalidate(ctx, tObj);
       break;
-    case GL_LINEAR_MIPMAP_NEAREST:
-      ti->mmMode=GR_MIPMAP_NEAREST;
-      ti->minFilt=GR_TEXTUREFILTER_BILINEAR;
-      ti->LODblend=FXFALSE;
+
+   case GL_TEXTURE_MAG_FILTER:
+      switch (param) {
+      case GL_NEAREST:
+        ti->maxFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
+        break;
+      case GL_LINEAR:
+        ti->maxFilt = GR_TEXTUREFILTER_BILINEAR;
+        break;
+      default:
+        break;
+      }
+      fxTexInvalidate(ctx, tObj);
       break;
-    case GL_NEAREST_MIPMAP_LINEAR:
-      if(fxMesa->haveTwoTMUs) {
-        ti->mmMode=GR_MIPMAP_NEAREST;
-        ti->LODblend=FXTRUE;
-      } else {
-        ti->mmMode=GR_MIPMAP_NEAREST_DITHER;
-        ti->LODblend=FXFALSE;
+
+   case GL_TEXTURE_WRAP_S:
+      switch (param) {
+      case GL_CLAMP:
+        ti->sClamp = GR_TEXTURECLAMP_CLAMP;
+        break;
+      case GL_REPEAT:
+        ti->sClamp = GR_TEXTURECLAMP_WRAP;
+        break;
+      default:
+        break;
       }
-      ti->minFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
+      fxMesa->new_state |= FX_NEW_TEXTURING;
       break;
-    case GL_LINEAR_MIPMAP_LINEAR:
-      if(fxMesa->haveTwoTMUs) {
-        ti->mmMode=GR_MIPMAP_NEAREST;
-        ti->LODblend=FXTRUE;
-      } else {
-        ti->mmMode=GR_MIPMAP_NEAREST_DITHER;
-        ti->LODblend=FXFALSE;
+
+   case GL_TEXTURE_WRAP_T:
+      switch (param) {
+      case GL_CLAMP:
+        ti->tClamp = GR_TEXTURECLAMP_CLAMP;
+        break;
+      case GL_REPEAT:
+        ti->tClamp = GR_TEXTURECLAMP_WRAP;
+        break;
+      default:
+        break;
       }
-      ti->minFilt=GR_TEXTUREFILTER_BILINEAR;
+      fxMesa->new_state |= FX_NEW_TEXTURING;
       break;
-    default:
+
+   case GL_TEXTURE_BORDER_COLOR:
+      /* TO DO */
       break;
-    }
-    fxTexInvalidate(ctx,tObj);
-    break;
-
-  case GL_TEXTURE_MAG_FILTER:
-    switch(param) {
-    case GL_NEAREST:
-      ti->maxFilt=GR_TEXTUREFILTER_POINT_SAMPLED;
+
+   case GL_TEXTURE_MIN_LOD:
+      /* TO DO */
       break;
-    case GL_LINEAR:
-      ti->maxFilt=GR_TEXTUREFILTER_BILINEAR;
+   case GL_TEXTURE_MAX_LOD:
+      /* TO DO */
       break;
-    default:
+   case GL_TEXTURE_BASE_LEVEL:
+      fxTexInvalidate(ctx, tObj);
       break;
-    }
-    fxTexInvalidate(ctx,tObj);
-    break;
-
-  case GL_TEXTURE_WRAP_S:
-    switch(param) {
-    case GL_CLAMP:
-      ti->sClamp=GR_TEXTURECLAMP_CLAMP;
+   case GL_TEXTURE_MAX_LEVEL:
+      fxTexInvalidate(ctx, tObj);
       break;
-    case GL_REPEAT:
-      ti->sClamp=GR_TEXTURECLAMP_WRAP;
+
+   default:
       break;
-    default:
+   }
+}
+
+void
+fxDDTexDel(GLcontext * ctx, struct gl_texture_object *tObj)
+{
+   fxMesaContext fxMesa = FX_CONTEXT(ctx);
+   tfxTexInfo *ti = fxTMGetTexInfo(tObj);
+
+   if (MESA_VERBOSE & VERBOSE_DRIVER) {
+      fprintf(stderr, "fxmesa: fxDDTexDel(%d,%p)\n", tObj->Name, ti);
+   }
+
+   if (!ti)
+      return;
+
+   fxTMFreeTexture(fxMesa, tObj);
+
+   FREE(ti);
+   tObj->DriverData = NULL;
+}
+
+
+
+/*
+ * Convert a gl_color_table texture palette to Glide's format.
+ */
+static void
+convertPalette(FxU32 data[256], const struct gl_color_table *table)
+{
+   const GLubyte *tableUB = (const GLubyte *) table->Table;
+   GLint width = table->Size;
+   FxU32 r, g, b, a;
+   GLint i;
+
+   ASSERT(!table->FloatTable);
+
+   switch (table->Format) {
+   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;
+      }
+      break;
+   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;
+      }
       break;
-    }
-    fxMesa->new_state|=FX_NEW_TEXTURING;
-    ctx->Driver.RenderStart = fxSetupFXUnits;
-    break;
-
-  case GL_TEXTURE_WRAP_T:
-    switch(param) {
-    case GL_CLAMP:
-      ti->tClamp=GR_TEXTURECLAMP_CLAMP;
+   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;
+      }
       break;
-    case GL_REPEAT:
-      ti->tClamp=GR_TEXTURECLAMP_WRAP;
+   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;
+      }
+      break;
+   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;
+      }
       break;
-    default:
+   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;
+      }
       break;
-    }
-    fxMesa->new_state|=FX_NEW_TEXTURING;
-    ctx->Driver.RenderStart = fxSetupFXUnits;
-    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:
-    fxTexInvalidate(ctx,tObj);
-    break;
-  case GL_TEXTURE_MAX_LEVEL:
-    fxTexInvalidate(ctx,tObj);
-    break;
-
-  default:
-    break;
-  }
+   }
 }
 
-void fxDDTexDel(GLcontext *ctx, struct gl_texture_object *tObj)
+
+void
+fxDDTexPalette(GLcontext * ctx, struct gl_texture_object *tObj)
 {
-  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
-  tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData;
+   fxMesaContext fxMesa = FX_CONTEXT(ctx);
 
-  if (MESA_VERBOSE&VERBOSE_DRIVER) {
-     fprintf(stderr,"fxmesa: fxDDTexDel(%d,%x)\n",tObj->Name,(GLuint)ti);
-  }
+   if (tObj) {
+      /* per-texture palette */
+      tfxTexInfo *ti;
+      if (MESA_VERBOSE & VERBOSE_DRIVER) {
+        fprintf(stderr, "fxmesa: fxDDTexPalette(%d,%x)\n",
+                tObj->Name, (GLuint) tObj->DriverData);
+      }
+      if (!tObj->DriverData)
+        tObj->DriverData = fxAllocTexObjData(fxMesa);
+      ti = fxTMGetTexInfo(tObj);
+      convertPalette(ti->palette.data, &tObj->Palette);
+      fxTexInvalidate(ctx, tObj);
+   }
+   else {
+      /* global texture palette */
+      if (MESA_VERBOSE & VERBOSE_DRIVER) {
+        fprintf(stderr, "fxmesa: fxDDTexPalette(global)\n");
+      }
+      convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette);
+      fxMesa->new_state |= FX_NEW_TEXTURING;
+   }
+}
 
-  if(!ti)
-    return;
 
-  fxTMFreeTexture(fxMesa,tObj);
+void
+fxDDTexUseGlbPalette(GLcontext * ctx, GLboolean state)
+{
+   fxMesaContext fxMesa = FX_CONTEXT(ctx);
 
-  free(ti);
-  tObj->DriverData=NULL;
+   if (MESA_VERBOSE & VERBOSE_DRIVER) {
+      fprintf(stderr, "fxmesa: fxDDTexUseGlbPalette(%d)\n", state);
+   }
+
+   if (state) {
+      fxMesa->haveGlobalPaletteTexture = 1;
+
+      FX_grTexDownloadTable(GR_TMU0, GR_TEXTABLE_PALETTE,
+                           &(fxMesa->glbPalette));
+      if (fxMesa->haveTwoTMUs)
+        FX_grTexDownloadTable(GR_TMU1, GR_TEXTABLE_PALETTE,
+                              &(fxMesa->glbPalette));
+   }
+   else {
+      fxMesa->haveGlobalPaletteTexture = 0;
 
-  ctx->NewState|=NEW_TEXTURING;
+      if ((ctx->Texture.Unit[0]._Current == ctx->Texture.Unit[0].Current2D) &&
+         (ctx->Texture.Unit[0]._Current != NULL)) {
+        struct gl_texture_object *tObj = ctx->Texture.Unit[0]._Current;
+
+        if (!tObj->DriverData)
+           tObj->DriverData = fxAllocTexObjData(fxMesa);
+
+        fxTexInvalidate(ctx, tObj);
+      }
+   }
 }
 
-void fxDDTexPalette(GLcontext *ctx, struct gl_texture_object *tObj)
+
+static int
+logbase2(int n)
 {
-  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
-  int i;
-  FxU32 r,g,b,a;
-  tfxTexInfo *ti;
-
-  if(tObj) {  
-     if (MESA_VERBOSE&VERBOSE_DRIVER) {
-       fprintf(stderr,"fxmesa: fxDDTexPalette(%d,%x)\n",tObj->Name,(GLuint)tObj->DriverData);
-     }
-
-    if(tObj->PaletteFormat!=GL_RGBA) {
-#ifndef FX_SILENT
-      fprintf(stderr,"fx Driver: unsupported palette format in texpalette()\n");
-#endif
-      return;
-    }
+   GLint i = 1;
+   GLint log2 = 0;
 
-    if(tObj->PaletteSize>256) {
-#ifndef FX_SILENT
-      fprintf(stderr,"fx Driver: unsupported palette size in texpalette()\n");
-#endif
-      return;
-    }
-
-    if(!tObj->DriverData)
-      tObj->DriverData=fxAllocTexObjData(fxMesa);
-  
-    ti=(tfxTexInfo *)tObj->DriverData;
-
-    for(i=0;i<tObj->PaletteSize;i++) {
-      r=tObj->Palette[i*4];
-      g=tObj->Palette[i*4+1];
-      b=tObj->Palette[i*4+2];
-      a=tObj->Palette[i*4+3];
-      ti->palette.data[i]=(a<<24)|(r<<16)|(g<<8)|b;
-    }
-
-    fxTexInvalidate(ctx,tObj);
-  } else {
-     if (MESA_VERBOSE&VERBOSE_DRIVER) {
-       fprintf(stderr,"fxmesa: fxDDTexPalette(global)\n");
-     }
-    if(ctx->Texture.PaletteFormat!=GL_RGBA) {
-#ifndef FX_SILENT
-      fprintf(stderr,"fx Driver: unsupported palette format in texpalette()\n");
-#endif
-      return;
-    }
+   if (n < 0) {
+      return -1;
+   }
 
-    if(ctx->Texture.PaletteSize>256) {
-#ifndef FX_SILENT
-      fprintf(stderr,"fx Driver: unsupported palette size in texpalette()\n");
-#endif
-      return;
-    }
-
-    for(i=0;i<ctx->Texture.PaletteSize;i++) {
-      r=ctx->Texture.Palette[i*4];
-      g=ctx->Texture.Palette[i*4+1];
-      b=ctx->Texture.Palette[i*4+2];
-      a=ctx->Texture.Palette[i*4+3];
-      fxMesa->glbPalette.data[i]=(a<<24)|(r<<16)|(g<<8)|b;
-    }
-
-    fxMesa->new_state|=FX_NEW_TEXTURING;
-    ctx->Driver.RenderStart = fxSetupFXUnits;
-  }
+   while (n > i) {
+      i *= 2;
+      log2++;
+   }
+   if (i != n) {
+      return -1;
+   }
+   else {
+      return log2;
+   }
 }
 
-void fxDDTexUseGlbPalette(GLcontext *ctx, GLboolean state)
+/* Need different versions for different cpus.
+ */
+#define INT_TRICK(l2) (0x800000 * l2)
+
+
+int
+fxTexGetInfo(int w, int h, GrLOD_t * lodlevel, GrAspectRatio_t * ar,
+            float *sscale, float *tscale,
+            int *i_sscale, int *i_tscale, int *wscale, int *hscale)
 {
-  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
 
-  if (MESA_VERBOSE&VERBOSE_DRIVER) {
-     fprintf(stderr,"fxmesa: fxDDTexUseGlbPalette(%d)\n",state);
-  }
+   static GrLOD_t lod[9] = { GR_LOD_256, GR_LOD_128, GR_LOD_64, GR_LOD_32,
+      GR_LOD_16, GR_LOD_8, GR_LOD_4, GR_LOD_2, GR_LOD_1
+   };
+
+   int logw, logh, ws, hs;
+   GrLOD_t l;
+   GrAspectRatio_t aspectratio;
+   float s, t;
+   int is, it;
+
+   logw = logbase2(w);
+   logh = logbase2(h);
+
+   switch (logw - logh) {
+   case 0:
+      aspectratio = GR_ASPECT_1x1;
+      l = lod[8 - logw];
+      s = t = 256.0f;
+      is = it = INT_TRICK(8);
+      ws = hs = 1;
+      break;
+   case 1:
+      aspectratio = GR_ASPECT_2x1;
+      l = lod[8 - logw];
+      s = 256.0f;
+      t = 128.0f;
+      is = INT_TRICK(8);
+      it = INT_TRICK(7);
+      ws = 1;
+      hs = 1;
+      break;
+   case 2:
+      aspectratio = GR_ASPECT_4x1;
+      l = lod[8 - logw];
+      s = 256.0f;
+      t = 64.0f;
+      is = INT_TRICK(8);
+      it = INT_TRICK(6);
+      ws = 1;
+      hs = 1;
+      break;
+   case 3:
+      aspectratio = GR_ASPECT_8x1;
+      l = lod[8 - logw];
+      s = 256.0f;
+      t = 32.0f;
+      is = INT_TRICK(8);
+      it = INT_TRICK(5);
+      ws = 1;
+      hs = 1;
+      break;
+   case 4:
+      aspectratio = GR_ASPECT_8x1;
+      l = lod[8 - logw];
+      s = 256.0f;
+      t = 32.0f;
+      is = INT_TRICK(8);
+      it = INT_TRICK(5);
+      ws = 1;
+      hs = 2;
+      break;
+   case 5:
+      aspectratio = GR_ASPECT_8x1;
+      l = lod[8 - logw];
+      s = 256.0f;
+      t = 32.0f;
+      is = INT_TRICK(8);
+      it = INT_TRICK(5);
+      ws = 1;
+      hs = 4;
+      break;
+   case 6:
+      aspectratio = GR_ASPECT_8x1;
+      l = lod[8 - logw];
+      s = 256.0f;
+      t = 32.0f;
+      is = INT_TRICK(8);
+      it = INT_TRICK(5);
+      ws = 1;
+      hs = 8;
+      break;
+   case 7:
+      aspectratio = GR_ASPECT_8x1;
+      l = lod[8 - logw];
+      s = 256.0f;
+      t = 32.0f;
+      is = INT_TRICK(8);
+      it = INT_TRICK(5);
+      ws = 1;
+      hs = 16;
+      break;
+   case 8:
+      aspectratio = GR_ASPECT_8x1;
+      l = lod[8 - logw];
+      s = 256.0f;
+      t = 32.0f;
+      is = INT_TRICK(8);
+      it = INT_TRICK(5);
+      ws = 1;
+      hs = 32;
+      break;
+   case -1:
+      aspectratio = GR_ASPECT_1x2;
+      l = lod[8 - logh];
+      s = 128.0f;
+      t = 256.0f;
+      is = INT_TRICK(7);
+      it = INT_TRICK(8);
+      ws = 1;
+      hs = 1;
+      break;
+   case -2:
+      aspectratio = GR_ASPECT_1x4;
+      l = lod[8 - logh];
+      s = 64.0f;
+      t = 256.0f;
+      is = INT_TRICK(6);
+      it = INT_TRICK(8);
+      ws = 1;
+      hs = 1;
+      break;
+   case -3:
+      aspectratio = GR_ASPECT_1x8;
+      l = lod[8 - logh];
+      s = 32.0f;
+      t = 256.0f;
+      is = INT_TRICK(5);
+      it = INT_TRICK(8);
+      ws = 1;
+      hs = 1;
+      break;
+   case -4:
+      aspectratio = GR_ASPECT_1x8;
+      l = lod[8 - logh];
+      s = 32.0f;
+      t = 256.0f;
+      is = INT_TRICK(5);
+      it = INT_TRICK(8);
+      ws = 2;
+      hs = 1;
+      break;
+   case -5:
+      aspectratio = GR_ASPECT_1x8;
+      l = lod[8 - logh];
+      s = 32.0f;
+      t = 256.0f;
+      is = INT_TRICK(5);
+      it = INT_TRICK(8);
+      ws = 4;
+      hs = 1;
+      break;
+   case -6:
+      aspectratio = GR_ASPECT_1x8;
+      l = lod[8 - logh];
+      s = 32.0f;
+      t = 256.0f;
+      is = INT_TRICK(5);
+      it = INT_TRICK(8);
+      ws = 8;
+      hs = 1;
+      break;
+   case -7:
+      aspectratio = GR_ASPECT_1x8;
+      l = lod[8 - logh];
+      s = 32.0f;
+      t = 256.0f;
+      is = INT_TRICK(5);
+      it = INT_TRICK(8);
+      ws = 16;
+      hs = 1;
+      break;
+   case -8:
+      aspectratio = GR_ASPECT_1x8;
+      l = lod[8 - logh];
+      s = 32.0f;
+      t = 256.0f;
+      is = INT_TRICK(5);
+      it = INT_TRICK(8);
+      ws = 32;
+      hs = 1;
+      break;
+   default:
+      return 0;
+      break;
+   }
 
-  if(state) {
-    fxMesa->haveGlobalPaletteTexture=1;
+   if (lodlevel)
+      (*lodlevel) = l;
 
-    FX_grTexDownloadTable(GR_TMU0,GR_TEXTABLE_PALETTE,&(fxMesa->glbPalette));
-    if (fxMesa->haveTwoTMUs)
-       FX_grTexDownloadTable(GR_TMU1,GR_TEXTABLE_PALETTE,&(fxMesa->glbPalette));
-  } else {
-    fxMesa->haveGlobalPaletteTexture=0;
+   if (ar)
+      (*ar) = aspectratio;
 
-    if((ctx->Texture.Unit[0].Current==ctx->Texture.Unit[0].CurrentD[2]) &&
-       (ctx->Texture.Unit[0].Current!=NULL)) {
-      struct gl_texture_object *tObj=ctx->Texture.Unit[0].Current;
-      tfxTexInfo *ti;
+   if (sscale)
+      (*sscale) = s;
+
+   if (tscale)
+      (*tscale) = t;
+
+   if (wscale)
+      (*wscale) = ws;
+
+   if (hscale)
+      (*hscale) = hs;
+
+   if (i_sscale)
+      *i_sscale = is;
 
-      if(!tObj->DriverData)
-        tObj->DriverData=fxAllocTexObjData(fxMesa);
-  
-      ti=(tfxTexInfo *)tObj->DriverData;
+   if (i_tscale)
+      *i_tscale = it;
 
-      fxTexInvalidate(ctx,tObj);
-    }
-  }
+
+   return 1;
 }
 
-static int logbase2(int n)
+/*
+ * Given an OpenGL internal texture format, return the corresponding
+ * Glide internal texture format and base texture format.
+ */
+void
+fxTexGetFormat(GLenum glformat, GrTextureFormat_t * tfmt, GLint * ifmt)
 {
-  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;
-  }
+   switch (glformat) {
+   case 1:
+   case GL_LUMINANCE:
+   case GL_LUMINANCE4:
+   case GL_LUMINANCE8:
+   case GL_LUMINANCE12:
+   case GL_LUMINANCE16:
+      if (tfmt)
+        (*tfmt) = GR_TEXFMT_INTENSITY_8;
+      if (ifmt)
+        (*ifmt) = GL_LUMINANCE;
+      break;
+   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:
+      if (tfmt)
+        (*tfmt) = GR_TEXFMT_ALPHA_INTENSITY_88;
+      if (ifmt)
+        (*ifmt) = GL_LUMINANCE_ALPHA;
+      break;
+   case GL_INTENSITY:
+   case GL_INTENSITY4:
+   case GL_INTENSITY8:
+   case GL_INTENSITY12:
+   case GL_INTENSITY16:
+      if (tfmt)
+        (*tfmt) = GR_TEXFMT_ALPHA_8;
+      if (ifmt)
+        (*ifmt) = GL_INTENSITY;
+      break;
+   case GL_ALPHA:
+   case GL_ALPHA4:
+   case GL_ALPHA8:
+   case GL_ALPHA12:
+   case GL_ALPHA16:
+      if (tfmt)
+        (*tfmt) = GR_TEXFMT_ALPHA_8;
+      if (ifmt)
+        (*ifmt) = GL_ALPHA;
+      break;
+   case 3:
+   case GL_RGB:
+   case GL_R3_G3_B2:
+   case GL_RGB4:
+   case GL_RGB5:
+   case GL_RGB8:
+   case GL_RGB10:
+   case GL_RGB12:
+   case GL_RGB16:
+      if (tfmt)
+        (*tfmt) = GR_TEXFMT_RGB_565;
+      if (ifmt)
+        (*ifmt) = GL_RGB;
+      break;
+   case 4:
+   case GL_RGBA:
+   case GL_RGBA2:
+   case GL_RGBA4:
+   case GL_RGBA8:
+   case GL_RGB10_A2:
+   case GL_RGBA12:
+   case GL_RGBA16:
+      if (tfmt)
+        (*tfmt) = GR_TEXFMT_ARGB_4444;
+      if (ifmt)
+        (*ifmt) = GL_RGBA;
+      break;
+   case GL_RGB5_A1:
+      if (tfmt)
+        (*tfmt) = GR_TEXFMT_ARGB_1555;
+      if (ifmt)
+        (*ifmt) = GL_RGBA;
+      break;
+   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:
+      if (tfmt)
+        (*tfmt) = GR_TEXFMT_P_8;
+      if (ifmt)
+        (*ifmt) = GL_RGBA;     /* XXX why is this RGBA? */
+      break;
+   default:
+      fprintf(stderr,
+             "fx Driver: unsupported internalFormat (0x%x) in fxTexGetFormat()\n",
+             glformat);
+      fxCloseHardware();
+      exit(-1);
+      break;
+   }
 }
 
-/* Need different versions for different cpus.
- */
-#define INT_TRICK(l2) (0x800000 * l2)
+static GLboolean
+fxIsTexSupported(GLenum target, GLint internalFormat,
+                const struct gl_texture_image *image)
+{
+   if (target != GL_TEXTURE_2D)
+      return GL_FALSE;
 
+   if (!fxTexGetInfo
+       (image->Width, image->Height, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+       NULL)) return GL_FALSE;
 
-int fxTexGetInfo(int w, int h, GrLOD_t *lodlevel, GrAspectRatio_t *ar,
-                 float *sscale, float *tscale,
-                 int *i_sscale, int *i_tscale,
-                 int *wscale, int *hscale)
-{
+   if (image->Border > 0)
+      return GL_FALSE;
 
-  static GrLOD_t lod[9]={GR_LOD_256,GR_LOD_128,GR_LOD_64,GR_LOD_32,
-                         GR_LOD_16,GR_LOD_8,GR_LOD_4,GR_LOD_2,GR_LOD_1};
-
-  int logw,logh,ws,hs;
-  GrLOD_t l;
-  GrAspectRatio_t aspectratio;
-  float s,t;
-  int is,it;
-
-  logw=logbase2(w);
-  logh=logbase2(h);
-
-  switch(logw-logh) {
-  case 0:
-    aspectratio=GR_ASPECT_1x1;
-    l=lod[8-logw];
-    s=t=256.0f;
-    is=it=INT_TRICK(8);
-    ws=hs=1;
-    break;
-  case 1:
-    aspectratio=GR_ASPECT_2x1;
-    l=lod[8-logw];
-    s=256.0f;
-    t=128.0f;
-    is=INT_TRICK(8);it=INT_TRICK(7);
-    ws=1;
-    hs=1;
-    break;
-  case 2:
-    aspectratio=GR_ASPECT_4x1;
-    l=lod[8-logw];
-    s=256.0f;
-    t=64.0f;
-    is=INT_TRICK(8);it=INT_TRICK(6);
-    ws=1;
-    hs=1;
-    break;
-  case 3:
-    aspectratio=GR_ASPECT_8x1;
-    l=lod[8-logw];
-    s=256.0f;
-    t=32.0f;
-    is=INT_TRICK(8);it=INT_TRICK(5);
-    ws=1;
-    hs=1;
-    break;
-  case 4:
-    aspectratio=GR_ASPECT_8x1;
-    l=lod[8-logw];
-    s=256.0f;
-    t=32.0f;
-    is=INT_TRICK(8);it=INT_TRICK(5);
-    ws=1;
-    hs=2;
-    break;
-  case 5:
-    aspectratio=GR_ASPECT_8x1;
-    l=lod[8-logw];
-    s=256.0f;
-    t=32.0f;
-    is=INT_TRICK(8);it=INT_TRICK(5);
-    ws=1;
-    hs=4;
-    break;
-  case 6:
-    aspectratio=GR_ASPECT_8x1;
-    l=lod[8-logw];
-    s=256.0f;
-    t=32.0f;
-    is=INT_TRICK(8);it=INT_TRICK(5);
-    ws=1;
-    hs=8;
-    break;
-  case 7:
-    aspectratio=GR_ASPECT_8x1;
-    l=lod[8-logw];
-    s=256.0f;
-    t=32.0f;
-    is=INT_TRICK(8);it=INT_TRICK(5);
-    ws=1;
-    hs=16;
-    break;
-  case 8:
-    aspectratio=GR_ASPECT_8x1;
-    l=lod[8-logw];
-    s=256.0f;
-    t=32.0f;
-    is=INT_TRICK(8);it=INT_TRICK(5);
-    ws=1;
-    hs=32;
-    break;
-  case -1:
-    aspectratio=GR_ASPECT_1x2;
-    l=lod[8-logh];
-    s=128.0f;
-    t=256.0f;
-    is=INT_TRICK(7);it=INT_TRICK(8);
-    ws=1;
-    hs=1;
-    break;
-  case -2:
-    aspectratio=GR_ASPECT_1x4;
-    l=lod[8-logh];
-    s=64.0f;
-    t=256.0f;
-    is=INT_TRICK(6);it=INT_TRICK(8);
-    ws=1;
-    hs=1;
-    break;
-  case -3:
-    aspectratio=GR_ASPECT_1x8;
-    l=lod[8-logh];
-    s=32.0f;
-    t=256.0f;
-    is=INT_TRICK(5);it=INT_TRICK(8);
-    ws=1;
-    hs=1;
-    break;
-  case -4:
-    aspectratio=GR_ASPECT_1x8;
-    l=lod[8-logh];
-    s=32.0f;
-    t=256.0f;
-    is=INT_TRICK(5);it=INT_TRICK(8);
-    ws=2;
-    hs=1;
-    break;
-  case -5:
-    aspectratio=GR_ASPECT_1x8;
-    l=lod[8-logh];
-    s=32.0f;
-    t=256.0f;
-    is=INT_TRICK(5);it=INT_TRICK(8);
-    ws=4;
-    hs=1;
-    break;
-  case -6:
-    aspectratio=GR_ASPECT_1x8;
-    l=lod[8-logh];
-    s=32.0f;
-    t=256.0f;
-    is=INT_TRICK(5);it=INT_TRICK(8);
-    ws=8;
-    hs=1;
-    break;
-  case -7:
-    aspectratio=GR_ASPECT_1x8;
-    l=lod[8-logh];
-    s=32.0f;
-    t=256.0f;
-    is=INT_TRICK(5);it=INT_TRICK(8);
-    ws=16;
-    hs=1;
-    break;
-  case -8:
-    aspectratio=GR_ASPECT_1x8;
-    l=lod[8-logh];
-    s=32.0f;
-    t=256.0f;
-    is=INT_TRICK(5);it=INT_TRICK(8);
-    ws=32;
-    hs=1;
-    break;
-  default:
-    return 0;
-    break;
-  }
-
-  if(lodlevel)
-    (*lodlevel)=l;
-
-  if(ar)
-    (*ar)=aspectratio;
-
-  if(sscale)
-    (*sscale)=s;
-
-  if(tscale)
-    (*tscale)=t;
-
-  if(wscale)
-    (*wscale)=ws;
-
-  if(hscale)
-    (*hscale)=hs;
-
-  if (i_sscale)
-     *i_sscale = is;
-
-  if (i_tscale)
-     *i_tscale = it;
-
-
-  return 1;
+   return GL_TRUE;
 }
 
-void fxTexGetFormat(GLenum glformat, GrTextureFormat_t *tfmt, GLint *ifmt)
+
+/**********************************************************************/
+/**** NEW TEXTURE IMAGE FUNCTIONS                                  ****/
+/**********************************************************************/
+
+/* 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.
+ */
+
+static void
+fetch_intensity8(const struct gl_texture_image *texImage,
+                GLint i, GLint j, GLint k, GLvoid * texelOut)
 {
-  switch(glformat) {
-  case 1:
-  case GL_LUMINANCE:
-  case GL_LUMINANCE4:
-  case GL_LUMINANCE8:
-  case GL_LUMINANCE12:
-  case GL_LUMINANCE16:
-    if(tfmt)
-      (*tfmt)=GR_TEXFMT_INTENSITY_8;
-    if(ifmt)
-      (*ifmt)=GL_LUMINANCE;
-    break;
-  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:
-    if(tfmt)
-      (*tfmt)=GR_TEXFMT_ALPHA_INTENSITY_88;
-    if(ifmt)
-      (*ifmt)=GL_LUMINANCE_ALPHA;
-    break;
-  case GL_INTENSITY:
-  case GL_INTENSITY4:
-  case GL_INTENSITY8:
-  case GL_INTENSITY12:
-  case GL_INTENSITY16:
-    if(tfmt)
-      (*tfmt)=GR_TEXFMT_ALPHA_8;
-    if(ifmt)
-      (*ifmt)=GL_INTENSITY;
-    break;
-  case GL_ALPHA:
-  case GL_ALPHA4:
-  case GL_ALPHA8:
-  case GL_ALPHA12:
-  case GL_ALPHA16:
-    if(tfmt)
-      (*tfmt)=GR_TEXFMT_ALPHA_8;
-    if(ifmt)
-      (*ifmt)=GL_ALPHA;
-    break;
-  case 3:
-  case GL_RGB:
-  case GL_R3_G3_B2:
-  case GL_RGB4:
-  case GL_RGB5:
-  case GL_RGB8:
-  case GL_RGB10:
-  case GL_RGB12:
-  case GL_RGB16:
-    if(tfmt)
-      (*tfmt)=GR_TEXFMT_RGB_565;
-    if(ifmt)
-      (*ifmt)=GL_RGB;
-    break;
-  case 4:
-  case GL_RGBA:
-  case GL_RGBA2:
-  case GL_RGBA4:
-  case GL_RGB5_A1:
-  case GL_RGBA8:
-  case GL_RGB10_A2:
-  case GL_RGBA12:
-  case GL_RGBA16:
-    if(tfmt)
-      (*tfmt)=GR_TEXFMT_ARGB_4444;
-    if(ifmt)
-      (*ifmt)=GL_RGBA;
-    break;
-  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:
-    if(tfmt)
-      (*tfmt)=GR_TEXFMT_P_8;
-    if(ifmt)
-      (*ifmt)=GL_RGBA;
-    break;
-  default:
-    fprintf(stderr,"fx Driver: unsupported internalFormat in fxTexGetFormat()\n");
-    fxCloseHardware();
-    exit(-1);
-    break;
-  }
+   GLchan *rgba = (GLchan *) texelOut;
+   const tfxMipMapLevel *mml = FX_MIPMAP_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 int fxIsTexSupported(GLenum target, GLint internalFormat,
-                            const struct gl_texture_image *image)
+
+static void
+fetch_luminance8(const struct gl_texture_image *texImage,
+                GLint i, GLint j, GLint k, GLvoid * texelOut)
 {
-  if(target!=GL_TEXTURE_2D)
-    return GL_FALSE;
-
-  switch(internalFormat) {
-  case GL_INTENSITY:
-  case GL_INTENSITY4:
-  case GL_INTENSITY8:
-  case GL_INTENSITY12:
-  case GL_INTENSITY16:
-  case 1:
-  case GL_LUMINANCE:
-  case GL_LUMINANCE4:
-  case GL_LUMINANCE8:
-  case GL_LUMINANCE12:
-  case GL_LUMINANCE16:
-  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_ALPHA:
-  case GL_ALPHA4:
-  case GL_ALPHA8:
-  case GL_ALPHA12:
-  case GL_ALPHA16:
-  case 3:
-  case GL_RGB:
-  case GL_R3_G3_B2:
-  case GL_RGB4:
-  case GL_RGB5:
-  case GL_RGB8:
-  case GL_RGB10:
-  case GL_RGB12:
-  case GL_RGB16:
-  case 4:
-  case GL_RGBA:
-  case GL_RGBA2:
-  case GL_RGBA4:
-  case GL_RGB5_A1:
-  case GL_RGBA8:
-  case GL_RGB10_A2:
-  case GL_RGBA12:
-  case GL_RGBA16:
-  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:
-    break;
-  default:
-    return GL_FALSE;
-  }
-
-  if(image->Width>256)
-    return GL_FALSE;
-
-  if(image->Height>256)
-    return GL_FALSE;
-
-  if(!fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,
-                  NULL,NULL))
-    return GL_FALSE;
-
-  return GL_TRUE;
+   GLchan *rgba = (GLchan *) texelOut;
+   const tfxMipMapLevel *mml = FX_MIPMAP_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 fxTexBuildImageMap(const struct gl_texture_image *image,
-                               GLint internalFormat, unsigned short **dest,
-                               GLboolean *istranslate)
+
+static void
+fetch_alpha8(const struct gl_texture_image *texImage,
+            GLint i, GLint j, GLint k, GLvoid * texelOut)
 {
-  unsigned short *src;
-  unsigned char *data;
-  int x,y,w,h,wscale,hscale,idx;
-
-  fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,
-              &wscale,&hscale);
-  w=image->Width*wscale;
-  h=image->Height*hscale;
-
-  data=image->Data;
-  switch(internalFormat) {
-  case GL_INTENSITY:
-  case GL_INTENSITY4:
-  case GL_INTENSITY8:
-  case GL_INTENSITY12:
-  case GL_INTENSITY16:
-  case 1:
-  case GL_LUMINANCE:
-  case GL_LUMINANCE4:
-  case GL_LUMINANCE8:
-  case GL_LUMINANCE12:
-  case GL_LUMINANCE16:
-  case GL_ALPHA:
-  case GL_ALPHA4:
-  case GL_ALPHA8:
-  case GL_ALPHA12:
-  case GL_ALPHA16:
-  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:
-    /* Optimized for GLQuake */
-
-    if(wscale==hscale==1) {
-      (*istranslate)=GL_FALSE;
-
-      (*dest)=(unsigned short *)data;
-    } else {
-      unsigned char *srcb;
-
-      (*istranslate)=GL_TRUE;
-
-      if(!(*dest)) {
-        if(!((*dest)=src=(unsigned short *)malloc(sizeof(unsigned char)*w*h))) {
-          fprintf(stderr,"fx Driver: out of memory !\n");
-          fxCloseHardware();
-          exit(-1);
-        }
-      } else
-        src=(*dest);
-
-      srcb=(unsigned char *)src;
-
-      for(y=0;y<h;y++)
-        for(x=0;x<w;x++) {
-          idx=(x/wscale+(y/hscale)*(w/wscale));
-          srcb[x+y*w]=data[idx];
-        }
-    }
-    break;
-  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:
-    (*istranslate)=GL_TRUE;
-
-    if(!(*dest)) {
-      if(!((*dest)=src=(unsigned short *)malloc(sizeof(unsigned short)*w*h))) {
-        fprintf(stderr,"fx Driver: out of memory !\n");
-        fxCloseHardware();
-        exit(-1);
-      }
-    } else
-      src=(*dest);
+   GLchan *rgba = (GLchan *) texelOut;
+   const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
+   const GLubyte *texel;
+
+   i = i * mml->wScale;
+   j = j * mml->hScale;
+   i = i * mml->width / texImage->Width;
+   j = j * mml->height / texImage->Height;
+
+   texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
+   rgba[RCOMP] = 255;
+   rgba[GCOMP] = 255;
+   rgba[BCOMP] = 255;
+   rgba[ACOMP] = *texel;
+}
 
-    if(wscale==hscale==1) {
-      int i=0;
-      int lenght=h*w;
-      unsigned short a,l;
 
-      while(i++<lenght) {
-        l=*data++;
-        a=*data++;
+static void
+fetch_index8(const struct gl_texture_image *texImage,
+            GLint i, GLint j, GLint k, GLvoid * texelOut)
+{
+   /* XXX todo */
+}
 
-        *src++=(a << 8) | l;
-      }
-    } else {
-      unsigned short a,l;
-
-      for(y=0;y<h;y++)
-        for(x=0;x<w;x++) {
-          idx=(x/wscale+(y/hscale)*(w/wscale))*2;
-          l=data[idx];
-          a=data[idx+1];
-
-          src[x+y*w]=(a << 8) | l;
-        }
-    }
-    break;
-  case 3:
-  case GL_RGB:
-  case GL_R3_G3_B2:
-  case GL_RGB4:
-  case GL_RGB5:
-  case GL_RGB8:
-  case GL_RGB10:
-  case GL_RGB12:
-  case GL_RGB16:
-    (*istranslate)=GL_TRUE;
-
-    if(!(*dest)) {
-      if(!((*dest)=src=(unsigned short *)malloc(sizeof(unsigned short)*w*h))) {
-        fprintf(stderr,"fx Driver: out of memory !\n");
-        fxCloseHardware();
-        exit(-1);
-      }
-    } else
-      src=(*dest);
-
-    if(wscale==hscale==1) {
-      int i=0;
-      int lenght=h*w;
-      unsigned short r,g,b;
-
-      while(i++<lenght) {
-        r=*data++;
-        g=*data++;
-        b=*data++;
-
-        *src++=((0xf8 & r) << (11-3))  |
-          ((0xfc & g) << (5-3+1))      |
-          ((0xf8 & b) >> 3); 
-      }
-    } else {
-      unsigned short r,g,b;
-
-      for(y=0;y<h;y++)
-        for(x=0;x<w;x++) {
-          idx=(x/wscale+(y/hscale)*(w/wscale))*3;
-          r=data[idx];
-          g=data[idx+1];
-          b=data[idx+2];
-
-          src[x+y*w]=((0xf8 & r) << (11-3))  |
-            ((0xfc & g) << (5-3+1))      |
-            ((0xf8 & b) >> 3); 
-        }
-    }
-    break;
-  case 4:
-  case GL_RGBA:
-  case GL_RGBA2:
-  case GL_RGBA4:
-  case GL_RGB5_A1:
-  case GL_RGBA8:
-  case GL_RGB10_A2:
-  case GL_RGBA12:
-  case GL_RGBA16:
-    (*istranslate)=GL_TRUE;
-
-    if(!(*dest)) {
-      if(!((*dest)=src=(unsigned short *)malloc(sizeof(unsigned short)*w*h))) {
-        fprintf(stderr,"fx Driver: out of memory !\n");
-        fxCloseHardware();
-        exit(-1);
-      }
-    } else
-      src=(*dest);
-
-    if(wscale==hscale==1) {
-      int i=0;
-      int lenght=h*w;
-      unsigned short r,g,b,a;
-
-      while(i++<lenght) {
-        r=*data++;
-        g=*data++;
-        b=*data++;
-        a=*data++;
-
-        *src++=((0xf0 & a) << 8) |
-          ((0xf0 & r) << 4)      |
-          (0xf0 & g)             |
-          ((0xf0 & b) >> 4);
-      }
-    } else {
-      unsigned short r,g,b,a;
-
-      for(y=0;y<h;y++)
-        for(x=0;x<w;x++) {
-          idx=(x/wscale+(y/hscale)*(w/wscale))*4;
-          r=data[idx];
-          g=data[idx+1];
-          b=data[idx+2];
-          a=data[idx+3];
-
-          src[x+y*w]=((0xf0 & a) << 8) |
-            ((0xf0 & r) << 4)      |
-            (0xf0 & g)             |
-            ((0xf0 & b) >> 4);
-        }
-    }
-    break;
-  default:
-    fprintf(stderr,"fx Driver: wrong internalFormat in texbuildimagemap()\n");
-    fxCloseHardware();
-    exit(-1);
-    break;
-  }
+
+static void
+fetch_luminance8_alpha8(const struct gl_texture_image *texImage,
+                       GLint i, GLint j, GLint k, GLvoid * texelOut)
+{
+   GLchan *rgba = (GLchan *) texelOut;
+   const tfxMipMapLevel *mml = FX_MIPMAP_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];
 }
 
-void fxDDTexImg(GLcontext *ctx, GLenum target,
-                struct gl_texture_object *tObj, GLint level, GLint internalFormat,
-                const struct gl_texture_image *image)
+
+static void
+fetch_r5g6b5(const struct gl_texture_image *texImage,
+            GLint i, GLint j, GLint k, GLvoid * texelOut)
 {
-  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
-  tfxTexInfo *ti;
-
-  if (MESA_VERBOSE&VERBOSE_DRIVER) {
-     fprintf(stderr,"fxmesa: (%d) fxDDTexImg(...,%d,%x,%d,%d...)\n",tObj->Name,
-            target,internalFormat,image->Width,image->Height);
-  }
-
-  if(target!=GL_TEXTURE_2D)
-    return;
-
-  if(!tObj->DriverData)
-    tObj->DriverData=fxAllocTexObjData(fxMesa);
-
-  ti=(tfxTexInfo *)tObj->DriverData;
-
-  if(fxIsTexSupported(target,internalFormat,image)) {
-    GrTextureFormat_t gldformat;
-    tfxMipMapLevel *mml=&ti->tmi.mipmapLevel[level];
-
-    fxTexGetFormat(internalFormat,&gldformat,NULL);
-    
-    if(mml->used) {
-      if((mml->glideFormat==gldformat) &&
-         (mml->width==image->Width) &&
-         (mml->height==image->Height)) {
-        fxTexBuildImageMap(image,internalFormat,&(mml->data),
-                           &(mml->translated));
-
-        if(ti->validated && ti->tmi.isInTM)
-          fxTMReloadMipMapLevel(fxMesa,tObj,level);
-        else
-          fxTexInvalidate(ctx,tObj);
-
-        return;
-      } else {
-        if(mml->translated)
-          free(mml->data);
-        mml->data=NULL;
-      }
-    }
+   GLchan *rgba = (GLchan *) texelOut;
+   const tfxMipMapLevel *mml = FX_MIPMAP_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;
+}
+
 
-    mml->glideFormat=gldformat;
-    mml->width=image->Width;
-    mml->height=image->Height;
-    mml->used=GL_TRUE;
+static void
+fetch_r4g4b4a4(const struct gl_texture_image *texImage,
+              GLint i, GLint j, GLint k, GLvoid * texelOut)
+{
+   GLchan *rgba = (GLchan *) texelOut;
+   const tfxMipMapLevel *mml = FX_MIPMAP_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;
+}
 
-    fxTexBuildImageMap(image,internalFormat,&(mml->data),
-                       &(mml->translated));
 
-    fxTexInvalidate(ctx,tObj);
-  }
-#ifndef FX_SILENT
-  else
-    fprintf(stderr,"fx Driver: unsupported texture in fxDDTexImg()\n");
-#endif
+static void
+fetch_r5g5b5a1(const struct gl_texture_image *texImage,
+              GLint i, GLint j, GLint k, GLvoid * texelOut)
+{
+   GLchan *rgba = (GLchan *) texelOut;
+   const tfxMipMapLevel *mml = FX_MIPMAP_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 fxTexBuildSubImageMap(const struct gl_texture_image *image,
-                                  GLint internalFormat,
-                                  GLint xoffset, GLint yoffset, GLint width, GLint height,
-                                  unsigned short *destimg)
+
+static void
+PrintTexture(int w, int h, int c, const GLubyte * data)
 {
-  fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,
-              NULL,NULL);
-
-  switch(internalFormat) {
-  case GL_INTENSITY:
-  case GL_INTENSITY4:
-  case GL_INTENSITY8:
-  case GL_INTENSITY12:
-  case GL_INTENSITY16:
-  case 1:
-  case GL_LUMINANCE:
-  case GL_LUMINANCE4:
-  case GL_LUMINANCE8:
-  case GL_LUMINANCE12:
-  case GL_LUMINANCE16:
-  case GL_ALPHA:
-  case GL_ALPHA4:
-  case GL_ALPHA8:
-  case GL_ALPHA12:
-  case GL_ALPHA16:
-  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:
-    {
-
-      int y;
-      unsigned char *bsrc,*bdst;
-
-      bsrc=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset));
-      bdst=((unsigned char *)destimg)+(yoffset*image->Width+xoffset);
-    
-      for(y=0;y<height;y++) {
-        MEMCPY(bdst,bsrc,width);
-        bsrc += image->Width;
-        bdst += image->Width;
-      }
-    }
-    break;
-  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:
-    {
-      int x,y;
-      unsigned char *src;
-      unsigned short *dst,a,l;
-      int simgw,dimgw;
-
-      src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*2);
-      dst=destimg+(yoffset*image->Width+xoffset);
-    
-      simgw=(image->Width-width)*2;
-      dimgw=image->Width-width;
-      for(y=0;y<height;y++) {
-        for(x=0;x<width;x++) {
-          l=*src++;
-          a=*src++;
-          *dst++=(a << 8) | l;
-        }
-
-        src += simgw;
-        dst += dimgw;
-      }
-    }
-    break;
-  case 3:
-  case GL_RGB:
-  case GL_R3_G3_B2:
-  case GL_RGB4:
-  case GL_RGB5:
-  case GL_RGB8:
-  case GL_RGB10:
-  case GL_RGB12:
-  case GL_RGB16:
-    {
-      int x,y;
-      unsigned char *src;
-      unsigned short *dst,r,g,b;
-      int simgw,dimgw;
-
-      src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*3);
-      dst=destimg+(yoffset*image->Width+xoffset);
-    
-      simgw=(image->Width-width)*3;
-      dimgw=image->Width-width;
-      for(y=0;y<height;y++) {
-        for(x=0;x<width;x++) {
-          r=*src++;
-          g=*src++;
-          b=*src++;
-          *dst++=((0xf8 & r) << (11-3))  |
-            ((0xfc & g) << (5-3+1))      |
-            ((0xf8 & b) >> 3); 
-        }
-
-        src += simgw;
-        dst += dimgw;
+   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;
       }
-    }
-    break;
-  case 4:
-  case GL_RGBA:
-  case GL_RGBA2:
-  case GL_RGBA4:
-  case GL_RGB5_A1:
-  case GL_RGBA8:
-  case GL_RGB10_A2:
-  case GL_RGBA12:
-  case GL_RGBA16:
-    {
-      int x,y;
-      unsigned char *src;
-      unsigned short *dst,r,g,b,a;
-      int simgw,dimgw;
-
-      src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*4);
-      dst=destimg+(yoffset*image->Width+xoffset);
-    
-      simgw=(image->Width-width)*4;
-      dimgw=image->Width-width;
-      for(y=0;y<height;y++) {
-        for(x=0;x<width;x++) {
-          r=*src++;
-          g=*src++;
-          b=*src++;
-          a=*src++;
-          *dst++=((0xf0 & a) << 8) |
-            ((0xf0 & r) << 4)      |
-            (0xf0 & g)             |
-            ((0xf0 & b) >> 4);
-        }
-
-        src += simgw;
-        dst += dimgw;
-      }
-    }
-    break;
-  default:
-    fprintf(stderr,"fx Driver: wrong internalFormat in fxTexBuildSubImageMap()\n");
-    fxCloseHardware();
-    exit(-1);
-    break;
-  }
+      printf("\n");
+   }
 }
 
-void fxDDTexSubImg(GLcontext *ctx, GLenum target,
-                   struct gl_texture_object *tObj, GLint level,
-                   GLint xoffset, GLint yoffset, GLint width, GLint height,
-                   GLint internalFormat, const struct gl_texture_image *image)
+
+void
+fxDDTexImage2D(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)
 {
-  fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
-  tfxTexInfo *ti;
-  GrTextureFormat_t gldformat;
-  int wscale,hscale;
-  tfxMipMapLevel *mml;
+   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+   GrTextureFormat_t gldformat;
+   tfxTexInfo *ti;
+   tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
+   MesaIntTexFormat mesaFormat;
+   GLint texelSize;
+   GLboolean success;
+
+   if (!fxIsTexSupported(target, internalFormat, texImage)) {
+      _mesa_problem(NULL, "fx Driver: unsupported texture in fxDDTexImg()\n");
+      return;
+   }
 
-  if (MESA_VERBOSE&VERBOSE_DRIVER) {
-     fprintf(stderr,"fxmesa: (%d) fxDDTexSubImg(...,%d,%x,%d,%d...)\n",tObj->Name,
-            target,internalFormat,image->Width,image->Height);
-  }
+   if (!texObj->DriverData)
+      texObj->DriverData = fxAllocTexObjData(fxMesa);
+   ti = fxTMGetTexInfo(texObj);
 
-  if(target!=GL_TEXTURE_2D)
-    return;
+   if (!mml) {
+      texImage->DriverData = MALLOC(sizeof(tfxMipMapLevel));
+      mml = FX_MIPMAP_DATA(texImage);
+   }
 
-  if(!tObj->DriverData)
-    return;
+   fxTexGetFormat(internalFormat, &gldformat, NULL);
 
-  ti=(tfxTexInfo *)tObj->DriverData;
-  mml=&ti->tmi.mipmapLevel[level];
+   fxTexGetInfo(width, height, NULL, NULL, NULL, NULL,
+               NULL, NULL, &mml->wScale, &mml->hScale);
 
-  fxTexGetFormat(internalFormat,&gldformat,NULL);
+   mml->width = width * mml->wScale;
+   mml->height = height * mml->hScale;
 
-  if(mml->glideFormat!=gldformat) {
-     if (MESA_VERBOSE&VERBOSE_DRIVER) {
-       fprintf(stderr,"fxmesa:  ti->info.format!=format in fxDDTexSubImg()\n");
-     }
-    fxDDTexImg(ctx,target,tObj,level,internalFormat,image);
+   switch (internalFormat) {
+   case GL_INTENSITY:
+   case GL_INTENSITY4:
+   case GL_INTENSITY8:
+   case GL_INTENSITY12:
+   case GL_INTENSITY16:
+      texImage->Format = GL_INTENSITY;
+      texImage->FetchTexel = fetch_intensity8;
+      texelSize = 1;
+      mesaFormat = MESA_I8;
+      break;
+   case 1:
+   case GL_LUMINANCE:
+   case GL_LUMINANCE4:
+   case GL_LUMINANCE8:
+   case GL_LUMINANCE12:
+   case GL_LUMINANCE16:
+      texImage->Format = GL_LUMINANCE;
+      texImage->FetchTexel = fetch_luminance8;
+      texelSize = 1;
+      mesaFormat = MESA_L8;
+      break;
+   case GL_ALPHA:
+   case GL_ALPHA4:
+   case GL_ALPHA8:
+   case GL_ALPHA12:
+   case GL_ALPHA16:
+      texImage->Format = GL_ALPHA;
+      texImage->FetchTexel = fetch_alpha8;
+      texelSize = 1;
+      mesaFormat = MESA_A8;
+      break;
+   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:
+      texImage->Format = GL_COLOR_INDEX;
+      texImage->FetchTexel = fetch_index8;
+      texelSize = 1;
+      mesaFormat = MESA_C8;
+      break;
+   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:
+      texImage->Format = GL_LUMINANCE_ALPHA;
+      texImage->FetchTexel = fetch_luminance8_alpha8;
+      texelSize = 2;
+      mesaFormat = MESA_A8_L8;
+      break;
+   case 3:
+   case GL_RGB:
+   case GL_R3_G3_B2:
+   case GL_RGB4:
+   case GL_RGB5:
+   case GL_RGB8:
+   case GL_RGB10:
+   case GL_RGB12:
+   case GL_RGB16:
+      texImage->Format = GL_RGB;
+      texImage->FetchTexel = fetch_r5g6b5;
+      texelSize = 2;
+      mesaFormat = MESA_R5_G6_B5;
+      break;
+   case 4:
+   case GL_RGBA:
+   case GL_RGBA2:
+   case GL_RGBA4:
+   case GL_RGBA8:
+   case GL_RGB10_A2:
+   case GL_RGBA12:
+   case GL_RGBA16:
+      texImage->Format = GL_RGBA;
+      texImage->FetchTexel = fetch_r4g4b4a4;
+      texelSize = 2;
+      mesaFormat = MESA_A4_R4_G4_B4;
+      break;
+   case GL_RGB5_A1:
+      texImage->Format = GL_RGBA;
+      texImage->FetchTexel = fetch_r5g5b5a1;
+      texelSize = 2;
+      mesaFormat = MESA_A1_R5_G5_B5;
+      break;
+   default:
+      _mesa_problem(NULL, "tdfx driver: texbuildimagemap() bad format");
+      return;
+   }
 
-    return;
-  }
+   _mesa_set_teximage_component_sizes(mesaFormat, texImage);
+   texImage->Type = 0;         /* indicates a driver-specific format */
 
-  fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,&wscale,&hscale);
+   /* allocate storage for texture image */
+   texImage->Data = MALLOC(mml->width * mml->height * texelSize);
+   if (!texImage->Data)
+      return;
 
-  if((wscale!=1) || (hscale!=1)) {
-     if (MESA_VERBOSE&VERBOSE_DRIVER) {
-       fprintf(stderr,"fxmesa:  (wscale!=1) || (hscale!=1) in fxDDTexSubImg()\n");
-     }
-    fxDDTexImg(ctx,target,tObj,level,internalFormat,image);
+   mml->glideFormat = gldformat;
+   fxTexInvalidate(ctx, texObj);
 
-    return;
-  }
+   /* store the texture image */
+   if (ctx->_ImageTransferState) {
+      success = GL_FALSE;
+   }
+   else {
+      success = _mesa_convert_teximage(mesaFormat, mml->width, mml->height,
+                                      texImage->Data, mml->width * texelSize,
+                                      width, height,
+                                      format, type, pixels, packing);
+   }
 
-  if(mml->translated)
-    fxTexBuildSubImageMap(image,internalFormat,xoffset,yoffset,
-                          width,height,mml->data);
+   if (!success) {
+      /* First attempt at texture conversion failed.  We may need to
+       * do fancy pixel transfer ops or convert from an obscure texture
+       * format.
+       */
+      GLenum simpleFormat = _mesa_base_tex_format(ctx, internalFormat);
+      GLint comps = _mesa_components_in_format(simpleFormat);
+      GLubyte *tempImage;
+
+      tempImage = MALLOC(width * height * comps * sizeof(GLubyte));
+
+      /* Apply pixel transfer ops and convert image format to something
+       * simple (format = simpleFormat, type = CHAN_TYPE).
+       */
+      _mesa_transfer_teximage(ctx, 2,  /* dimensions */
+                             simpleFormat,     /* dest format */
+                             tempImage,        /* dest addr */
+                             width, height, 1, /* src size */
+                             0, 0, 0,  /* dst offsets */
+                             width * comps,    /* dstRowStride */
+                             0,        /* dstImageStride */
+                             format, type, pixels, packing /* src info */ );
+
+      /* this conversion better work! */
+      success = _mesa_convert_teximage(mesaFormat, mml->width, mml->height,
+                                      texImage->Data, mml->width * texelSize,
+                                      width, height,
+                                      simpleFormat, CHAN_TYPE, tempImage,
+                                      &_mesa_native_packing);
+      assert(success);
+      FREE(tempImage);
+   }
+
+   if (ti->validated && ti->isInTM) {
+      /*printf("reloadmipmaplevels\n"); */
+      fxTMReloadMipMapLevel(fxMesa, texObj, level);
+   }
+   else {
+      /*printf("invalidate2\n"); */
+      fxTexInvalidate(ctx, texObj);
+   }
+}
+
+
+void
+fxDDTexSubImage2D(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)
+{
+   fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+   tfxTexInfo *ti;
+   GLint texelSize;
+   tfxMipMapLevel *mml;
+   GLboolean success;
+   MesaIntTexFormat mesaFormat;
+
+   if (!texObj->DriverData) {
+      _mesa_problem(ctx, "problem in fxDDTexSubImage2D");
+      return;
+   }
+
+   ti = fxTMGetTexInfo(texObj);
+   assert(ti);
+   mml = FX_MIPMAP_DATA(texImage);
+   assert(mml);
+
+   assert(texImage->Data);     /* must have an existing texture image! */
+
+   switch (mml->glideFormat) {
+   case GR_TEXFMT_INTENSITY_8:
+      texelSize = 1;
+      mesaFormat = MESA_I8;
+      break;
+   case GR_TEXFMT_ALPHA_8:
+      texelSize = 1;
+      mesaFormat = MESA_A8;
+      break;
+   case GR_TEXFMT_P_8:
+      texelSize = 1;
+      mesaFormat = MESA_C8;
+      break;
+   case GR_TEXFMT_ALPHA_INTENSITY_88:
+      texelSize = 2;
+      mesaFormat = MESA_A8_L8;
+      break;
+   case GR_TEXFMT_RGB_565:
+      texelSize = 2;
+      mesaFormat = MESA_R5_G6_B5;
+      break;
+   case GR_TEXFMT_ARGB_4444:
+      texelSize = 2;
+      mesaFormat = MESA_A4_R4_G4_B4;
+      break;
+   case GR_TEXFMT_ARGB_1555:
+      texelSize = 2;
+      mesaFormat = MESA_A1_R5_G5_B5;
+      break;
+   default:
+      _mesa_problem(NULL, "tdfx driver: fxTexBuildSubImageMap() bad format");
+      return;
+   }
+
+   if (ctx->_ImageTransferState) {
+      success = GL_FALSE;
+   }
+   else {
+      success = _mesa_convert_texsubimage(mesaFormat, xoffset, yoffset,
+                                         mml->width, mml->height,
+                                         texImage->Data,
+                                         mml->width * texelSize,
+                                         width, height,
+                                         texImage->Width, texImage->Height,
+                                         format, type, pixels, packing);
+   }
+
+   if (!success) {
+      /* Incoming image might need scale/bias or is in an uncommon format
+       * that _mesa_convert_texsubimage() can't deal with.  Convert it to
+       * a simpler format now.
+       */
+
+      GLenum simpleFormat = _mesa_base_tex_format(ctx, texImage->IntFormat);
+      GLint comps = _mesa_components_in_format(simpleFormat);
+      GLubyte *tempImage;
+      GLboolean success;
+
+      tempImage = MALLOC(width * height * comps * sizeof(GLubyte));
+
+      /* Apply pixel transfer ops and convert image format to something
+       * simple (format = simpleFormat, type = CHAN_TYPE).
+       */
+      _mesa_transfer_teximage(ctx, 2,  /* dimensions */
+                             simpleFormat,     /* dest format */
+                             tempImage,        /* dest addr */
+                             width, height, 1, /* src size */
+                             0, 0, 0,  /* dst offsets */
+                             width * comps,    /* dstRowStride */
+                             0,        /* dstImageStride */
+                             format, type, pixels, packing /* src info */ );
+
+      /* this conversion better work! */
+      success = _mesa_convert_texsubimage(mesaFormat, xoffset, yoffset,
+                                         mml->width, mml->height,
+                                         texImage->Data, mml->width * texelSize,       /* dstRowStride */
+                                         width * mml->wScale,
+                                         height * mml->hScale,
+                                         width, height,
+                                         simpleFormat, CHAN_TYPE, tempImage,
+                                         &_mesa_native_packing);
+      assert(success);
+      FREE(tempImage);
+   }
 
-  if(ti->validated && ti->tmi.isInTM)
-    fxTMReloadSubMipMapLevel(fxMesa,tObj,level,yoffset,height);
-  else
-    fxTexInvalidate(ctx,tObj);
+   if (ti->validated && ti->isInTM)
+      fxTMReloadMipMapLevel(fxMesa, texObj, level);
+   else
+      fxTexInvalidate(ctx, texObj);
 }
 
 
@@ -1291,9 +1350,11 @@ void fxDDTexSubImg(GLcontext *ctx, GLenum target,
  * Need this to provide at least one external definition.
  */
 
-int gl_fx_dummy_function_ddtex(void)
+extern int gl_fx_dummy_function_ddtex(void);
+int
+gl_fx_dummy_function_ddtex(void)
 {
-  return 0;
+   return 0;
 }
 
-#endif  /* FX */
+#endif /* FX */