diff options
Diffstat (limited to 'src/mesa/drivers/glide/fxtexman.c')
-rw-r--r-- | src/mesa/drivers/glide/fxtexman.c | 1269 |
1 files changed, 658 insertions, 611 deletions
diff --git a/src/mesa/drivers/glide/fxtexman.c b/src/mesa/drivers/glide/fxtexman.c index 9dc2d890ad..2e989a04b4 100644 --- a/src/mesa/drivers/glide/fxtexman.c +++ b/src/mesa/drivers/glide/fxtexman.c @@ -53,7 +53,7 @@ #include "fxdrv.h" -int texSwaps=0; +int texSwaps = 0; #define FX_2MB_SPLIT 0x200000 @@ -62,697 +62,743 @@ static struct gl_texture_object *fxTMFindOldestObject(fxMesaContext fxMesa, #ifdef TEXSANITY -static void fubar() +static void +fubar() { } /* Sanity Check */ -static void sanity(fxMesaContext fxMesa) +static void +sanity(fxMesaContext fxMesa) { - MemRange *tmp, *prev, *pos; - - prev=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) { - 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; - } + MemRange *tmp, *prev, *pos; + + prev = 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) { + 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 -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; +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; } -static void fxTMDeleteRangeNode(fxMesaContext fxMesa, MemRange *range) +static void +fxTMDeleteRangeNode(fxMesaContext fxMesa, MemRange * range) { - range->next=fxMesa->tmPool; - fxMesa->tmPool=range; + range->next = fxMesa->tmPool; + fxMesa->tmPool = range; } -static void fxTMUInit(fxMesaContext fxMesa, int tmu) +static void +fxTMUInit(fxMesaContext fxMesa, int tmu) { - MemRange *tmn, *last; - FxU32 start,end,blockstart,blockend; - - start=FX_grTexMinAddress(tmu); - end=FX_grTexMaxAddress(tmu); + MemRange *tmn, *last; + FxU32 start, end, blockstart, blockend; + + start = FX_grTexMinAddress(tmu); + end = FX_grTexMaxAddress(tmu); + + if (fxMesa->verbose) { + fprintf(stderr, "Voodoo %s configuration:", + (tmu == FX_TMU0) ? "TMU0" : "TMU1"); + fprintf(stderr, "Voodoo Lower texture memory address (%u)\n", + (unsigned int) start); + fprintf(stderr, "Voodoo Higher texture memory address (%u)\n", + (unsigned int) end); + fprintf(stderr, "Voodoo Splitting Texture memory in 2b blocks:\n"); + } + + fxMesa->freeTexMem[tmu] = end - start; + fxMesa->tmFree[tmu] = NULL; + + last = 0; + blockstart = start; + while (blockstart < end) { + if (blockstart + FX_2MB_SPLIT > end) + blockend = end; + else + blockend = blockstart + FX_2MB_SPLIT; - if(fxMesa->verbose) { - fprintf(stderr,"Voodoo %s configuration:",(tmu==FX_TMU0) ? "TMU0" : "TMU1"); - fprintf(stderr,"Voodoo Lower texture memory address (%u)\n",(unsigned int)start); - fprintf(stderr,"Voodoo Higher texture memory address (%u)\n",(unsigned int)end); - fprintf(stderr,"Voodoo Splitting Texture memory in 2b blocks:\n"); - } + if (fxMesa->verbose) + fprintf(stderr, "Voodoo %07u-%07u\n", + (unsigned int) blockstart, (unsigned int) blockend); - fxMesa->freeTexMem[tmu]=end-start; - fxMesa->tmFree[tmu]=NULL; + tmn = fxTMNewRangeNode(fxMesa, blockstart, blockend); + tmn->next = 0; - last=0; - blockstart=start; - while (blockstart<end) { - if (blockstart+FX_2MB_SPLIT>end) blockend=end; - else blockend=blockstart+FX_2MB_SPLIT; + if (last) + last->next = tmn; + else + fxMesa->tmFree[tmu] = tmn; + last = tmn; - if(fxMesa->verbose) - fprintf(stderr,"Voodoo %07u-%07u\n", - (unsigned int)blockstart,(unsigned int)blockend); + blockstart += FX_2MB_SPLIT; + } +} - tmn=fxTMNewRangeNode(fxMesa, blockstart, blockend); - tmn->next=0; +static int +fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size) +{ + 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); + } + fxMesa->freeTexMem[tmu] -= size; + return result; + } + prev = tmp; + tmp = tmp->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); + texSwaps++; + } +} - if (last) last->next=tmn; - else fxMesa->tmFree[tmu]=tmn; - last=tmn; +static void +fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range) +{ + MemRange *tmp, *prev; - blockstart+=FX_2MB_SPLIT; - } + if (range->startAddr == range->endAddr) { + fxTMDeleteRangeNode(fxMesa, range); + return; + } + fxMesa->freeTexMem[tmu] += range->endAddr - range->startAddr; + prev = 0; + tmp = fxMesa->tmFree[tmu]; + while (tmp) { + if (range->startAddr > tmp->startAddr) { + prev = tmp; + tmp = tmp->next; + } + else + break; + } + /* 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; + } } -static int fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size) +static struct gl_texture_object * +fxTMFindOldestObject(fxMesaContext fxMesa, int tmu) { - 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); - } - fxMesa->freeTexMem[tmu]-=size; - return result; + 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; + } } - prev=tmp; - tmp=tmp->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); - texSwaps++; - } + tmp = tmp->Next; + } + return obj; } -static void fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange *range) +static MemRange * +fxTMAddObj(fxMesaContext fxMesa, + struct gl_texture_object *tObj, GLint tmu, int texmemsize) { - 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) { - if (range->startAddr>tmp->startAddr) { - prev=tmp; - tmp=tmp->next; - } else break; - } - /* 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; - } + FxU32 startAddr; + MemRange *range; + + startAddr = fxTMFindStartAddr(fxMesa, tmu, texmemsize); + if (startAddr < 0) + return 0; + range = fxTMNewRangeNode(fxMesa, startAddr, startAddr + texmemsize); + return range; } -static struct gl_texture_object *fxTMFindOldestObject(fxMesaContext fxMesa, - int tmu) +/* External Functions */ + +void +fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, + GLint where) { - 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; + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + int i, l; + int texmemsize; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxTMMoveInTM(%d)\n", tObj->Name); + } - if (age>=old) { - old=age; - obj=tmp; + fxMesa->stats.reqTexUpload++; + + if (!ti->validated) { + fprintf(stderr, + "fx Driver: internal error in fxTMMoveInTM() -> not validated\n"); + fxCloseHardware(); + exit(-1); + } + + 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; } - } - tmp=tmp->Next; - } - return obj; + } + + 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->whichTMU = (FxU32) where; + + switch (where) { + case FX_TMU0: + case FX_TMU1: + texmemsize = + (int) FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH, + &(ti->info)); + 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++) { + struct gl_texture_image *texImage = tObj->Image[l]; + 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, + texImage->Data); + } + break; + case FX_TMU_SPLIT: + texmemsize = + (int) FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_ODD, + &(ti->info)); + 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->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++) { + struct gl_texture_image *texImage = tObj->Image[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_ODD, + texImage->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, + texImage->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++) { + struct gl_texture_image *texImage = tObj->Image[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, + texImage->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, + texImage->Data); + } + break; + default: + fprintf(stderr, + "fx Driver: internal error in fxTMMoveInTM() -> wrong tmu (%d)\n", + where); + fxCloseHardware(); + exit(-1); + } + + fxMesa->stats.texUpload++; + + ti->isInTM = GL_TRUE; } -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; +void +fxTMMoveInTM(fxMesaContext fxMesa, struct gl_texture_object *tObj, + GLint where) +{ + BEGIN_BOARD_LOCK(); + fxTMMoveInTM_NoLock(fxMesa, tObj, where); + END_BOARD_LOCK(); } -/* External Functions */ -void fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint where) +void +fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, + GLint level) +{ + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + GrLOD_t lodlevel; + GLint tmu; + struct gl_texture_image *texImage = tObj->Image[level]; + tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + + assert(mml); + + if (!ti->validated) { + fprintf(stderr, + "fx Driver: internal error in fxTMReloadMipMapLevel() -> not validated\n"); + fxCloseHardware(); + exit(-1); + } + + tmu = (int) ti->whichTMU; + fxTMMoveInTM(fxMesa, tObj, tmu); + + fxTexGetInfo(mml->width, mml->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)), + FX_largeLodLog2(ti->info), + FX_aspectRatioLog2(ti->info), + ti->info.format, + GR_MIPMAPLEVELMASK_BOTH, texImage->Data); + break; + case FX_TMU_SPLIT: + 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_ODD, texImage->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_EVEN, texImage->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, texImage->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, texImage->Data); + break; + + default: + fprintf(stderr, + "fx Driver: internal error in fxTMReloadMipMapLevel() -> wrong tmu (%d)\n", + tmu); + fxCloseHardware(); + exit(-1); + } +} + +void +fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, + struct gl_texture_object *tObj, + GLint level, GLint yoffset, GLint height) { - tfxTexInfo *ti=fxTMGetTexInfo(tObj); - int i,l; - int texmemsize; - - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxTMMoveInTM(%d)\n",tObj->Name); - } - - fxMesa->stats.reqTexUpload++; - - if (!ti->validated) { - fprintf(stderr,"fx Driver: internal error in fxTMMoveInTM() -> not validated\n"); - fxCloseHardware(); - exit(-1); - } - - 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); - } - - ti->whichTMU=(FxU32)where; - - switch (where) { - case FX_TMU0: - case FX_TMU1: - texmemsize=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH, - &(ti->info)); - 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++) { - struct gl_texture_image *texImage = tObj->Image[l]; - FX_grTexDownloadMipMapLevel_NoLock(where, - ti->tm[where]->startAddr, - FX_valueToLod(i), + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + GrLOD_t lodlevel; + unsigned short *data; + GLint tmu; + struct gl_texture_image *texImage = tObj->Image[level]; + tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + + assert(mml); + + if (!ti->validated) { + fprintf(stderr, + "fx Driver: internal error in fxTMReloadSubMipMapLevel() -> not validated\n"); + fxCloseHardware(); + exit(-1); + } + + tmu = (int) ti->whichTMU; + fxTMMoveInTM(fxMesa, tObj, tmu); + + fxTexGetInfo(mml->width, mml->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 = (GLushort *) texImage->Data + ((yoffset * mml->width) >> 1); + else + data = (GLushort *) texImage->Data + yoffset * mml->width; + + switch (tmu) { + case FX_TMU0: + case FX_TMU1: + FX_grTexDownloadMipMapLevelPartial(tmu, + ti->tm[tmu]->startAddr, + FX_valueToLod(FX_lodToValue(lodlevel) + + level), FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - texImage->Data); - } - break; - case FX_TMU_SPLIT: - texmemsize=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_ODD, - &(ti->info)); - 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->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++) { - struct gl_texture_image *texImage = tObj->Image[l]; - - FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0, + GR_MIPMAPLEVELMASK_BOTH, data, + yoffset, yoffset + height - 1); + break; + case FX_TMU_SPLIT: + FX_grTexDownloadMipMapLevelPartial(GR_TMU0, ti->tm[FX_TMU0]->startAddr, - FX_valueToLod(i), + FX_valueToLod(FX_lodToValue(lodlevel) + + level), FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, - GR_MIPMAPLEVELMASK_ODD, - texImage->Data); + GR_MIPMAPLEVELMASK_ODD, data, + yoffset, yoffset + height - 1); - FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1, + FX_grTexDownloadMipMapLevelPartial(GR_TMU1, ti->tm[FX_TMU1]->startAddr, - FX_valueToLod(i), + FX_valueToLod(FX_lodToValue(lodlevel) + + level), FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, - GR_MIPMAPLEVELMASK_EVEN, - texImage->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++) { - struct gl_texture_image *texImage = tObj->Image[l]; - FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0, + GR_MIPMAPLEVELMASK_EVEN, data, + yoffset, yoffset + height - 1); + break; + case FX_TMU_BOTH: + FX_grTexDownloadMipMapLevelPartial(GR_TMU0, ti->tm[FX_TMU0]->startAddr, - FX_valueToLod(i), + FX_valueToLod(FX_lodToValue(lodlevel) + + level), FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - texImage->Data); + GR_MIPMAPLEVELMASK_BOTH, data, + yoffset, yoffset + height - 1); - FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1, + FX_grTexDownloadMipMapLevelPartial(GR_TMU1, ti->tm[FX_TMU1]->startAddr, - FX_valueToLod(i), + FX_valueToLod(FX_lodToValue(lodlevel) + + level), FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - texImage->Data); - } - break; - default: - fprintf(stderr,"fx Driver: internal error in fxTMMoveInTM() -> wrong tmu (%d)\n",where); - fxCloseHardware(); - exit(-1); - } - - fxMesa->stats.texUpload++; - - ti->isInTM=GL_TRUE; + GR_MIPMAPLEVELMASK_BOTH, data, + yoffset, yoffset + height - 1); + break; + default: + fprintf(stderr, + "fx Driver: internal error in fxTMReloadSubMipMapLevel() -> wrong tmu (%d)\n", + tmu); + fxCloseHardware(); + exit(-1); + } } - void -fxTMMoveInTM(fxMesaContext fxMesa, struct gl_texture_object *tObj, GLint where) +fxTMMoveOutTM(fxMesaContext fxMesa, struct gl_texture_object *tObj) { - BEGIN_BOARD_LOCK(); - fxTMMoveInTM_NoLock(fxMesa, tObj, where); - END_BOARD_LOCK(); -} + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxTMMoveOutTM(%x (%d))\n", (GLuint) tObj, + tObj->Name); + } + + if (!ti->isInTM) + return; + + switch (ti->whichTMU) { + case FX_TMU0: + case FX_TMU1: + 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; + default: + fprintf(stderr, "fx Driver: internal error in fxTMMoveOutTM()\n"); + fxCloseHardware(); + exit(-1); + } + ti->isInTM = GL_FALSE; + ti->whichTMU = FX_TMU_NONE; +} void -fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, - GLint level) +fxTMFreeTexture(fxMesaContext fxMesa, struct gl_texture_object *tObj) { - tfxTexInfo *ti = fxTMGetTexInfo(tObj); - GrLOD_t lodlevel; - GLint tmu; - struct gl_texture_image *texImage = tObj->Image[level]; - tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); - - assert(mml); + tfxTexInfo *ti = fxTMGetTexInfo(tObj); + int i; - if (!ti->validated) { - fprintf(stderr,"fx Driver: internal error in fxTMReloadMipMapLevel() -> not validated\n"); - fxCloseHardware(); - exit(-1); - } + fxTMMoveOutTM(fxMesa, tObj); - tmu = (int)ti->whichTMU; - fxTMMoveInTM(fxMesa, tObj, tmu); - - fxTexGetInfo(mml->width, mml->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)), - FX_largeLodLog2(ti->info), - FX_aspectRatioLog2(ti->info), - ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - texImage->Data); - break; - case FX_TMU_SPLIT: - 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_ODD, - texImage->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_EVEN, - texImage->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, - texImage->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, - texImage->Data); - break; - - default: - fprintf(stderr,"fx Driver: internal error in fxTMReloadMipMapLevel() -> wrong tmu (%d)\n",tmu); - fxCloseHardware(); - exit(-1); - } + for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { + struct gl_texture_image *texImage = tObj->Image[i]; + if (texImage->Data) { + FREE(texImage->Data); + texImage->Data = NULL; + } + if (texImage->DriverData) { + FREE(texImage->DriverData); + texImage->DriverData = NULL; + } + } + switch (ti->whichTMU) { + case FX_TMU0: + case FX_TMU1: + 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 fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, - struct gl_texture_object *tObj, - GLint level, GLint yoffset, GLint height) +void +fxTMInit(fxMesaContext fxMesa) { - tfxTexInfo *ti=fxTMGetTexInfo(tObj); - GrLOD_t lodlevel; - unsigned short *data; - GLint tmu; - struct gl_texture_image *texImage = tObj->Image[level]; - tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); - - assert(mml); - - if (!ti->validated) { - fprintf(stderr,"fx Driver: internal error in fxTMReloadSubMipMapLevel() -> not validated\n"); - fxCloseHardware(); - exit(-1); - } - - tmu=(int)ti->whichTMU; - fxTMMoveInTM(fxMesa, tObj, tmu); - - fxTexGetInfo(mml->width, mml->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 = (GLushort *) texImage->Data + ((yoffset * mml->width) >> 1); - else - data = (GLushort *) texImage->Data + yoffset * mml->width; - - switch(tmu) { - case FX_TMU0: - case FX_TMU1: - FX_grTexDownloadMipMapLevelPartial(tmu, - 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: - 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_ODD, - 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_EVEN, - 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(); - exit(-1); - } -} + fxMesa->texBindNumber = 0; + fxMesa->tmPool = 0; -void fxTMMoveOutTM(fxMesaContext fxMesa, struct gl_texture_object *tObj) -{ - tfxTexInfo *ti=fxTMGetTexInfo(tObj); - - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxTMMoveOutTM(%x (%d))\n",(GLuint)tObj,tObj->Name); - } - - if (!ti->isInTM) return; - - switch(ti->whichTMU) { - case FX_TMU0: - case FX_TMU1: - 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; - default: - fprintf(stderr,"fx Driver: internal error in fxTMMoveOutTM()\n"); - fxCloseHardware(); - exit(-1); - } - - ti->isInTM=GL_FALSE; - ti->whichTMU=FX_TMU_NONE; -} + fxTMUInit(fxMesa, FX_TMU0); -void fxTMFreeTexture(fxMesaContext fxMesa, struct gl_texture_object *tObj) -{ - tfxTexInfo *ti=fxTMGetTexInfo(tObj); - int i; - - fxTMMoveOutTM(fxMesa, tObj); - - for (i=0; i<MAX_TEXTURE_LEVELS; i++) { - struct gl_texture_image *texImage = tObj->Image[i]; - if (texImage->Data) { - FREE(texImage->Data); - texImage->Data = NULL; - } - if (texImage->DriverData) { - FREE(texImage->DriverData); - texImage->DriverData = NULL; - } - } - switch (ti->whichTMU) { - case FX_TMU0: - case FX_TMU1: - 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; - } + if (fxMesa->haveTwoTMUs) + fxTMUInit(fxMesa, FX_TMU1); } -void fxTMInit(fxMesaContext fxMesa) +void +fxTMClose(fxMesaContext fxMesa) { - fxMesa->texBindNumber=0; - fxMesa->tmPool=0; - - fxTMUInit(fxMesa,FX_TMU0); - - if(fxMesa->haveTwoTMUs) - fxTMUInit(fxMesa,FX_TMU1); -} + MemRange *tmp, *next; -void fxTMClose(fxMesaContext fxMesa) -{ - 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; + 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; - } - } + tmp = next; + } + if (fxMesa->haveTwoTMUs) { + tmp = fxMesa->tmFree[FX_TMU1]; + while (tmp) { + next = tmp->next; + FREE(tmp); + tmp = next; + } + } } void -fxTMRestoreTextures_NoLock(fxMesaContext ctx) { - tfxTexInfo *ti; - struct gl_texture_object *tObj; - int i, where; - - tObj=ctx->glCtx->Shared->TexObjectList; - while (tObj) { - 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 */ - where=ti->whichTMU; - fxTMMoveOutTM_NoLock(ctx, tObj); - fxTMMoveInTM_NoLock(ctx, tObj, where); - break; - } - if (i==MAX_TEXTURE_UNITS) /* Mark the texture as off the board */ - fxTMMoveOutTM_NoLock(ctx, tObj); - } - tObj=tObj->Next; - } +fxTMRestoreTextures_NoLock(fxMesaContext ctx) +{ + tfxTexInfo *ti; + struct gl_texture_object *tObj; + int i, where; + + tObj = ctx->glCtx->Shared->TexObjectList; + while (tObj) { + 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 */ + where = ti->whichTMU; + fxTMMoveOutTM_NoLock(ctx, tObj); + fxTMMoveInTM_NoLock(ctx, tObj, where); + break; + } + if (i == MAX_TEXTURE_UNITS) /* Mark the texture as off the board */ + fxTMMoveOutTM_NoLock(ctx, tObj); + } + tObj = tObj->Next; + } } #else @@ -763,9 +809,10 @@ fxTMRestoreTextures_NoLock(fxMesaContext ctx) { */ extern int gl_fx_dummy_function_texman(void); -int gl_fx_dummy_function_texman(void) +int +gl_fx_dummy_function_texman(void) { - return 0; + return 0; } -#endif /* FX */ +#endif /* FX */ |