diff options
Diffstat (limited to 'nx-X11/extras/Mesa/src/mesa/drivers/dri/mach64/mach64_texmem.c')
-rw-r--r-- | nx-X11/extras/Mesa/src/mesa/drivers/dri/mach64/mach64_texmem.c | 867 |
1 files changed, 0 insertions, 867 deletions
diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/mach64/mach64_texmem.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/mach64/mach64_texmem.c deleted file mode 100644 index f771818c8..000000000 --- a/nx-X11/extras/Mesa/src/mesa/drivers/dri/mach64/mach64_texmem.c +++ /dev/null @@ -1,867 +0,0 @@ -/* $XFree86$ */ /* -*- mode: c; c-basic-offset: 3 -*- */ -/* - * Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., - * Cedar Park, Texas. - * 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 - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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. - */ - -/* - * Authors: - * Gareth Hughes <gareth@valinux.com> - * Leif Delgass <ldelgass@retinalburn.net> - * Jose Fonseca <j_r_fonseca@yahoo.co.uk> - */ - -#include "mach64_context.h" -#include "mach64_state.h" -#include "mach64_ioctl.h" -#include "mach64_vb.h" -#include "mach64_tris.h" -#include "mach64_tex.h" - -#include "context.h" -#include "macros.h" -#include "simple_list.h" -#include "texformat.h" -#include "imports.h" - - -/* Destroy hardware state associated with texture `t'. - */ -void mach64DestroyTexObj( mach64ContextPtr mmesa, mach64TexObjPtr t ) -{ -#if ENABLE_PERF_BOXES - /* Bump the performace counter */ - if (mmesa) - mmesa->c_textureSwaps++; -#endif - if ( !t ) return; - -#if 0 - if ( t->tObj && t->memBlock && mmesa ) { - /* not a placeholder, so release from global LRU if necessary */ - int heap = t->heap; - drmTextureRegion *list = mmesa->sarea->tex_list[heap]; - int log2sz = mmesa->mach64Screen->logTexGranularity[heap]; - int start = t->memBlock->ofs >> log2sz; - int end = (t->memBlock->ofs + t->memBlock->size - 1) >> log2sz; - int i; - - mmesa->lastTexAge[heap] = ++mmesa->sarea->tex_age[heap]; - - /* Update the global LRU */ - for ( i = start ; i <= end ; i++ ) { - /* do we own this block? */ - if (list[i].in_use == mmesa->hHWContext) { - list[i].in_use = 0; - list[i].age = mmesa->lastTexAge[heap]; - - /* remove_from_list(i) */ - list[(GLuint)list[i].next].prev = list[i].prev; - list[(GLuint)list[i].prev].next = list[i].next; - } - } - } -#endif - - if ( t->memBlock ) { - mmFreeMem( t->memBlock ); - t->memBlock = NULL; - } - - if ( t->tObj ) { - t->tObj->DriverData = NULL; - } - - if ( t->bound && mmesa ) - mmesa->CurrentTexObj[t->bound-1] = NULL; - - remove_from_list( t ); - FREE( t ); -} - -/* Keep track of swapped out texture objects. - */ -void mach64SwapOutTexObj( mach64ContextPtr mmesa, - mach64TexObjPtr t ) -{ -#if ENABLE_PERF_BOXES - /* Bump the performace counter */ - if (mmesa) - mmesa->c_textureSwaps++; -#endif - -#if 0 - if ( t->tObj && t->memBlock && mmesa ) { - /* not a placeholder, so release from global LRU if necessary */ - int heap = t->heap; - drmTextureRegion *list = mmesa->sarea->tex_list[heap]; - int log2sz = mmesa->mach64Screen->logTexGranularity[heap]; - int start = t->memBlock->ofs >> log2sz; - int end = (t->memBlock->ofs + t->memBlock->size - 1) >> log2sz; - int i; - - mmesa->lastTexAge[heap] = ++mmesa->sarea->tex_age[heap]; - - /* Update the global LRU */ - for ( i = start ; i <= end ; i++ ) { - /* do we own this block? */ - if (list[i].in_use == mmesa->hHWContext) { - list[i].in_use = 0; - list[i].age = mmesa->lastTexAge[heap]; - - /* remove_from_list(i) */ - list[(GLuint)list[i].next].prev = list[i].prev; - list[(GLuint)list[i].prev].next = list[i].next; - } - } - } -#endif - - if ( t->memBlock ) { - mmFreeMem( t->memBlock ); - t->memBlock = NULL; - } - - t->dirty = ~0; - move_to_tail( &mmesa->SwappedOut, t ); -} - -/* Print out debugging information about texture LRU. - */ -void mach64PrintLocalLRU( mach64ContextPtr mmesa, int heap ) -{ - mach64TexObjPtr t; - int sz = 1 << (mmesa->mach64Screen->logTexGranularity[heap]); - - fprintf( stderr, "\nLocal LRU, heap %d:\n", heap ); - - foreach( t, &mmesa->TexObjList[heap] ) { - if ( !t->tObj ) { - fprintf( stderr, "Placeholder %d at 0x%x sz 0x%x\n", - t->memBlock->ofs / sz, - t->memBlock->ofs, - t->memBlock->size ); - } else { - fprintf( stderr, "Texture (bound %d) at 0x%x sz 0x%x\n", - t->bound, - t->memBlock->ofs, - t->memBlock->size ); - } - } - - fprintf( stderr, "\n" ); -} - -void mach64PrintGlobalLRU( mach64ContextPtr mmesa, int heap ) -{ - drm_tex_region_t *list = mmesa->sarea->tex_list[heap]; - int i, j; - - fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list ); - - for ( i = 0, j = MACH64_NR_TEX_REGIONS ; i < MACH64_NR_TEX_REGIONS ; i++ ) { - fprintf( stderr, "list[%d] age %d in_use %d next %d prev %d\n", - j, list[j].age, list[j].in_use, list[j].next, list[j].prev ); - j = list[j].next; - if ( j == MACH64_NR_TEX_REGIONS ) break; - } - - if ( j != MACH64_NR_TEX_REGIONS ) { - fprintf( stderr, "Loop detected in global LRU\n" ); - for ( i = 0 ; i < MACH64_NR_TEX_REGIONS ; i++ ) { - fprintf( stderr, "list[%d] age %d in_use %d next %d prev %d\n", - i, list[i].age, list[i].in_use, list[i].next, list[i].prev ); - } - } - - fprintf( stderr, "\n" ); -} - -/* Reset the global texture LRU. - */ -/* NOTE: This function is only called while holding the hardware lock */ -static void mach64ResetGlobalLRU( mach64ContextPtr mmesa, int heap ) -{ - drm_tex_region_t *list = mmesa->sarea->tex_list[heap]; - int sz = 1 << mmesa->mach64Screen->logTexGranularity[heap]; - int i; - - /* (Re)initialize the global circular LRU list. The last element in - * the array (MACH64_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 <= mmesa->mach64Screen->texSize[heap] ; i++ ) { - list[i].prev = i-1; - list[i].next = i+1; - list[i].age = 0; - list[i].in_use = 0; - } - - i--; - list[0].prev = MACH64_NR_TEX_REGIONS; - list[i].prev = i-1; - list[i].next = MACH64_NR_TEX_REGIONS; - list[MACH64_NR_TEX_REGIONS].prev = i; - list[MACH64_NR_TEX_REGIONS].next = 0; - mmesa->sarea->tex_age[heap] = 0; -} - -/* Update the local and global texture LRUs. - */ -/* NOTE: This function is only called while holding the hardware lock */ -void mach64UpdateTexLRU( mach64ContextPtr mmesa, - mach64TexObjPtr t ) -{ - int heap = t->heap; - drm_tex_region_t *list = mmesa->sarea->tex_list[heap]; - int log2sz = mmesa->mach64Screen->logTexGranularity[heap]; - int start = t->memBlock->ofs >> log2sz; - int end = (t->memBlock->ofs + t->memBlock->size - 1) >> log2sz; - int i; - - mmesa->lastTexAge[heap] = ++mmesa->sarea->tex_age[heap]; - - if ( !t->memBlock ) { - fprintf( stderr, "no memblock\n\n" ); - return; - } - - /* Update our local LRU */ - move_to_head( &mmesa->TexObjList[heap], t ); - - /* Update the global LRU */ - for ( i = start ; i <= end ; i++ ) { - list[i].in_use = mmesa->hHWContext; - list[i].age = mmesa->lastTexAge[heap]; - -#if 0 - /* if this is the last region, it's not in the list */ - if ( !(i*(1<<log2sz) > mmesa->mach64Screen->texSize[heap] ) ) { -#endif - /* remove_from_list(i) */ - list[(GLuint)list[i].next].prev = list[i].prev; - list[(GLuint)list[i].prev].next = list[i].next; -#if 0 - } -#endif - - /* insert_at_head(list, i) */ - list[i].prev = MACH64_NR_TEX_REGIONS; - list[i].next = list[MACH64_NR_TEX_REGIONS].next; - list[(GLuint)list[MACH64_NR_TEX_REGIONS].next].prev = i; - list[MACH64_NR_TEX_REGIONS].next = i; - } - - if ( MACH64_DEBUG & DEBUG_VERBOSE_LRU ) { - mach64PrintGlobalLRU( mmesa, t->heap ); - mach64PrintLocalLRU( mmesa, t->heap ); - } -} - -/* Update our notion of what textures have been changed since we last - * held the lock. This pertains to both our local textures and the - * textures belonging to other clients. Keep track of other client's - * textures by pushing a placeholder texture onto the LRU list -- these - * are denoted by (tObj == NULL). - */ -/* NOTE: This function is only called while holding the hardware lock */ -static void mach64TexturesGone( mach64ContextPtr mmesa, int heap, - int offset, int size, int in_use ) -{ - mach64TexObjPtr t, tmp; - - foreach_s ( t, tmp, &mmesa->TexObjList[heap] ) { - if ( t->memBlock->ofs >= offset + size || - t->memBlock->ofs + t->memBlock->size <= offset ) - continue; - - /* It overlaps - kick it out. Need to hold onto the currently - * bound objects, however. - */ - if ( t->bound ) { - mach64SwapOutTexObj( mmesa, t ); - } else { - mach64DestroyTexObj( mmesa, t ); - } - } - - if ( in_use > 0 && in_use != mmesa->hHWContext ) { - t = (mach64TexObjPtr) CALLOC( sizeof(*t) ); - if (!t) return; - - t->memBlock = mmAllocMem( mmesa->texHeap[heap], size, 0, offset ); - if ( !t->memBlock ) { - fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n", - (int)size, (int)offset ); - mmDumpMemInfo( mmesa->texHeap[heap] ); - return; - } - insert_at_head( &mmesa->TexObjList[heap], t ); - } -} - -/* Update our client's shared texture state. If another client has - * modified a region in which we have textures, then we need to figure - * out which of our textures has been removed, and update our global - * LRU. - */ -void mach64AgeTextures( mach64ContextPtr mmesa, int heap ) -{ - drm_mach64_sarea_t *sarea = mmesa->sarea; - - if ( sarea->tex_age[heap] != mmesa->lastTexAge[heap] ) { - int sz = 1 << mmesa->mach64Screen->logTexGranularity[heap]; - int nr = 0; - int idx; - - /* Have to go right round from the back to ensure stuff ends up - * LRU in our local list... Fix with a cursor pointer. - */ - for ( idx = sarea->tex_list[heap][MACH64_NR_TEX_REGIONS].prev ; - idx != MACH64_NR_TEX_REGIONS && nr < MACH64_NR_TEX_REGIONS ; - idx = sarea->tex_list[heap][idx].prev, nr++ ) - { - /* If switching texturing schemes, then the SAREA might not - * have been properly cleared, so we need to reset the - * global texture LRU. - */ - if ( idx * sz > mmesa->mach64Screen->texSize[heap] ) { - nr = MACH64_NR_TEX_REGIONS; - break; - } - - if ( sarea->tex_list[heap][idx].age > mmesa->lastTexAge[heap] ) { - mach64TexturesGone( mmesa, heap, idx * sz, sz, - sarea->tex_list[heap][idx].in_use ); - } - } - - /* If switching texturing schemes, then the SAREA might not - * have been properly cleared, so we need to reset the - * global texture LRU. - */ - if ( nr == MACH64_NR_TEX_REGIONS ) { - mach64TexturesGone( mmesa, heap, 0, - mmesa->mach64Screen->texSize[heap], 0 ); - mach64ResetGlobalLRU( mmesa, heap ); - } - - if ( 0 ) { - mach64PrintGlobalLRU( mmesa, heap ); - mach64PrintLocalLRU( mmesa, heap ); - } - - mmesa->dirty |= (MACH64_UPLOAD_CONTEXT | - MACH64_UPLOAD_TEX0IMAGE | - MACH64_UPLOAD_TEX1IMAGE); - mmesa->lastTexAge[heap] = sarea->tex_age[heap]; - } -} - -/* Upload the texture image associated with texture `t' at level `level' - * at the address relative to `start'. - */ -static void mach64UploadAGPSubImage( mach64ContextPtr mmesa, - mach64TexObjPtr t, int level, - int x, int y, int width, int height ) -{ - mach64ScreenRec *mach64Screen = mmesa->mach64Screen; - struct gl_texture_image *image; - int texelsPerDword = 0; - int dwords; - - /* Ensure we have a valid texture to upload */ - if ( ( level < 0 ) || ( level > mmesa->glCtx->Const.MaxTextureLevels ) ) - return; - - image = t->tObj->Image[0][level]; - if ( !image ) - return; - - switch ( image->TexFormat->TexelBytes ) { - case 1: texelsPerDword = 4; break; - case 2: texelsPerDword = 2; break; - case 4: texelsPerDword = 1; break; - } - -#if 1 - /* FIXME: The subimage index calcs are wrong... */ - x = 0; - y = 0; - width = image->Width; - height = image->Height; -#endif - - dwords = width * height / texelsPerDword; - -#if ENABLE_PERF_BOXES - /* Bump the performance counter */ - mmesa->c_agpTextureBytes += (dwords << 2); -#endif - - if ( MACH64_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "mach64UploadSubImage: %d,%d of %d,%d at %d,%d\n", - width, height, image->Width, image->Height, x, y ); - fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x dwords: %d\n", - (GLuint)t->offset, (GLint)width, dwords ); - mmDumpMemInfo( mmesa->texHeap[t->heap] ); - } - - assert(image->Data); - - { - CARD32 *dst = (CARD32 *)((char *)mach64Screen->agpTextures.map + t->memBlock->ofs); - const GLubyte *src = (const GLubyte *) image->Data + - (y * image->Width + x) * image->TexFormat->TexelBytes; - const GLuint bytes = width * height * image->TexFormat->TexelBytes; - memcpy(dst, src, bytes); - } - -} - -/* Upload the texture image associated with texture `t' at level `level' - * at the address relative to `start'. - */ -static void mach64UploadLocalSubImage( mach64ContextPtr mmesa, - mach64TexObjPtr t, int level, - int x, int y, int width, int height ) -{ - struct gl_texture_image *image; - int texelsPerDword = 0; - int imageWidth, imageHeight; - int remaining, rows; - int format, dwords; - const int maxdwords = (MACH64_BUFFER_MAX_DWORDS - (MACH64_HOSTDATA_BLIT_OFFSET / 4)); - CARD32 pitch, offset; - int i; - - /* Ensure we have a valid texture to upload */ - if ( ( level < 0 ) || ( level > mmesa->glCtx->Const.MaxTextureLevels ) ) - return; - - image = t->tObj->Image[0][level]; - if ( !image ) - return; - - switch ( image->TexFormat->TexelBytes ) { - case 1: texelsPerDword = 4; break; - case 2: texelsPerDword = 2; break; - case 4: texelsPerDword = 1; break; - } - -#if 1 - /* FIXME: The subimage index calcs are wrong... */ - x = 0; - y = 0; - width = image->Width; - height = image->Height; -#endif - - imageWidth = image->Width; - imageHeight = image->Height; - - format = t->textureFormat; - - /* The texel upload routines have a minimum width, so force the size - * if needed. - */ - if ( imageWidth < texelsPerDword ) { - int factor; - - factor = texelsPerDword / imageWidth; - imageWidth = texelsPerDword; - imageHeight /= factor; - if ( imageHeight == 0 ) { - /* In this case, the texel converter will actually walk a - * texel or two off the end of the image, but normal malloc - * alignment should prevent it from ever causing a fault. - */ - imageHeight = 1; - } - } - - /* We can't upload to a pitch less than 64 texels so we will need to - * linearly upload all modified rows for textures smaller than this. - * This makes the x/y/width/height different for the blitter and the - * texture walker. - */ - if ( imageWidth >= 64 ) { - /* The texture walker and the blitter look identical */ - pitch = imageWidth >> 3; - } else { - int factor; - int y2; - int start, end; - - start = (y * imageWidth) & ~63; - end = (y + height) * imageWidth; - - if ( end - start < 64 ) { - /* Handle the case where the total number of texels - * uploaded is < 64. - */ - x = 0; - y = start / 64; - width = end - start; - height = 1; - } else { - /* Upload some number of full 64 texel blit rows */ - factor = 64 / imageWidth; - - y2 = y + height - 1; - y /= factor; - y2 /= factor; - - x = 0; - width = 64; - height = y2 - y + 1; - } - - /* Fixed pitch of 64 */ - pitch = 8; - } - - dwords = width * height / texelsPerDword; - offset = t->offset; - -#if ENABLE_PERF_BOXES - /* Bump the performance counter */ - mmesa->c_textureBytes += (dwords << 2); -#endif - - if ( MACH64_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "mach64UploadSubImage: %d,%d of %d,%d at %d,%d\n", - width, height, image->Width, image->Height, x, y ); - fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x dwords: %d\n", - (GLuint)offset, (GLint)width, dwords ); - mmDumpMemInfo( mmesa->texHeap[t->heap] ); - } - - /* Subdivide the texture if required (account for the registers added by the drm) */ - if ( dwords <= maxdwords ) { - rows = height; - } else { - rows = (maxdwords * texelsPerDword) / (2 * width); - } - - for ( i = 0, remaining = height ; - remaining > 0 ; - remaining -= rows, y += rows, i++ ) - { - drmBufPtr buffer; - CARD32 *dst; - - height = MIN2(remaining, rows); - - /* Grab the dma buffer for the texture blit */ - buffer = mach64GetBufferLocked( mmesa ); - - dst = (CARD32 *)((char *)buffer->address + MACH64_HOSTDATA_BLIT_OFFSET); - - assert(image->Data); - - { - const GLubyte *src = (const GLubyte *) image->Data + - (y * image->Width + x) * image->TexFormat->TexelBytes; - const GLuint bytes = width * height * image->TexFormat->TexelBytes; - memcpy(dst, src, bytes); - } - - mach64FireBlitLocked( mmesa, buffer, offset, pitch, format, - x, y, width, height ); - - } - - mmesa->new_state |= MACH64_NEW_CONTEXT; - mmesa->dirty |= MACH64_UPLOAD_CONTEXT | MACH64_UPLOAD_MISC; -} - - -/* Upload the texture images associated with texture `t'. This might - * require removing our own and/or other client's texture objects to - * make room for these images. - */ -void mach64UploadTexImages( mach64ContextPtr mmesa, mach64TexObjPtr t ) -{ - GLint heap; - - if ( MACH64_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p, %p )\n", - __FUNCTION__, mmesa->glCtx, t ); - } - - assert(t); - assert(t->tObj); - - /* Choose the heap appropriately */ - heap = MACH64_CARD_HEAP; - - if ( !mmesa->mach64Screen->IsPCI && - t->size > mmesa->mach64Screen->texSize[heap] ) { - heap = MACH64_AGP_HEAP; - } - - /* Do we need to eject LRU texture objects? */ - if ( !t->memBlock ) { - t->heap = heap; - - /* Allocate a memory block on a 64-byte boundary */ - t->memBlock = mmAllocMem( mmesa->texHeap[heap], t->size, 6, 0 ); - - /* Try AGP before kicking anything out of local mem */ - if ( !mmesa->mach64Screen->IsPCI && !t->memBlock && heap == MACH64_CARD_HEAP ) { - t->memBlock = mmAllocMem( mmesa->texHeap[MACH64_AGP_HEAP], - t->size, 6, 0 ); - - if ( t->memBlock ) - heap = t->heap = MACH64_AGP_HEAP; - } - - /* Kick out textures until the requested texture fits */ - while ( !t->memBlock ) { - if ( mmesa->TexObjList[heap].prev->bound ) { - fprintf( stderr, - "mach64UploadTexImages: ran into bound texture\n" ); - return; - } - if ( mmesa->TexObjList[heap].prev == &mmesa->TexObjList[heap] ) { - if ( mmesa->mach64Screen->IsPCI ) { - fprintf( stderr, "%s: upload texture failure on " - "local texture heaps, sz=%d\n", __FUNCTION__, - t->size ); - return; - } else if ( heap == MACH64_CARD_HEAP ) { - heap = t->heap = MACH64_AGP_HEAP; - continue; - } else { - int i; - fprintf( stderr, "%s: upload texture failure on " - "%sAGP texture heaps, sz=%d\n", __FUNCTION__, - mmesa->firstTexHeap == MACH64_CARD_HEAP ? "both local and " : "", - t->size ); - for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) { - mach64PrintLocalLRU( mmesa, i ); - mmDumpMemInfo( mmesa->texHeap[i] ); - } - exit(-1); - return; - } - } - - mach64SwapOutTexObj( mmesa, mmesa->TexObjList[heap].prev ); - - t->memBlock = mmAllocMem( mmesa->texHeap[heap], t->size, 6, 0 ); - } - - /* Set the base offset of the texture image */ - t->offset = mmesa->mach64Screen->texOffset[heap] + t->memBlock->ofs; - - /* Force loading the new state into the hardware */ - mmesa->dirty |= (MACH64_UPLOAD_SCALE_3D_CNTL | - MACH64_UPLOAD_TEXTURE); - } - - /* Let the world know we've used this memory recently */ - mach64UpdateTexLRU( mmesa, t ); - - /* Upload any images that are new */ - if ( t->dirty ) { - if (t->heap == MACH64_AGP_HEAP) { - /* Need to make sure any vertex buffers in the queue complete */ - mach64WaitForIdleLocked( mmesa ); - mach64UploadAGPSubImage( mmesa, t, t->tObj->BaseLevel, 0, 0, - t->tObj->Image[0][t->tObj->BaseLevel]->Width, - t->tObj->Image[0][t->tObj->BaseLevel]->Height ); - } else { - mach64UploadLocalSubImage( mmesa, t, t->tObj->BaseLevel, 0, 0, - t->tObj->Image[0][t->tObj->BaseLevel]->Width, - t->tObj->Image[0][t->tObj->BaseLevel]->Height ); - } - - mmesa->setup.tex_cntl |= MACH64_TEX_CACHE_FLUSH; - } - - mmesa->dirty |= MACH64_UPLOAD_TEXTURE; - - t->dirty = 0; -} - -/* The mach64 needs to have both primary and secondary textures in either - * local or AGP memory, so we need a "buddy system" to make sure that allocation - * succeeds or fails for both textures. - * FIXME: This needs to be optimized better. - */ -void mach64UploadMultiTexImages( mach64ContextPtr mmesa, - mach64TexObjPtr t0, - mach64TexObjPtr t1 ) -{ - GLint heap; - - if ( MACH64_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p, %p %p )\n", - __FUNCTION__, mmesa->glCtx, t0, t1 ); - } - - assert(t0 && t1); - assert(t0->tObj && t1->tObj); - - /* Choose the heap appropriately */ - heap = MACH64_CARD_HEAP; - - if ( !mmesa->mach64Screen->IsPCI && - ((t0->size + t1->size) > mmesa->mach64Screen->texSize[heap]) ) { - heap = MACH64_AGP_HEAP; - } - - /* Do we need to eject LRU texture objects? */ - if ( !t0->memBlock || !t1->memBlock || t0->heap != t1->heap ) { - /* FIXME: starting from scratch for now to keep it simple */ - if ( t0->memBlock ) { - mach64SwapOutTexObj( mmesa, t0 ); - } - if ( t1->memBlock ) { - mach64SwapOutTexObj( mmesa, t1 ); - } - t0->heap = t1->heap = heap; - /* Allocate a memory block on a 64-byte boundary */ - t0->memBlock = mmAllocMem( mmesa->texHeap[heap], t0->size, 6, 0 ); - if ( t0->memBlock ) { - t1->memBlock = mmAllocMem( mmesa->texHeap[heap], t1->size, 6, 0 ); - if ( !t1->memBlock ) { - mmFreeMem( t0->memBlock ); - t0->memBlock = NULL; - } - } - /* Try AGP before kicking anything out of local mem */ - if ( (!t0->memBlock || !t1->memBlock) && heap == MACH64_CARD_HEAP ) { - t0->memBlock = mmAllocMem( mmesa->texHeap[MACH64_AGP_HEAP], t0->size, 6, 0 ); - if ( t0->memBlock ) { - t1->memBlock = mmAllocMem( mmesa->texHeap[MACH64_AGP_HEAP], t1->size, 6, 0 ); - if ( !t1->memBlock ) { - mmFreeMem( t0->memBlock ); - t0->memBlock = NULL; - } - } - - if ( t0->memBlock && t1->memBlock ) - heap = t0->heap = t1->heap = MACH64_AGP_HEAP; - } - - /* Kick out textures until the requested texture fits */ - while ( !t0->memBlock || !t1->memBlock ) { - if ( mmesa->TexObjList[heap].prev->bound ) { - fprintf( stderr, - "%s: ran into bound texture\n", __FUNCTION__ ); - return; - } - if ( mmesa->TexObjList[heap].prev == &mmesa->TexObjList[heap] ) { - if ( mmesa->mach64Screen->IsPCI ) { - fprintf( stderr, "%s: upload texture failure on local " - "texture heaps, tex0 sz=%d tex1 sz=%d\n", __FUNCTION__, - t0->size, t1->size ); - return; - } else if ( heap == MACH64_CARD_HEAP ) { - /* If only one allocation succeeded, start over again in AGP */ - if (t0->memBlock) { - mmFreeMem( t0->memBlock ); - t0->memBlock = NULL; - } - if (t1->memBlock) { - mmFreeMem( t1->memBlock ); - t1->memBlock = NULL; - } - heap = t0->heap = t1->heap = MACH64_AGP_HEAP; - continue; - } else { - int i; - fprintf( stderr, "%s: upload texture failure on %s" - "AGP texture heaps, tex0 sz=%d tex1 sz=%d\n", __FUNCTION__, - mmesa->firstTexHeap == MACH64_CARD_HEAP ? "both local and " : "", - t0->size, t1->size ); - for ( i = mmesa->firstTexHeap ; i < mmesa->lastTexHeap ; i++ ) { - mach64PrintLocalLRU( mmesa, i ); - mmDumpMemInfo( mmesa->texHeap[i] ); - } - exit(-1); - return; - } - } - - mach64SwapOutTexObj( mmesa, mmesa->TexObjList[heap].prev ); - - if (!t0->memBlock) - t0->memBlock = mmAllocMem( mmesa->texHeap[heap], t0->size, 6, 0 ); - if (!t1->memBlock) - t1->memBlock = mmAllocMem( mmesa->texHeap[heap], t1->size, 6, 0 ); - } - - /* Set the base offset of the texture image */ - t0->offset = mmesa->mach64Screen->texOffset[heap] + t0->memBlock->ofs; - t1->offset = mmesa->mach64Screen->texOffset[heap] + t1->memBlock->ofs; - - /* Force loading the new state into the hardware */ - mmesa->dirty |= (MACH64_UPLOAD_SCALE_3D_CNTL | - MACH64_UPLOAD_TEXTURE); - } - - /* Let the world know we've used this memory recently */ - mach64UpdateTexLRU( mmesa, t0 ); - mach64UpdateTexLRU( mmesa, t1 ); - - /* Upload any images that are new */ - if ( t0->dirty ) { - if (t0->heap == MACH64_AGP_HEAP) { - /* Need to make sure any vertex buffers in the queue complete */ - mach64WaitForIdleLocked( mmesa ); - mach64UploadAGPSubImage( mmesa, t0, t0->tObj->BaseLevel, 0, 0, - t0->tObj->Image[0][t0->tObj->BaseLevel]->Width, - t0->tObj->Image[0][t0->tObj->BaseLevel]->Height ); - } else { - mach64UploadLocalSubImage( mmesa, t0, t0->tObj->BaseLevel, 0, 0, - t0->tObj->Image[0][t0->tObj->BaseLevel]->Width, - t0->tObj->Image[0][t0->tObj->BaseLevel]->Height ); - } - mmesa->setup.tex_cntl |= MACH64_TEX_CACHE_FLUSH; - } - if ( t1->dirty ) { - if (t1->heap == MACH64_AGP_HEAP) { - /* Need to make sure any vertex buffers in the queue complete */ - mach64WaitForIdleLocked( mmesa ); - mach64UploadAGPSubImage( mmesa, t1, t1->tObj->BaseLevel, 0, 0, - t1->tObj->Image[0][t1->tObj->BaseLevel]->Width, - t1->tObj->Image[0][t1->tObj->BaseLevel]->Height ); - } else { - mach64UploadLocalSubImage( mmesa, t1, t1->tObj->BaseLevel, 0, 0, - t1->tObj->Image[0][t1->tObj->BaseLevel]->Width, - t1->tObj->Image[0][t1->tObj->BaseLevel]->Height ); - } - - mmesa->setup.tex_cntl |= MACH64_TEX_CACHE_FLUSH; - } - - mmesa->dirty |= MACH64_UPLOAD_TEXTURE; - - t0->dirty = 0; - t1->dirty = 0; -} |