From d91fb9f5929d8a80dc8ea0b16d69c00342e34319 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 10 Dec 1999 19:11:23 +0000 Subject: [PATCH] applied Daryll's patches --- src/mesa/drivers/glide/fxglidew.h | 9 - src/mesa/drivers/glide/fxsetup.c | 138 +++--- src/mesa/drivers/glide/fxtexman.c | 670 +++++++++++++++--------------- 3 files changed, 409 insertions(+), 408 deletions(-) diff --git a/src/mesa/drivers/glide/fxglidew.h b/src/mesa/drivers/glide/fxglidew.h index fc41445db19..49c28f222ce 100644 --- a/src/mesa/drivers/glide/fxglidew.h +++ b/src/mesa/drivers/glide/fxglidew.h @@ -76,7 +76,6 @@ /* * Genral warper functions for Glide2/Glide3: */ -extern FxI32 grGetInteger(FxU32 pname); extern FxI32 FX_grGetInteger(FxU32 pname); /* @@ -334,15 +333,7 @@ typedef struct */ #define FX_grDrawTriangle(a,b,c) \ do { \ - /* int big=0; */ \ BEGIN_CLIP_LOOP(); \ - /* if (((GrVertex*)a)->x>2000 || ((GrVertex*)a)->x<-2000 || \ - ((GrVertex*)a)->y>2000 || ((GrVertex*)a)->y<-2000 || \ - ((GrVertex*)a)->z>65000 || ((GrVertex*)a)->z<-65000) { \ - fprintf(stderr, "Extreme triangle (%f,%f,%f)\n", \ - ((GrVertex*)a)->x, ((GrVertex*)a)->y, ((GrVertex*)a)->z); \ - big=1; \ - } else */ \ grDrawTriangle(a,b,c); \ END_CLIP_LOOP(); \ } while (0) diff --git a/src/mesa/drivers/glide/fxsetup.c b/src/mesa/drivers/glide/fxsetup.c index 8de34ef90c5..b27d5c98334 100644 --- a/src/mesa/drivers/glide/fxsetup.c +++ b/src/mesa/drivers/glide/fxsetup.c @@ -72,11 +72,10 @@ static void fxSetupCull(GLcontext *ctx); static void gl_print_fx_state_flags( const char *msg, GLuint flags); static GLboolean fxMultipassTexture( struct vertex_buffer *, GLuint ); - static void fxTexValidate(GLcontext *ctx, struct gl_texture_object *tObj) { - tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData; - GLint minl,maxl; + tfxTexInfo *ti=fxTMGetTexInfo(tObj); + GLint minl, maxl; if (MESA_VERBOSE&VERBOSE_DRIVER) { fprintf(stderr,"fxmesa: fxTexValidate(...) Start\n"); @@ -89,15 +88,15 @@ static void fxTexValidate(GLcontext *ctx, struct gl_texture_object *tObj) return; } + ti->tObj=tObj; minl=ti->minLevel=tObj->BaseLevel; maxl=ti->maxLevel=MIN2(tObj->MaxLevel,tObj->Image[0]->MaxLog2); - fxTexGetInfo(tObj->Image[minl]->Width,tObj->Image[minl]->Height, - &(FX_largeLodLog2(ti->info)),&(FX_aspectRatioLog2(ti->info)), - &(ti->sScale),&(ti->tScale), - &(ti->int_sScale),&(ti->int_tScale), - NULL,NULL); - + fxTexGetInfo(tObj->Image[minl]->Width, tObj->Image[minl]->Height, + &(FX_largeLodLog2(ti->info)), &(FX_aspectRatioLog2(ti->info)), + &(ti->sScale), &(ti->tScale), + &(ti->int_sScale), &(ti->int_tScale), + NULL, NULL); if((tObj->MinFilter!=GL_NEAREST) && (tObj->MinFilter!=GL_LINEAR)) fxTexGetInfo(tObj->Image[maxl]->Width,tObj->Image[maxl]->Height, @@ -110,6 +109,27 @@ static void fxTexValidate(GLcontext *ctx, struct gl_texture_object *tObj) fxTexGetFormat(tObj->Image[minl]->Format,&(ti->info.format),&(ti->baseLevelInternalFormat)); + switch (tObj->WrapS) { + case GL_CLAMP_TO_EDGE: + /* What's this really mean compared to GL_CLAMP? */ + case GL_CLAMP: + ti->sClamp=1; + break; + case GL_REPEAT: + ti->sClamp=0; + break; + } + switch (tObj->WrapT) { + case GL_CLAMP_TO_EDGE: + /* What's this really mean compared to GL_CLAMP? */ + case GL_CLAMP: + ti->tClamp=1; + break; + case GL_REPEAT: + ti->tClamp=0; + break; + } + ti->validated=GL_TRUE; ti->info.data=NULL; @@ -173,7 +193,7 @@ static GLuint fxGetTexSetConfiguration(GLcontext *ctx, unitsmode|=FX_UM_COLOR_CONSTANT; if(tObj0) { - tfxTexInfo *ti0=(tfxTexInfo *)tObj0->DriverData; + tfxTexInfo *ti0=fxTMGetTexInfo(tObj0); switch(ti0->baseLevelInternalFormat) { case GL_ALPHA: @@ -219,7 +239,7 @@ static GLuint fxGetTexSetConfiguration(GLcontext *ctx, } if(tObj1) { - tfxTexInfo *ti1=(tfxTexInfo *)tObj1->DriverData; + tfxTexInfo *ti1=fxTMGetTexInfo(tObj1); switch(ti1->baseLevelInternalFormat) { case GL_ALPHA: @@ -283,9 +303,9 @@ static GLuint fxGetTexSetConfiguration(GLcontext *ctx, static void fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj) { - tfxTexInfo *ti=(tfxTexInfo *)tObj->DriverData; + tfxTexInfo *ti=fxTMGetTexInfo(tObj); - if (!ti->tmi.isInTM) { + if (!ti->isInTM) { if (ti->LODblend) fxTMMoveInTM_NoLock(fxMesa,tObj,FX_TMU_SPLIT); else { @@ -301,7 +321,7 @@ static void fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_obje } } - if (ti->LODblend && ti->tmi.whichTMU == FX_TMU_SPLIT) { + if (ti->LODblend && ti->whichTMU == FX_TMU_SPLIT) { if ((ti->info.format==GR_TEXFMT_P_8) && (!fxMesa->haveGlobalPaletteTexture)) { if (MESA_VERBOSE&VERBOSE_DRIVER) { fprintf(stderr,"fxmesa: uploading texture palette\n"); @@ -317,16 +337,16 @@ static void fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_obje FX_grTexMipMapMode_NoLock(GR_TMU0,ti->mmMode,ti->LODblend); FX_grTexMipMapMode_NoLock(GR_TMU1,ti->mmMode,ti->LODblend); - FX_grTexSource_NoLock(GR_TMU0,ti->tmi.tm[FX_TMU0]->startAddress, + FX_grTexSource_NoLock(GR_TMU0,ti->tm[FX_TMU0]->startAddr, GR_MIPMAPLEVELMASK_ODD,&(ti->info)); - FX_grTexSource_NoLock(GR_TMU1,ti->tmi.tm[FX_TMU1]->startAddress, + FX_grTexSource_NoLock(GR_TMU1,ti->tm[FX_TMU1]->startAddr, GR_MIPMAPLEVELMASK_EVEN,&(ti->info)); } else { if((ti->info.format==GR_TEXFMT_P_8) && (!fxMesa->haveGlobalPaletteTexture)) { if (MESA_VERBOSE&VERBOSE_DRIVER) { fprintf(stderr,"fxmesa: uploading texture palette\n"); } - FX_grTexDownloadTable_NoLock(ti->tmi.whichTMU,GR_TEXTABLE_PALETTE,&(ti->palette)); + FX_grTexDownloadTable_NoLock(ti->whichTMU,GR_TEXTABLE_PALETTE,&(ti->palette)); } /* KW: The alternative is to do the download to the other tmu. If @@ -336,12 +356,12 @@ static void fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_obje if (ti->LODblend && (MESA_VERBOSE&VERBOSE_DRIVER)) fprintf(stderr, "fxmesa: not blending texture - only on one tmu\n"); - FX_grTexClampMode_NoLock(ti->tmi.whichTMU,ti->sClamp,ti->tClamp); - FX_grTexFilterMode_NoLock(ti->tmi.whichTMU,ti->minFilt,ti->maxFilt); - FX_grTexMipMapMode_NoLock(ti->tmi.whichTMU,ti->mmMode,FXFALSE); + FX_grTexClampMode_NoLock(ti->whichTMU,ti->sClamp,ti->tClamp); + FX_grTexFilterMode_NoLock(ti->whichTMU,ti->minFilt,ti->maxFilt); + FX_grTexMipMapMode_NoLock(ti->whichTMU,ti->mmMode,FXFALSE); - FX_grTexSource_NoLock(ti->tmi.whichTMU, - ti->tmi.tm[ti->tmi.whichTMU]->startAddress, + FX_grTexSource_NoLock(ti->whichTMU, + ti->tm[ti->whichTMU]->startAddr, GR_MIPMAPLEVELMASK_BOTH,&(ti->info)); } } @@ -411,14 +431,14 @@ static void fxSetupTextureSingleTMU_NoLock(GLcontext *ctx, GLuint textureset) fprintf(stderr,"fxmesa: fxSetupTextureSingleTMU(...) Start\n"); } - ti=(tfxTexInfo *)tObj->DriverData; + ti=fxTMGetTexInfo(tObj); fxTexValidate(ctx,tObj); fxSetupSingleTMU_NoLock(fxMesa,tObj); - if(fxMesa->tmuSrc!=ti->tmi.whichTMU) - fxSelectSingleTMUSrc_NoLock(fxMesa,ti->tmi.whichTMU,ti->LODblend); + if(fxMesa->tmuSrc!=ti->whichTMU) + fxSelectSingleTMUSrc_NoLock(fxMesa,ti->whichTMU,ti->LODblend); if(textureset==0 || !fxMesa->haveTwoTMUs) unitsmode=fxGetTexSetConfiguration(ctx,tObj,NULL); @@ -547,18 +567,18 @@ static void fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa, #define T0_IN_TMU1 0x10 #define T1_IN_TMU1 0x20 - tfxTexInfo *ti0=(tfxTexInfo *)tObj0->DriverData; - tfxTexInfo *ti1=(tfxTexInfo *)tObj1->DriverData; + tfxTexInfo *ti0=fxTMGetTexInfo(tObj0); + tfxTexInfo *ti1=fxTMGetTexInfo(tObj1); GLuint tstate=0; if (MESA_VERBOSE&VERBOSE_DRIVER) { fprintf(stderr,"fxmesa: fxSetupDoubleTMU(...)\n"); } - if(ti0->tmi.isInTM) { - if(ti0->tmi.whichTMU==FX_TMU0) + if(ti0->isInTM) { + if(ti0->whichTMU==FX_TMU0) tstate|=T0_IN_TMU0; - else if(ti0->tmi.whichTMU==FX_TMU1) + else if(ti0->whichTMU==FX_TMU1) tstate|=T0_IN_TMU1; else { fxTMMoveOutTM(fxMesa,tObj0); @@ -567,10 +587,10 @@ static void fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa, } else tstate|=T0_NOT_IN_TMU; - if(ti1->tmi.isInTM) { - if(ti1->tmi.whichTMU==FX_TMU0) + if(ti1->isInTM) { + if(ti1->whichTMU==FX_TMU0) tstate|=T1_IN_TMU0; - else if(ti1->tmi.whichTMU==FX_TMU1) + else if(ti1->whichTMU==FX_TMU1) tstate|=T1_IN_TMU1; else { fxTMMoveOutTM(fxMesa,tObj1); @@ -579,8 +599,8 @@ static void fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa, } else tstate|=T1_NOT_IN_TMU; - ti0->tmi.lastTimeUsed=fxMesa->texBindNumber; - ti1->tmi.lastTimeUsed=fxMesa->texBindNumber; + ti0->lastTimeUsed=fxMesa->texBindNumber; + ti1->lastTimeUsed=fxMesa->texBindNumber; /* Move texture maps in TMUs */ @@ -638,30 +658,30 @@ static void fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa, if (MESA_VERBOSE&VERBOSE_DRIVER) { fprintf(stderr,"fxmesa: uploading texture palette TMU0\n"); } - FX_grTexDownloadTable_NoLock(ti0->tmi.whichTMU,GR_TEXTABLE_PALETTE,&(ti0->palette)); + FX_grTexDownloadTable_NoLock(ti0->whichTMU,GR_TEXTABLE_PALETTE,&(ti0->palette)); } if (ti1->info.format==GR_TEXFMT_P_8) { if (MESA_VERBOSE&VERBOSE_DRIVER) { fprintf(stderr,"fxmesa: uploading texture palette TMU1\n"); } - FX_grTexDownloadTable_NoLock(ti1->tmi.whichTMU, GR_TEXTABLE_PALETTE,&(ti1->palette)); + FX_grTexDownloadTable_NoLock(ti1->whichTMU, GR_TEXTABLE_PALETTE,&(ti1->palette)); } } - FX_grTexClampMode_NoLock(ti0->tmi.whichTMU,ti0->sClamp,ti0->tClamp); - FX_grTexFilterMode_NoLock(ti0->tmi.whichTMU,ti0->minFilt,ti0->maxFilt); - FX_grTexMipMapMode_NoLock(ti0->tmi.whichTMU,ti0->mmMode,FXFALSE); - FX_grTexSource_NoLock(ti0->tmi.whichTMU, - ti0->tmi.tm[ti0->tmi.whichTMU]->startAddress, + FX_grTexSource_NoLock(ti0->whichTMU, + ti0->tm[ti0->whichTMU]->startAddr, GR_MIPMAPLEVELMASK_BOTH,&(ti0->info)); + FX_grTexClampMode_NoLock(ti0->whichTMU,ti0->sClamp,ti0->tClamp); + FX_grTexFilterMode_NoLock(ti0->whichTMU,ti0->minFilt,ti0->maxFilt); + FX_grTexMipMapMode_NoLock(ti0->whichTMU,ti0->mmMode,FXFALSE); - FX_grTexClampMode_NoLock(ti1->tmi.whichTMU,ti1->sClamp,ti1->tClamp); - FX_grTexFilterMode_NoLock(ti1->tmi.whichTMU,ti1->minFilt,ti1->maxFilt); - FX_grTexMipMapMode_NoLock(ti1->tmi.whichTMU,ti1->mmMode,FXFALSE); - FX_grTexSource_NoLock(ti1->tmi.whichTMU, - ti1->tmi.tm[ti1->tmi.whichTMU]->startAddress, + FX_grTexSource_NoLock(ti1->whichTMU, + ti1->tm[ti1->whichTMU]->startAddr, GR_MIPMAPLEVELMASK_BOTH,&(ti1->info)); + FX_grTexClampMode_NoLock(ti1->whichTMU,ti1->sClamp,ti1->tClamp); + FX_grTexFilterMode_NoLock(ti1->whichTMU,ti1->minFilt,ti1->maxFilt); + FX_grTexMipMapMode_NoLock(ti1->whichTMU,ti1->mmMode,FXFALSE); #undef T0_NOT_IN_TMU #undef T1_NOT_IN_TMU @@ -684,10 +704,10 @@ static void fxSetupTextureDoubleTMU_NoLock(GLcontext *ctx) fprintf(stderr,"fxmesa: fxSetupTextureDoubleTMU(...) Start\n"); } - ti0=(tfxTexInfo *)tObj0->DriverData; + ti0=fxTMGetTexInfo(tObj0); fxTexValidate(ctx,tObj0); - ti1=(tfxTexInfo *)tObj1->DriverData; + ti1=fxTMGetTexInfo(tObj1); fxTexValidate(ctx,tObj1); fxSetupDoubleTMU_NoLock(fxMesa,tObj0,tObj1); @@ -729,14 +749,14 @@ static void fxSetupTextureDoubleTMU_NoLock(GLcontext *ctx) GLboolean isalpha[FX_NUM_TMU]; if(ti0->baseLevelInternalFormat==GL_ALPHA) - isalpha[ti0->tmi.whichTMU]=GL_TRUE; + isalpha[ti0->whichTMU]=GL_TRUE; else - isalpha[ti0->tmi.whichTMU]=GL_FALSE; + isalpha[ti0->whichTMU]=GL_FALSE; if(ti1->baseLevelInternalFormat==GL_ALPHA) - isalpha[ti1->tmi.whichTMU]=GL_TRUE; + isalpha[ti1->whichTMU]=GL_TRUE; else - isalpha[ti1->tmi.whichTMU]=GL_FALSE; + isalpha[ti1->whichTMU]=GL_FALSE; if(isalpha[FX_TMU1]) FX_grTexCombine_NoLock(GR_TMU1, @@ -782,7 +802,7 @@ static void fxSetupTextureDoubleTMU_NoLock(GLcontext *ctx) break; } case (FX_UM_E0_REPLACE | FX_UM_E1_BLEND): /* Only for GLQuake */ - if(ti1->tmi.whichTMU==FX_TMU1) { + if(ti1->whichTMU==FX_TMU1) { FX_grTexCombine_NoLock(GR_TMU1, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, @@ -825,7 +845,7 @@ static void fxSetupTextureDoubleTMU_NoLock(GLcontext *ctx) FXFALSE); break; case (FX_UM_E0_REPLACE | FX_UM_E1_MODULATE): /* Quake 2 and 3 */ - if(ti1->tmi.whichTMU==FX_TMU1) { + if(ti1->whichTMU==FX_TMU1) { FX_grTexCombine_NoLock(GR_TMU1, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, @@ -883,14 +903,14 @@ static void fxSetupTextureDoubleTMU_NoLock(GLcontext *ctx) GLboolean isalpha[FX_NUM_TMU]; if(ti0->baseLevelInternalFormat==GL_ALPHA) - isalpha[ti0->tmi.whichTMU]=GL_TRUE; + isalpha[ti0->whichTMU]=GL_TRUE; else - isalpha[ti0->tmi.whichTMU]=GL_FALSE; + isalpha[ti0->whichTMU]=GL_FALSE; if(ti1->baseLevelInternalFormat==GL_ALPHA) - isalpha[ti1->tmi.whichTMU]=GL_TRUE; + isalpha[ti1->whichTMU]=GL_TRUE; else - isalpha[ti1->tmi.whichTMU]=GL_FALSE; + isalpha[ti1->whichTMU]=GL_FALSE; if(isalpha[FX_TMU1]) FX_grTexCombine_NoLock(GR_TMU1, diff --git a/src/mesa/drivers/glide/fxtexman.c b/src/mesa/drivers/glide/fxtexman.c index 97577fca26a..770f095ab8c 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 -- 2.30.2