summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/glide/fxtexman.c
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>1999-12-10 19:11:23 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>1999-12-10 19:11:23 +0000
commitd91fb9f5929d8a80dc8ea0b16d69c00342e34319 (patch)
tree4f8d2100e142a0e1c467de7c085823dcbd1654af /src/mesa/drivers/glide/fxtexman.c
parent4c44d63f01a01f134d7e4456d4209edee97f9ef5 (diff)
applied Daryll's patches
Diffstat (limited to 'src/mesa/drivers/glide/fxtexman.c')
-rw-r--r--src/mesa/drivers/glide/fxtexman.c670
1 files changed, 330 insertions, 340 deletions
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 (blockstart<end) {
+ if (blockstart+FX_2MB_SPLIT>end) 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(startadr<tmfree->startAddress) {
- 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;i<MAX_TEXTURE_LEVELS;i++) {
- if(ti->tmi.mipmapLevel[i].used &&
- ti->tmi.mipmapLevel[i].translated)
- FREE(ti->tmi.mipmapLevel[i].data);
+ for(i=0; i<MAX_TEXTURE_LEVELS; i++) {
+ if (ti->mipmapLevel[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; 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 */
@@ -698,8 +690,6 @@ fxTMRestoreTextures(fxMesaContext ctx) {
}
tObj=tObj->Next;
}
- ctx->lastUnitsMode=0;
- fxSetupTexture_NoLock(ctx->glCtx);
}
#else