fix tabbing
[mesa.git] / src / mesa / drivers / glide / fxtexman.c
index 5189816cdefa858036c53f7bbe4af00fea50a24b..940c8fd0b97d92c9d065b6b8753ae2a61a0193aa 100644 (file)
@@ -1,5 +1,3 @@
-/* $Id: fxtexman.c,v 1.16 2003/08/19 15:52:53 brianp Exp $ */
-
 /*
  * Mesa 3-D graphics library
  * Version:  4.0
 
 #if defined(FX)
 
+#include "hash.h"
 #include "fxdrv.h"
 
 int texSwaps = 0;
+static FxU32 texBoundMask;
 
 #define FX_2MB_SPLIT 0x200000
 
@@ -116,7 +116,7 @@ fxTMNewRangeNode(fxMesaContext fxMesa, FxU32 start, FxU32 end)
    }
    else {
       if (!(result = MALLOC(sizeof(MemRange)))) {
-        fprintf(stderr, "fxDriver: out of memory!\n");
+        fprintf(stderr, "fxTMNewRangeNode: ERROR: out of memory!\n");
         fxCloseHardware();
         exit(-1);
       }
@@ -126,30 +126,34 @@ fxTMNewRangeNode(fxMesaContext fxMesa, FxU32 start, FxU32 end)
    return result;
 }
 
+#if 1
+#define fxTMDeleteRangeNode(fxMesa, range) \
+   do {                                    \
+       range->next = fxMesa->tmPool;       \
+       fxMesa->tmPool = range;             \
+   } while (0);
+#else
 static void
 fxTMDeleteRangeNode(fxMesaContext fxMesa, MemRange * range)
 {
    range->next = fxMesa->tmPool;
    fxMesa->tmPool = range;
 }
+#endif
 
 static void
 fxTMUInit(fxMesaContext fxMesa, int tmu)
 {
    MemRange *tmn, *last;
-   FxU32 start, end, blockstart, blockend;
+   FxU32 start, end, blockstart, blockend, chunk;
 
    start = grTexMinAddress(tmu);
    end = grTexMaxAddress(tmu);
 
+   chunk = (fxMesa->type >= GR_SSTTYPE_Banshee) ? (end - start) : FX_2MB_SPLIT;
+
    if (fxMesa->verbose) {
-      fprintf(stderr, "Voodoo %s configuration:\n",
-             (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");
+      fprintf(stderr, "Voodoo TMU%d configuration:\n", tmu);
    }
 
    fxMesa->freeTexMem[tmu] = end - start;
@@ -158,17 +162,18 @@ fxTMUInit(fxMesaContext fxMesa, int tmu)
    last = 0;
    blockstart = start;
    while (blockstart < end) {
-      if (blockstart + FX_2MB_SPLIT > end)
+      if (blockstart + chunk > end)
         blockend = end;
       else
-        blockend = blockstart + FX_2MB_SPLIT;
+        blockend = blockstart + chunk;
 
       if (fxMesa->verbose)
-        fprintf(stderr, "Voodoo    %07u-%07u\n",
+        fprintf(stderr, "Voodoo   %08u-%08u\n",
                 (unsigned int) blockstart, (unsigned int) blockend);
 
       tmn = fxTMNewRangeNode(fxMesa, blockstart, blockend);
-      tmn->next = 0;
+      tmn->next = NULL;
+
 
       if (last)
         last->next = tmn;
@@ -176,7 +181,7 @@ fxTMUInit(fxMesaContext fxMesa, int tmu)
         fxMesa->tmFree[tmu] = tmn;
       last = tmn;
 
-      blockstart += FX_2MB_SPLIT;
+      blockstart += chunk;
    }
 }
 
@@ -187,6 +192,10 @@ fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size)
    int result;
    struct gl_texture_object *obj;
 
+   if (fxMesa->HaveTexUma) {
+      tmu = FX_TMU0;
+   }
+
    while (1) {
       prev = 0;
       tmp = fxMesa->tmFree[tmu];
@@ -210,9 +219,12 @@ fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size)
         tmp = tmp->next;
       }
       /* No free space. Discard oldest */
+      if (TDFX_DEBUG & VERBOSE_TEXTURE) {
+        fprintf(stderr, "fxTMFindStartAddr: No free space. Discard oldest\n");
+      }
       obj = fxTMFindOldestObject(fxMesa, tmu);
       if (!obj) {
-        fprintf(stderr, "fx Driver: No space for texture\n");
+        fprintf(stderr, "fxTMFindStartAddr: ERROR: No space for texture\n");
         return -1;
       }
       fxTMMoveOutTM(fxMesa, obj);
@@ -220,11 +232,37 @@ fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size)
    }
 }
 
+int fxTMCheckStartAddr (fxMesaContext fxMesa, GLint tmu, tfxTexInfo *ti)
+{
+ MemRange *tmp;
+ int size;
+
+ if (fxMesa->HaveTexUma) {
+    return FXTRUE;
+ }
+
+ size = grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
+
+ tmp = fxMesa->tmFree[tmu];
+ while (tmp) {
+       if (tmp->endAddr - tmp->startAddr >= size) { /* Fits here */
+          return FXTRUE;
+       }
+       tmp = tmp->next;
+ }
+
+ return FXFALSE;
+}
+
 static void
 fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range)
 {
    MemRange *tmp, *prev;
 
+   if (fxMesa->HaveTexUma) {
+      tmu = FX_TMU0;
+   }
+
    if (range->startAddr == range->endAddr) {
       fxTMDeleteRangeNode(fxMesa, range);
       return;
@@ -246,7 +284,7 @@ fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range)
    range->next = tmp;
    if (tmp) {
       if (range->endAddr == tmp->startAddr
-         && tmp->startAddr & (FX_2MB_SPLIT - 1)) {
+         && tmp->startAddr & texBoundMask) {
         /* Combine */
         tmp->startAddr = range->startAddr;
         fxTMDeleteRangeNode(fxMesa, range);
@@ -255,7 +293,7 @@ fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range)
    }
    if (prev) {
       if (prev->endAddr == range->startAddr
-         && range->startAddr & (FX_2MB_SPLIT - 1)) {
+         && range->startAddr & texBoundMask) {
         /* Combine */
         prev->endAddr = range->endAddr;
         prev->next = range->next;
@@ -273,22 +311,36 @@ static struct gl_texture_object *
 fxTMFindOldestObject(fxMesaContext fxMesa, int tmu)
 {
    GLuint age, old, lasttime, bindnumber;
-   tfxTexInfo *info;
-   struct gl_texture_object *obj, *tmp;
+   GLfloat lowestPriority;
+   struct gl_texture_object *obj, *lowestPriorityObj;
+   struct _mesa_HashTable *textures = fxMesa->glCtx->Shared->TexObjects;
+   GLuint id;
 
-   tmp = fxMesa->glCtx->Shared->TexObjectList;
-   if (!tmp)
+   if (!_mesa_HashFirstEntry(textures))
       return 0;
-   obj = 0;
+
+   obj = NULL;
    old = 0;
 
+   lowestPriorityObj = NULL;
+   lowestPriority = 1.0F;
+
    bindnumber = fxMesa->texBindNumber;
-   while (tmp) {
-      info = fxTMGetTexInfo(tmp);
+
+   for (id = _mesa_HashFirstEntry(textures);
+        id;
+        id = _mesa_HashNextEntry(textures, id)) {
+      struct gl_texture_object *tmp
+         = (struct gl_texture_object *) _mesa_HashLookup(textures, id);
+      tfxTexInfo *info = fxTMGetTexInfo(tmp);
 
       if (info && info->isInTM &&
-         ((info->whichTMU == tmu) || (info->whichTMU == FX_TMU_BOTH) ||
-          (info->whichTMU == FX_TMU_SPLIT))) {
+         ((info->whichTMU == tmu) ||
+          (info->whichTMU == FX_TMU_BOTH) ||
+          (info->whichTMU == FX_TMU_SPLIT) ||
+          fxMesa->HaveTexUma
+         )
+        ) {
         lasttime = info->lastTimeUsed;
 
         if (lasttime > bindnumber)
@@ -300,10 +352,29 @@ fxTMFindOldestObject(fxMesaContext fxMesa, int tmu)
            old = age;
            obj = tmp;
         }
+
+         /* examine priority */
+         if (tmp->Priority < lowestPriority) {
+            lowestPriority = tmp->Priority;
+            lowestPriorityObj = tmp;
+         }
       }
-      tmp = tmp->Next;
    }
-   return obj;
+
+   if (lowestPriorityObj != NULL) {
+       if (TDFX_DEBUG & VERBOSE_TEXTURE) {
+          fprintf(stderr, "fxTMFindOldestObject: %d pri=%f\n", lowestPriorityObj->Name, lowestPriority);
+       }
+       return lowestPriorityObj;
+   }
+   else {
+       if (TDFX_DEBUG & VERBOSE_TEXTURE) {
+          if (obj != NULL) {
+             fprintf(stderr, "fxTMFindOldestObject: %d age=%d\n", obj->Name, old);
+          }
+       }
+       return obj;
+   }
 }
 
 static MemRange *
@@ -330,15 +401,14 @@ fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj,
    int i, l;
    int texmemsize;
 
-   if (MESA_VERBOSE & VERBOSE_DRIVER) {
-      fprintf(stderr, "fxmesa: fxTMMoveInTM(%d)\n", tObj->Name);
+   if (TDFX_DEBUG & VERBOSE_DRIVER) {
+      fprintf(stderr, "fxTMMoveInTM_NoLock(%d)\n", tObj->Name);
    }
 
    fxMesa->stats.reqTexUpload++;
 
    if (!ti->validated) {
-      fprintf(stderr,
-             "fx Driver: internal error in fxTMMoveInTM() -> not validated\n");
+      fprintf(stderr, "fxTMMoveInTM_NoLock: INTERNAL ERROR: not validated\n");
       fxCloseHardware();
       exit(-1);
    }
@@ -355,9 +425,9 @@ fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj,
       }
    }
 
-   if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) {
-      fprintf(stderr, "fxmesa: downloading %x (%d) in texture memory in %d\n",
-             (GLuint) tObj, tObj->Name, where);
+   if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) {
+      fprintf(stderr, "fxTMMoveInTM_NoLock: downloading %p (%d) in texture memory in %d\n",
+                     (void *)tObj, tObj->Name, where);
    }
 
    ti->whichTMU = (FxU32) where;
@@ -371,7 +441,7 @@ fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj,
 
       for (i = FX_largeLodValue(ti->info), l = ti->minLevel;
           i <= FX_smallLodValue(ti->info); i++, l++) {
-        struct gl_texture_image *texImage = tObj->Image[l];
+        struct gl_texture_image *texImage = tObj->Image[0][l];
         grTexDownloadMipMapLevel(where,
                                            ti->tm[where]->startAddr,
                                            FX_valueToLod(i),
@@ -393,7 +463,7 @@ fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj,
 
       for (i = FX_largeLodValue(ti->info), l = ti->minLevel;
           i <= FX_smallLodValue(ti->info); i++, l++) {
-        struct gl_texture_image *texImage = tObj->Image[l];
+        struct gl_texture_image *texImage = tObj->Image[0][l];
 
         grTexDownloadMipMapLevel(GR_TMU0,
                                            ti->tm[FX_TMU0]->startAddr,
@@ -419,13 +489,13 @@ fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj,
       ti->tm[FX_TMU0] = fxTMAddObj(fxMesa, tObj, FX_TMU0, texmemsize);
       fxMesa->stats.memTexUpload += texmemsize;
 
-      texmemsize = (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
+      /*texmemsize = (int)grTexTextureMemRequired(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];
+        struct gl_texture_image *texImage = tObj->Image[0][l];
         grTexDownloadMipMapLevel(GR_TMU0,
                                            ti->tm[FX_TMU0]->startAddr,
                                            FX_valueToLod(i),
@@ -446,9 +516,7 @@ fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj,
       }
       break;
    default:
-      fprintf(stderr,
-             "fx Driver: internal error in fxTMMoveInTM() -> wrong tmu (%d)\n",
-             where);
+      fprintf(stderr, "fxTMMoveInTM_NoLock: INTERNAL ERROR: wrong tmu (%d)\n", where);
       fxCloseHardware();
       exit(-1);
    }
@@ -476,34 +544,37 @@ fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj,
    tfxTexInfo *ti = fxTMGetTexInfo(tObj);
    GrLOD_t lodlevel;
    GLint tmu;
-   struct gl_texture_image *texImage = tObj->Image[level];
+   struct gl_texture_image *texImage = tObj->Image[0][level];
    tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
 
+   if (TDFX_DEBUG & VERBOSE_TEXTURE) {
+      fprintf(stderr, "fxTMReloadMipMapLevel(%p (%d), %d)\n", (void *)tObj, tObj->Name, level);
+   }
+
    assert(mml);
    assert(mml->width > 0);
    assert(mml->height > 0);
    assert(mml->glideFormat > 0);
+   assert(ti->isInTM);
 
    if (!ti->validated) {
-      fprintf(stderr,
-             "fx Driver: internal error in fxTMReloadMipMapLevel() -> not validated\n");
+      fprintf(stderr, "fxTMReloadMipMapLevel: INTERNAL ERROR: not validated\n");
       fxCloseHardware();
       exit(-1);
    }
 
    tmu = (int) ti->whichTMU;
-   fxTMMoveInTM(fxMesa, tObj, tmu);
+   fxMesa->stats.reqTexUpload++;
+   fxMesa->stats.texUpload++;
 
-   fxTexGetInfo(mml->width, mml->height,
-               &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+   lodlevel =  ti->info.largeLodLog2 - (level - ti->minLevel);
 
-   lodlevel -= level;
    switch (tmu) {
    case FX_TMU0:
    case FX_TMU1:
       grTexDownloadMipMapLevel(tmu,
                                  ti->tm[tmu]->startAddr,
-                                 FX_valueToLod(FX_lodToValue(lodlevel)),
+                                 lodlevel,
                                  FX_largeLodLog2(ti->info),
                                  FX_aspectRatioLog2(ti->info),
                                  ti->info.format,
@@ -512,7 +583,7 @@ fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj,
    case FX_TMU_SPLIT:
       grTexDownloadMipMapLevel(GR_TMU0,
                                  ti->tm[GR_TMU0]->startAddr,
-                                 FX_valueToLod(FX_lodToValue(lodlevel)),
+                                 lodlevel,
                                  FX_largeLodLog2(ti->info),
                                  FX_aspectRatioLog2(ti->info),
                                  ti->info.format,
@@ -520,7 +591,7 @@ fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj,
 
       grTexDownloadMipMapLevel(GR_TMU1,
                                  ti->tm[GR_TMU1]->startAddr,
-                                 FX_valueToLod(FX_lodToValue(lodlevel)),
+                                 lodlevel,
                                  FX_largeLodLog2(ti->info),
                                  FX_aspectRatioLog2(ti->info),
                                  ti->info.format,
@@ -529,7 +600,7 @@ fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj,
    case FX_TMU_BOTH:
       grTexDownloadMipMapLevel(GR_TMU0,
                                  ti->tm[GR_TMU0]->startAddr,
-                                 FX_valueToLod(FX_lodToValue(lodlevel)),
+                                 lodlevel,
                                  FX_largeLodLog2(ti->info),
                                  FX_aspectRatioLog2(ti->info),
                                  ti->info.format,
@@ -537,7 +608,7 @@ fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj,
 
       grTexDownloadMipMapLevel(GR_TMU1,
                                  ti->tm[GR_TMU1]->startAddr,
-                                 FX_valueToLod(FX_lodToValue(lodlevel)),
+                                 lodlevel,
                                  FX_largeLodLog2(ti->info),
                                  FX_aspectRatioLog2(ti->info),
                                  ti->info.format,
@@ -545,9 +616,7 @@ fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj,
       break;
 
    default:
-      fprintf(stderr,
-             "fx Driver: internal error in fxTMReloadMipMapLevel() -> wrong tmu (%d)\n",
-             tmu);
+      fprintf(stderr, "fxTMReloadMipMapLevel: INTERNAL ERROR: wrong tmu (%d)\n", tmu);
       fxCloseHardware();
       exit(-1);
    }
@@ -562,14 +631,13 @@ fxTMReloadSubMipMapLevel(fxMesaContext fxMesa,
    GrLOD_t lodlevel;
    unsigned short *data;
    GLint tmu;
-   struct gl_texture_image *texImage = tObj->Image[level];
+   struct gl_texture_image *texImage = tObj->Image[0][level];
    tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
 
    assert(mml);
 
    if (!ti->validated) {
-      fprintf(stderr,
-             "fx Driver: internal error in fxTMReloadSubMipMapLevel() -> not validated\n");
+      fprintf(stderr, "fxTMReloadSubMipMapLevel: INTERNAL ERROR: not validated\n");
       fxCloseHardware();
       exit(-1);
    }
@@ -578,7 +646,7 @@ fxTMReloadSubMipMapLevel(fxMesaContext fxMesa,
    fxTMMoveInTM(fxMesa, tObj, tmu);
 
    fxTexGetInfo(mml->width, mml->height,
-               &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+               &lodlevel, NULL, NULL, NULL, NULL, NULL);
 
    if ((ti->info.format == GR_TEXFMT_INTENSITY_8) ||
        (ti->info.format == GR_TEXFMT_P_8) ||
@@ -643,9 +711,7 @@ fxTMReloadSubMipMapLevel(fxMesaContext fxMesa,
                                         yoffset, yoffset + height - 1);
       break;
    default:
-      fprintf(stderr,
-             "fx Driver: internal error in fxTMReloadSubMipMapLevel() -> wrong tmu (%d)\n",
-             tmu);
+      fprintf(stderr, "fxTMReloadSubMipMapLevel: INTERNAL ERROR: wrong tmu (%d)\n", tmu);
       fxCloseHardware();
       exit(-1);
    }
@@ -656,9 +722,8 @@ 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 (TDFX_DEBUG & VERBOSE_DRIVER) {
+      fprintf(stderr, "fxTMMoveOutTM(%p (%d))\n", (void *)tObj, tObj->Name);
    }
 
    if (!ti->isInTM)
@@ -675,7 +740,7 @@ fxTMMoveOutTM(fxMesaContext fxMesa, struct gl_texture_object *tObj)
       fxTMRemoveRange(fxMesa, FX_TMU1, ti->tm[FX_TMU1]);
       break;
    default:
-      fprintf(stderr, "fx Driver: internal error in fxTMMoveOutTM()\n");
+      fprintf(stderr, "fxTMMoveOutTM: INTERNAL ERROR: bad TMU (%ld)\n", ti->whichTMU);
       fxCloseHardware();
       exit(-1);
    }
@@ -690,15 +755,15 @@ fxTMFreeTexture(fxMesaContext fxMesa, struct gl_texture_object *tObj)
    tfxTexInfo *ti = fxTMGetTexInfo(tObj);
    int i;
 
+   if (TDFX_DEBUG & VERBOSE_TEXTURE) {
+      fprintf(stderr, "fxTMFreeTexture(%p (%d))\n", (void *)tObj, tObj->Name);
+   }
+
    fxTMMoveOutTM(fxMesa, tObj);
 
    for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
-      struct gl_texture_image *texImage = tObj->Image[i];
+      struct gl_texture_image *texImage = tObj->Image[0][i];
       if (texImage) {
-         if (texImage->Data) {
-            FREE(texImage->Data);
-            texImage->Data = NULL;
-         }
          if (texImage->DriverData) {
             FREE(texImage->DriverData);
             texImage->DriverData = NULL;
@@ -724,10 +789,16 @@ fxTMInit(fxMesaContext fxMesa)
    fxMesa->texBindNumber = 0;
    fxMesa->tmPool = 0;
 
+   if (fxMesa->HaveTexUma) {
+      grEnable(GR_TEXTURE_UMA_EXT);
+   }
+
    fxTMUInit(fxMesa, FX_TMU0);
 
-   if (fxMesa->haveTwoTMUs)
+   if (!fxMesa->HaveTexUma && fxMesa->haveTwoTMUs)
       fxTMUInit(fxMesa, FX_TMU1);
+
+   texBoundMask = (fxMesa->type >= GR_SSTTYPE_Banshee) ? -1 : (FX_2MB_SPLIT - 1);
 }
 
 void
@@ -760,26 +831,29 @@ fxTMClose(fxMesaContext fxMesa)
 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);
+   struct _mesa_HashTable *textures = ctx->glCtx->Shared->TexObjects;
+   GLuint id;
+
+   for (id = _mesa_HashFirstEntry(textures);
+        id;
+        id = _mesa_HashNextEntry(textures, id)) {
+      struct gl_texture_object *tObj
+         = (struct gl_texture_object *) _mesa_HashLookup(textures, id);
+      tfxTexInfo *ti = fxTMGetTexInfo(tObj);
       if (ti && ti->isInTM) {
-        for (i = 0; i < MAX_TEXTURE_UNITS; i++)
+         int i;
+        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;
+              int 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;
    }
 }