fix some float/ubyte mistakes (Daniel Borca)
[mesa.git] / src / mesa / drivers / glide / fxtexman.c
index 280a2c574c9e461e17b7d6f519b6bb1e576da118..b03122f8c1ba88c04dced11e9a013157feca179d 100644 (file)
@@ -1,10 +1,10 @@
-/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
+/* $Id: fxtexman.c,v 1.15 2001/09/23 16:50:01 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.3
+ * Version:  4.0
  *
- * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * 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"),
  * 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.
- *
- * Thank you for your contribution, David!
- *
- * 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.
- *
- * Additional Mesa/3Dfx driver developers:
- *   Daryll Strauss <daryll@precisioninsight.com>
- *   Keith Whitwell <keith@precisioninsight.com>
- *
- * See fxapi.h for more revision/author details.
  */
 
+/* Authors:
+ *    David Bucciarelli
+ *    Brian Paul
+ *    Daryll Strauss
+ *    Keith Whitwell
+ */
 
 /* fxtexman.c - 3Dfx VooDoo texture memory functions */
 
@@ -54,7 +42,7 @@
 
 #include "fxdrv.h"
 
-int texSwaps=0;
+int texSwaps = 0;
 
 #define FX_2MB_SPLIT 0x200000
 
@@ -63,674 +51,748 @@ static struct gl_texture_object *fxTMFindOldestObject(fxMesaContext fxMesa,
 
 
 #ifdef TEXSANITY
-static void fubar()
+static void
+fubar()
 {
 }
 
   /* Sanity Check */
-static void sanity(fxMesaContext fxMesa)
+static void
+sanity(fxMesaContext fxMesa)
 {
-  MemRange *tmp, *prev, *pos;
-
-  prev=0;
-  tmp = fxMesa->tmFree[0];
-  while (tmp) {
-    if (!tmp->startAddr && !tmp->endAddr) {
-      fprintf(stderr, "Textures fubar\n");
-      fubar();
-    }
-    if (tmp->startAddr>=tmp->endAddr) {
-      fprintf(stderr, "Node fubar\n");
-      fubar();
-    }
-    if (prev && (prev->startAddr>=tmp->startAddr || 
-       prev->endAddr>tmp->startAddr)) {
-      fprintf(stderr, "Sorting fubar\n");
-      fubar();
-    }
-    prev=tmp;
-    tmp=tmp->next;
-  }
-  prev=0;
-  tmp = fxMesa->tmFree[1];
-  while (tmp) {
-    if (!tmp->startAddr && !tmp->endAddr) {
-      fprintf(stderr, "Textures fubar\n");
-      fubar();
-    }
-    if (tmp->startAddr>=tmp->endAddr) {
-      fprintf(stderr, "Node fubar\n");
-      fubar();
-    }
-    if (prev && (prev->startAddr>=tmp->startAddr || 
-       prev->endAddr>tmp->startAddr)) {
-      fprintf(stderr, "Sorting fubar\n");
-      fubar();
-    }
-    prev=tmp;
-    tmp=tmp->next;
-  }
+   MemRange *tmp, *prev, *pos;
+
+   prev = 0;
+   tmp = fxMesa->tmFree[0];
+   while (tmp) {
+      if (!tmp->startAddr && !tmp->endAddr) {
+        fprintf(stderr, "Textures fubar\n");
+        fubar();
+      }
+      if (tmp->startAddr >= tmp->endAddr) {
+        fprintf(stderr, "Node fubar\n");
+        fubar();
+      }
+      if (prev && (prev->startAddr >= tmp->startAddr ||
+                  prev->endAddr > tmp->startAddr)) {
+        fprintf(stderr, "Sorting fubar\n");
+        fubar();
+      }
+      prev = tmp;
+      tmp = tmp->next;
+   }
+   prev = 0;
+   tmp = fxMesa->tmFree[1];
+   while (tmp) {
+      if (!tmp->startAddr && !tmp->endAddr) {
+        fprintf(stderr, "Textures fubar\n");
+        fubar();
+      }
+      if (tmp->startAddr >= tmp->endAddr) {
+        fprintf(stderr, "Node fubar\n");
+        fubar();
+      }
+      if (prev && (prev->startAddr >= tmp->startAddr ||
+                  prev->endAddr > tmp->startAddr)) {
+        fprintf(stderr, "Sorting fubar\n");
+        fubar();
+      }
+      prev = tmp;
+      tmp = tmp->next;
+   }
 }
 #endif
 
-static MemRange *fxTMNewRangeNode(fxMesaContext fxMesa, FxU32 start, FxU32 end) {
-  MemRange *result=0;
-
-  if (fxMesa->tmPool) {
-    result=fxMesa->tmPool;
-    fxMesa->tmPool=fxMesa->tmPool->next;
-  } else {
-    if (!(result=MALLOC(sizeof(MemRange)))) {
-      fprintf(stderr, "fxDriver: out of memory!\n");
-      fxCloseHardware();
-      exit(-1);
-    }
-  }
-  result->startAddr=start;
-  result->endAddr=end;
-  return result;
+static MemRange *
+fxTMNewRangeNode(fxMesaContext fxMesa, FxU32 start, FxU32 end)
+{
+   MemRange *result = 0;
+
+   if (fxMesa->tmPool) {
+      result = fxMesa->tmPool;
+      fxMesa->tmPool = fxMesa->tmPool->next;
+   }
+   else {
+      if (!(result = MALLOC(sizeof(MemRange)))) {
+        fprintf(stderr, "fxDriver: out of memory!\n");
+        fxCloseHardware();
+        exit(-1);
+      }
+   }
+   result->startAddr = start;
+   result->endAddr = end;
+   return result;
 }
 
-static void fxTMDeleteRangeNode(fxMesaContext fxMesa, MemRange *range)
+static void
+fxTMDeleteRangeNode(fxMesaContext fxMesa, MemRange * range)
 {
-  range->next=fxMesa->tmPool;
-  fxMesa->tmPool=range;
+   range->next = fxMesa->tmPool;
+   fxMesa->tmPool = range;
 }
 
-static void fxTMUInit(fxMesaContext fxMesa, int tmu)
+static void
+fxTMUInit(fxMesaContext fxMesa, int tmu)
 {
-  MemRange *tmn, *last;
-  FxU32 start,end,blockstart,blockend;
-
-  start=FX_grTexMinAddress(tmu);
-  end=FX_grTexMaxAddress(tmu);
+   MemRange *tmn, *last;
+   FxU32 start, end, blockstart, blockend;
+
+   start = FX_grTexMinAddress(tmu);
+   end = FX_grTexMaxAddress(tmu);
+
+   if (fxMesa->verbose) {
+      fprintf(stderr, "Voodoo %s configuration:",
+             (tmu == FX_TMU0) ? "TMU0" : "TMU1");
+      fprintf(stderr, "Voodoo  Lower texture memory address (%u)\n",
+             (unsigned int) start);
+      fprintf(stderr, "Voodoo  Higher texture memory address (%u)\n",
+             (unsigned int) end);
+      fprintf(stderr, "Voodoo  Splitting Texture memory in 2b blocks:\n");
+   }
+
+   fxMesa->freeTexMem[tmu] = end - start;
+   fxMesa->tmFree[tmu] = NULL;
+
+   last = 0;
+   blockstart = start;
+   while (blockstart < end) {
+      if (blockstart + FX_2MB_SPLIT > end)
+        blockend = end;
+      else
+        blockend = blockstart + FX_2MB_SPLIT;
 
-  if(fxMesa->verbose) {
-    fprintf(stderr,"%s configuration:",(tmu==FX_TMU0) ? "TMU0" : "TMU1");
-    fprintf(stderr,"  Lower texture memory address (%u)\n",(unsigned int)start);
-    fprintf(stderr,"  Higher texture memory address (%u)\n",(unsigned int)end);
-    fprintf(stderr,"  Splitting Texture memory in 2b blocks:\n");
-  }
+      if (fxMesa->verbose)
+        fprintf(stderr, "Voodoo    %07u-%07u\n",
+                (unsigned int) blockstart, (unsigned int) blockend);
 
-  fxMesa->freeTexMem[tmu]=end-start;
-  fxMesa->tmFree[tmu]=NULL;
+      tmn = fxTMNewRangeNode(fxMesa, blockstart, blockend);
+      tmn->next = 0;
 
-  last=0;
-  blockstart=start;
-  while (blockstart<end) {
-    if (blockstart+FX_2MB_SPLIT>end) blockend=end;
-    else blockend=blockstart+FX_2MB_SPLIT;
+      if (last)
+        last->next = tmn;
+      else
+        fxMesa->tmFree[tmu] = tmn;
+      last = tmn;
 
-    if(fxMesa->verbose)
-      fprintf(stderr,"    %07u-%07u\n",
-             (unsigned int)blockstart,(unsigned int)blockend);
+      blockstart += FX_2MB_SPLIT;
+   }
+}
 
-    tmn=fxTMNewRangeNode(fxMesa, blockstart, blockend);
-    tmn->next=0;
+static int
+fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size)
+{
+   MemRange *prev, *tmp;
+   int result;
+   struct gl_texture_object *obj;
+
+   while (1) {
+      prev = 0;
+      tmp = fxMesa->tmFree[tmu];
+      while (tmp) {
+        if (tmp->endAddr - tmp->startAddr >= size) {   /* Fits here */
+           result = tmp->startAddr;
+           tmp->startAddr += size;
+           if (tmp->startAddr == tmp->endAddr) {       /* Empty */
+              if (prev) {
+                 prev->next = tmp->next;
+              }
+              else {
+                 fxMesa->tmFree[tmu] = tmp->next;
+              }
+              fxTMDeleteRangeNode(fxMesa, tmp);
+           }
+           fxMesa->freeTexMem[tmu] -= size;
+           return result;
+        }
+        prev = tmp;
+        tmp = tmp->next;
+      }
+      /* No free space. Discard oldest */
+      obj = fxTMFindOldestObject(fxMesa, tmu);
+      if (!obj) {
+        fprintf(stderr, "fx Driver: No space for texture\n");
+        return -1;
+      }
+      fxTMMoveOutTM(fxMesa, obj);
+      texSwaps++;
+   }
+}
 
-    if (last) last->next=tmn;
-    else fxMesa->tmFree[tmu]=tmn;
-    last=tmn;
+static void
+fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range)
+{
+   MemRange *tmp, *prev;
 
-    blockstart+=FX_2MB_SPLIT;
-  }
+   if (range->startAddr == range->endAddr) {
+      fxTMDeleteRangeNode(fxMesa, range);
+      return;
+   }
+   fxMesa->freeTexMem[tmu] += range->endAddr - range->startAddr;
+   prev = 0;
+   tmp = fxMesa->tmFree[tmu];
+   while (tmp) {
+      if (range->startAddr > tmp->startAddr) {
+        prev = tmp;
+        tmp = tmp->next;
+      }
+      else
+        break;
+   }
+   /* When we create the regions, we make a split at the 2MB boundary.
+      Now we have to make sure we don't join those 2MB boundary regions
+      back together again. */
+   range->next = tmp;
+   if (tmp) {
+      if (range->endAddr == tmp->startAddr
+         && tmp->startAddr & (FX_2MB_SPLIT - 1)) {
+        /* Combine */
+        tmp->startAddr = range->startAddr;
+        fxTMDeleteRangeNode(fxMesa, range);
+        range = tmp;
+      }
+   }
+   if (prev) {
+      if (prev->endAddr == range->startAddr
+         && range->startAddr & (FX_2MB_SPLIT - 1)) {
+        /* Combine */
+        prev->endAddr = range->endAddr;
+        prev->next = range->next;
+        fxTMDeleteRangeNode(fxMesa, range);
+      }
+      else
+        prev->next = range;
+   }
+   else {
+      fxMesa->tmFree[tmu] = range;
+   }
 }
 
-static int fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size)
+static struct gl_texture_object *
+fxTMFindOldestObject(fxMesaContext fxMesa, int tmu)
 {
-  MemRange *prev, *tmp;
-  int result;
-  struct gl_texture_object *obj;
-
-  while (1) {
-    prev=0;
-    tmp=fxMesa->tmFree[tmu];
-    while (tmp) {
-      if (tmp->endAddr-tmp->startAddr>=size) { /* Fits here */
-       result=tmp->startAddr;
-       tmp->startAddr+=size;
-       if (tmp->startAddr==tmp->endAddr) { /* Empty */
-         if (prev) {
-           prev->next=tmp->next;
-         } else {
-           fxMesa->tmFree[tmu]=tmp->next;
-         }
-         fxTMDeleteRangeNode(fxMesa, tmp);
-       }
-       fxMesa->freeTexMem[tmu]-=size;
-       return result;
+   GLuint age, old, lasttime, bindnumber;
+   tfxTexInfo *info;
+   struct gl_texture_object *obj, *tmp;
+
+   tmp = fxMesa->glCtx->Shared->TexObjectList;
+   if (!tmp)
+      return 0;
+   obj = 0;
+   old = 0;
+
+   bindnumber = fxMesa->texBindNumber;
+   while (tmp) {
+      info = fxTMGetTexInfo(tmp);
+
+      if (info && info->isInTM &&
+         ((info->whichTMU == tmu) || (info->whichTMU == FX_TMU_BOTH) ||
+          (info->whichTMU == FX_TMU_SPLIT))) {
+        lasttime = info->lastTimeUsed;
+
+        if (lasttime > bindnumber)
+           age = bindnumber + (UINT_MAX - lasttime + 1);       /* TO DO: check wrap around */
+        else
+           age = bindnumber - lasttime;
+
+        if (age >= old) {
+           old = age;
+           obj = tmp;
+        }
       }
-      prev=tmp;
-      tmp=tmp->next;
-    }
-    /* No free space. Discard oldest */
-    obj=fxTMFindOldestObject(fxMesa, tmu);
-    if (!obj) {
-      fprintf(stderr, "fx Driver: No space for texture\n");
-      return -1;
-    }
-    fxTMMoveOutTM(fxMesa, obj);
-    texSwaps++;
-  }
+      tmp = tmp->Next;
+   }
+   return obj;
 }
 
-static void fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange *range)
+static MemRange *
+fxTMAddObj(fxMesaContext fxMesa,
+          struct gl_texture_object *tObj, GLint tmu, int texmemsize)
 {
-  MemRange *tmp, *prev;
-
-  if (range->startAddr==range->endAddr) {
-    fxTMDeleteRangeNode(fxMesa, range);
-    return;
-  }
-  fxMesa->freeTexMem[tmu]+=range->endAddr-range->startAddr;
-  prev=0;
-  tmp=fxMesa->tmFree[tmu];
-  while (tmp) {
-    if (range->startAddr>tmp->startAddr) {
-      prev=tmp;
-      tmp=tmp->next;
-    } else break;
-  }
-  /* When we create the regions, we make a split at the 2MB boundary.
-     Now we have to make sure we don't join those 2MB boundary regions
-     back together again. */
-  range->next=tmp;
-  if (tmp) {
-    if (range->endAddr==tmp->startAddr && tmp->startAddr&(FX_2MB_SPLIT-1)) { 
-      /* Combine */
-      tmp->startAddr=range->startAddr;
-      fxTMDeleteRangeNode(fxMesa, range);
-      range=tmp;
-    }
-  }
-  if (prev) {
-    if (prev->endAddr==range->startAddr && range->startAddr&(FX_2MB_SPLIT-1)) { 
-      /* Combine */
-      prev->endAddr=range->endAddr;
-      prev->next=range->next;
-      fxTMDeleteRangeNode(fxMesa, range);
-    } else prev->next=range;
-  } else {
-    fxMesa->tmFree[tmu]=range;
-  }
+   FxU32 startAddr;
+   MemRange *range;
+
+   startAddr = fxTMFindStartAddr(fxMesa, tmu, texmemsize);
+   if (startAddr < 0)
+      return 0;
+   range = fxTMNewRangeNode(fxMesa, startAddr, startAddr + texmemsize);
+   return range;
 }
 
-static struct gl_texture_object *fxTMFindOldestObject(fxMesaContext fxMesa,
-                                                     int tmu)
+/* External Functions */
+
+void
+fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj,
+                   GLint where)
 {
-  GLuint age, old, lasttime, bindnumber;
-  tfxTexInfo *info;
-  struct gl_texture_object *obj, *tmp;
-
-  tmp=fxMesa->glCtx->Shared->TexObjectList;
-  if (!tmp) return 0;
-  obj=0;
-  old=0;
-
-  bindnumber=fxMesa->texBindNumber;
-  while (tmp) {
-    info=fxTMGetTexInfo(tmp);
-
-    if (info && info->isInTM &&
-       ((info->whichTMU==tmu) || (info->whichTMU==FX_TMU_BOTH) || 
-       (info->whichTMU==FX_TMU_SPLIT))) {
-      lasttime=info->lastTimeUsed;
-
-      if (lasttime>bindnumber)
-       age=bindnumber+(UINT_MAX-lasttime+1); /* TO DO: check wrap around */
-      else
-       age=bindnumber-lasttime;
+   tfxTexInfo *ti = fxTMGetTexInfo(tObj);
+   int i, l;
+   int texmemsize;
+
+   if (MESA_VERBOSE & VERBOSE_DRIVER) {
+      fprintf(stderr, "fxmesa: fxTMMoveInTM(%d)\n", tObj->Name);
+   }
 
-      if (age>=old) {
-       old=age;
-       obj=tmp;
+   fxMesa->stats.reqTexUpload++;
+
+   if (!ti->validated) {
+      fprintf(stderr,
+             "fx Driver: internal error in fxTMMoveInTM() -> not validated\n");
+      fxCloseHardware();
+      exit(-1);
+   }
+
+   if (ti->isInTM) {
+      if (ti->whichTMU == where)
+        return;
+      if (where == FX_TMU_SPLIT || ti->whichTMU == FX_TMU_SPLIT)
+        fxTMMoveOutTM_NoLock(fxMesa, tObj);
+      else {
+        if (ti->whichTMU == FX_TMU_BOTH)
+           return;
+        where = FX_TMU_BOTH;
       }
-    }
-    tmp=tmp->Next;
-  }
-  return obj;
+   }
+
+   if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) {
+      fprintf(stderr, "fxmesa: downloading %x (%d) in texture memory in %d\n",
+             (GLuint) tObj, tObj->Name, where);
+   }
+
+   ti->whichTMU = (FxU32) where;
+
+   switch (where) {
+   case FX_TMU0:
+   case FX_TMU1:
+      texmemsize =
+        (int) FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH,
+                                                &(ti->info));
+      ti->tm[where] = fxTMAddObj(fxMesa, tObj, where, texmemsize);
+      fxMesa->stats.memTexUpload += texmemsize;
+
+      for (i = FX_largeLodValue(ti->info), l = ti->minLevel;
+          i <= FX_smallLodValue(ti->info); i++, l++) {
+        struct gl_texture_image *texImage = tObj->Image[l];
+        FX_grTexDownloadMipMapLevel_NoLock(where,
+                                           ti->tm[where]->startAddr,
+                                           FX_valueToLod(i),
+                                           FX_largeLodLog2(ti->info),
+                                           FX_aspectRatioLog2(ti->info),
+                                           ti->info.format,
+                                           GR_MIPMAPLEVELMASK_BOTH,
+                                           texImage->Data);
+      }
+      break;
+   case FX_TMU_SPLIT:
+      texmemsize =
+        (int) FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_ODD,
+                                                &(ti->info));
+      ti->tm[FX_TMU0] = fxTMAddObj(fxMesa, tObj, FX_TMU0, texmemsize);
+      fxMesa->stats.memTexUpload += texmemsize;
+
+      texmemsize =
+        (int) FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_EVEN,
+                                                &(ti->info));
+      ti->tm[FX_TMU1] = fxTMAddObj(fxMesa, tObj, FX_TMU1, texmemsize);
+      fxMesa->stats.memTexUpload += texmemsize;
+
+      for (i = FX_largeLodValue(ti->info), l = ti->minLevel;
+          i <= FX_smallLodValue(ti->info); i++, l++) {
+        struct gl_texture_image *texImage = tObj->Image[l];
+
+        FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0,
+                                           ti->tm[FX_TMU0]->startAddr,
+                                           FX_valueToLod(i),
+                                           FX_largeLodLog2(ti->info),
+                                           FX_aspectRatioLog2(ti->info),
+                                           ti->info.format,
+                                           GR_MIPMAPLEVELMASK_ODD,
+                                           texImage->Data);
+
+        FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1,
+                                           ti->tm[FX_TMU1]->startAddr,
+                                           FX_valueToLod(i),
+                                           FX_largeLodLog2(ti->info),
+                                           FX_aspectRatioLog2(ti->info),
+                                           ti->info.format,
+                                           GR_MIPMAPLEVELMASK_EVEN,
+                                           texImage->Data);
+      }
+      break;
+   case FX_TMU_BOTH:
+      texmemsize =
+        (int) FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH,
+                                                &(ti->info));
+      ti->tm[FX_TMU0] = fxTMAddObj(fxMesa, tObj, FX_TMU0, texmemsize);
+      fxMesa->stats.memTexUpload += texmemsize;
+
+      texmemsize =
+        (int) FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH,
+                                                &(ti->info));
+      ti->tm[FX_TMU1] = fxTMAddObj(fxMesa, tObj, FX_TMU1, texmemsize);
+      fxMesa->stats.memTexUpload += texmemsize;
+
+      for (i = FX_largeLodValue(ti->info), l = ti->minLevel;
+          i <= FX_smallLodValue(ti->info); i++, l++) {
+        struct gl_texture_image *texImage = tObj->Image[l];
+        FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0,
+                                           ti->tm[FX_TMU0]->startAddr,
+                                           FX_valueToLod(i),
+                                           FX_largeLodLog2(ti->info),
+                                           FX_aspectRatioLog2(ti->info),
+                                           ti->info.format,
+                                           GR_MIPMAPLEVELMASK_BOTH,
+                                           texImage->Data);
+
+        FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1,
+                                           ti->tm[FX_TMU1]->startAddr,
+                                           FX_valueToLod(i),
+                                           FX_largeLodLog2(ti->info),
+                                           FX_aspectRatioLog2(ti->info),
+                                           ti->info.format,
+                                           GR_MIPMAPLEVELMASK_BOTH,
+                                           texImage->Data);
+      }
+      break;
+   default:
+      fprintf(stderr,
+             "fx Driver: internal error in fxTMMoveInTM() -> wrong tmu (%d)\n",
+             where);
+      fxCloseHardware();
+      exit(-1);
+   }
+
+   fxMesa->stats.texUpload++;
+
+   ti->isInTM = GL_TRUE;
 }
 
-static MemRange *fxTMAddObj(fxMesaContext fxMesa, 
-                           struct gl_texture_object *tObj,
-                           GLint tmu, int texmemsize)
-{
-  FxU32 startAddr;
-  MemRange *range;
 
-  startAddr=fxTMFindStartAddr(fxMesa, tmu, texmemsize);
-  if (startAddr<0) return 0;
-  range=fxTMNewRangeNode(fxMesa, startAddr, startAddr+texmemsize);
-  return range;
+void
+fxTMMoveInTM(fxMesaContext fxMesa, struct gl_texture_object *tObj,
+            GLint where)
+{
+   BEGIN_BOARD_LOCK();
+   fxTMMoveInTM_NoLock(fxMesa, tObj, where);
+   END_BOARD_LOCK();
 }
 
-/* External Functions */
 
-void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint where)
+void
+fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj,
+                     GLint level)
 {
-  tfxTexInfo *ti=fxTMGetTexInfo(tObj);
-  int i,l;
-  int texmemsize;
-
-  if (MESA_VERBOSE&VERBOSE_DRIVER) {
-     fprintf(stderr,"fxmesa: fxTMMoveInTM(%d)\n",tObj->Name);
-  }
-
-  fxMesa->stats.reqTexUpload++;
-
-  if (!ti->validated) {
-    fprintf(stderr,"fx Driver: internal error in fxTMMoveInTM() -> not validated\n");
-    fxCloseHardware();
-    exit(-1);
-  }
-
-  if (ti->isInTM) {
-    if (ti->whichTMU==where) return;
-    if (where==FX_TMU_SPLIT || ti->whichTMU==FX_TMU_SPLIT)
-      fxTMMoveOutTM_NoLock(fxMesa, tObj);
-    else {
-      if (ti->whichTMU==FX_TMU_BOTH) return;
-      where=FX_TMU_BOTH;
-    }
-  }
-
-  if (MESA_VERBOSE&(VERBOSE_DRIVER|VERBOSE_TEXTURE)) {
-     fprintf(stderr,"fxmesa: downloading %x (%d) in texture memory in %d\n",(GLuint)tObj,tObj->Name,where);
-  }
-
-  ti->whichTMU=(FxU32)where;
-
-  switch (where) {
-  case FX_TMU0:
-  case FX_TMU1:
-    texmemsize=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH,
-                                                     &(ti->info));
-    ti->tm[where]=fxTMAddObj(fxMesa, tObj, where, texmemsize);
-    fxMesa->stats.memTexUpload+=texmemsize;
-
-    for (i=FX_largeLodValue(ti->info), l=ti->minLevel;
-        i<=FX_smallLodValue(ti->info);
-        i++,l++)
-      FX_grTexDownloadMipMapLevel_NoLock(where,
-                                        ti->tm[where]->startAddr,
-                                        FX_valueToLod(i),
+   tfxTexInfo *ti = fxTMGetTexInfo(tObj);
+   GrLOD_t lodlevel;
+   GLint tmu;
+   struct gl_texture_image *texImage = tObj->Image[level];
+   tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
+
+   assert(mml);
+   assert(mml->width > 0);
+   assert(mml->height > 0);
+   assert(mml->glideFormat > 0);
+
+   if (!ti->validated) {
+      fprintf(stderr,
+             "fx Driver: internal error in fxTMReloadMipMapLevel() -> not validated\n");
+      fxCloseHardware();
+      exit(-1);
+   }
+
+   tmu = (int) ti->whichTMU;
+   fxTMMoveInTM(fxMesa, tObj, tmu);
+
+   fxTexGetInfo(mml->width, mml->height,
+               &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+
+#ifdef FX_GLIDE3
+   lodlevel -= level;
+#else
+   lodlevel += level;
+#endif
+   switch (tmu) {
+   case FX_TMU0:
+   case FX_TMU1:
+      FX_grTexDownloadMipMapLevel(tmu,
+                                 ti->tm[tmu]->startAddr,
+                                 FX_valueToLod(FX_lodToValue(lodlevel)),
+                                 FX_largeLodLog2(ti->info),
+                                 FX_aspectRatioLog2(ti->info),
+                                 ti->info.format,
+                                 GR_MIPMAPLEVELMASK_BOTH, texImage->Data);
+      break;
+   case FX_TMU_SPLIT:
+      FX_grTexDownloadMipMapLevel(GR_TMU0,
+                                 ti->tm[GR_TMU0]->startAddr,
+                                 FX_valueToLod(FX_lodToValue(lodlevel)),
+                                 FX_largeLodLog2(ti->info),
+                                 FX_aspectRatioLog2(ti->info),
+                                 ti->info.format,
+                                 GR_MIPMAPLEVELMASK_ODD, texImage->Data);
+
+      FX_grTexDownloadMipMapLevel(GR_TMU1,
+                                 ti->tm[GR_TMU1]->startAddr,
+                                 FX_valueToLod(FX_lodToValue(lodlevel)),
+                                 FX_largeLodLog2(ti->info),
+                                 FX_aspectRatioLog2(ti->info),
+                                 ti->info.format,
+                                 GR_MIPMAPLEVELMASK_EVEN, texImage->Data);
+      break;
+   case FX_TMU_BOTH:
+      FX_grTexDownloadMipMapLevel(GR_TMU0,
+                                 ti->tm[GR_TMU0]->startAddr,
+                                 FX_valueToLod(FX_lodToValue(lodlevel)),
+                                 FX_largeLodLog2(ti->info),
+                                 FX_aspectRatioLog2(ti->info),
+                                 ti->info.format,
+                                 GR_MIPMAPLEVELMASK_BOTH, texImage->Data);
+
+      FX_grTexDownloadMipMapLevel(GR_TMU1,
+                                 ti->tm[GR_TMU1]->startAddr,
+                                 FX_valueToLod(FX_lodToValue(lodlevel)),
+                                 FX_largeLodLog2(ti->info),
+                                 FX_aspectRatioLog2(ti->info),
+                                 ti->info.format,
+                                 GR_MIPMAPLEVELMASK_BOTH, texImage->Data);
+      break;
+
+   default:
+      fprintf(stderr,
+             "fx Driver: internal error in fxTMReloadMipMapLevel() -> wrong tmu (%d)\n",
+             tmu);
+      fxCloseHardware();
+      exit(-1);
+   }
+}
+
+void
+fxTMReloadSubMipMapLevel(fxMesaContext fxMesa,
+                        struct gl_texture_object *tObj,
+                        GLint level, GLint yoffset, GLint height)
+{
+   tfxTexInfo *ti = fxTMGetTexInfo(tObj);
+   GrLOD_t lodlevel;
+   unsigned short *data;
+   GLint tmu;
+   struct gl_texture_image *texImage = tObj->Image[level];
+   tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
+
+   assert(mml);
+
+   if (!ti->validated) {
+      fprintf(stderr,
+             "fx Driver: internal error in fxTMReloadSubMipMapLevel() -> not validated\n");
+      fxCloseHardware();
+      exit(-1);
+   }
+
+   tmu = (int) ti->whichTMU;
+   fxTMMoveInTM(fxMesa, tObj, tmu);
+
+   fxTexGetInfo(mml->width, mml->height,
+               &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+
+   if ((ti->info.format == GR_TEXFMT_INTENSITY_8) ||
+       (ti->info.format == GR_TEXFMT_P_8) ||
+       (ti->info.format == GR_TEXFMT_ALPHA_8))
+        data = (GLushort *) texImage->Data + ((yoffset * mml->width) >> 1);
+   else
+      data = (GLushort *) texImage->Data + yoffset * mml->width;
+
+   switch (tmu) {
+   case FX_TMU0:
+   case FX_TMU1:
+      FX_grTexDownloadMipMapLevelPartial(tmu,
+                                        ti->tm[tmu]->startAddr,
+                                        FX_valueToLod(FX_lodToValue(lodlevel)
+                                                      + level),
                                         FX_largeLodLog2(ti->info),
                                         FX_aspectRatioLog2(ti->info),
                                         ti->info.format,
-                                        GR_MIPMAPLEVELMASK_BOTH,
-                                        ti->mipmapLevel[l].data);
-    break;
-  case FX_TMU_SPLIT: 
-    texmemsize=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_ODD,
-                                                     &(ti->info));
-    ti->tm[FX_TMU0]=fxTMAddObj(fxMesa, tObj, FX_TMU0, texmemsize);
-    fxMesa->stats.memTexUpload+=texmemsize;
-
-    texmemsize=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_EVEN,
-                                                     &(ti->info));
-    ti->tm[FX_TMU1]=fxTMAddObj(fxMesa, tObj, FX_TMU1, texmemsize);
-    fxMesa->stats.memTexUpload+=texmemsize;
-
-    for (i=FX_largeLodValue(ti->info),l=ti->minLevel;
-        i<=FX_smallLodValue(ti->info);
-        i++,l++) {
-      FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0,
+                                        GR_MIPMAPLEVELMASK_BOTH, data,
+                                        yoffset, yoffset + height - 1);
+      break;
+   case FX_TMU_SPLIT:
+      FX_grTexDownloadMipMapLevelPartial(GR_TMU0,
                                         ti->tm[FX_TMU0]->startAddr,
-                                        FX_valueToLod(i),
+                                        FX_valueToLod(FX_lodToValue(lodlevel)
+                                                      + level),
                                         FX_largeLodLog2(ti->info),
                                         FX_aspectRatioLog2(ti->info),
                                         ti->info.format,
-                                        GR_MIPMAPLEVELMASK_ODD,
-                                        ti->mipmapLevel[l].data);
+                                        GR_MIPMAPLEVELMASK_ODD, data,
+                                        yoffset, yoffset + height - 1);
 
-      FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1,
+      FX_grTexDownloadMipMapLevelPartial(GR_TMU1,
                                         ti->tm[FX_TMU1]->startAddr,
-                                        FX_valueToLod(i),
+                                        FX_valueToLod(FX_lodToValue(lodlevel)
+                                                      + level),
                                         FX_largeLodLog2(ti->info),
                                         FX_aspectRatioLog2(ti->info),
                                         ti->info.format,
-                                        GR_MIPMAPLEVELMASK_EVEN,
-                                        ti->mipmapLevel[l].data);
-    }
-    break;
-  case FX_TMU_BOTH:
-    texmemsize=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH,
-                                                     &(ti->info));
-    ti->tm[FX_TMU0]=fxTMAddObj(fxMesa, tObj, FX_TMU0, texmemsize);
-    fxMesa->stats.memTexUpload+=texmemsize;
-
-    texmemsize=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH,
-                                                     &(ti->info));
-    ti->tm[FX_TMU1]=fxTMAddObj(fxMesa, tObj, FX_TMU1, texmemsize);
-    fxMesa->stats.memTexUpload+=texmemsize;
-
-    for (i=FX_largeLodValue(ti->info),l=ti->minLevel;
-        i<=FX_smallLodValue(ti->info);
-        i++,l++) {
-      FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0,
+                                        GR_MIPMAPLEVELMASK_EVEN, data,
+                                        yoffset, yoffset + height - 1);
+      break;
+   case FX_TMU_BOTH:
+      FX_grTexDownloadMipMapLevelPartial(GR_TMU0,
                                         ti->tm[FX_TMU0]->startAddr,
-                                        FX_valueToLod(i),
+                                        FX_valueToLod(FX_lodToValue(lodlevel)
+                                                      + level),
                                         FX_largeLodLog2(ti->info),
                                         FX_aspectRatioLog2(ti->info),
                                         ti->info.format,
-                                        GR_MIPMAPLEVELMASK_BOTH,
-                                        ti->mipmapLevel[l].data);
+                                        GR_MIPMAPLEVELMASK_BOTH, data,
+                                        yoffset, yoffset + height - 1);
 
-      FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1,
+      FX_grTexDownloadMipMapLevelPartial(GR_TMU1,
                                         ti->tm[FX_TMU1]->startAddr,
-                                        FX_valueToLod(i),
+                                        FX_valueToLod(FX_lodToValue(lodlevel)
+                                                      + level),
                                         FX_largeLodLog2(ti->info),
                                         FX_aspectRatioLog2(ti->info),
                                         ti->info.format,
-                                        GR_MIPMAPLEVELMASK_BOTH,
-                                        ti->mipmapLevel[l].data);
-    }
-    break;
-  default:
-    fprintf(stderr,"fx Driver: internal error in fxTMMoveInTM() -> wrong tmu (%d)\n",where);
-    fxCloseHardware();
-    exit(-1);
-  }
-
-  fxMesa->stats.texUpload++;
-
-  ti->isInTM=GL_TRUE;
-}
-
-void fxTMMoveInTM(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint where) {
-  BEGIN_BOARD_LOCK();
-  fxTMMoveInTM_NoLock(fxMesa, tObj, where);
-  END_BOARD_LOCK();
-}
-
-void fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint level)
-{
-  tfxTexInfo *ti=fxTMGetTexInfo(tObj);
-  GrLOD_t lodlevel;
-  GLint tmu;
-
-  if (!ti->validated) {
-    fprintf(stderr,"fx Driver: internal error in fxTMReloadMipMapLevel() -> not validated\n");
-    fxCloseHardware();
-    exit(-1);
-  }
-
-  tmu=(int)ti->whichTMU;
-  fxTMMoveInTM(fxMesa, tObj, tmu);
-
-  fxTexGetInfo(ti->mipmapLevel[0].width,ti->mipmapLevel[0].height,
-              &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
-
-#ifdef FX_GLIDE3
-  lodlevel-=level;
-#else
-  lodlevel+=level;
-#endif
-  switch(tmu) {
-  case FX_TMU0:
-  case FX_TMU1:
-    FX_grTexDownloadMipMapLevel(tmu,
-                               ti->tm[tmu]->startAddr,
-                               FX_valueToLod(FX_lodToValue(lodlevel)),
-                               FX_largeLodLog2(ti->info),
-                               FX_aspectRatioLog2(ti->info),
-                               ti->info.format,
-                               GR_MIPMAPLEVELMASK_BOTH,
-                               ti->mipmapLevel[level].data);
-    break;
-  case FX_TMU_SPLIT:
-    FX_grTexDownloadMipMapLevel(GR_TMU0,
-                               ti->tm[GR_TMU0]->startAddr,
-                               FX_valueToLod(FX_lodToValue(lodlevel)),
-                               FX_largeLodLog2(ti->info),
-                               FX_aspectRatioLog2(ti->info),
-                               ti->info.format,
-                               GR_MIPMAPLEVELMASK_ODD,
-                               ti->mipmapLevel[level].data);
-    
-    FX_grTexDownloadMipMapLevel(GR_TMU1,
-                               ti->tm[GR_TMU1]->startAddr,
-                               FX_valueToLod(FX_lodToValue(lodlevel)),
-                               FX_largeLodLog2(ti->info),
-                               FX_aspectRatioLog2(ti->info),
-                               ti->info.format,
-                               GR_MIPMAPLEVELMASK_EVEN,
-                               ti->mipmapLevel[level].data);
-    break;
-  case FX_TMU_BOTH:
-    FX_grTexDownloadMipMapLevel(GR_TMU0,
-                               ti->tm[GR_TMU0]->startAddr,
-                               FX_valueToLod(FX_lodToValue(lodlevel)),
-                               FX_largeLodLog2(ti->info),
-                               FX_aspectRatioLog2(ti->info),
-                               ti->info.format,
-                               GR_MIPMAPLEVELMASK_BOTH,
-                               ti->mipmapLevel[level].data);
-    
-    FX_grTexDownloadMipMapLevel(GR_TMU1,
-                               ti->tm[GR_TMU1]->startAddr,
-                               FX_valueToLod(FX_lodToValue(lodlevel)),
-                               FX_largeLodLog2(ti->info),
-                               FX_aspectRatioLog2(ti->info),
-                               ti->info.format,
-                               GR_MIPMAPLEVELMASK_BOTH,
-                               ti->mipmapLevel[level].data);
-    break;
-
-  default:
-    fprintf(stderr,"fx Driver: internal error in fxTMReloadMipMapLevel() -> wrong tmu (%d)\n",tmu);
-    fxCloseHardware();
-    exit(-1);
-  }
+                                        GR_MIPMAPLEVELMASK_BOTH, data,
+                                        yoffset, yoffset + height - 1);
+      break;
+   default:
+      fprintf(stderr,
+             "fx Driver: internal error in fxTMReloadSubMipMapLevel() -> wrong tmu (%d)\n",
+             tmu);
+      fxCloseHardware();
+      exit(-1);
+   }
 }
 
-void fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, 
-                             struct gl_texture_object *tObj,
-                             GLint level, GLint yoffset, GLint height)
+void
+fxTMMoveOutTM(fxMesaContext fxMesa, struct gl_texture_object *tObj)
 {
-  tfxTexInfo *ti=fxTMGetTexInfo(tObj);
-  GrLOD_t lodlevel;
-  unsigned short *data;
-  GLint tmu;
-
-  if(!ti->validated) {
-    fprintf(stderr,"fx Driver: internal error in fxTMReloadSubMipMapLevel() -> not validated\n");
-    fxCloseHardware();
-    exit(-1);
-  }
-
-  tmu=(int)ti->whichTMU;
-  fxTMMoveInTM(fxMesa, tObj, tmu);
-
-  fxTexGetInfo(ti->mipmapLevel[0].width, ti->mipmapLevel[0].height,
-              &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
-
-  if((ti->info.format==GR_TEXFMT_INTENSITY_8) ||
-     (ti->info.format==GR_TEXFMT_P_8) ||
-     (ti->info.format==GR_TEXFMT_ALPHA_8))
-    data=ti->mipmapLevel[level].data+((yoffset*ti->mipmapLevel[level].width)>>1);
-  else
-    data=ti->mipmapLevel[level].data+yoffset*ti->mipmapLevel[level].width;
-
-  switch(tmu) {
-  case FX_TMU0:
-  case FX_TMU1:
-    FX_grTexDownloadMipMapLevelPartial(tmu,
-                                      ti->tm[tmu]->startAddr,
-                                      FX_valueToLod(FX_lodToValue(lodlevel)+level),
-                                      FX_largeLodLog2(ti->info),
-                                      FX_aspectRatioLog2(ti->info),
-                                      ti->info.format,
-                                      GR_MIPMAPLEVELMASK_BOTH,
-                                      data,
-                                      yoffset,yoffset+height-1);
-    break;
-  case FX_TMU_SPLIT:
-    FX_grTexDownloadMipMapLevelPartial(GR_TMU0,
-                                      ti->tm[FX_TMU0]->startAddr,
-                                      FX_valueToLod(FX_lodToValue(lodlevel)+level),
-                                      FX_largeLodLog2(ti->info),
-                                      FX_aspectRatioLog2(ti->info),
-                                      ti->info.format,
-                                      GR_MIPMAPLEVELMASK_ODD,
-                                      data,
-                                      yoffset,yoffset+height-1);
-
-    FX_grTexDownloadMipMapLevelPartial(GR_TMU1,
-                                      ti->tm[FX_TMU1]->startAddr,
-                                      FX_valueToLod(FX_lodToValue(lodlevel)+level),
-                                      FX_largeLodLog2(ti->info),
-                                      FX_aspectRatioLog2(ti->info),
-                                      ti->info.format,
-                                      GR_MIPMAPLEVELMASK_EVEN,
-                                      data,
-                                      yoffset,yoffset+height-1);
-    break;
-  case FX_TMU_BOTH:
-    FX_grTexDownloadMipMapLevelPartial(GR_TMU0,
-                                      ti->tm[FX_TMU0]->startAddr,
-                                      FX_valueToLod(FX_lodToValue(lodlevel)+level),
-                                      FX_largeLodLog2(ti->info),
-                                      FX_aspectRatioLog2(ti->info),
-                                      ti->info.format,
-                                      GR_MIPMAPLEVELMASK_BOTH,
-                                      data,
-                                      yoffset,yoffset+height-1);
-
-    FX_grTexDownloadMipMapLevelPartial(GR_TMU1,
-                                      ti->tm[FX_TMU1]->startAddr,
-                                      FX_valueToLod(FX_lodToValue(lodlevel)+level),
-                                      FX_largeLodLog2(ti->info),
-                                      FX_aspectRatioLog2(ti->info),
-                                      ti->info.format,
-                                      GR_MIPMAPLEVELMASK_BOTH,
-                                      data,
-                                      yoffset,yoffset+height-1);
-    break;
-  default:
-    fprintf(stderr,"fx Driver: internal error in fxTMReloadSubMipMapLevel() -> wrong tmu (%d)\n",tmu);
-    fxCloseHardware();
-    exit(-1);
-  }
-}
+   tfxTexInfo *ti = fxTMGetTexInfo(tObj);
+
+   if (MESA_VERBOSE & VERBOSE_DRIVER) {
+      fprintf(stderr, "fxmesa: fxTMMoveOutTM(%x (%d))\n", (GLuint) tObj,
+             tObj->Name);
+   }
+
+   if (!ti->isInTM)
+      return;
+
+   switch (ti->whichTMU) {
+   case FX_TMU0:
+   case FX_TMU1:
+      fxTMRemoveRange(fxMesa, (int) ti->whichTMU, ti->tm[ti->whichTMU]);
+      break;
+   case FX_TMU_SPLIT:
+   case FX_TMU_BOTH:
+      fxTMRemoveRange(fxMesa, FX_TMU0, ti->tm[FX_TMU0]);
+      fxTMRemoveRange(fxMesa, FX_TMU1, ti->tm[FX_TMU1]);
+      break;
+   default:
+      fprintf(stderr, "fx Driver: internal error in fxTMMoveOutTM()\n");
+      fxCloseHardware();
+      exit(-1);
+   }
 
-void fxTMMoveOutTM(fxMesaContext fxMesa, struct gl_texture_object *tObj)
-{
-  tfxTexInfo *ti=fxTMGetTexInfo(tObj);
-
-  if (MESA_VERBOSE&VERBOSE_DRIVER) {
-     fprintf(stderr,"fxmesa: fxTMMoveOutTM(%x (%d))\n",(GLuint)tObj,tObj->Name);
-  }
-
-  if (!ti->isInTM)  return;
-
-  switch(ti->whichTMU) {
-  case FX_TMU0:
-  case FX_TMU1:
-    fxTMRemoveRange(fxMesa, (int)ti->whichTMU, ti->tm[ti->whichTMU]);
-    break;
-  case FX_TMU_SPLIT:
-  case FX_TMU_BOTH:
-    fxTMRemoveRange(fxMesa, FX_TMU0, ti->tm[FX_TMU0]);
-    fxTMRemoveRange(fxMesa, FX_TMU1, ti->tm[FX_TMU1]);
-    break;
-  default:
-    fprintf(stderr,"fx Driver: internal error in fxTMMoveOutTM()\n");
-    fxCloseHardware();
-    exit(-1);
-  }
-
-  ti->isInTM=GL_FALSE;
-  ti->whichTMU=FX_TMU_NONE;
+   ti->isInTM = GL_FALSE;
+   ti->whichTMU = FX_TMU_NONE;
 }
 
-void fxTMFreeTexture(fxMesaContext fxMesa, struct gl_texture_object *tObj)
+void
+fxTMFreeTexture(fxMesaContext fxMesa, struct gl_texture_object *tObj)
 {
-  tfxTexInfo *ti=fxTMGetTexInfo(tObj);
-  int i;
-
-  fxTMMoveOutTM(fxMesa, tObj);
-
-  for(i=0; i<MAX_TEXTURE_LEVELS; i++) {
-    if (ti->mipmapLevel[i].used &&
-       ti->mipmapLevel[i].translated)
-      FREE(ti->mipmapLevel[i].data);
-
-    (void)ti->mipmapLevel[i].data;
-  }
-  switch (ti->whichTMU) {
-  case FX_TMU0:
-  case FX_TMU1:
-    fxTMDeleteRangeNode(fxMesa, ti->tm[ti->whichTMU]);
-    break;
-  case FX_TMU_SPLIT:
-  case FX_TMU_BOTH:
-    fxTMDeleteRangeNode(fxMesa, ti->tm[FX_TMU0]);
-    fxTMDeleteRangeNode(fxMesa, ti->tm[FX_TMU1]);
-    break;
-  }
+   tfxTexInfo *ti = fxTMGetTexInfo(tObj);
+   int i;
+
+   fxTMMoveOutTM(fxMesa, tObj);
+
+   for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
+      struct gl_texture_image *texImage = tObj->Image[i];
+      if (texImage) {
+         if (texImage->Data) {
+            FREE(texImage->Data);
+            texImage->Data = NULL;
+         }
+         if (texImage->DriverData) {
+            FREE(texImage->DriverData);
+            texImage->DriverData = NULL;
+         }
+      }
+   }
+   switch (ti->whichTMU) {
+   case FX_TMU0:
+   case FX_TMU1:
+      fxTMDeleteRangeNode(fxMesa, ti->tm[ti->whichTMU]);
+      break;
+   case FX_TMU_SPLIT:
+   case FX_TMU_BOTH:
+      fxTMDeleteRangeNode(fxMesa, ti->tm[FX_TMU0]);
+      fxTMDeleteRangeNode(fxMesa, ti->tm[FX_TMU1]);
+      break;
+   }
 }
 
-void fxTMInit(fxMesaContext fxMesa)
+void
+fxTMInit(fxMesaContext fxMesa)
 {
-  fxMesa->texBindNumber=0;
-  fxMesa->tmPool=0;
+   fxMesa->texBindNumber = 0;
+   fxMesa->tmPool = 0;
 
-  fxTMUInit(fxMesa,FX_TMU0);
+   fxTMUInit(fxMesa, FX_TMU0);
 
-  if(fxMesa->haveTwoTMUs)
-    fxTMUInit(fxMesa,FX_TMU1);
+   if (fxMesa->haveTwoTMUs)
+      fxTMUInit(fxMesa, FX_TMU1);
 }
 
-void fxTMClose(fxMesaContext fxMesa)
+void
+fxTMClose(fxMesaContext fxMesa)
 {
-  MemRange *tmp, *next;
-
-  tmp=fxMesa->tmPool;
-  while (tmp) {
-    next=tmp->next;
-    FREE(tmp);
-    tmp=next;
-  }
-  tmp=fxMesa->tmFree[FX_TMU0];
-  while (tmp) {
-    next=tmp->next;
-    FREE(tmp);
-    tmp=next;
-  }
-  if (fxMesa->haveTwoTMUs) {
-    tmp=fxMesa->tmFree[FX_TMU1];
-    while (tmp) {
-      next=tmp->next;
+   MemRange *tmp, *next;
+
+   tmp = fxMesa->tmPool;
+   while (tmp) {
+      next = tmp->next;
+      FREE(tmp);
+      tmp = next;
+   }
+   tmp = fxMesa->tmFree[FX_TMU0];
+   while (tmp) {
+      next = tmp->next;
       FREE(tmp);
-      tmp=next;
-    }
-  }
+      tmp = next;
+   }
+   if (fxMesa->haveTwoTMUs) {
+      tmp = fxMesa->tmFree[FX_TMU1];
+      while (tmp) {
+        next = tmp->next;
+        FREE(tmp);
+        tmp = next;
+      }
+   }
 }
 
 void
-fxTMRestoreTextures_NoLock(fxMesaContext ctx) {
-  tfxTexInfo *ti;
-  struct gl_texture_object *tObj;
-  int i, where;
-
-  tObj=ctx->glCtx->Shared->TexObjectList;
-  while (tObj) {
-    ti=fxTMGetTexInfo(tObj);
-    if (ti && ti->isInTM) {
-      for (i=0; i<MAX_TEXTURE_UNITS; i++)
-       if (ctx->glCtx->Texture.Unit[i].Current==tObj) {
-         /* Force the texture onto the board, as it could be in use */
-         where=ti->whichTMU;
-         ti->whichTMU=FX_TMU_NONE;
-         fxTMMoveInTM_NoLock(ctx, tObj, where);
-         break;
-       }
-      if (i==MAX_TEXTURE_UNITS) /* Mark the texture as off the board */
-       fxTMMoveOutTM_NoLock(ctx, tObj);
-    }
-    tObj=tObj->Next;
-  }
+fxTMRestoreTextures_NoLock(fxMesaContext ctx)
+{
+   tfxTexInfo *ti;
+   struct gl_texture_object *tObj;
+   int i, where;
+
+   tObj = ctx->glCtx->Shared->TexObjectList;
+   while (tObj) {
+      ti = fxTMGetTexInfo(tObj);
+      if (ti && ti->isInTM) {
+        for (i = 0; i < MAX_TEXTURE_UNITS; i++)
+           if (ctx->glCtx->Texture.Unit[i]._Current == tObj) {
+              /* Force the texture onto the board, as it could be in use */
+              where = ti->whichTMU;
+              fxTMMoveOutTM_NoLock(ctx, tObj);
+              fxTMMoveInTM_NoLock(ctx, tObj, where);
+              break;
+           }
+        if (i == MAX_TEXTURE_UNITS)    /* Mark the texture as off the board */
+           fxTMMoveOutTM_NoLock(ctx, tObj);
+      }
+      tObj = tObj->Next;
+   }
 }
 
 #else
@@ -740,9 +802,11 @@ fxTMRestoreTextures_NoLock(fxMesaContext ctx) {
  * Need this to provide at least one external definition.
  */
 
-int gl_fx_dummy_function_texman(void)
+extern int gl_fx_dummy_function_texman(void);
+int
+gl_fx_dummy_function_texman(void)
 {
-  return 0;
+   return 0;
 }
 
-#endif  /* FX */
+#endif /* FX */