From d91fb9f5929d8a80dc8ea0b16d69c00342e34319 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 10 Dec 1999 19:11:23 +0000 Subject: applied Daryll's patches --- src/mesa/drivers/glide/fxtexman.c | 670 +++++++++++++++++++------------------- 1 file changed, 330 insertions(+), 340 deletions(-) (limited to 'src/mesa/drivers/glide/fxtexman.c') diff --git a/src/mesa/drivers/glide/fxtexman.c b/src/mesa/drivers/glide/fxtexman.c index 97577fca26..770f095ab8 100644 --- a/src/mesa/drivers/glide/fxtexman.c +++ b/src/mesa/drivers/glide/fxtexman.c @@ -54,32 +54,81 @@ #include "fxdrv.h" -static tfxTMFreeNode *fxTMNewTMFreeNode(FxU32 start, FxU32 end) +#define FX_2MB_SPLIT 0x200000 + +static struct gl_texture_object *fxTMFindOldestObject(fxMesaContext fxMesa, + int tmu); + + +#if 0 +static void fubar() { - tfxTMFreeNode *tmn; +} - if(!(tmn=MALLOC(sizeof(tfxTMFreeNode)))) { - fprintf(stderr,"fx Driver: out of memory !\n"); - fxCloseHardware(); - exit(-1); + /* Sanity Check */ +static void sanity(fxMesaContext fxMesa, int tmu) +{ + MemRange *tmp, *prev; + int i; + + prev=0; + tmp = fxMesa->tmFree[tmu]; + i=0; + while (tmp) { + fprintf(stderr, "TMU %d Sanity %d %d-%d\n", tmu, i, + tmp->startAddr, tmp->endAddr); + i++; + 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 - tmn->next=NULL; - tmn->startAddress=start; - tmn->endAddress=end; +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; +} - return tmn; +static void fxTMDeleteRangeNode(fxMesaContext fxMesa, MemRange *range) +{ + range->next=fxMesa->tmPool; + fxMesa->tmPool=range; } -/* Notice this uses grTex{Min,Max}Address directly with FX_ because it - is only used during initialization where the lock is already held. */ static void fxTMUInit(fxMesaContext fxMesa, int tmu) { - tfxTMFreeNode *tmn,*tmntmp; + MemRange *tmn, *last; FxU32 start,end,blockstart,blockend; start=FX_grTexMinAddress(tmu); end=FX_grTexMaxAddress(tmu); + fxMesa->texStart[tmu]=start; if(fxMesa->verbose) { fprintf(stderr,"%s configuration:",(tmu==FX_TMU0) ? "TMU0" : "TMU1"); @@ -90,169 +139,158 @@ static void fxTMUInit(fxMesaContext fxMesa, int tmu) fxMesa->freeTexMem[tmu]=end-start; fxMesa->tmFree[tmu]=NULL; - fxMesa->tmAlloc[tmu]=NULL; + last=0; blockstart=start; - while(blockstart<=end) { - if(blockstart+0x1fffff>end) - blockend=end; - else - blockend=blockstart+0x1fffff; + while (blockstartend) blockend=end; + else blockend=blockstart+FX_2MB_SPLIT; if(fxMesa->verbose) - fprintf(stderr," %07u-%07u\n",(unsigned int)blockstart,(unsigned int)blockend); + fprintf(stderr," %07u-%07u\n", + (unsigned int)blockstart,(unsigned int)blockend); - tmn=fxTMNewTMFreeNode(blockstart,blockend); + tmn=fxTMNewRangeNode(fxMesa, blockstart, blockend); + tmn->next=0; - if(fxMesa->tmFree[tmu]) { - for(tmntmp=fxMesa->tmFree[tmu];tmntmp->next!=NULL;tmntmp=tmntmp->next){}; - tmntmp->next=tmn; - } else - fxMesa->tmFree[tmu]=tmn; + if (last) last->next=tmn; + else fxMesa->tmFree[tmu]=tmn; + last=tmn; - blockstart+=0x1fffff+1; + blockstart+=FX_2MB_SPLIT; } } -void fxTMInit(fxMesaContext fxMesa) -{ - fxTMUInit(fxMesa,FX_TMU0); - - if(fxMesa->haveTwoTMUs) - fxTMUInit(fxMesa,FX_TMU1); - - fxMesa->texBindNumber=0; -} - -static struct gl_texture_object *fxTMFindOldestTMBlock(fxMesaContext fxMesa, - tfxTMAllocNode *tmalloc, - GLuint texbindnumber) +static int fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size) { - GLuint age,oldestage,lasttimeused; - struct gl_texture_object *oldesttexobj; - - (void)fxMesa; - oldesttexobj=tmalloc->tObj; - oldestage=0; - - while(tmalloc) { - lasttimeused=((tfxTexInfo *)(tmalloc->tObj->DriverData))->tmi.lastTimeUsed; - - if(lasttimeused>texbindnumber) - age=texbindnumber+(UINT_MAX-lasttimeused+1); /* TO DO: check */ - else - age=texbindnumber-lasttimeused; - - if(age>=oldestage) { - oldestage=age; - oldesttexobj=tmalloc->tObj; + 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); + } + return result; + } + prev=tmp; + tmp=tmp->next; } - - tmalloc=tmalloc->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); } - - return oldesttexobj; -} - -static GLboolean fxTMFreeOldTMBlock(fxMesaContext fxMesa, GLint tmu) -{ - struct gl_texture_object *oldesttexobj; - - if(!fxMesa->tmAlloc[tmu]) - return GL_FALSE; - - oldesttexobj=fxTMFindOldestTMBlock(fxMesa,fxMesa->tmAlloc[tmu],fxMesa->texBindNumber); - - fxTMMoveOutTM(fxMesa,oldesttexobj); - - return GL_TRUE; } -static tfxTMFreeNode *fxTMExtractTMFreeBlock(tfxTMFreeNode *tmfree, int texmemsize, - GLboolean *success, FxU32 *startadr) +static void fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange *range) { - int blocksize; - - /* TO DO: cut recursion */ + MemRange *tmp, *prev, *next; - if(!tmfree) { - *success=GL_FALSE; - return NULL; + if (range->startAddr==range->endAddr) { + fxTMDeleteRangeNode(fxMesa, range); + return; } - - blocksize=(int)tmfree->endAddress-(int)tmfree->startAddress+1; - - if(blocksize==texmemsize) { - tfxTMFreeNode *nexttmfree; - - *success=GL_TRUE; - *startadr=tmfree->startAddress; - - nexttmfree=tmfree->next; - FREE(tmfree); - - return nexttmfree; + prev=0; + tmp=fxMesa->tmFree[tmu]; + while (tmp) { + if (range->startAddr>tmp->startAddr) { + prev=tmp; + tmp=tmp->next; + } else break; } - - if(blocksize>texmemsize) { - *success=GL_TRUE; - *startadr=tmfree->startAddress; - - tmfree->startAddress+=texmemsize; - - return tmfree; + /* 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; } - - tmfree->next=fxTMExtractTMFreeBlock(tmfree->next,texmemsize,success,startadr); - - return tmfree; } -static tfxTMAllocNode *fxTMGetTMBlock(fxMesaContext fxMesa, struct gl_texture_object *tObj, - GLint tmu, int texmemsize) +static struct gl_texture_object *fxTMFindOldestObject(fxMesaContext fxMesa, + int tmu) { - tfxTMFreeNode *newtmfree; - tfxTMAllocNode *newtmalloc; - GLboolean success; - FxU32 startadr; - - for(;;) { /* TO DO: improve performaces */ - newtmfree=fxTMExtractTMFreeBlock(fxMesa->tmFree[tmu],texmemsize,&success,&startadr); - - if(success) { - fxMesa->tmFree[tmu]=newtmfree; - - fxMesa->freeTexMem[tmu]-=texmemsize; - - if(!(newtmalloc=MALLOC(sizeof(tfxTMAllocNode)))) { - fprintf(stderr,"fx Driver: out of memory !\n"); - fxCloseHardware(); - exit(-1); + 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; } - - newtmalloc->next=fxMesa->tmAlloc[tmu]; - newtmalloc->startAddress=startadr; - newtmalloc->endAddress=startadr+texmemsize-1; - newtmalloc->tObj=tObj; - - fxMesa->tmAlloc[tmu]=newtmalloc; - - return newtmalloc; - } - - if(!fxTMFreeOldTMBlock(fxMesa,tmu)) { - fprintf(stderr,"fx Driver: internal error in fxTMGetTMBlock()\n"); - fprintf(stderr," TMU: %d Size: %d\n",tmu,texmemsize); - - fxCloseHardware(); - exit(-1); } + tmp=tmp->Next; } + return obj; } +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; +} + +/* External Functions */ + void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint where) { - tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData; + tfxTexInfo *ti=fxTMGetTexInfo(tObj); int i,l; int texmemsize; @@ -262,68 +300,71 @@ void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, G fxMesa->stats.reqTexUpload++; - if(!ti->validated) { + if (!ti->validated) { fprintf(stderr,"fx Driver: internal error in fxTMMoveInTM() -> not validated\n"); fxCloseHardware(); exit(-1); } - if(ti->tmi.isInTM) - return; + if (ti->isInTM) return; 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->tmi.whichTMU=(FxU32)where; + ti->whichTMU=(FxU32)where; - switch(where) { + switch (where) { case FX_TMU0: case FX_TMU1: texmemsize=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); - ti->tmi.tm[where]=fxTMGetTMBlock(fxMesa,tObj,where,texmemsize); + 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++) + for (i=FX_largeLodValue(ti->info), l=ti->minLevel; + i<=FX_smallLodValue(ti->info); + i++,l++) FX_grTexDownloadMipMapLevel_NoLock(where, - ti->tmi.tm[where]->startAddress, + ti->tm[where]->startAddr, FX_valueToLod(i), FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_BOTH, - ti->tmi.mipmapLevel[l].data); + ti->mipmapLevel[l].data); break; case FX_TMU_SPLIT: /* TO DO: alternate even/odd TMU0/TMU1 */ texmemsize=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_ODD, &(ti->info)); - ti->tmi.tm[FX_TMU0]=fxTMGetTMBlock(fxMesa,tObj,FX_TMU0,texmemsize); + 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->tmi.tm[FX_TMU1]=fxTMGetTMBlock(fxMesa,tObj,FX_TMU1,texmemsize); + 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++) { + for (i=FX_largeLodValue(ti->info),l=ti->minLevel; + i<=FX_smallLodValue(ti->info); + i++,l++) { FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0, - ti->tmi.tm[FX_TMU0]->startAddress, + ti->tm[FX_TMU0]->startAddr, FX_valueToLod(i), FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_ODD, - ti->tmi.mipmapLevel[l].data); + ti->mipmapLevel[l].data); FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1, - ti->tmi.tm[FX_TMU1]->startAddress, + ti->tm[FX_TMU1]->startAddr, FX_valueToLod(i), FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_EVEN, - ti->tmi.mipmapLevel[l].data); + ti->mipmapLevel[l].data); } break; default: @@ -334,7 +375,7 @@ void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, G fxMesa->stats.texUpload++; - ti->tmi.isInTM=GL_TRUE; + ti->isInTM=GL_TRUE; } void fxTMMoveInTM(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint where) { @@ -345,43 +386,52 @@ void fxTMMoveInTM(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint wh void fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint level) { - tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData; + tfxTexInfo *ti=fxTMGetTexInfo(tObj); GrLOD_t lodlevel; GLint tmu; - if(!ti->validated) { + if (!ti->validated) { fprintf(stderr,"fx Driver: internal error in fxTMReloadMipMapLevel() -> not validated\n"); fxCloseHardware(); exit(-1); } - tmu=(int)ti->tmi.whichTMU; - fxTMMoveInTM(fxMesa,tObj,tmu); + tmu=(int)ti->whichTMU; + fxTMMoveInTM(fxMesa, tObj, tmu); - fxTexGetInfo(ti->tmi.mipmapLevel[0].width,ti->tmi.mipmapLevel[0].height, - &lodlevel,NULL,NULL,NULL,NULL,NULL,NULL,NULL); + fxTexGetInfo(ti->mipmapLevel[0].width,ti->mipmapLevel[0].height, + &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL); switch(tmu) { case FX_TMU0: case FX_TMU1: FX_grTexDownloadMipMapLevel(tmu, - ti->tmi.tm[tmu]->startAddress,FX_valueToLod(FX_lodToValue(lodlevel)+level), - FX_largeLodLog2(ti->info),FX_aspectRatioLog2(ti->info), - ti->info.format,GR_MIPMAPLEVELMASK_BOTH, - ti->tmi.mipmapLevel[level].data); + 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[level].data); break; case FX_TMU_SPLIT: /* TO DO: alternate even/odd TMU0/TMU1 */ FX_grTexDownloadMipMapLevel(GR_TMU0, - ti->tmi.tm[GR_TMU0]->startAddress,FX_valueToLod(FX_lodToValue(lodlevel)+level), - FX_largeLodLog2(ti->info),FX_aspectRatioLog2(ti->info), - ti->info.format,GR_MIPMAPLEVELMASK_ODD, - ti->tmi.mipmapLevel[level].data); + ti->tm[GR_TMU0]->startAddr, + FX_valueToLod(FX_lodToValue(lodlevel)+level), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_ODD, + ti->mipmapLevel[level].data); FX_grTexDownloadMipMapLevel(GR_TMU1, - ti->tmi.tm[GR_TMU1]->startAddress,FX_valueToLod(FX_lodToValue(lodlevel)+level), - FX_largeLodLog2(ti->info),FX_aspectRatioLog2(ti->info), - ti->info.format,GR_MIPMAPLEVELMASK_EVEN, - ti->tmi.mipmapLevel[level].data); + ti->tm[GR_TMU1]->startAddr, + FX_valueToLod(FX_lodToValue(lodlevel)+level), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_EVEN, + ti->mipmapLevel[level].data); break; default: fprintf(stderr,"fx Driver: internal error in fxTMReloadMipMapLevel() -> wrong tmu (%d)\n",tmu); @@ -390,10 +440,11 @@ void fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, } } -void fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, +void fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, + struct gl_texture_object *tObj, GLint level, GLint yoffset, GLint height) { - tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData; + tfxTexInfo *ti=fxTMGetTexInfo(tObj); GrLOD_t lodlevel; unsigned short *data; GLint tmu; @@ -404,43 +455,52 @@ void fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tO exit(-1); } - tmu=(int)ti->tmi.whichTMU; - fxTMMoveInTM(fxMesa,tObj,tmu); + tmu=(int)ti->whichTMU; + fxTMMoveInTM(fxMesa, tObj, tmu); - fxTexGetInfo(ti->tmi.mipmapLevel[0].width,ti->tmi.mipmapLevel[0].height, - &lodlevel,NULL,NULL,NULL,NULL,NULL,NULL,NULL); + 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->tmi.mipmapLevel[level].data+((yoffset*ti->tmi.mipmapLevel[level].width)>>1); + data=ti->mipmapLevel[level].data+((yoffset*ti->mipmapLevel[level].width)>>1); else - data=ti->tmi.mipmapLevel[level].data+yoffset*ti->tmi.mipmapLevel[level].width; + data=ti->mipmapLevel[level].data+yoffset*ti->mipmapLevel[level].width; switch(tmu) { case FX_TMU0: case FX_TMU1: FX_grTexDownloadMipMapLevelPartial(tmu, - ti->tmi.tm[tmu]->startAddress,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); + 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: /* TO DO: alternate even/odd TMU0/TMU1 */ FX_grTexDownloadMipMapLevelPartial(GR_TMU0, - ti->tmi.tm[FX_TMU0]->startAddress,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); + 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->tmi.tm[FX_TMU1]->startAddress,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); + 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; default: fprintf(stderr,"fx Driver: internal error in fxTMReloadSubMipMapLevel() -> wrong tmu (%d)\n",tmu); @@ -449,103 +509,24 @@ void fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tO } } -static tfxTMAllocNode *fxTMFreeTMAllocBlock(tfxTMAllocNode *tmalloc, - tfxTMAllocNode *tmunalloc) -{ - if(!tmalloc) - return NULL; - - if(tmalloc==tmunalloc) { - tfxTMAllocNode *newtmalloc; - - newtmalloc=tmalloc->next; - FREE(tmalloc); - - return newtmalloc; - } - - tmalloc->next=fxTMFreeTMAllocBlock(tmalloc->next,tmunalloc); - - return tmalloc; -} - -static tfxTMFreeNode *fxTMAddTMFree(tfxTMFreeNode *tmfree, FxU32 startadr, FxU32 endadr) -{ - if(!tmfree) - return fxTMNewTMFreeNode(startadr,endadr); - - if((endadr+1==tmfree->startAddress) && (tmfree->startAddress & 0x1fffff)) { - tmfree->startAddress=startadr; - - return tmfree; - } - - if((startadr-1==tmfree->endAddress) && (startadr & 0x1fffff)) { - tmfree->endAddress=endadr; - - if((tmfree->next && (endadr+1==tmfree->next->startAddress) && - (tmfree->next->startAddress & 0x1fffff))) { - tfxTMFreeNode *nexttmfree; - - tmfree->endAddress=tmfree->next->endAddress; - - nexttmfree=tmfree->next->next; - FREE(tmfree->next); - - tmfree->next=nexttmfree; - } - - - return tmfree; - } - - if(startadrstartAddress) { - tfxTMFreeNode *newtmfree; - - newtmfree=fxTMNewTMFreeNode(startadr,endadr); - newtmfree->next=tmfree; - - return newtmfree; - } - - tmfree->next=fxTMAddTMFree(tmfree->next,startadr,endadr); - - return tmfree; -} - -static void fxTMFreeTMBlock(fxMesaContext fxMesa, GLint tmu, tfxTMAllocNode *tmalloc) -{ - FxU32 startadr,endadr; - - startadr=tmalloc->startAddress; - endadr=tmalloc->endAddress; - - fxMesa->tmAlloc[tmu]=fxTMFreeTMAllocBlock(fxMesa->tmAlloc[tmu],tmalloc); - - fxMesa->tmFree[tmu]=fxTMAddTMFree(fxMesa->tmFree[tmu],startadr,endadr); - - fxMesa->freeTexMem[tmu]+=endadr-startadr+1; -} - void fxTMMoveOutTM(fxMesaContext fxMesa, struct gl_texture_object *tObj) { - tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData; + tfxTexInfo *ti=fxTMGetTexInfo(tObj); if (MESA_VERBOSE&VERBOSE_DRIVER) { fprintf(stderr,"fxmesa: fxTMMoveOutTM(%x (%d))\n",(GLuint)tObj,tObj->Name); } - if(!ti->tmi.isInTM) - return; + if (!ti->isInTM) return; - switch(ti->tmi.whichTMU) { + switch(ti->whichTMU) { case FX_TMU0: case FX_TMU1: - fxTMFreeTMBlock(fxMesa,(int)ti->tmi.whichTMU,ti->tmi.tm[ti->tmi.whichTMU]); + fxTMRemoveRange(fxMesa, (int)ti->whichTMU, ti->tm[ti->whichTMU]); break; case FX_TMU_SPLIT: - fxTMFreeTMBlock(fxMesa,FX_TMU0,ti->tmi.tm[FX_TMU0]); - fxTMFreeTMBlock(fxMesa,FX_TMU1,ti->tmi.tm[FX_TMU1]); + 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"); @@ -553,65 +534,75 @@ void fxTMMoveOutTM(fxMesaContext fxMesa, struct gl_texture_object *tObj) exit(-1); } - ti->tmi.whichTMU=FX_TMU_NONE; - ti->tmi.isInTM=GL_FALSE; + ti->isInTM=GL_FALSE; + ti->whichTMU=FX_TMU_NONE; } void fxTMFreeTexture(fxMesaContext fxMesa, struct gl_texture_object *tObj) { - tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData; + tfxTexInfo *ti=fxTMGetTexInfo(tObj); int i; - fxTMMoveOutTM(fxMesa,tObj); + fxTMMoveOutTM(fxMesa, tObj); - for(i=0;itmi.mipmapLevel[i].used && - ti->tmi.mipmapLevel[i].translated) - FREE(ti->tmi.mipmapLevel[i].data); + for(i=0; imipmapLevel[i].used && + ti->mipmapLevel[i].translated) + FREE(ti->mipmapLevel[i].data); - (void)ti->tmi.mipmapLevel[i].data; + (void)ti->mipmapLevel[i].data; + } + switch (ti->whichTMU) { + case FX_TMU0: + 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 fxTMFreeAllFreeNode(tfxTMFreeNode *fn) -{ - if(!fn) - return; - - if(fn->next) - fxTMFreeAllFreeNode(fn->next); - - FREE(fn); -} - -void fxTMFreeAllAllocNode(tfxTMAllocNode *an) +void fxTMInit(fxMesaContext fxMesa) { - if(!an) - return; + fxTMUInit(fxMesa,FX_TMU0); - if(an->next) - fxTMFreeAllAllocNode(an->next); + if(fxMesa->haveTwoTMUs) + fxTMUInit(fxMesa,FX_TMU1); - FREE(an); + fxMesa->texBindNumber=0; } void fxTMClose(fxMesaContext fxMesa) { - fxTMFreeAllFreeNode(fxMesa->tmFree[FX_TMU0]); - fxTMFreeAllAllocNode(fxMesa->tmAlloc[FX_TMU0]); - fxMesa->tmFree[FX_TMU0] = NULL; - fxMesa->tmAlloc[FX_TMU0] = NULL; - if(fxMesa->haveTwoTMUs) { - fxTMFreeAllFreeNode(fxMesa->tmFree[FX_TMU1]); - fxTMFreeAllAllocNode(fxMesa->tmAlloc[FX_TMU1]); - fxMesa->tmFree[FX_TMU1] = NULL; - fxMesa->tmAlloc[FX_TMU1] = NULL; + 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; + FREE(tmp); + tmp=next; + } } } void fxTMRestore_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj) { - tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData; + tfxTexInfo *ti=fxTMGetTexInfo(tObj); int i,l, where; if (MESA_VERBOSE&VERBOSE_DRIVER) { @@ -624,9 +615,10 @@ void fxTMRestore_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj) exit(-1); } - where=ti->tmi.whichTMU; + where=ti->whichTMU; if (MESA_VERBOSE&(VERBOSE_DRIVER|VERBOSE_TEXTURE)) { - fprintf(stderr,"fxmesa: reloading %x (%d) in texture memory in %d\n",(GLuint)tObj,tObj->Name,where); + fprintf(stderr,"fxmesa: reloading %x (%d) in texture memory in %d\n", + (GLuint)tObj, tObj->Name, where); } switch(where) { @@ -635,38 +627,38 @@ void fxTMRestore_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj) for (i=FX_largeLodValue_NoLock(ti->info), l=ti->minLevel; i<=FX_smallLodValue_NoLock(ti->info); i++,l++) - if (ti->tmi.mipmapLevel[l].data) + if (ti->mipmapLevel[l].data) FX_grTexDownloadMipMapLevel_NoLock(where, - ti->tmi.tm[where]->startAddress, + ti->tm[where]->startAddr, FX_valueToLod(i), FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_BOTH, - ti->tmi.mipmapLevel[l].data); + ti->mipmapLevel[l].data); break; case FX_TMU_SPLIT: /* TO DO: alternate even/odd TMU0/TMU1 */ for (i=FX_largeLodValue_NoLock(ti->info),l=ti->minLevel; i<=FX_smallLodValue_NoLock(ti->info); i++,l++) { - if (ti->tmi.mipmapLevel[l].data) + if (ti->mipmapLevel[l].data) FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0, - ti->tmi.tm[FX_TMU0]->startAddress, + ti->tm[FX_TMU0]->startAddr, FX_valueToLod(i), FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_ODD, - ti->tmi.mipmapLevel[l].data); - if (ti->tmi.mipmapLevel[l].data) + ti->mipmapLevel[l].data); + if (ti->mipmapLevel[l].data) FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1, - ti->tmi.tm[FX_TMU1]->startAddress, + ti->tm[FX_TMU1]->startAddr, FX_valueToLod(i), FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, GR_MIPMAPLEVELMASK_EVEN, - ti->tmi.mipmapLevel[l].data); + ti->mipmapLevel[l].data); } break; default: @@ -685,8 +677,8 @@ fxTMRestoreTextures(fxMesaContext ctx) { tObj=ctx->glCtx->Shared->TexObjectList; while (tObj) { - ti=(tfxTexInfo*)tObj->DriverData; - if (ti && ti->tmi.isInTM) { + 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 */ @@ -698,8 +690,6 @@ fxTMRestoreTextures(fxMesaContext ctx) { } tObj=tObj->Next; } - ctx->lastUnitsMode=0; - fxSetupTexture_NoLock(ctx->glCtx); } #else -- cgit v1.2.3