From: Felix Kuehling Date: Mon, 24 Jan 2005 01:15:12 +0000 (+0000) Subject: Converted the Savage texture management to use Ian's common texmem code. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=428a5e82fc41689d1737d34560b10d921f28b98b;p=mesa.git Converted the Savage texture management to use Ian's common texmem code. --- diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c index c2eb8d10b17..2c31aefce11 100644 --- a/src/mesa/drivers/dri/savage/savage_xmesa.c +++ b/src/mesa/drivers/dri/savage/savage_xmesa.c @@ -55,6 +55,8 @@ #include "savage_dri.h" +#include "texmem.h" + #include "xmlpool.h" /* Driver-specific options @@ -295,7 +297,6 @@ savageCreateContext( const __GLcontextModes *mesaVis, savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private; drm_savage_sarea_t *saPriv=(drm_savage_sarea_t *)(((char*)sPriv->pSAREA)+ savageScreen->sarea_priv_offset); - GLuint maxTextureSize, minTextureSize, maxTextureLevels; int i; imesa = (savageContextPtr)Xcalloc(sizeof(savageContext), 1); if (!imesa) { @@ -332,60 +333,6 @@ savageCreateContext( const __GLcontextModes *mesaVis, imesa->float_depth = driQueryOptionb(&imesa->optionCache, "float_depth") && savageScreen->chipset >= S3_SAVAGE4; imesa->no_rast = driQueryOptionb(&imesa->optionCache, "no_rast"); - imesa->texture_depth = driQueryOptioni (&imesa->optionCache, - "texture_depth"); - if (imesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB) - imesa->texture_depth = ( savageScreen->cpp == 4 ) ? - DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16; - - if (savageScreen->chipset >= S3_SAVAGE4) - ctx->Const.MaxTextureUnits = 2; - else - ctx->Const.MaxTextureUnits = 1; - if (driQueryOptioni(&imesa->optionCache, "texture_units") < - ctx->Const.MaxTextureUnits) - ctx->Const.MaxTextureUnits = - driQueryOptioni(&imesa->optionCache, "texture_units"); - ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits; - ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits; - - /* Set the maximum texture size small enough that we can guarentee - * that all texture units can bind a maximal texture and have them - * in memory at once. - */ - if (savageScreen->textureSize[SAVAGE_CARD_HEAP] > - savageScreen->textureSize[SAVAGE_AGP_HEAP]) { - maxTextureSize = savageScreen->textureSize[SAVAGE_CARD_HEAP]; - minTextureSize = savageScreen->textureSize[SAVAGE_AGP_HEAP]; - } else { - maxTextureSize = savageScreen->textureSize[SAVAGE_AGP_HEAP]; - minTextureSize = savageScreen->textureSize[SAVAGE_CARD_HEAP]; - } - if (ctx->Const.MaxTextureUnits == 2) { - /* How to distribute two maximum sized textures to two texture heaps? - * If the smaller heap is less then half the size of the bigger one - * then the maximum size is half the size of the bigger heap. - * Otherwise it's the size of the smaller heap. */ - if (minTextureSize < maxTextureSize / 2) - maxTextureSize = maxTextureSize / 2; - else - maxTextureSize = minTextureSize; - } - for (maxTextureLevels = 1; maxTextureLevels <= 11; ++maxTextureLevels) { - GLuint size = 1 << maxTextureLevels; - size *= size * 4; /* 4 bytes per texel */ - size = size * 4/3; /* all mipmap levels together take roughly - 4/3 the size of the biggest level */ - if (size > maxTextureSize) - break; - } - ctx->Const.MaxTextureLevels = maxTextureLevels; - if (ctx->Const.MaxTextureLevels <= 6) { /*spec requires at least 64x64*/ - __driUtilMessage("Not enough texture memory. " - "Falling back to indirect rendering."); - Xfree(imesa); - return GL_FALSE; - } #if 0 ctx->Const.MinLineWidth = 1.0; @@ -419,19 +366,56 @@ savageCreateContext( const __GLcontextModes *mesaVis, /* change texHeap initialize to support two kind of texture heap*/ /* here is some parts of initialization, others in InitDriver() */ + (void) memset( imesa->textureHeaps, 0, sizeof( imesa->textureHeaps ) ); + make_empty_list( & imesa->swapped ); + imesa->lastTexHeap = savageScreen->texVirtual[SAVAGE_AGP_HEAP] ? 2 : 1; - - /*allocate texHeap for multi-tex*/ - { - int i; - - for(i=0;ilastTexHeap;i++) - { - imesa->texHeap[i] = mmInit( 0, savageScreen->textureSize[i] ); - make_empty_list(&imesa->TexObjList[i]); - } - - make_empty_list(&imesa->SwappedOut); + for (i = 0; i < imesa->lastTexHeap; i++) { + imesa->textureHeaps[i] = driCreateTextureHeap( + i, imesa, + savageScreen->textureSize[i], + 11, /* 2^11 = 2k alignment */ + SAVAGE_NR_TEX_REGIONS, + (drmTextureRegionPtr)imesa->sarea->texList[i], + &imesa->sarea->texAge[i], + &imesa->swapped, + sizeof( savageTexObj ), + (destroy_texture_object_t *) savageDestroyTexObj ); + driSetTextureSwapCounterLocation( imesa->textureHeaps[i], + & imesa->c_textureSwaps ); + } + imesa->texture_depth = driQueryOptioni (&imesa->optionCache, + "texture_depth"); + if (imesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB) + imesa->texture_depth = ( savageScreen->cpp == 4 ) ? + DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16; + + if (savageScreen->chipset >= S3_SAVAGE4) + ctx->Const.MaxTextureUnits = 2; + else + ctx->Const.MaxTextureUnits = 1; + if (driQueryOptioni(&imesa->optionCache, "texture_units") < + ctx->Const.MaxTextureUnits) + ctx->Const.MaxTextureUnits = + driQueryOptioni(&imesa->optionCache, "texture_units"); + ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits; + ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits; + + driCalculateMaxTextureLevels( imesa->textureHeaps, + imesa->lastTexHeap, + & ctx->Const, + 4, + 11, /* max 2D texture size is 2048x2048 */ + 0, /* 3D textures unsupported. */ + 0, /* cube textures unsupported. */ + 0, /* texture rectangles unsupported. */ + 12, + GL_FALSE ); + if (ctx->Const.MaxTextureLevels <= 6) { /*spec requires at least 64x64*/ + __driUtilMessage("Not enough texture memory. " + "Falling back to indirect rendering."); + Xfree(imesa); + return GL_FALSE; } imesa->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24; @@ -464,11 +448,8 @@ savageCreateContext( const __GLcontextModes *mesaVis, imesa->RenderIndex = ~0; imesa->dirty = ~0; imesa->lostContext = GL_TRUE; - imesa->TextureMode = ctx->Texture.Unit[0].EnvMode; imesa->CurrentTexObj[0] = 0; imesa->CurrentTexObj[1] = 0; - imesa->texAge[SAVAGE_CARD_HEAP]=0; - imesa->texAge[SAVAGE_AGP_HEAP]=0; /* Initialize the software rasterizer and helper modules. */ @@ -529,25 +510,17 @@ static void savageDestroyContext(__DRIcontextPrivate *driContextPriv) { savageContextPtr imesa = (savageContextPtr) driContextPriv->driverPrivate; + GLuint i; assert (imesa); /* should never be NULL */ if (imesa) { - savageTextureObjectPtr next_t, t; - savageFlushVertices(imesa); savageReleaseIndexedVerts(imesa); savageFlushCmdBuf(imesa, GL_TRUE); /* release DMA buffer */ WAIT_IDLE_EMPTY(imesa); - /* update for multi-tex*/ - { - int i; - for(i=0;ilastTexHeap;i++) - foreach_s (t, next_t, &(imesa->TexObjList[i])) - savageDestroyTexObj(imesa, t); - } - foreach_s (t, next_t, &(imesa->SwappedOut)) - savageDestroyTexObj(imesa, t); + for (i = 0; i < imesa->lastTexHeap; i++) + driDestroyTextureHeap(imesa->textureHeaps[i]); free(imesa->cmdBuf.base); free(imesa->clientVtxBuf.buf); @@ -785,43 +758,10 @@ void savageGetLock( savageContextPtr imesa, GLuint flags ) sarea->ctxOwner = me; } - /* Shared texture managment - if another client has played with - * texture space, figure out which if any of our textures have been - * ejected, and update our global LRU. - */ - /*frank just for compiling,texAge,texList,AGP*/ - - for(heap= 0 ;heap < imesa->lastTexHeap ; heap++) - { - if (sarea->texAge[heap] != imesa->texAge[heap]) { - int sz = 1 << (imesa->savageScreen->logTextureGranularity[heap]); - int idx, nr = 0; - - /* Have to go right round from the back to ensure stuff ends up - * LRU in our local list... - */ - for (idx = sarea->texList[heap][SAVAGE_NR_TEX_REGIONS].prev ; - idx != SAVAGE_NR_TEX_REGIONS && nr < SAVAGE_NR_TEX_REGIONS ; - idx = sarea->texList[heap][idx].prev, nr++) - { - if (sarea->texList[heap][idx].age > imesa->texAge[heap]) - { - savageTexturesGone(imesa, heap ,idx * sz, sz, - sarea->texList[heap][idx].in_use); - } - } - - if (nr == SAVAGE_NR_TEX_REGIONS) - { - savageTexturesGone(imesa, heap, 0, - imesa->savageScreen->textureSize[heap], 0); - savageResetGlobalLRU( imesa , heap ); - } - - imesa->texAge[heap] = sarea->texAge[heap]; - } - } /* end of for loop */ - + for (heap = 0; heap < imesa->lastTexHeap; ++heap) { + DRI_AGE_TEXTURES( imesa->textureHeaps[heap] ); + } + if (dPriv->lastStamp != stamp) savageXMesaWindowMoved( imesa ); diff --git a/src/mesa/drivers/dri/savage/savagecontext.h b/src/mesa/drivers/dri/savage/savagecontext.h index a1ed14031fe..21385ed7ec4 100644 --- a/src/mesa/drivers/dri/savage/savagecontext.h +++ b/src/mesa/drivers/dri/savage/savagecontext.h @@ -38,10 +38,11 @@ typedef struct savage_texture_object_t *savageTextureObjectPtr; #include "drm.h" #include "savage_drm.h" #include "savage_init.h" +#include "savage_3d_reg.h" #include "mm.h" #include "tnl/t_vertex.h" -#include "savagetex.h" +#include "texmem.h" #include "xmlconfig.h" @@ -153,18 +154,11 @@ struct savage_context_t { GLcontext *glCtx; int lastTexHeap; - savageTextureObjectPtr CurrentTexObj[2]; - - struct savage_texture_object_t TexObjList[SAVAGE_NR_TEX_HEAPS]; - struct savage_texture_object_t SwappedOut; - - GLuint c_texupload; - GLuint c_texusage; - GLuint tex_thrash; - - GLuint TextureMode; - - + driTexHeap *textureHeaps[SAVAGE_NR_TEX_HEAPS]; + driTextureObject swapped; + + driTextureObject *CurrentTexObj[2]; + /* Hardware state */ @@ -192,7 +186,6 @@ struct savage_context_t { /* Manage hardware state */ GLuint dirty; GLboolean lostContext; - memHeap_t *texHeap[SAVAGE_NR_TEX_HEAPS]; GLuint bTexEn1; /* One of the few bits of hardware state that can't be calculated * completely on the fly: @@ -275,9 +268,6 @@ struct savage_context_t { drm_clip_rect_t draw_rect; drm_clip_rect_t scissor_rect; - /*Texture aging and DMA based aging*/ - unsigned int texAge[SAVAGE_NR_TEX_HEAPS]; - drm_context_t hHWContext; drm_hw_lock_t *driHwLock; GLuint driFd; @@ -298,6 +288,10 @@ struct savage_context_t { GLboolean hw_stencil; + /* Performance counters + */ + GLuint c_textureSwaps; + /* Configuration cache */ driOptionCache optionCache; diff --git a/src/mesa/drivers/dri/savage/savagetex.c b/src/mesa/drivers/dri/savage/savagetex.c index dd8b4e89043..e6954a048ab 100644 --- a/src/mesa/drivers/dri/savage/savagetex.c +++ b/src/mesa/drivers/dri/savage/savagetex.c @@ -186,9 +186,9 @@ static void savageUploadTiny (const savageTileInfo *tileInfo, /** \brief Upload an image from mesa's internal copy. */ -static void savageUploadTexLevel( savageTextureObjectPtr t, int level ) +static void savageUploadTexLevel( savageTexObjPtr t, int level ) { - const struct gl_texture_image *image = t->image[level].image; + const struct gl_texture_image *image = t->base.tObj->Image[0][level]; const savageTileInfo *tileInfo = t->tileInfo; GLuint width = image->Width2, height = image->Height2; GLuint bpp = t->texelBytes; @@ -207,7 +207,7 @@ static void savageUploadTexLevel( savageTextureObjectPtr t, int level ) GLuint wInTiles = width / tileInfo->width; GLuint hInTiles = height / tileInfo->height; GLubyte *srcTRow = image->Data, *src; - GLubyte *dest = (GLubyte *)(t->BufAddr + t->image[level].offset); + GLubyte *dest = (GLubyte *)(t->bufAddr + t->image[level].offset); GLuint x, y; for (y = 0; y < hInTiles; ++y) { src = srcTRow; @@ -224,7 +224,7 @@ static void savageUploadTexLevel( savageTextureObjectPtr t, int level ) savageUploadTile (tileInfo, width / tileInfo->subWidth, height / tileInfo->subHeight, bpp, image->Data, width * bpp, - (GLubyte *)(t->BufAddr+t->image[level].offset)); + (GLubyte *)(t->bufAddr+t->image[level].offset)); } } else { GLuint minHeight, minWidth, hRepeat, vRepeat, x, y; @@ -241,7 +241,7 @@ static void savageUploadTexLevel( savageTextureObjectPtr t, int level ) GLuint offset = y * tileInfo->subWidth*height * bpp; for (x = 0; x < hRepeat; ++x) { savageUploadTiny (tileInfo, width, height, bpp, image->Data, - (GLubyte *)(t->BufAddr + + (GLubyte *)(t->bufAddr + t->image[level].offset+offset)); offset += width * bpp; } @@ -270,48 +270,47 @@ static GLuint savageTexImageSize (GLuint width, GLuint height, GLuint bpp) { return 64 * bpp; } -static void savageSetTexWrapping(savageTextureObjectPtr tex, GLenum s, GLenum t) +static void savageSetTexWrapping(savageTexObjPtr tex, GLenum s, GLenum t) { - tex->texParams.sWrapMode = s; - tex->texParams.tWrapMode = t; + tex->setup.sWrapMode = s; + tex->setup.tWrapMode = t; } -static void savageSetTexFilter(savageTextureObjectPtr t, - GLenum minf, GLenum magf) +static void savageSetTexFilter(savageTexObjPtr t, GLenum minf, GLenum magf) { - t->texParams.minFilter = minf; - t->texParams.magFilter = magf; + t->setup.minFilter = minf; + t->setup.magFilter = magf; } /* Need a fallback ? */ -static void savageSetTexBorderColor(savageTextureObjectPtr t, GLubyte color[4]) +static void savageSetTexBorderColor(savageTexObjPtr t, GLubyte color[4]) { /* t->Setup[SAVAGE_TEXREG_TEXBORDERCOL] = */ - t->texParams.boarderColor = SAVAGEPACKCOLOR8888(color[0],color[1],color[2],color[3]); + /*t->setup.borderColor = SAVAGEPACKCOLOR8888(color[0],color[1],color[2],color[3]); */ } -static savageTextureObjectPtr +static savageTexObjPtr savageAllocTexObj( struct gl_texture_object *texObj ) { - savageTextureObjectPtr t; + savageTexObjPtr t; - t = (savageTextureObjectPtr) calloc(1,sizeof(*t)); + t = (savageTexObjPtr) calloc(1,sizeof(*t)); texObj->DriverData = t; if ( t != NULL ) { /* Initialize non-image-dependent parts of the state: */ - t->globj = texObj; + t->base.tObj = texObj; /* FIXME Something here to set initial values for other parts of * FIXME t->setup? */ - make_empty_list( t ); + make_empty_list( &t->base ); savageSetTexWrapping(t,texObj->WrapS,texObj->WrapT); savageSetTexFilter(t,texObj->MinFilter,texObj->MagFilter); @@ -333,7 +332,6 @@ savageChooseTextureFormat( GLcontext *ctx, GLint internalFormat, ( imesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16 ); const GLboolean isSavage4 = (imesa->savageScreen->chipset >= S3_SAVAGE4); (void) format; - (void) type; switch ( internalFormat ) { case 4: @@ -468,9 +466,10 @@ savageChooseTextureFormat( GLcontext *ctx, GLint internalFormat, static void savageSetTexImages( savageContextPtr imesa, const struct gl_texture_object *tObj ) { - savageTextureObjectPtr t = (savageTextureObjectPtr) tObj->DriverData; + savageTexObjPtr t = (savageTexObjPtr) tObj->DriverData; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; GLuint offset, i, textureFormat, size; + GLint firstLevel, lastLevel; assert(t); assert(image); @@ -508,6 +507,7 @@ static void savageSetTexImages( savageContextPtr imesa, _mesa_problem(imesa->glCtx, "Bad texture format in %s", __FUNCTION__); return; } + t->hwFormat = textureFormat; /* Select tiling format depending on the chipset and bytes per texel */ if (imesa->savageScreen->chipset <= S3_SAVAGE4) @@ -515,288 +515,92 @@ static void savageSetTexImages( savageContextPtr imesa, else t->tileInfo = &tileInfo_pro[t->texelBytes]; + /* Compute which mipmap levels we really want to send to the hardware. + */ + driCalculateTextureFirstLastLevel( &t->base ); + firstLevel = t->base.firstLevel; + lastLevel = t->base.lastLevel; + /* Figure out the size now (and count the levels). Upload won't be done * until later. */ - t->dirty_images = 0; offset = 0; size = 1; - for ( i = 0 ; i < SAVAGE_TEX_MAXLEVELS && tObj->Image[0][i] ; i++ ) { - image = tObj->Image[0][i]; - t->image[i].image = image; + for ( i = firstLevel ; i <= lastLevel && tObj->Image[0][i] ; i++ ) { t->image[i].offset = offset; - t->image[i].internalFormat = textureFormat; - t->dirty_images |= (1<Image[0][i]; size = savageTexImageSize (image->Width2, image->Height2, t->texelBytes); offset += size; } - t->totalSize = offset; + t->base.lastLevel = i-1; + t->base.totalSize = offset; /* the last three mipmap levels don't add to the offset. They are packed * into 64 pixels. */ if (size == 0) - t->totalSize += 64 * t->texelBytes; - /* 2k-aligned */ - t->totalSize = (t->totalSize + 2047UL) & ~2047UL; - t->max_level = i-1; - t->min_level = 0; -} - -void savageDestroyTexObj(savageContextPtr imesa, savageTextureObjectPtr t) -{ - if (!t) return; - - /* This is sad - need to sync *in case* we upload a texture - * to this newly free memory... - */ - if (t->MemBlock) { - mmFreeMem(t->MemBlock); - t->MemBlock = 0; - - if (t->age > imesa->dirtyAge) - imesa->dirtyAge = t->age; - } - - if (t->globj) - t->globj->DriverData = 0; - - remove_from_list(t); - free(t); -} - - -static void savageSwapOutTexObj(savageContextPtr imesa, savageTextureObjectPtr t) -{ - if (t->MemBlock) { - mmFreeMem(t->MemBlock); - t->MemBlock = 0; - - if (t->age > imesa->dirtyAge) - imesa->dirtyAge = t->age; - } - - t->dirty_images = ~0; - move_to_tail(&(imesa->SwappedOut), t); -} - - - -void savagePrintLocalLRU( savageContextPtr imesa , GLuint heap) -{ - savageTextureObjectPtr t; - int sz = 1 << (imesa->savageScreen->logTextureGranularity[heap]); - - foreach( t, &imesa->TexObjList[heap] ) { - if (!t->globj) - fprintf(stderr, "Placeholder %d at %x sz %x\n", - t->MemBlock->ofs / sz, - t->MemBlock->ofs, - t->MemBlock->size); - else - fprintf(stderr, "Texture (bound %d) at %x sz %x\n", - t->bound, - t->MemBlock->ofs, - t->MemBlock->size); - - } + t->base.totalSize += 64 * t->texelBytes; + /* 2k-aligned (really needed?) */ + t->base.totalSize = (t->base.totalSize + 2047UL) & ~2047UL; } -void savagePrintGlobalLRU( savageContextPtr imesa , GLuint heap) -{ - int i, j; - - drm_tex_region_t *list = imesa->sarea->texList[heap]; - - - for (i = 0, j = SAVAGE_NR_TEX_REGIONS ; i < SAVAGE_NR_TEX_REGIONS ; i++) { - fprintf(stderr, "list[%d] age %d next %d prev %d\n", - j, list[j].age, list[j].next, list[j].prev); - j = list[j].next; - if (j == SAVAGE_NR_TEX_REGIONS) break; - } - - if (j != SAVAGE_NR_TEX_REGIONS) - fprintf(stderr, "Loop detected in global LRU\n"); - for (i = 0 ; i < SAVAGE_NR_TEX_REGIONS ; i++) - { - fprintf(stderr,"list[%d] age %d next %d prev %d\n", - i, list[i].age, list[i].next, list[i].prev); - } -} - - -void savageResetGlobalLRU( savageContextPtr imesa, GLuint heap ) +void savageDestroyTexObj(savageContextPtr imesa, driTextureObject *t) { - drm_tex_region_t *list = imesa->sarea->texList[heap]; - int sz = 1 << imesa->savageScreen->logTextureGranularity[heap]; - int i; - - /* (Re)initialize the global circular LRU list. The last element - * in the array (SAVAGE_NR_TEX_REGIONS) is the sentinal. Keeping it - * at the end of the array allows it to be addressed rationally - * when looking up objects at a particular location in texture - * memory. - */ - for (i = 0 ; (i+1) * sz <= imesa->savageScreen->textureSize[heap]; i++) { - list[i].prev = i-1; - list[i].next = i+1; - list[i].age = 0; - } - - i--; - list[0].prev = SAVAGE_NR_TEX_REGIONS; - list[i].prev = i-1; - list[i].next = SAVAGE_NR_TEX_REGIONS; - list[SAVAGE_NR_TEX_REGIONS].prev = i; - list[SAVAGE_NR_TEX_REGIONS].next = 0; - imesa->sarea->texAge[heap] = 0; -} - - -static void savageUpdateTexLRU( savageContextPtr imesa, savageTextureObjectPtr t ) -{ - int i; - int heap = t->heap; - int logsz = imesa->savageScreen->logTextureGranularity[heap]; - int start = t->MemBlock->ofs >> logsz; - int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; - drm_tex_region_t *list = imesa->sarea->texList[heap]; - - imesa->texAge[heap] = ++imesa->sarea->texAge[heap]; - - /* Update our local LRU - */ - move_to_head( &(imesa->TexObjList[heap]), t ); - - /* Update the global LRU - */ - for (i = start ; i <= end ; i++) { - - list[i].in_use = 1; - list[i].age = imesa->texAge[heap]; + /* See if it was the driver's current object. + */ - /* remove_from_list(i) - */ - list[(unsigned)list[i].next].prev = list[i].prev; - list[(unsigned)list[i].prev].next = list[i].next; - - /* insert_at_head(list, i) - */ - list[i].prev = SAVAGE_NR_TEX_REGIONS; - list[i].next = list[SAVAGE_NR_TEX_REGIONS].next; - list[(unsigned)list[SAVAGE_NR_TEX_REGIONS].next].prev = i; - list[SAVAGE_NR_TEX_REGIONS].next = i; - } + if ( imesa != NULL ) + { + GLuint i; + for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) + { + if ( t == imesa->CurrentTexObj[ i ] ) { + assert( t->bound & (1 << i) ); + imesa->CurrentTexObj[ i ] = NULL; + } + } + } } - -/* Called for every shared texture region which has increased in age - * since we last held the lock. - * - * Figures out which of our textures have been ejected by other clients, - * and pushes a placeholder texture onto the LRU list to represent - * the other client's textures. +/* Upload a texture's images to one of the texture heaps. May have to + * eject our own and/or other client's texture objects to make room + * for the upload. */ -void savageTexturesGone( savageContextPtr imesa, - GLuint heap, - GLuint offset, - GLuint size, - GLuint in_use ) +static void savageUploadTexImages( savageContextPtr imesa, savageTexObjPtr t ) { - savageTextureObjectPtr t, tmp; - - foreach_s ( t, tmp, &imesa->TexObjList[heap] ) { - - if (t->MemBlock->ofs >= offset + size || - t->MemBlock->ofs + t->MemBlock->size <= offset) - continue; - - /* It overlaps - kick it off. Need to hold onto the currently bound - * objects, however. - */ - if (t->bound) - savageSwapOutTexObj( imesa, t ); - else - savageDestroyTexObj( imesa, t ); - } - - - if (in_use) { - t = (savageTextureObjectPtr) calloc(1,sizeof(*t)); - if (!t) return; - - t->heap = heap; - t->MemBlock = mmAllocMem( imesa->texHeap[heap], size, 0, offset); - if(!t->MemBlock) - { - free(t); - return; - } - insert_at_head( &imesa->TexObjList[heap], t ); - } -} - - - + const GLint numLevels = t->base.lastLevel - t->base.firstLevel + 1; + GLuint i; + assert(t); -/* This is called with the lock held. May have to eject our own and/or - * other client's texture objects to make room for the upload. - */ -int savageUploadTexImages( savageContextPtr imesa, savageTextureObjectPtr t ) -{ - int heap; - int i; - int ofs; + LOCK_HARDWARE(imesa); - heap = t->heap = SAVAGE_CARD_HEAP; - /* Do we need to eject LRU texture objects? */ - if (!t->MemBlock) { - while (1) - { - t->MemBlock = mmAllocMem( imesa->texHeap[heap], t->totalSize, 12, 0 ); - if (t->MemBlock) - break; - else if (imesa->lastTexHeap == 2) - { - heap = t->heap = SAVAGE_AGP_HEAP; - t->MemBlock = mmAllocMem( imesa->texHeap[heap], t->totalSize, 12, 0 ); - - if (t->MemBlock) - break; - } - - if (imesa->TexObjList[heap].prev->bound) { - fprintf(stderr, "Hit bound texture in upload\n"); - savagePrintLocalLRU( imesa,heap ); - return -1; - } - - if (imesa->TexObjList[heap].prev == &(imesa->TexObjList[heap])) { - fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize); - mmDumpMemInfo( imesa->texHeap[heap] ); - return -1; - } - - savageSwapOutTexObj( imesa, imesa->TexObjList[heap].prev ); + if (!t->base.memBlock) { + GLint heap; + GLuint ofs; + + heap = driAllocateTexture(imesa->textureHeaps, imesa->lastTexHeap, + (driTextureObject *)t); + if (heap == -1) { + UNLOCK_HARDWARE(imesa); + return; } - - ofs = t->MemBlock->ofs; - t->texParams.hwPhysAddress = imesa->savageScreen->textureOffset[heap] + ofs; - t->BufAddr = (char *)((GLuint) imesa->savageScreen->texVirtual[heap] + ofs); + + ofs = t->base.memBlock->ofs; + t->setup.physAddr = imesa->savageScreen->textureOffset[heap] + ofs; + t->bufAddr = (char *)((GLuint) imesa->savageScreen->texVirtual[heap] + ofs); imesa->dirty |= SAVAGE_UPLOAD_GLOBAL; /* FIXME: really needed? */ } /* Let the world know we've used this memory recently. */ - LOCK_HARDWARE(imesa); - savageUpdateTexLRU( imesa, t ); + driUpdateTextureLRU( &t->base ); UNLOCK_HARDWARE(imesa); - if (t->dirty_images) { + if (t->base.dirty_images[0]) { savageFlushVertices (imesa); LOCK_HARDWARE(imesa); savageFlushCmdBufLocked (imesa, GL_FALSE); @@ -804,22 +608,14 @@ int savageUploadTexImages( savageContextPtr imesa, savageTextureObjectPtr t ) if (SAVAGE_DEBUG & DEBUG_VERBOSE_LRU) fprintf(stderr, "*"); - for (i = t->min_level ; i <= t->max_level ; i++) - if (t->dirty_images & (1<base.firstLevel + i; /* the texObj's level */ + if (t->base.dirty_images[0] & (1<base.dirty_images[0] = 0; } - - - t->dirty_images = 0; - return 0; -} - -static void savageTexSetUnit( savageTextureObjectPtr t, GLuint unit ) -{ - if (t->current_unit == unit) return; - - t->current_unit = unit; } @@ -829,7 +625,8 @@ static void savageUpdateTex0State_s4( GLcontext *ctx ) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); struct gl_texture_object *tObj; - savageTextureObjectPtr t; + struct gl_texture_image *image; + savageTexObjPtr t; GLuint format; /* disable */ @@ -857,19 +654,15 @@ static void savageUpdateTex0State_s4( GLcontext *ctx ) return; } - if (t->current_unit != 0) - savageTexSetUnit( t, 0 ); - - imesa->CurrentTexObj[0] = t; - t->bound |= 1; + imesa->CurrentTexObj[0] = &t->base; + t->base.bound |= 1; - if (t->dirty_images) { + if (t->base.dirty_images[0]) { savageSetTexImages(imesa, tObj); - savageUploadTexImages(imesa, imesa->CurrentTexObj[0]); + savageUploadTexImages(imesa, t); } - if (t->MemBlock) - savageUpdateTexLRU( imesa, t ); + driUpdateTextureLRU( &t->base ); format = tObj->Image[0][tObj->BaseLevel]->Format; @@ -1026,11 +819,11 @@ static void savageUpdateTex0State_s4( GLcontext *ctx ) } imesa->regs.s4.texCtrl[0].ni.uMode = - t->texParams.sWrapMode == GL_REPEAT ? 0 : 1; + t->setup.sWrapMode == GL_REPEAT ? 0 : 1; imesa->regs.s4.texCtrl[0].ni.vMode = - t->texParams.tWrapMode == GL_REPEAT ? 0 : 1; + t->setup.tWrapMode == GL_REPEAT ? 0 : 1; - switch (t->texParams.minFilter) + switch (t->setup.minFilter) { case GL_NEAREST: imesa->regs.s4.texCtrl[0].ni.filterMode = TFM_Point; @@ -1070,17 +863,18 @@ static void savageUpdateTex0State_s4( GLcontext *ctx ) imesa->regs.s4.texCtrl[0].ni.dBias = bias & 0x1ff; } + image = tObj->Image[0][tObj->BaseLevel]; imesa->regs.s4.texDescr.ni.tex0En = GL_TRUE; - imesa->regs.s4.texDescr.ni.tex0Width = t->image[0].image->WidthLog2; - imesa->regs.s4.texDescr.ni.tex0Height = t->image[0].image->HeightLog2; - imesa->regs.s4.texDescr.ni.tex0Fmt = t->image[0].internalFormat; - imesa->regs.s4.texCtrl[0].ni.dMax = t->max_level; + imesa->regs.s4.texDescr.ni.tex0Width = image->WidthLog2; + imesa->regs.s4.texDescr.ni.tex0Height = image->HeightLog2; + imesa->regs.s4.texDescr.ni.tex0Fmt = t->hwFormat; + imesa->regs.s4.texCtrl[0].ni.dMax = t->base.lastLevel - t->base.firstLevel; if (imesa->regs.s4.texDescr.ni.tex1En) imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE; - imesa->regs.s4.texAddr[0].ui = (u_int32_t) t->texParams.hwPhysAddress | 0x2; - if(t->heap == SAVAGE_AGP_HEAP) + imesa->regs.s4.texAddr[0].ui = (u_int32_t) t->setup.physAddr | 0x2; + if(t->base.heap->heapId == SAVAGE_AGP_HEAP) imesa->regs.s4.texAddr[0].ui |= 0x1; return; @@ -1089,7 +883,8 @@ static void savageUpdateTex1State_s4( GLcontext *ctx ) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); struct gl_texture_object *tObj; - savageTextureObjectPtr t; + struct gl_texture_image *image; + savageTexObjPtr t; GLuint format; /* disable */ @@ -1125,20 +920,16 @@ static void savageUpdateTex1State_s4( GLcontext *ctx ) return; } - if (t->current_unit != 1) - savageTexSetUnit( t, 1 ); + imesa->CurrentTexObj[1] = &t->base; - imesa->CurrentTexObj[1] = t; + t->base.bound |= 2; - t->bound |= 2; - - if (t->dirty_images) { + if (t->base.dirty_images[0]) { savageSetTexImages(imesa, tObj); - savageUploadTexImages(imesa, imesa->CurrentTexObj[1]); + savageUploadTexImages(imesa, t); } - if (t->MemBlock) - savageUpdateTexLRU( imesa, t ); + driUpdateTextureLRU( &t->base ); format = tObj->Image[0][tObj->BaseLevel]->Format; @@ -1229,11 +1020,11 @@ static void savageUpdateTex1State_s4( GLcontext *ctx ) } imesa->regs.s4.texCtrl[1].ni.uMode = - t->texParams.sWrapMode == GL_REPEAT ? 0 : 1; + t->setup.sWrapMode == GL_REPEAT ? 0 : 1; imesa->regs.s4.texCtrl[1].ni.vMode = - t->texParams.tWrapMode == GL_REPEAT ? 0 : 1; + t->setup.tWrapMode == GL_REPEAT ? 0 : 1; - switch (t->texParams.minFilter) + switch (t->setup.minFilter) { case GL_NEAREST: imesa->regs.s4.texCtrl[1].ni.filterMode = TFM_Point; @@ -1273,22 +1064,24 @@ static void savageUpdateTex1State_s4( GLcontext *ctx ) imesa->regs.s4.texCtrl[1].ni.dBias = bias & 0x1ff; } + image = tObj->Image[0][tObj->BaseLevel]; imesa->regs.s4.texDescr.ni.tex1En = GL_TRUE; - imesa->regs.s4.texDescr.ni.tex1Width = t->image[0].image->WidthLog2; - imesa->regs.s4.texDescr.ni.tex1Height = t->image[0].image->HeightLog2; - imesa->regs.s4.texDescr.ni.tex1Fmt = t->image[0].internalFormat; - imesa->regs.s4.texCtrl[1].ni.dMax = t->max_level; + imesa->regs.s4.texDescr.ni.tex1Width = image->WidthLog2; + imesa->regs.s4.texDescr.ni.tex1Height = image->HeightLog2; + imesa->regs.s4.texDescr.ni.tex1Fmt = t->hwFormat; + imesa->regs.s4.texCtrl[1].ni.dMax = t->base.lastLevel - t->base.firstLevel; imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE; - imesa->regs.s4.texAddr[1].ui = (u_int32_t) t->texParams.hwPhysAddress| 2; - if(t->heap == SAVAGE_AGP_HEAP) + imesa->regs.s4.texAddr[1].ui = (u_int32_t) t->setup.physAddr | 2; + if(t->base.heap->heapId == SAVAGE_AGP_HEAP) imesa->regs.s4.texAddr[1].ui |= 0x1; } static void savageUpdateTexState_s3d( GLcontext *ctx ) { savageContextPtr imesa = SAVAGE_CONTEXT(ctx); struct gl_texture_object *tObj; - savageTextureObjectPtr t; + struct gl_texture_image *image; + savageTexObjPtr t; GLuint format; /* disable */ @@ -1316,19 +1109,15 @@ static void savageUpdateTexState_s3d( GLcontext *ctx ) return; } - if (t->current_unit != 0) - savageTexSetUnit( t, 0 ); - - imesa->CurrentTexObj[0] = t; - t->bound |= 1; + imesa->CurrentTexObj[0] = &t->base; + t->base.bound |= 1; - if (t->dirty_images) { + if (t->base.dirty_images[0]) { savageSetTexImages(imesa, tObj); - savageUploadTexImages(imesa, imesa->CurrentTexObj[0]); + savageUploadTexImages(imesa, t); } - if (t->MemBlock) - savageUpdateTexLRU( imesa, t ); + driUpdateTextureLRU( &t->base ); format = tObj->Image[0][tObj->BaseLevel]->Format; @@ -1357,12 +1146,12 @@ static void savageUpdateTexState_s3d( GLcontext *ctx ) truth. */ imesa->regs.s3d.texCtrl.ni.uWrapEn = 0; imesa->regs.s3d.texCtrl.ni.vWrapEn = 0; - if (t->texParams.sWrapMode == GL_CLAMP) + if (t->setup.sWrapMode == GL_CLAMP) imesa->regs.s3d.texCtrl.ni.wrapMode = TAM_Clamp; else imesa->regs.s3d.texCtrl.ni.wrapMode = TAM_Wrap; - switch (t->texParams.minFilter) { + switch (t->setup.minFilter) { case GL_NEAREST: imesa->regs.s3d.texCtrl.ni.filterMode = TFM_Point; imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_TRUE; @@ -1413,14 +1202,15 @@ static void savageUpdateTexState_s3d( GLcontext *ctx ) imesa->regs.s3d.texCtrl.ni.dBias = bias & 0x1ff; } + image = tObj->Image[0][tObj->BaseLevel]; imesa->regs.s3d.texCtrl.ni.texEn = GL_TRUE; - imesa->regs.s3d.texDescr.ni.texWidth = t->image[0].image->WidthLog2; - imesa->regs.s3d.texDescr.ni.texHeight = t->image[0].image->HeightLog2; - assert (t->image[0].internalFormat <= 7); - imesa->regs.s3d.texDescr.ni.texFmt = t->image[0].internalFormat; + imesa->regs.s3d.texDescr.ni.texWidth = image->WidthLog2; + imesa->regs.s3d.texDescr.ni.texHeight = image->HeightLog2; + assert (t->hwFormat <= 7); + imesa->regs.s3d.texDescr.ni.texFmt = t->hwFormat; - imesa->regs.s3d.texAddr.ui = (u_int32_t) t->texParams.hwPhysAddress| 2; - if(t->heap == SAVAGE_AGP_HEAP) + imesa->regs.s3d.texAddr.ui = (u_int32_t) t->setup.physAddr | 2; + if(t->base.heap->heapId == SAVAGE_AGP_HEAP) imesa->regs.s3d.texAddr.ui |= 0x1; } @@ -1500,9 +1290,9 @@ static void savageTexImage1D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - savageTextureObjectPtr t = (savageTextureObjectPtr) texObj->DriverData; + savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData; if (t) { - savageSwapOutTexObj( SAVAGE_CONTEXT(ctx), t ); + driSwapOutTextureObject( &t->base ); } else { t = savageAllocTexObj(texObj); if (!t) { @@ -1513,7 +1303,7 @@ static void savageTexImage1D( GLcontext *ctx, GLenum target, GLint level, _mesa_store_teximage1d( ctx, target, level, internalFormat, width, border, format, type, pixels, packing, texObj, texImage ); - t->dirty_images |= (1 << level); + t->base.dirty_images[0] |= (1 << level); SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE; } @@ -1528,10 +1318,10 @@ static void savageTexSubImage1D( GLcontext *ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - savageTextureObjectPtr t = (savageTextureObjectPtr) texObj->DriverData; + savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData; assert( t ); /* this _should_ be true */ if (t) { - savageSwapOutTexObj( SAVAGE_CONTEXT(ctx), t ); + driSwapOutTextureObject( &t->base ); } else { t = savageAllocTexObj(texObj); if (!t) { @@ -1542,7 +1332,7 @@ static void savageTexSubImage1D( GLcontext *ctx, _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, format, type, pixels, packing, texObj, texImage); - t->dirty_images |= (1 << level); + t->base.dirty_images[0] |= (1 << level); SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE; } @@ -1554,9 +1344,9 @@ static void savageTexImage2D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - savageTextureObjectPtr t = (savageTextureObjectPtr) texObj->DriverData; + savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData; if (t) { - savageSwapOutTexObj( SAVAGE_CONTEXT(ctx), t ); + driSwapOutTextureObject( &t->base ); } else { t = savageAllocTexObj(texObj); if (!t) { @@ -1567,7 +1357,7 @@ static void savageTexImage2D( GLcontext *ctx, GLenum target, GLint level, _mesa_store_teximage2d( ctx, target, level, internalFormat, width, height, border, format, type, pixels, packing, texObj, texImage ); - t->dirty_images |= (1 << level); + t->base.dirty_images[0] |= (1 << level); SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE; } @@ -1582,10 +1372,10 @@ static void savageTexSubImage2D( GLcontext *ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - savageTextureObjectPtr t = (savageTextureObjectPtr) texObj->DriverData; + savageTexObjPtr t = (savageTexObjPtr) texObj->DriverData; assert( t ); /* this _should_ be true */ if (t) { - savageSwapOutTexObj( SAVAGE_CONTEXT(ctx), t ); + driSwapOutTextureObject( &t->base ); } else { t = savageAllocTexObj(texObj); if (!t) { @@ -1596,7 +1386,7 @@ static void savageTexSubImage2D( GLcontext *ctx, _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, height, format, type, pixels, packing, texObj, texImage); - t->dirty_images |= (1 << level); + t->base.dirty_images[0] |= (1 << level); SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE; } @@ -1604,7 +1394,7 @@ static void savageTexParameter( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLenum pname, const GLfloat *params ) { - savageTextureObjectPtr t = (savageTextureObjectPtr) tObj->DriverData; + savageTexObjPtr t = (savageTexObjPtr) tObj->DriverData; savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); if (!t || (target != GL_TEXTURE_1D && target != GL_TEXTURE_2D)) @@ -1645,37 +1435,21 @@ static void savageBindTexture( GLcontext *ctx, GLenum target, static void savageDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) { - savageTextureObjectPtr t = (savageTextureObjectPtr)tObj->DriverData; + driTextureObject *t = (driTextureObject *)tObj->DriverData; savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); if (t) { - if (t->bound) { - imesa->CurrentTexObj[t->bound-1] = 0; - imesa->new_state |= SAVAGE_NEW_TEXTURE; + FLUSH_BATCH(imesa); } - savageDestroyTexObj(imesa,t); - tObj->DriverData=0; + driDestroyTextureObject(t); } /* Free mipmap images and the texture object itself */ _mesa_delete_texture_object(ctx, tObj); } -static GLboolean savageIsTextureResident( GLcontext *ctx, - struct gl_texture_object *t ) -{ - savageTextureObjectPtr mt; - -/* LOCK_HARDWARE; */ - mt = (savageTextureObjectPtr)t->DriverData; -/* UNLOCK_HARDWARE; */ - - return mt && mt->MemBlock; -} - - static struct gl_texture_object * savageNewTextureObject( GLcontext *ctx, GLuint name, GLenum target ) { @@ -1697,6 +1471,6 @@ void savageDDInitTextureFuncs( struct dd_function_table *functions ) functions->BindTexture = savageBindTexture; functions->NewTextureObject = savageNewTextureObject; functions->DeleteTexture = savageDeleteTexture; - functions->IsTextureResident = savageIsTextureResident; + functions->IsTextureResident = driIsTextureResident; functions->TexParameter = savageTexParameter; } diff --git a/src/mesa/drivers/dri/savage/savagetex.h b/src/mesa/drivers/dri/savage/savagetex.h index d26f625f4dd..a6732a3dce7 100644 --- a/src/mesa/drivers/dri/savage/savagetex.h +++ b/src/mesa/drivers/dri/savage/savagetex.h @@ -27,39 +27,11 @@ #define SAVAGETEX_INC #include "mtypes.h" -#include "mm.h" #include "savagecontext.h" -#include "savage_3d_reg.h" - -#define VALID_SAVAGE_TEXTURE_OBJECT(tobj) (tobj) +#include "texmem.h" #define SAVAGE_TEX_MAXLEVELS 11 -#define MIN_TILE_CHUNK 8 -#define MIPMAP_CHUNK 4 - - - -/* For shared texture space managment, these texture objects may also - * be used as proxies for regions of texture memory containing other - * client's textures. Such proxy textures (not to be confused with GL - * proxy textures) are subject to the same LRU aging we use for our - * own private textures, and thus we have a mechanism where we can - * fairly decide between kicking out our own textures and those of - * other clients. - * - * Non-local texture objects have a valid MemBlock to describe the - * region managed by the other client, and can be identified by - * 't->globj == 0' - */ -typedef struct { - GLuint sWrapMode; - GLuint tWrapMode; - GLuint minFilter; - GLuint magFilter; - GLuint boarderColor; - GLuint hwPhysAddress; -} savage_texture_parameter_t; /** \brief Texture tiling information */ typedef struct savage_tileinfo_t { @@ -69,36 +41,29 @@ typedef struct savage_tileinfo_t { GLuint tinyOffset[2]; /**< internal offsets size 1 and 2 images */ } savageTileInfo, *savageTileInfoPtr; -struct savage_texture_object_t { - struct savage_texture_object_t *next, *prev; - struct gl_texture_object *globj; - GLuint age; - - const savageTileInfo *tileInfo; - GLuint texelBytes; - GLuint totalSize; - GLuint bound; - GLuint heap; - - PMemBlock MemBlock; - char *BufAddr; - - GLuint min_level; - GLuint max_level; - GLuint dirty_images; - - struct { - const struct gl_texture_image *image; - GLuint offset; /* into BufAddr */ - GLuint height; - GLuint internalFormat; - } image[SAVAGE_TEX_MAXLEVELS]; - - /* Support for multitexture. - */ - GLuint current_unit; - savage_texture_parameter_t texParams; -}; +typedef struct { + GLuint offset; + GLuint *dirtyTiles; /* bit vector of dirty tiles (still unused) */ +} savageTexImage; + +typedef struct { + driTextureObject base; + + GLubyte *bufAddr; + + GLuint age; + savageTexImage image[SAVAGE_TEX_MAXLEVELS]; + + struct { + GLuint sWrapMode, tWrapMode; + GLuint minFilter, magFilter; + GLuint physAddr; + } setup; + + GLuint hwFormat; + GLuint texelBytes; + const savageTileInfo *tileInfo; +} savageTexObj, *savageTexObjPtr; #define SAVAGE_NO_PALETTE 0x0 #define SAVAGE_USE_PALETTE 0x1 @@ -111,15 +76,6 @@ struct savage_texture_object_t { void savageUpdateTextureState( GLcontext *ctx ); void savageDDInitTextureFuncs( struct dd_function_table *functions ); -void savageDestroyTexObj( savageContextPtr imesa, savageTextureObjectPtr t); -int savageUploadTexImages( savageContextPtr imesa, savageTextureObjectPtr t ); - -void savageResetGlobalLRU( savageContextPtr imesa , GLuint heap); -void savageTexturesGone( savageContextPtr imesa, GLuint heap, - GLuint start, GLuint end, - GLuint in_use ); - -void savagePrintLocalLRU( savageContextPtr imesa ,GLuint heap); -void savagePrintGlobalLRU( savageContextPtr imesa ,GLuint heap); +void savageDestroyTexObj( savageContextPtr imesa, driTextureObject *t ); #endif