diff options
Diffstat (limited to 'src/mesa/drivers/glide/fxtexman.c')
-rw-r--r-- | src/mesa/drivers/glide/fxtexman.c | 235 |
1 files changed, 138 insertions, 97 deletions
diff --git a/src/mesa/drivers/glide/fxtexman.c b/src/mesa/drivers/glide/fxtexman.c index 770f095ab8..3f4439549d 100644 --- a/src/mesa/drivers/glide/fxtexman.c +++ b/src/mesa/drivers/glide/fxtexman.c @@ -54,30 +54,46 @@ #include "fxdrv.h" +int texSwaps=0; + #define FX_2MB_SPLIT 0x200000 static struct gl_texture_object *fxTMFindOldestObject(fxMesaContext fxMesa, int tmu); -#if 0 +#ifdef TEXSANITY static void fubar() { } /* Sanity Check */ -static void sanity(fxMesaContext fxMesa, int tmu) +static void sanity(fxMesaContext fxMesa) { - MemRange *tmp, *prev; - int i; + MemRange *tmp, *prev, *pos; prev=0; - tmp = fxMesa->tmFree[tmu]; - i=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) { - 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(); @@ -87,7 +103,7 @@ static void sanity(fxMesaContext fxMesa, int tmu) fubar(); } if (prev && (prev->startAddr>=tmp->startAddr || - prev->endAddr>=tmp->startAddr)) { + prev->endAddr>tmp->startAddr)) { fprintf(stderr, "Sorting fubar\n"); fubar(); } @@ -128,13 +144,12 @@ static void fxTMUInit(fxMesaContext fxMesa, int tmu) start=FX_grTexMinAddress(tmu); end=FX_grTexMaxAddress(tmu); - fxMesa->texStart[tmu]=start; if(fxMesa->verbose) { fprintf(stderr,"%s configuration:",(tmu==FX_TMU0) ? "TMU0" : "TMU1"); fprintf(stderr," Lower texture memory address (%u)\n",(unsigned int)start); fprintf(stderr," Higher texture memory address (%u)\n",(unsigned int)end); - fprintf(stderr," Splitting Texture memory in 2Mb blocks:\n"); + fprintf(stderr," Splitting Texture memory in 2b blocks:\n"); } fxMesa->freeTexMem[tmu]=end-start; @@ -182,6 +197,7 @@ static int fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size) } fxTMDeleteRangeNode(fxMesa, tmp); } + fxMesa->freeTexMem[tmu]-=size; return result; } prev=tmp; @@ -194,17 +210,19 @@ static int fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size) return -1; } fxTMMoveOutTM(fxMesa, obj); + texSwaps++; } } static void fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange *range) { - MemRange *tmp, *prev, *next; + 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) { @@ -254,8 +272,8 @@ static struct gl_texture_object *fxTMFindOldestObject(fxMesaContext fxMesa, info=fxTMGetTexInfo(tmp); if (info && info->isInTM && - (info->whichTMU==tmu || info->whichTMU==FX_TMU_BOTH || - info->whichTMU==FX_TMU_SPLIT)) { + ((info->whichTMU==tmu) || (info->whichTMU==FX_TMU_BOTH) || + (info->whichTMU==FX_TMU_SPLIT))) { lasttime=info->lastTimeUsed; if (lasttime>bindnumber) @@ -306,7 +324,15 @@ void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, G exit(-1); } - if (ti->isInTM) return; + 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); @@ -334,7 +360,7 @@ void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, G GR_MIPMAPLEVELMASK_BOTH, ti->mipmapLevel[l].data); break; - case FX_TMU_SPLIT: /* TO DO: alternate even/odd TMU0/TMU1 */ + case FX_TMU_SPLIT: texmemsize=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_ODD, &(ti->info)); ti->tm[FX_TMU0]=fxTMAddObj(fxMesa, tObj, FX_TMU0, texmemsize); @@ -367,6 +393,39 @@ void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, G 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, + ti->tm[FX_TMU0]->startAddr, + FX_valueToLod(i), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, + ti->mipmapLevel[l].data); + + FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1, + ti->tm[FX_TMU1]->startAddr, + FX_valueToLod(i), + 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(); @@ -402,22 +461,27 @@ void fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, fxTexGetInfo(ti->mipmapLevel[0].width,ti->mipmapLevel[0].height, &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL); +#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)+level), + 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: /* TO DO: alternate even/odd TMU0/TMU1 */ + case FX_TMU_SPLIT: FX_grTexDownloadMipMapLevel(GR_TMU0, ti->tm[GR_TMU0]->startAddr, - FX_valueToLod(FX_lodToValue(lodlevel)+level), + FX_valueToLod(FX_lodToValue(lodlevel)), FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, @@ -426,13 +490,33 @@ void fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, FX_grTexDownloadMipMapLevel(GR_TMU1, ti->tm[GR_TMU1]->startAddr, - FX_valueToLod(FX_lodToValue(lodlevel)+level), + 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(); @@ -481,7 +565,7 @@ void fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, data, yoffset,yoffset+height-1); break; - case FX_TMU_SPLIT: /* TO DO: alternate even/odd TMU0/TMU1 */ + case FX_TMU_SPLIT: FX_grTexDownloadMipMapLevelPartial(GR_TMU0, ti->tm[FX_TMU0]->startAddr, FX_valueToLod(FX_lodToValue(lodlevel)+level), @@ -502,6 +586,27 @@ void fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, 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(); @@ -525,6 +630,7 @@ void fxTMMoveOutTM(fxMesaContext fxMesa, struct gl_texture_object *tObj) 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; @@ -554,6 +660,7 @@ void fxTMFreeTexture(fxMesaContext fxMesa, struct gl_texture_object *tObj) } switch (ti->whichTMU) { case FX_TMU0: + case FX_TMU1: fxTMDeleteRangeNode(fxMesa, ti->tm[ti->whichTMU]); break; case FX_TMU_SPLIT: @@ -566,12 +673,13 @@ void fxTMFreeTexture(fxMesaContext fxMesa, struct gl_texture_object *tObj) void fxTMInit(fxMesaContext fxMesa) { + fxMesa->texBindNumber=0; + fxMesa->tmPool=0; + fxTMUInit(fxMesa,FX_TMU0); if(fxMesa->haveTwoTMUs) fxTMUInit(fxMesa,FX_TMU1); - - fxMesa->texBindNumber=0; } void fxTMClose(fxMesaContext fxMesa) @@ -600,80 +708,11 @@ void fxTMClose(fxMesaContext fxMesa) } } -void fxTMRestore_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj) -{ - tfxTexInfo *ti=fxTMGetTexInfo(tObj); - int i,l, where; - - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxRestore(%d)\n",tObj->Name); - } - - if (!ti->validated) { - fprintf(stderr,"fxDriver: internal error in fxRestore -> not validated\n"); - fxCloseHardware(); - exit(-1); - } - - 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); - } - - switch(where) { - case FX_TMU0: - case FX_TMU1: - for (i=FX_largeLodValue_NoLock(ti->info), l=ti->minLevel; - i<=FX_smallLodValue_NoLock(ti->info); - i++,l++) - if (ti->mipmapLevel[l].data) - FX_grTexDownloadMipMapLevel_NoLock(where, - ti->tm[where]->startAddr, - FX_valueToLod(i), - FX_largeLodLog2(ti->info), - FX_aspectRatioLog2(ti->info), - ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - 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->mipmapLevel[l].data) - FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0, - ti->tm[FX_TMU0]->startAddr, - FX_valueToLod(i), - FX_largeLodLog2(ti->info), - FX_aspectRatioLog2(ti->info), - ti->info.format, - GR_MIPMAPLEVELMASK_ODD, - ti->mipmapLevel[l].data); - if (ti->mipmapLevel[l].data) - FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1, - ti->tm[FX_TMU1]->startAddr, - FX_valueToLod(i), - FX_largeLodLog2(ti->info), - FX_aspectRatioLog2(ti->info), - ti->info.format, - GR_MIPMAPLEVELMASK_EVEN, - ti->mipmapLevel[l].data); - } - break; - default: - fprintf(stderr,"fxDriver: internal error in fxRestore -> bad tmu (%d)\n", - where); - fxCloseHardware(); - exit(-1); - } -} - void -fxTMRestoreTextures(fxMesaContext ctx) { +fxTMRestoreTextures_NoLock(fxMesaContext ctx) { tfxTexInfo *ti; struct gl_texture_object *tObj; - int i; + int i, where; tObj=ctx->glCtx->Shared->TexObjectList; while (tObj) { @@ -682,11 +721,13 @@ fxTMRestoreTextures(fxMesaContext ctx) { 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 */ - fxTMRestore_NoLock(ctx, tObj); + where=ti->whichTMU; + ti->whichTMU=FX_TMU_NONE; + fxTMMoveInTM_NoLock(ctx, tObj, where); break; } if (i==MAX_TEXTURE_UNITS) /* Mark the texture as off the board */ - fxTMMoveOutTM(ctx, tObj); + fxTMMoveOutTM_NoLock(ctx, tObj); } tObj=tObj->Next; } |