X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmesa%2Fdrivers%2Fglide%2Ffxtexman.c;h=940c8fd0b97d92c9d065b6b8753ae2a61a0193aa;hb=59d54334c96f44ed1d8bf660dc96221362a77d04;hp=b98ccedd3f9d121c731b7c52b36f1e54cb7a1fe0;hpb=ad2ac216fa0cbebc36530bf9e5256e902710b892;p=mesa.git diff --git a/src/mesa/drivers/glide/fxtexman.c b/src/mesa/drivers/glide/fxtexman.c index b98ccedd3f9..940c8fd0b97 100644 --- a/src/mesa/drivers/glide/fxtexman.c +++ b/src/mesa/drivers/glide/fxtexman.c @@ -1,9 +1,8 @@ - /* * 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"), @@ -21,26 +20,16 @@ * 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 - * Keith Whitwell - * - * See fxapi.h for more revision/author details. */ +/* Authors: + * David Bucciarelli + * Brian Paul + * Daryll Strauss + * Keith Whitwell + * Daniel Borca + * Hiroshi Morii + */ /* fxtexman.c - 3Dfx VooDoo texture memory functions */ @@ -51,9 +40,11 @@ #if defined(FX) +#include "hash.h" #include "fxdrv.h" -int texSwaps=0; +int texSwaps = 0; +static FxU32 texBoundMask; #define FX_2MB_SPLIT 0x200000 @@ -62,673 +53,808 @@ 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, "fxTMNewRangeNode: ERROR: out of memory!\n"); + fxCloseHardware(); + exit(-1); + } + } + result->startAddr = start; + result->endAddr = end; + return result; } -static void fxTMDeleteRangeNode(fxMesaContext fxMesa, MemRange *range) +#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; + range->next = fxMesa->tmPool; + fxMesa->tmPool = range; } +#endif -static void fxTMUInit(fxMesaContext fxMesa, int tmu) +static void +fxTMUInit(fxMesaContext fxMesa, int tmu) { - MemRange *tmn, *last; - FxU32 start,end,blockstart,blockend; + MemRange *tmn, *last; + FxU32 start, end, blockstart, blockend, chunk; - start=FX_grTexMinAddress(tmu); - end=FX_grTexMaxAddress(tmu); + start = grTexMinAddress(tmu); + end = 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"); - } + chunk = (fxMesa->type >= GR_SSTTYPE_Banshee) ? (end - start) : FX_2MB_SPLIT; - fxMesa->freeTexMem[tmu]=end-start; - fxMesa->tmFree[tmu]=NULL; + if (fxMesa->verbose) { + fprintf(stderr, "Voodoo TMU%d configuration:\n", tmu); + } - last=0; - blockstart=start; - while (blockstartend) blockend=end; - else blockend=blockstart+FX_2MB_SPLIT; + fxMesa->freeTexMem[tmu] = end - start; + fxMesa->tmFree[tmu] = NULL; - if(fxMesa->verbose) - fprintf(stderr,"Voodoo %07u-%07u\n", - (unsigned int)blockstart,(unsigned int)blockend); + last = 0; + blockstart = start; + while (blockstart < end) { + if (blockstart + chunk > end) + blockend = end; + else + blockend = blockstart + chunk; + + if (fxMesa->verbose) + fprintf(stderr, "Voodoo %08u-%08u\n", + (unsigned int) blockstart, (unsigned int) blockend); + + tmn = fxTMNewRangeNode(fxMesa, blockstart, blockend); + tmn->next = NULL; - tmn=fxTMNewRangeNode(fxMesa, blockstart, blockend); - tmn->next=0; - if (last) last->next=tmn; - else fxMesa->tmFree[tmu]=tmn; - last=tmn; + if (last) + last->next = tmn; + else + fxMesa->tmFree[tmu] = tmn; + last = tmn; - blockstart+=FX_2MB_SPLIT; - } + blockstart += chunk; + } } -static int fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size) +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; + MemRange *prev, *tmp; + int result; + struct gl_texture_object *obj; + + if (fxMesa->HaveTexUma) { + tmu = FX_TMU0; + } + + 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 */ + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxTMFindStartAddr: No free space. Discard oldest\n"); + } + obj = fxTMFindOldestObject(fxMesa, tmu); + if (!obj) { + fprintf(stderr, "fxTMFindStartAddr: ERROR: No space for texture\n"); + return -1; } - 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++; - } + fxTMMoveOutTM(fxMesa, obj); + texSwaps++; + } } -static void fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange *range) +int fxTMCheckStartAddr (fxMesaContext fxMesa, GLint tmu, tfxTexInfo *ti) { - 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; - } + 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 struct gl_texture_object *fxTMFindOldestObject(fxMesaContext fxMesa, - int tmu) +static void +fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range) { - 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; + MemRange *tmp, *prev; + + if (fxMesa->HaveTexUma) { + tmu = FX_TMU0; + } - if (age>=old) { - old=age; - obj=tmp; + 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 & texBoundMask) { + /* Combine */ + tmp->startAddr = range->startAddr; + fxTMDeleteRangeNode(fxMesa, range); + range = tmp; + } + } + if (prev) { + if (prev->endAddr == range->startAddr + && range->startAddr & texBoundMask) { + /* Combine */ + prev->endAddr = range->endAddr; + prev->next = range->next; + fxTMDeleteRangeNode(fxMesa, range); } - } - tmp=tmp->Next; - } - return obj; + else + prev->next = range; + } + else { + fxMesa->tmFree[tmu] = range; + } } -static MemRange *fxTMAddObj(fxMesaContext fxMesa, - struct gl_texture_object *tObj, - GLint tmu, int texmemsize) +static struct gl_texture_object * +fxTMFindOldestObject(fxMesaContext fxMesa, int tmu) { - FxU32 startAddr; - MemRange *range; + GLuint age, old, lasttime, bindnumber; + GLfloat lowestPriority; + struct gl_texture_object *obj, *lowestPriorityObj; + struct _mesa_HashTable *textures = fxMesa->glCtx->Shared->TexObjects; + GLuint id; + + if (!_mesa_HashFirstEntry(textures)) + return 0; + + obj = NULL; + old = 0; + + lowestPriorityObj = NULL; + lowestPriority = 1.0F; + + bindnumber = fxMesa->texBindNumber; + + 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) || + fxMesa->HaveTexUma + ) + ) { + 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; + } + + /* examine priority */ + if (tmp->Priority < lowestPriority) { + lowestPriority = tmp->Priority; + lowestPriorityObj = tmp; + } + } + } + + 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; + } +} - startAddr=fxTMFindStartAddr(fxMesa, tmu, texmemsize); - if (startAddr<0) return 0; - range=fxTMNewRangeNode(fxMesa, startAddr, startAddr+texmemsize); - return range; +static MemRange * +fxTMAddObj(fxMesaContext fxMesa, + struct gl_texture_object *tObj, GLint tmu, int texmemsize) +{ + FxI32 startAddr; + MemRange *range; + + startAddr = fxTMFindStartAddr(fxMesa, tmu, texmemsize); + if (startAddr < 0) + return 0; + range = fxTMNewRangeNode(fxMesa, startAddr, startAddr + texmemsize); + return range; } /* External Functions */ -void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint where) +void +fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, + GLint where) { - 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); + int i, l; + int texmemsize; + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxTMMoveInTM_NoLock(%d)\n", tObj->Name); + } + + fxMesa->stats.reqTexUpload++; + + if (!ti->validated) { + fprintf(stderr, "fxTMMoveInTM_NoLock: INTERNAL ERROR: 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 (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; + + switch (where) { + case FX_TMU0: + case FX_TMU1: + texmemsize = (int)grTexTextureMemRequired(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[0][l]; + grTexDownloadMipMapLevel(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)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_ODD, &(ti->info)); + ti->tm[FX_TMU0] = fxTMAddObj(fxMesa, tObj, FX_TMU0, texmemsize); + fxMesa->stats.memTexUpload += texmemsize; + + texmemsize = (int)grTexTextureMemRequired(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[0][l]; + + grTexDownloadMipMapLevel(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); + + grTexDownloadMipMapLevel(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)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); + ti->tm[FX_TMU0] = fxTMAddObj(fxMesa, tObj, FX_TMU0, texmemsize); + fxMesa->stats.memTexUpload += texmemsize; + + /*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[0][l]; + grTexDownloadMipMapLevel(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); + + grTexDownloadMipMapLevel(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, "fxTMMoveInTM_NoLock: INTERNAL ERROR: 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; + 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, "fxTMReloadMipMapLevel: INTERNAL ERROR: not validated\n"); + fxCloseHardware(); + exit(-1); + } + + tmu = (int) ti->whichTMU; + fxMesa->stats.reqTexUpload++; + fxMesa->stats.texUpload++; + + lodlevel = ti->info.largeLodLog2 - (level - ti->minLevel); + + switch (tmu) { + case FX_TMU0: + case FX_TMU1: + grTexDownloadMipMapLevel(tmu, + ti->tm[tmu]->startAddr, + lodlevel, + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, texImage->Data); + break; + case FX_TMU_SPLIT: + grTexDownloadMipMapLevel(GR_TMU0, + ti->tm[GR_TMU0]->startAddr, + lodlevel, + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_ODD, texImage->Data); + + grTexDownloadMipMapLevel(GR_TMU1, + ti->tm[GR_TMU1]->startAddr, + lodlevel, + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_EVEN, texImage->Data); + break; + case FX_TMU_BOTH: + grTexDownloadMipMapLevel(GR_TMU0, + ti->tm[GR_TMU0]->startAddr, + lodlevel, + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, texImage->Data); + + grTexDownloadMipMapLevel(GR_TMU1, + ti->tm[GR_TMU1]->startAddr, + lodlevel, + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, texImage->Data); + break; + + default: + fprintf(stderr, "fxTMReloadMipMapLevel: INTERNAL ERROR: 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[0][level]; + tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + + assert(mml); + + if (!ti->validated) { + fprintf(stderr, "fxTMReloadSubMipMapLevel: INTERNAL ERROR: 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); + + 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: + 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: + 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, + 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: + 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, + 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(); + GR_MIPMAPLEVELMASK_BOTH, data, + yoffset, yoffset + height - 1); + break; + default: + fprintf(stderr, "fxTMReloadSubMipMapLevel: INTERNAL ERROR: wrong tmu (%d)\n", tmu); + fxCloseHardware(); + exit(-1); + } } -void fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint level) +void +fxTMMoveOutTM(fxMesaContext fxMesa, struct gl_texture_object *tObj) { - 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); + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxTMMoveOutTM(%p (%d))\n", (void *)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, "fxTMMoveOutTM: INTERNAL ERROR: bad TMU (%ld)\n", ti->whichTMU); + fxCloseHardware(); + exit(-1); + } -#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); - } + ti->isInTM = GL_FALSE; + ti->whichTMU = FX_TMU_NONE; } -void fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, - struct gl_texture_object *tObj, - GLint level, GLint yoffset, GLint height) +void +fxTMFreeTexture(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); + 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[0][i]; + if (texImage) { + 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 fxTMMoveOutTM(fxMesaContext fxMesa, struct gl_texture_object *tObj) +void +fxTMInit(fxMesaContext fxMesa) { - 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; -} + fxMesa->texBindNumber = 0; + fxMesa->tmPool = 0; -void fxTMFreeTexture(fxMesaContext fxMesa, struct gl_texture_object *tObj) -{ - tfxTexInfo *ti=fxTMGetTexInfo(tObj); - int i; - - fxTMMoveOutTM(fxMesa, tObj); - - for (i=0; imipmapLevel[i].data) { - FREE(ti->mipmapLevel[i].data); - ti->mipmapLevel[i].data = 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; - } -} + if (fxMesa->HaveTexUma) { + grEnable(GR_TEXTURE_UMA_EXT); + } -void fxTMInit(fxMesaContext fxMesa) -{ - fxMesa->texBindNumber=0; - fxMesa->tmPool=0; + fxTMUInit(fxMesa, FX_TMU0); - fxTMUInit(fxMesa,FX_TMU0); + if (!fxMesa->HaveTexUma && fxMesa->haveTwoTMUs) + fxTMUInit(fxMesa, FX_TMU1); - if(fxMesa->haveTwoTMUs) - fxTMUInit(fxMesa,FX_TMU1); + texBoundMask = (fxMesa->type >= GR_SSTTYPE_Banshee) ? -1 : (FX_2MB_SPLIT - 1); } -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; iglCtx->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; - } +fxTMRestoreTextures_NoLock(fxMesaContext ctx) +{ + 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) { + 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 */ + 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); + } + } } #else @@ -739,9 +865,10 @@ fxTMRestoreTextures_NoLock(fxMesaContext ctx) { */ extern int gl_fx_dummy_function_texman(void); -int gl_fx_dummy_function_texman(void) +int +gl_fx_dummy_function_texman(void) { - return 0; + return 0; } -#endif /* FX */ +#endif /* FX */