diff options
Diffstat (limited to 'nx-X11/extras/Mesa/src/mesa/drivers/dri/tdfx/tdfx_texman.c')
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/dri/tdfx/tdfx_texman.c | 994 |
1 files changed, 0 insertions, 994 deletions
diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/tdfx/tdfx_texman.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/tdfx/tdfx_texman.c deleted file mode 100644 index 63cae17e4..000000000 --- a/nx-X11/extras/Mesa/src/mesa/drivers/dri/tdfx/tdfx_texman.c +++ /dev/null @@ -1,994 +0,0 @@ -/* -*- mode: c; c-basic-offset: 3 -*- - * - * Copyright 2000 VA Linux Systems Inc., Fremont, California. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c,v 1.5 2002/02/22 21:45:04 dawes Exp $ */ - -/* - * Original rewrite: - * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 - * - * Authors: - * Gareth Hughes <gareth@valinux.com> - * Brian Paul <brianp@valinux.com> - * - */ - -#include "tdfx_context.h" -#include "tdfx_tex.h" -#include "tdfx_texman.h" -#include "hash.h" - - -#define BAD_ADDRESS ((FxU32) -1) - - -#if 0 /* DEBUG use */ -/* - * Verify the consistancy of the texture memory manager. - * This involves: - * Traversing all texture objects and computing total memory used. - * Traverse the free block list and computing total memory free. - * Compare the total free and total used amounts to the total memory size. - * Make various assertions about the results. - */ -static void -VerifyFreeList(tdfxContextPtr fxMesa, FxU32 tmu) -{ - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; - tdfxMemRange *block; - int prevStart = -1, prevEnd = -1; - int totalFree = 0; - int numObj = 0, numRes = 0; - int totalUsed = 0; - - for (block = shared->tmFree[tmu]; block; block = block->next) { - assert( block->endAddr > 0 ); - assert( block->startAddr <= shared->totalTexMem[tmu] ); - assert( block->endAddr <= shared->totalTexMem[tmu] ); - assert( (int) block->startAddr > prevStart ); - assert( (int) block->startAddr >= prevEnd ); - prevStart = (int) block->startAddr; - prevEnd = (int) block->endAddr; - totalFree += (block->endAddr - block->startAddr); - } - assert(totalFree == shared->freeTexMem[tmu]); - - { - struct _mesa_HashTable *textures = fxMesa->glCtx->Shared->TexObjects; - GLuint id; - for (id = _mesa_HashFirstEntry(textures); - id; - id = _mesa_HashNextEntry(textures, id)) { - struct gl_texture_object *tObj; - tObj = (struct gl_texture_object *) _mesa_HashLookup(textures, id); - tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); - if (ti) { - if (ti->isInTM) { - numRes++; - assert(ti->tm[0]); - if (ti->tm[tmu]) - totalUsed += (ti->tm[tmu]->endAddr - ti->tm[tmu]->startAddr); - } - else { - assert(!ti->tm[0]); - } - } - } - } - - printf("totalFree: %d totalUsed: %d totalMem: %d #objs=%d #res=%d\n", - shared->freeTexMem[tmu], totalUsed, shared->totalTexMem[tmu], - numObj, numRes); - - assert(totalUsed + totalFree == shared->totalTexMem[tmu]); -} - - -static void -dump_texmem(tdfxContextPtr fxMesa) -{ - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - struct _mesa_HashTable *textures = mesaShared->TexObjects; - struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; - tdfxMemRange *r; - FxU32 prev; - GLuint id; - - printf("DUMP Objects:\n"); - for (id = _mesa_HashFirstEntry(textures); - id; - id = _mesa_HashNextEntry(textures, id)) { - struct gl_texture_object *obj - = (struct gl_texture_object *) _mesa_HashLookup(textures, id); - tdfxTexInfo *info = TDFX_TEXTURE_DATA(obj); - - if (info && info->isInTM) { - printf("Obj %8p: %4d info = %p\n", obj, obj->Name, info); - - printf(" isInTM=%d whichTMU=%d lastTimeUsed=%d\n", - info->isInTM, info->whichTMU, info->lastTimeUsed); - printf(" tm[0] = %p", info->tm[0]); - assert(info->tm[0]); - if (info->tm[0]) { - printf(" tm startAddr = %d endAddr = %d", - info->tm[0]->startAddr, - info->tm[0]->endAddr); - } - printf("\n"); - printf(" tm[1] = %p", info->tm[1]); - if (info->tm[1]) { - printf(" tm startAddr = %d endAddr = %d", - info->tm[1]->startAddr, - info->tm[1]->endAddr); - } - printf("\n"); - } - } - - VerifyFreeList(fxMesa, 0); - VerifyFreeList(fxMesa, 1); - - printf("Free memory unit 0: %d bytes\n", shared->freeTexMem[0]); - prev = 0; - for (r = shared->tmFree[0]; r; r = r->next) { - printf("%8p: start %8d end %8d size %8d gap %8d\n", r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, r->startAddr - prev); - prev = r->endAddr; - } - - printf("Free memory unit 1: %d bytes\n", shared->freeTexMem[1]); - prev = 0; - for (r = shared->tmFree[1]; r; r = r->next) { - printf("%8p: start %8d end %8d size %8d gap %8d\n", r, r->startAddr, r->endAddr, r->endAddr - r->startAddr, r->startAddr - prev); - prev = r->endAddr; - } - -} -#endif - - - -#ifdef TEXSANITY -static void -fubar(void) -{ -} - -/* - * Sanity Check - */ -static void -sanity(tdfxContextPtr fxMesa) -{ - tdfxMemRange *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 - - - - - -/* - * Allocate and initialize a new MemRange struct. - * Try to allocate it from the pool of free MemRange nodes rather than malloc. - */ -static tdfxMemRange * -NewRangeNode(tdfxContextPtr fxMesa, FxU32 start, FxU32 end) -{ - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; - tdfxMemRange *result; - - _glthread_LOCK_MUTEX(mesaShared->Mutex); - if (shared && shared->tmPool) { - result = shared->tmPool; - shared->tmPool = shared->tmPool->next; - } - else { - result = MALLOC(sizeof(tdfxMemRange)); - - } - _glthread_UNLOCK_MUTEX(mesaShared->Mutex); - - if (!result) { - /*fprintf(stderr, "fxDriver: out of memory!\n");*/ - return NULL; - } - - result->startAddr = start; - result->endAddr = end; - result->next = NULL; - - return result; -} - - -/* - * Initialize texture memory. - * We take care of one or both TMU's here. - */ -void -tdfxTMInit(tdfxContextPtr fxMesa) -{ - if (!fxMesa->glCtx->Shared->DriverData) { - const char *extensions; - struct tdfxSharedState *shared = CALLOC_STRUCT(tdfxSharedState); - if (!shared) - return; - - LOCK_HARDWARE(fxMesa); - extensions = fxMesa->Glide.grGetString(GR_EXTENSION); - UNLOCK_HARDWARE(fxMesa); - if (strstr(extensions, "TEXUMA")) { - FxU32 start, end; - shared->umaTexMemory = GL_TRUE; - LOCK_HARDWARE(fxMesa); - fxMesa->Glide.grEnable(GR_TEXTURE_UMA_EXT); - start = fxMesa->Glide.grTexMinAddress(0); - end = fxMesa->Glide.grTexMaxAddress(0); - UNLOCK_HARDWARE(fxMesa); - shared->totalTexMem[0] = end - start; - shared->totalTexMem[1] = 0; - shared->freeTexMem[0] = end - start; - shared->freeTexMem[1] = 0; - shared->tmFree[0] = NewRangeNode(fxMesa, start, end); - shared->tmFree[1] = NULL; - /*printf("UMA tex memory: %d\n", (int) (end - start));*/ - } - else { - const int numTMUs = fxMesa->haveTwoTMUs ? 2 : 1; - int tmu; - shared->umaTexMemory = GL_FALSE; - LOCK_HARDWARE(fxMesa); - for (tmu = 0; tmu < numTMUs; tmu++) { - FxU32 start = fxMesa->Glide.grTexMinAddress(tmu); - FxU32 end = fxMesa->Glide.grTexMaxAddress(tmu); - shared->totalTexMem[tmu] = end - start; - shared->freeTexMem[tmu] = end - start; - shared->tmFree[tmu] = NewRangeNode(fxMesa, start, end); - /*printf("Split tex memory: %d\n", (int) (end - start));*/ - } - UNLOCK_HARDWARE(fxMesa); - } - - shared->tmPool = NULL; - fxMesa->glCtx->Shared->DriverData = shared; - /*printf("Texture memory init UMA: %d\n", shared->umaTexMemory);*/ - } -} - - -/* - * Clean-up texture memory before destroying context. - */ -void -tdfxTMClose(tdfxContextPtr fxMesa) -{ - if (fxMesa->glCtx->Shared->RefCount == 1 && fxMesa->driDrawable) { - /* refcount will soon go to zero, free our 3dfx stuff */ - struct tdfxSharedState *shared = (struct tdfxSharedState *) fxMesa->glCtx->Shared->DriverData; - - const int numTMUs = fxMesa->haveTwoTMUs ? 2 : 1; - int tmu; - tdfxMemRange *tmp, *next; - - /* Deallocate the pool of free tdfxMemRange nodes */ - tmp = shared->tmPool; - while (tmp) { - next = tmp->next; - FREE(tmp); - tmp = next; - } - - /* Delete the texture memory block tdfxMemRange nodes */ - for (tmu = 0; tmu < numTMUs; tmu++) { - tmp = shared->tmFree[tmu]; - while (tmp) { - next = tmp->next; - FREE(tmp); - tmp = next; - } - } - - FREE(shared); - fxMesa->glCtx->Shared->DriverData = NULL; - } -} - - - -/* - * Delete a tdfxMemRange struct. - * We keep a linked list of free/available tdfxMemRange structs to - * avoid extra malloc/free calls. - */ -#if 0 -static void -DeleteRangeNode_NoLock(struct TdfxSharedState *shared, tdfxMemRange *range) -{ - /* insert at head of list */ - range->next = shared->tmPool; - shared->tmPool = range; -} -#endif - -#define DELETE_RANGE_NODE(shared, range) \ - (range)->next = (shared)->tmPool; \ - (shared)->tmPool = (range) - - - -/* - * When we've run out of texture memory we have to throw out an - * existing texture to make room for the new one. This function - * determins the texture to throw out. - */ -static struct gl_texture_object * -FindOldestObject(tdfxContextPtr fxMesa, FxU32 tmu) -{ - const GLuint bindnumber = fxMesa->texBindNumber; - struct gl_texture_object *oldestObj, *lowestPriorityObj; - GLfloat lowestPriority; - GLuint oldestAge; - GLuint id; - struct _mesa_HashTable *textures = fxMesa->glCtx->Shared->TexObjects; - - oldestObj = NULL; - oldestAge = 0; - - lowestPriority = 1.0F; - lowestPriorityObj = NULL; - - for (id = _mesa_HashFirstEntry(textures); - id; - id = _mesa_HashNextEntry(textures, id)) { - struct gl_texture_object *obj - = (struct gl_texture_object *) _mesa_HashLookup(textures, id); - tdfxTexInfo *info = TDFX_TEXTURE_DATA(obj); - - if (info && info->isInTM && - ((info->whichTMU == tmu) || (info->whichTMU == TDFX_TMU_BOTH) || - (info->whichTMU == TDFX_TMU_SPLIT))) { - GLuint age, lasttime; - - assert(info->tm[0]); - lasttime = info->lastTimeUsed; - - if (lasttime > bindnumber) - age = bindnumber + (UINT_MAX - lasttime + 1); /* TO DO: check wrap around */ - else - age = bindnumber - lasttime; - - if (age >= oldestAge) { - oldestAge = age; - oldestObj = obj; - } - - /* examine priority */ - if (obj->Priority < lowestPriority) { - lowestPriority = obj->Priority; - lowestPriorityObj = obj; - } - } - } - - if (lowestPriority < 1.0) { - ASSERT(lowestPriorityObj); - /* - printf("discard %d pri=%f\n", lowestPriorityObj->Name, lowestPriority); - */ - return lowestPriorityObj; - } - else { - /* - printf("discard %d age=%d\n", oldestObj->Name, oldestAge); - */ - return oldestObj; - } -} - - -#if 0 -static void -FlushTexMemory(tdfxContextPtr fxMesa) -{ - struct _mesa_HashTable *textures = fxMesa->glCtx->Shared->TexObjects; - GLuint id; - - for (id = _mesa_HashFirstEntry(textures); - id; - id = _mesa_HashNextEntry(textures, id)) { - struct gl_texture_object *obj - = (struct gl_texture_object *) _mesa_HashLookup(textures, id); - if (obj->RefCount < 2) { - /* don't flush currently bound textures */ - tdfxTMMoveOutTM_NoLock(fxMesa, obj); - } - } -} -#endif - - -/* - * Find the address (offset?) at which we can store a new texture. - * <tmu> is the texture unit. - * <size> is the texture size in bytes. - */ -static FxU32 -FindStartAddr(tdfxContextPtr fxMesa, FxU32 tmu, FxU32 size) -{ - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; - tdfxMemRange *prev, *block; - FxU32 result; -#if 0 - int discardedCount = 0; -#define MAX_DISCARDS 10 -#endif - - if (shared->umaTexMemory) { - assert(tmu == TDFX_TMU0); - } - - _glthread_LOCK_MUTEX(mesaShared->Mutex); - while (1) { - prev = NULL; - block = shared->tmFree[tmu]; - while (block) { - if (block->endAddr - block->startAddr >= size) { - /* The texture will fit here */ - result = block->startAddr; - block->startAddr += size; - if (block->startAddr == block->endAddr) { - /* Remove this node since it's empty */ - if (prev) { - prev->next = block->next; - } - else { - shared->tmFree[tmu] = block->next; - } - DELETE_RANGE_NODE(shared, block); - } - shared->freeTexMem[tmu] -= size; - _glthread_UNLOCK_MUTEX(mesaShared->Mutex); - return result; - } - prev = block; - block = block->next; - } - /* We failed to find a block large enough to accomodate <size> bytes. - * Find the oldest texObject and free it. - */ -#if 0 - discardedCount++; - if (discardedCount > MAX_DISCARDS + 1) { - _mesa_problem(NULL, "%s: extreme texmem fragmentation", __FUNCTION__); - _glthread_UNLOCK_MUTEX(mesaShared->Mutex); - return BAD_ADDRESS; - } - else if (discardedCount > MAX_DISCARDS) { - /* texture memory is probably really fragmented, flush it */ - FlushTexMemory(fxMesa); - } - else -#endif - { - struct gl_texture_object *obj = FindOldestObject(fxMesa, tmu); - if (obj) { - tdfxTMMoveOutTM_NoLock(fxMesa, obj); - fxMesa->stats.texSwaps++; - } - else { - _mesa_problem(NULL, "%s: extreme texmem fragmentation", __FUNCTION__); - _glthread_UNLOCK_MUTEX(mesaShared->Mutex); - return BAD_ADDRESS; - } - } - } - - /* never get here, but play it safe */ - _glthread_UNLOCK_MUTEX(mesaShared->Mutex); - return BAD_ADDRESS; -} - - -/* - * Remove the given tdfxMemRange node from hardware texture memory. - */ -static void -RemoveRange_NoLock(tdfxContextPtr fxMesa, FxU32 tmu, tdfxMemRange *range) -{ - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; - tdfxMemRange *block, *prev; - - if (shared->umaTexMemory) { - assert(tmu == TDFX_TMU0); - } - - if (!range) - return; - - if (range->startAddr == range->endAddr) { - DELETE_RANGE_NODE(shared, range); - return; - } - shared->freeTexMem[tmu] += range->endAddr - range->startAddr; - - /* find position in linked list to insert this tdfxMemRange node */ - prev = NULL; - block = shared->tmFree[tmu]; - while (block) { - assert(range->startAddr != block->startAddr); - if (range->startAddr > block->startAddr) { - prev = block; - block = block->next; - } - else { - break; - } - } - - /* Insert the free block, combine with adjacent blocks when possible */ - range->next = block; - if (block) { - if (range->endAddr == block->startAddr) { - /* Combine */ - block->startAddr = range->startAddr; - DELETE_RANGE_NODE(shared, range); - range = block; - } - } - if (prev) { - if (prev->endAddr == range->startAddr) { - /* Combine */ - prev->endAddr = range->endAddr; - prev->next = range->next; - DELETE_RANGE_NODE(shared, range); - } - else { - prev->next = range; - } - } - else { - shared->tmFree[tmu] = range; - } -} - - -#if 0 /* NOT USED */ -static void -RemoveRange(tdfxContextPtr fxMesa, FxU32 tmu, tdfxMemRange *range) -{ - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - _glthread_LOCK_MUTEX(mesaShared->Mutex); - RemoveRange_NoLock(fxMesa, tmu, range); - _glthread_UNLOCK_MUTEX(mesaShared->Mutex); -} -#endif - - -/* - * Allocate space for a texture image. - * <tmu> is the texture unit - * <texmemsize> is the number of bytes to allocate - */ -static tdfxMemRange * -AllocTexMem(tdfxContextPtr fxMesa, FxU32 tmu, FxU32 texmemsize) -{ - FxU32 startAddr; - startAddr = FindStartAddr(fxMesa, tmu, texmemsize); - if (startAddr == BAD_ADDRESS) { - _mesa_problem(fxMesa->glCtx, "%s returned NULL! tmu=%d texmemsize=%d", - __FUNCTION__, (int) tmu, (int) texmemsize); - return NULL; - } - else { - tdfxMemRange *range; - range = NewRangeNode(fxMesa, startAddr, startAddr + texmemsize); - return range; - } -} - - -/* - * Download (copy) the given texture data (all mipmap levels) into the - * Voodoo's texture memory. - * The texture memory must have already been allocated. - */ -void -tdfxTMDownloadTexture(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) -{ - tdfxTexInfo *ti; - GLint l; - FxU32 targetTMU; - - assert(tObj); - ti = TDFX_TEXTURE_DATA(tObj); - assert(ti); - targetTMU = ti->whichTMU; - - switch (targetTMU) { - case TDFX_TMU0: - case TDFX_TMU1: - if (ti->tm[targetTMU]) { - for (l = ti->minLevel; l <= ti->maxLevel - && tObj->Image[0][l]->Data; l++) { - GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel; - fxMesa->Glide.grTexDownloadMipMapLevel(targetTMU, - ti->tm[targetTMU]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - tObj->Image[0][l]->Data); - } - } - break; - case TDFX_TMU_SPLIT: - if (ti->tm[TDFX_TMU0] && ti->tm[TDFX_TMU1]) { - for (l = ti->minLevel; l <= ti->maxLevel - && tObj->Image[0][l]->Data; l++) { - GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel; - fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0, - ti->tm[TDFX_TMU0]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_ODD, - tObj->Image[0][l]->Data); - - fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1, - ti->tm[TDFX_TMU1]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_EVEN, - tObj->Image[0][l]->Data); - } - } - break; - case TDFX_TMU_BOTH: - if (ti->tm[TDFX_TMU0] && ti->tm[TDFX_TMU1]) { - for (l = ti->minLevel; l <= ti->maxLevel - && tObj->Image[0][l]->Data; l++) { - GrLOD_t glideLod = ti->info.largeLodLog2 - l + tObj->BaseLevel; - fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0, - ti->tm[TDFX_TMU0]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - tObj->Image[0][l]->Data); - - fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1, - ti->tm[TDFX_TMU1]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - tObj->Image[0][l]->Data); - } - } - break; - default: - _mesa_problem(NULL, "%s: bad tmu (%d)", __FUNCTION__, (int)targetTMU); - return; - } -} - - -void -tdfxTMReloadMipMapLevel(GLcontext *ctx, struct gl_texture_object *tObj, - GLint level) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); - GrLOD_t glideLod; - FxU32 tmu; - - tmu = ti->whichTMU; - glideLod = ti->info.largeLodLog2 - level + tObj->BaseLevel; - ASSERT(ti->isInTM); - - LOCK_HARDWARE(fxMesa); - - switch (tmu) { - case TDFX_TMU0: - case TDFX_TMU1: - fxMesa->Glide.grTexDownloadMipMapLevel(tmu, - ti->tm[tmu]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - tObj->Image[0][level]->Data); - break; - case TDFX_TMU_SPLIT: - fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0, - ti->tm[GR_TMU0]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_ODD, - tObj->Image[0][level]->Data); - - fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1, - ti->tm[GR_TMU1]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_EVEN, - tObj->Image[0][level]->Data); - break; - case TDFX_TMU_BOTH: - fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU0, - ti->tm[GR_TMU0]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - tObj->Image[0][level]->Data); - - fxMesa->Glide.grTexDownloadMipMapLevel(GR_TMU1, - ti->tm[GR_TMU1]->startAddr, - glideLod, - ti->info.largeLodLog2, - ti->info.aspectRatioLog2, - ti->info.format, - GR_MIPMAPLEVELMASK_BOTH, - tObj->Image[0][level]->Data); - break; - - default: - _mesa_problem(ctx, "%s: bad tmu (%d)", __FUNCTION__, (int)tmu); - break; - } - UNLOCK_HARDWARE(fxMesa); -} - - -/* - * Allocate space for the given texture in texture memory then - * download (copy) it into that space. - */ -void -tdfxTMMoveInTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj, - FxU32 targetTMU ) -{ - tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); - FxU32 texmemsize; - - fxMesa->stats.reqTexUpload++; - - if (ti->isInTM) { - if (ti->whichTMU == targetTMU) - return; - if (targetTMU == TDFX_TMU_SPLIT || ti->whichTMU == TDFX_TMU_SPLIT) { - tdfxTMMoveOutTM_NoLock(fxMesa, tObj); - } - else { - if (ti->whichTMU == TDFX_TMU_BOTH) - return; - targetTMU = TDFX_TMU_BOTH; - } - } - - ti->whichTMU = targetTMU; - - switch (targetTMU) { - case TDFX_TMU0: - case TDFX_TMU1: - texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, - &(ti->info)); - ti->tm[targetTMU] = AllocTexMem(fxMesa, targetTMU, texmemsize); - break; - case TDFX_TMU_SPLIT: - texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_ODD, - &(ti->info)); - ti->tm[TDFX_TMU0] = AllocTexMem(fxMesa, TDFX_TMU0, texmemsize); - if (ti->tm[TDFX_TMU0]) - fxMesa->stats.memTexUpload += texmemsize; - - texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_EVEN, - &(ti->info)); - ti->tm[TDFX_TMU1] = AllocTexMem(fxMesa, TDFX_TMU1, texmemsize); - break; - case TDFX_TMU_BOTH: - texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, - &(ti->info)); - ti->tm[TDFX_TMU0] = AllocTexMem(fxMesa, TDFX_TMU0, texmemsize); - if (ti->tm[TDFX_TMU0]) - fxMesa->stats.memTexUpload += texmemsize; - - /*texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, - &(ti->info));*/ - ti->tm[TDFX_TMU1] = AllocTexMem(fxMesa, TDFX_TMU1, texmemsize); - break; - default: - _mesa_problem(NULL, "%s: bad tmu (%d)", __FUNCTION__, (int)targetTMU); - return; - } - - ti->reloadImages = GL_TRUE; - ti->isInTM = GL_TRUE; - - fxMesa->stats.texUpload++; -} - - -/* - * Move the given texture out of hardware texture memory. - * This deallocates the texture's memory space. - */ -void -tdfxTMMoveOutTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj ) -{ - struct gl_shared_state *mesaShared = fxMesa->glCtx->Shared; - struct tdfxSharedState *shared = (struct tdfxSharedState *) mesaShared->DriverData; - tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); - - if (MESA_VERBOSE & VERBOSE_DRIVER) { - fprintf(stderr, "fxmesa: %s(%p (%d))\n", __FUNCTION__, (void *)tObj, tObj->Name); - } - - /* - VerifyFreeList(fxMesa, 0); - VerifyFreeList(fxMesa, 1); - */ - - if (!ti || !ti->isInTM) - return; - - switch (ti->whichTMU) { - case TDFX_TMU0: - case TDFX_TMU1: - RemoveRange_NoLock(fxMesa, ti->whichTMU, ti->tm[ti->whichTMU]); - break; - case TDFX_TMU_SPLIT: - case TDFX_TMU_BOTH: - assert(!shared->umaTexMemory); - RemoveRange_NoLock(fxMesa, TDFX_TMU0, ti->tm[TDFX_TMU0]); - RemoveRange_NoLock(fxMesa, TDFX_TMU1, ti->tm[TDFX_TMU1]); - break; - default: - _mesa_problem(NULL, "%s: bad tmu (%d)", __FUNCTION__, (int)ti->whichTMU); - return; - } - - ti->isInTM = GL_FALSE; - ti->tm[0] = NULL; - ti->tm[1] = NULL; - ti->whichTMU = TDFX_TMU_NONE; - - /* - VerifyFreeList(fxMesa, 0); - VerifyFreeList(fxMesa, 1); - */ -} - - -/* - * Called via glDeleteTexture to delete a texture object. - */ -void -tdfxTMFreeTexture(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) -{ - tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); - if (ti) { - tdfxTMMoveOutTM(fxMesa, tObj); - FREE(ti); - tObj->DriverData = NULL; - } - /* - VerifyFreeList(fxMesa, 0); - VerifyFreeList(fxMesa, 1); - */ -} - - - -/* - * After a context switch this function will be called to restore - * texture memory for the new context. - */ -void tdfxTMRestoreTextures_NoLock( tdfxContextPtr fxMesa ) -{ - GLcontext *ctx = fxMesa->glCtx; - struct _mesa_HashTable *textures = fxMesa->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); - tdfxTexInfo *ti = TDFX_TEXTURE_DATA( tObj ); - if ( ti && ti->isInTM ) { - int i; - for ( i = 0 ; i < MAX_TEXTURE_UNITS ; i++ ) { - if ( ctx->Texture.Unit[i]._Current == tObj ) { - tdfxTMDownloadTexture( fxMesa, tObj ); - break; - } - } - if ( i == MAX_TEXTURE_UNITS ) { - tdfxTMMoveOutTM_NoLock( fxMesa, tObj ); - } - } - } - /* - VerifyFreeList(fxMesa, 0); - VerifyFreeList(fxMesa, 1); - */ -} |