X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fglide%2Ffxtexman.c;h=940c8fd0b97d92c9d065b6b8753ae2a61a0193aa;hb=646ed82e6b2c092c6db364bf87d6881f39e83eec;hp=5189816cdefa858036c53f7bbe4af00fea50a24b;hpb=9ec58c2c5bbf90428a0e8e1c4f4af3805c602cd3;p=mesa.git diff --git a/src/mesa/drivers/glide/fxtexman.c b/src/mesa/drivers/glide/fxtexman.c index 5189816cdef..940c8fd0b97 100644 --- a/src/mesa/drivers/glide/fxtexman.c +++ b/src/mesa/drivers/glide/fxtexman.c @@ -1,5 +1,3 @@ -/* $Id: fxtexman.c,v 1.16 2003/08/19 15:52:53 brianp Exp $ */ - /* * Mesa 3-D graphics library * Version: 4.0 @@ -42,9 +40,11 @@ #if defined(FX) +#include "hash.h" #include "fxdrv.h" int texSwaps = 0; +static FxU32 texBoundMask; #define FX_2MB_SPLIT 0x200000 @@ -116,7 +116,7 @@ fxTMNewRangeNode(fxMesaContext fxMesa, FxU32 start, FxU32 end) } else { if (!(result = MALLOC(sizeof(MemRange)))) { - fprintf(stderr, "fxDriver: out of memory!\n"); + fprintf(stderr, "fxTMNewRangeNode: ERROR: out of memory!\n"); fxCloseHardware(); exit(-1); } @@ -126,30 +126,34 @@ fxTMNewRangeNode(fxMesaContext fxMesa, FxU32 start, FxU32 end) return result; } +#if 1 +#define fxTMDeleteRangeNode(fxMesa, range) \ + do { \ + range->next = fxMesa->tmPool; \ + fxMesa->tmPool = range; \ + } while (0); +#else static void fxTMDeleteRangeNode(fxMesaContext fxMesa, MemRange * range) { range->next = fxMesa->tmPool; fxMesa->tmPool = range; } +#endif static void fxTMUInit(fxMesaContext fxMesa, int tmu) { MemRange *tmn, *last; - FxU32 start, end, blockstart, blockend; + FxU32 start, end, blockstart, blockend, chunk; start = grTexMinAddress(tmu); end = grTexMaxAddress(tmu); + chunk = (fxMesa->type >= GR_SSTTYPE_Banshee) ? (end - start) : FX_2MB_SPLIT; + if (fxMesa->verbose) { - fprintf(stderr, "Voodoo %s configuration:\n", - (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"); + fprintf(stderr, "Voodoo TMU%d configuration:\n", tmu); } fxMesa->freeTexMem[tmu] = end - start; @@ -158,17 +162,18 @@ fxTMUInit(fxMesaContext fxMesa, int tmu) last = 0; blockstart = start; while (blockstart < end) { - if (blockstart + FX_2MB_SPLIT > end) + if (blockstart + chunk > end) blockend = end; else - blockend = blockstart + FX_2MB_SPLIT; + blockend = blockstart + chunk; if (fxMesa->verbose) - fprintf(stderr, "Voodoo %07u-%07u\n", + fprintf(stderr, "Voodoo %08u-%08u\n", (unsigned int) blockstart, (unsigned int) blockend); tmn = fxTMNewRangeNode(fxMesa, blockstart, blockend); - tmn->next = 0; + tmn->next = NULL; + if (last) last->next = tmn; @@ -176,7 +181,7 @@ fxTMUInit(fxMesaContext fxMesa, int tmu) fxMesa->tmFree[tmu] = tmn; last = tmn; - blockstart += FX_2MB_SPLIT; + blockstart += chunk; } } @@ -187,6 +192,10 @@ fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size) int result; struct gl_texture_object *obj; + if (fxMesa->HaveTexUma) { + tmu = FX_TMU0; + } + while (1) { prev = 0; tmp = fxMesa->tmFree[tmu]; @@ -210,9 +219,12 @@ fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size) tmp = tmp->next; } /* No free space. Discard oldest */ + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxTMFindStartAddr: No free space. Discard oldest\n"); + } obj = fxTMFindOldestObject(fxMesa, tmu); if (!obj) { - fprintf(stderr, "fx Driver: No space for texture\n"); + fprintf(stderr, "fxTMFindStartAddr: ERROR: No space for texture\n"); return -1; } fxTMMoveOutTM(fxMesa, obj); @@ -220,11 +232,37 @@ fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size) } } +int fxTMCheckStartAddr (fxMesaContext fxMesa, GLint tmu, tfxTexInfo *ti) +{ + MemRange *tmp; + int size; + + if (fxMesa->HaveTexUma) { + return FXTRUE; + } + + size = grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); + + tmp = fxMesa->tmFree[tmu]; + while (tmp) { + if (tmp->endAddr - tmp->startAddr >= size) { /* Fits here */ + return FXTRUE; + } + tmp = tmp->next; + } + + return FXFALSE; +} + static void fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range) { MemRange *tmp, *prev; + if (fxMesa->HaveTexUma) { + tmu = FX_TMU0; + } + if (range->startAddr == range->endAddr) { fxTMDeleteRangeNode(fxMesa, range); return; @@ -246,7 +284,7 @@ fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range) range->next = tmp; if (tmp) { if (range->endAddr == tmp->startAddr - && tmp->startAddr & (FX_2MB_SPLIT - 1)) { + && tmp->startAddr & texBoundMask) { /* Combine */ tmp->startAddr = range->startAddr; fxTMDeleteRangeNode(fxMesa, range); @@ -255,7 +293,7 @@ fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range) } if (prev) { if (prev->endAddr == range->startAddr - && range->startAddr & (FX_2MB_SPLIT - 1)) { + && range->startAddr & texBoundMask) { /* Combine */ prev->endAddr = range->endAddr; prev->next = range->next; @@ -273,22 +311,36 @@ static struct gl_texture_object * fxTMFindOldestObject(fxMesaContext fxMesa, int tmu) { GLuint age, old, lasttime, bindnumber; - tfxTexInfo *info; - struct gl_texture_object *obj, *tmp; + GLfloat lowestPriority; + struct gl_texture_object *obj, *lowestPriorityObj; + struct _mesa_HashTable *textures = fxMesa->glCtx->Shared->TexObjects; + GLuint id; - tmp = fxMesa->glCtx->Shared->TexObjectList; - if (!tmp) + if (!_mesa_HashFirstEntry(textures)) return 0; - obj = 0; + + obj = NULL; old = 0; + lowestPriorityObj = NULL; + lowestPriority = 1.0F; + bindnumber = fxMesa->texBindNumber; - while (tmp) { - info = fxTMGetTexInfo(tmp); + + for (id = _mesa_HashFirstEntry(textures); + id; + id = _mesa_HashNextEntry(textures, id)) { + struct gl_texture_object *tmp + = (struct gl_texture_object *) _mesa_HashLookup(textures, id); + tfxTexInfo *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) || + fxMesa->HaveTexUma + ) + ) { lasttime = info->lastTimeUsed; if (lasttime > bindnumber) @@ -300,10 +352,29 @@ fxTMFindOldestObject(fxMesaContext fxMesa, int tmu) old = age; obj = tmp; } + + /* examine priority */ + if (tmp->Priority < lowestPriority) { + lowestPriority = tmp->Priority; + lowestPriorityObj = tmp; + } } - tmp = tmp->Next; } - return obj; + + if (lowestPriorityObj != NULL) { + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxTMFindOldestObject: %d pri=%f\n", lowestPriorityObj->Name, lowestPriority); + } + return lowestPriorityObj; + } + else { + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + if (obj != NULL) { + fprintf(stderr, "fxTMFindOldestObject: %d age=%d\n", obj->Name, old); + } + } + return obj; + } } static MemRange * @@ -330,15 +401,14 @@ fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, int i, l; int texmemsize; - if (MESA_VERBOSE & VERBOSE_DRIVER) { - fprintf(stderr, "fxmesa: fxTMMoveInTM(%d)\n", tObj->Name); + if (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxTMMoveInTM_NoLock(%d)\n", tObj->Name); } fxMesa->stats.reqTexUpload++; if (!ti->validated) { - fprintf(stderr, - "fx Driver: internal error in fxTMMoveInTM() -> not validated\n"); + fprintf(stderr, "fxTMMoveInTM_NoLock: INTERNAL ERROR: not validated\n"); fxCloseHardware(); exit(-1); } @@ -355,9 +425,9 @@ fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, } } - if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) { - fprintf(stderr, "fxmesa: downloading %x (%d) in texture memory in %d\n", - (GLuint) tObj, tObj->Name, where); + if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) { + fprintf(stderr, "fxTMMoveInTM_NoLock: downloading %p (%d) in texture memory in %d\n", + (void *)tObj, tObj->Name, where); } ti->whichTMU = (FxU32) where; @@ -371,7 +441,7 @@ fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, for (i = FX_largeLodValue(ti->info), l = ti->minLevel; i <= FX_smallLodValue(ti->info); i++, l++) { - struct gl_texture_image *texImage = tObj->Image[l]; + struct gl_texture_image *texImage = tObj->Image[0][l]; grTexDownloadMipMapLevel(where, ti->tm[where]->startAddr, FX_valueToLod(i), @@ -393,7 +463,7 @@ fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, for (i = FX_largeLodValue(ti->info), l = ti->minLevel; i <= FX_smallLodValue(ti->info); i++, l++) { - struct gl_texture_image *texImage = tObj->Image[l]; + struct gl_texture_image *texImage = tObj->Image[0][l]; grTexDownloadMipMapLevel(GR_TMU0, ti->tm[FX_TMU0]->startAddr, @@ -419,13 +489,13 @@ fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, ti->tm[FX_TMU0] = fxTMAddObj(fxMesa, tObj, FX_TMU0, texmemsize); fxMesa->stats.memTexUpload += texmemsize; - texmemsize = (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &(ti->info)); + /*texmemsize = (int)grTexTextureMemRequired(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]; + struct gl_texture_image *texImage = tObj->Image[0][l]; grTexDownloadMipMapLevel(GR_TMU0, ti->tm[FX_TMU0]->startAddr, FX_valueToLod(i), @@ -446,9 +516,7 @@ fxTMMoveInTM_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj, } break; default: - fprintf(stderr, - "fx Driver: internal error in fxTMMoveInTM() -> wrong tmu (%d)\n", - where); + fprintf(stderr, "fxTMMoveInTM_NoLock: INTERNAL ERROR: wrong tmu (%d)\n", where); fxCloseHardware(); exit(-1); } @@ -476,34 +544,37 @@ fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, tfxTexInfo *ti = fxTMGetTexInfo(tObj); GrLOD_t lodlevel; GLint tmu; - struct gl_texture_image *texImage = tObj->Image[level]; + struct gl_texture_image *texImage = tObj->Image[0][level]; tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxTMReloadMipMapLevel(%p (%d), %d)\n", (void *)tObj, tObj->Name, level); + } + assert(mml); assert(mml->width > 0); assert(mml->height > 0); assert(mml->glideFormat > 0); + assert(ti->isInTM); if (!ti->validated) { - fprintf(stderr, - "fx Driver: internal error in fxTMReloadMipMapLevel() -> not validated\n"); + fprintf(stderr, "fxTMReloadMipMapLevel: INTERNAL ERROR: not validated\n"); fxCloseHardware(); exit(-1); } tmu = (int) ti->whichTMU; - fxTMMoveInTM(fxMesa, tObj, tmu); + fxMesa->stats.reqTexUpload++; + fxMesa->stats.texUpload++; - fxTexGetInfo(mml->width, mml->height, - &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + lodlevel = ti->info.largeLodLog2 - (level - ti->minLevel); - lodlevel -= level; switch (tmu) { case FX_TMU0: case FX_TMU1: grTexDownloadMipMapLevel(tmu, ti->tm[tmu]->startAddr, - FX_valueToLod(FX_lodToValue(lodlevel)), + lodlevel, FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, @@ -512,7 +583,7 @@ fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, case FX_TMU_SPLIT: grTexDownloadMipMapLevel(GR_TMU0, ti->tm[GR_TMU0]->startAddr, - FX_valueToLod(FX_lodToValue(lodlevel)), + lodlevel, FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, @@ -520,7 +591,7 @@ fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, grTexDownloadMipMapLevel(GR_TMU1, ti->tm[GR_TMU1]->startAddr, - FX_valueToLod(FX_lodToValue(lodlevel)), + lodlevel, FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, @@ -529,7 +600,7 @@ fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, case FX_TMU_BOTH: grTexDownloadMipMapLevel(GR_TMU0, ti->tm[GR_TMU0]->startAddr, - FX_valueToLod(FX_lodToValue(lodlevel)), + lodlevel, FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, @@ -537,7 +608,7 @@ fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, grTexDownloadMipMapLevel(GR_TMU1, ti->tm[GR_TMU1]->startAddr, - FX_valueToLod(FX_lodToValue(lodlevel)), + lodlevel, FX_largeLodLog2(ti->info), FX_aspectRatioLog2(ti->info), ti->info.format, @@ -545,9 +616,7 @@ fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj, break; default: - fprintf(stderr, - "fx Driver: internal error in fxTMReloadMipMapLevel() -> wrong tmu (%d)\n", - tmu); + fprintf(stderr, "fxTMReloadMipMapLevel: INTERNAL ERROR: wrong tmu (%d)\n", tmu); fxCloseHardware(); exit(-1); } @@ -562,14 +631,13 @@ fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, GrLOD_t lodlevel; unsigned short *data; GLint tmu; - struct gl_texture_image *texImage = tObj->Image[level]; + struct gl_texture_image *texImage = tObj->Image[0][level]; tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage); assert(mml); if (!ti->validated) { - fprintf(stderr, - "fx Driver: internal error in fxTMReloadSubMipMapLevel() -> not validated\n"); + fprintf(stderr, "fxTMReloadSubMipMapLevel: INTERNAL ERROR: not validated\n"); fxCloseHardware(); exit(-1); } @@ -578,7 +646,7 @@ fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, fxTMMoveInTM(fxMesa, tObj, tmu); fxTexGetInfo(mml->width, mml->height, - &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + &lodlevel, NULL, NULL, NULL, NULL, NULL); if ((ti->info.format == GR_TEXFMT_INTENSITY_8) || (ti->info.format == GR_TEXFMT_P_8) || @@ -643,9 +711,7 @@ fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, yoffset, yoffset + height - 1); break; default: - fprintf(stderr, - "fx Driver: internal error in fxTMReloadSubMipMapLevel() -> wrong tmu (%d)\n", - tmu); + fprintf(stderr, "fxTMReloadSubMipMapLevel: INTERNAL ERROR: wrong tmu (%d)\n", tmu); fxCloseHardware(); exit(-1); } @@ -656,9 +722,8 @@ 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 (TDFX_DEBUG & VERBOSE_DRIVER) { + fprintf(stderr, "fxTMMoveOutTM(%p (%d))\n", (void *)tObj, tObj->Name); } if (!ti->isInTM) @@ -675,7 +740,7 @@ fxTMMoveOutTM(fxMesaContext fxMesa, struct gl_texture_object *tObj) fxTMRemoveRange(fxMesa, FX_TMU1, ti->tm[FX_TMU1]); break; default: - fprintf(stderr, "fx Driver: internal error in fxTMMoveOutTM()\n"); + fprintf(stderr, "fxTMMoveOutTM: INTERNAL ERROR: bad TMU (%ld)\n", ti->whichTMU); fxCloseHardware(); exit(-1); } @@ -690,15 +755,15 @@ fxTMFreeTexture(fxMesaContext fxMesa, struct gl_texture_object *tObj) tfxTexInfo *ti = fxTMGetTexInfo(tObj); int i; + if (TDFX_DEBUG & VERBOSE_TEXTURE) { + fprintf(stderr, "fxTMFreeTexture(%p (%d))\n", (void *)tObj, tObj->Name); + } + fxTMMoveOutTM(fxMesa, tObj); for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { - struct gl_texture_image *texImage = tObj->Image[i]; + struct gl_texture_image *texImage = tObj->Image[0][i]; if (texImage) { - if (texImage->Data) { - FREE(texImage->Data); - texImage->Data = NULL; - } if (texImage->DriverData) { FREE(texImage->DriverData); texImage->DriverData = NULL; @@ -724,10 +789,16 @@ fxTMInit(fxMesaContext fxMesa) fxMesa->texBindNumber = 0; fxMesa->tmPool = 0; + if (fxMesa->HaveTexUma) { + grEnable(GR_TEXTURE_UMA_EXT); + } + fxTMUInit(fxMesa, FX_TMU0); - if (fxMesa->haveTwoTMUs) + if (!fxMesa->HaveTexUma && fxMesa->haveTwoTMUs) fxTMUInit(fxMesa, FX_TMU1); + + texBoundMask = (fxMesa->type >= GR_SSTTYPE_Banshee) ? -1 : (FX_2MB_SPLIT - 1); } void @@ -760,26 +831,29 @@ fxTMClose(fxMesaContext fxMesa) 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); + struct _mesa_HashTable *textures = ctx->glCtx->Shared->TexObjects; + GLuint id; + + for (id = _mesa_HashFirstEntry(textures); + id; + id = _mesa_HashNextEntry(textures, id)) { + struct gl_texture_object *tObj + = (struct gl_texture_object *) _mesa_HashLookup(textures, id); + tfxTexInfo *ti = fxTMGetTexInfo(tObj); if (ti && ti->isInTM) { - for (i = 0; i < MAX_TEXTURE_UNITS; i++) + int i; + 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; + int 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; } }