summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/glide/fxtexman.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/glide/fxtexman.c')
-rw-r--r--src/mesa/drivers/glide/fxtexman.c235
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;
}