diff options
Diffstat (limited to 'xc/lib/GL/mesa/src')
108 files changed, 8458 insertions, 7546 deletions
diff --git a/xc/lib/GL/mesa/src/drv/common/Imakefile b/xc/lib/GL/mesa/src/drv/common/Imakefile index 4f1c19b5f..91a3aed2b 100644 --- a/xc/lib/GL/mesa/src/drv/common/Imakefile +++ b/xc/lib/GL/mesa/src/drv/common/Imakefile @@ -1,5 +1,7 @@ XCOMM $XFree86: xc/lib/GL/mesa/src/drv/common/Imakefile,v 1.6 2001/04/03 02:29:34 dawes Exp $ +#include <Threads.tmpl> + #if GlxUseBuiltInDRIDriver #define DoNormalLib (NormalLibGlx || SharedLibGlxWithoutPIC) #define DoSharedLib (SharedLibGlx && !SharedLibGlxWithoutPIC) diff --git a/xc/lib/GL/mesa/src/drv/common/Imakefile.inc b/xc/lib/GL/mesa/src/drv/common/Imakefile.inc index 24b614c96..fbc751712 100644 --- a/xc/lib/GL/mesa/src/drv/common/Imakefile.inc +++ b/xc/lib/GL/mesa/src/drv/common/Imakefile.inc @@ -16,29 +16,58 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL #endif #if BuildXF86DRI - DRI_DEFINES = GlxDefines - DRI_INCLUDES = + DRI_DEFINES = GlxDefines -DX_BYTE_ORDER=ByteOrder + DRI_INCLUDES = -I$(GLXLIBSRC)/dri \ + -I$(GLXLIBSRC)/glx \ + -I$(INCLUDESRC) \ + -I$(INCLUDESRC)/GL \ + -I$(SERVERSRC)/GL/dri \ + -I$(XF86OSSRC) \ + -I$(XF86DRIVERSRC)/ati \ + -I$(XF86COMSRC) \ + -I$(GLXLIBSRC)/dri/drm \ + -I$(GLXLIBSRC)/include \ + -I$(XTOP)/include #endif -MESA_INCLUDES = -I$(MESADRVSRCDIR)/common +MESA_INCLUDES = -I$(MESASRCDIR)/src \ + -I$(MESADRVSRCDIR)/common X_INCLUDES = -I$(XINCLUDESRC) -I$(EXTINCSRC) COMMONSRCS = $(MESADRVCOMMONBUILDDIR)hwlog.c \ - $(MESADRVCOMMONBUILDDIR)mm.c + $(MESADRVCOMMONBUILDDIR)mm.c \ + $(MESADRVCOMMONBUILDDIR)utils.c \ + $(MESADRVCOMMONBUILDDIR)vblank.c \ + $(MESADRVCOMMONBUILDDIR)texmem.c COMMONOBJS = $(MESADRVCOMMONBUILDDIR)hwlog.o \ - $(MESADRVCOMMONBUILDDIR)mm.o + $(MESADRVCOMMONBUILDDIR)mm.o \ + $(MESADRVCOMMONBUILDDIR)utils.o \ + $(MESADRVCOMMONBUILDDIR)vblank.o \ + $(MESADRVCOMMONBUILDDIR)texmem.o COMMONUOBJS = $(MESADRVCOMMONBUILDDIR)unshared/hwlog.o \ - $(MESADRVCOMMONBUILDDIR)unshared/mm.o + $(MESADRVCOMMONBUILDDIR)unshared/mm.o \ + $(MESADRVCOMMONBUILDDIR)unshared/utils.o \ + $(MESADRVCOMMONBUILDDIR)unshared/vblank.o \ + $(MESADRVCOMMONBUILDDIR)unshared/texmem.o COMMONDOBJS = $(MESADRVCOMMONBUILDDIR)debugger/hwlog.o \ - $(MESADRVCOMMONBUILDDIR)debugger/mm.o + $(MESADRVCOMMONBUILDDIR)debugger/mm.o \ + $(MESADRVCOMMONBUILDDIR)debugger/utils.o \ + $(MESADRVCOMMONBUILDDIR)debugger/vblank.o \ + $(MESADRVCOMMONBUILDDIR)debugger/texmem.o COMMONPOBJS = $(MESADRVCOMMONBUILDDIR)profiled/hwlog.o \ - $(MESADRVCOMMONBUILDDIR)profiled/mm.o + $(MESADRVCOMMONBUILDDIR)profiled/mm.o \ + $(MESADRVCOMMONBUILDDIR)profiled/utils.o \ + $(MESADRVCOMMONBUILDDIR)profiled/vblank.o \ + $(MESADRVCOMMONBUILDDIR)profiled/texmem.o #ifdef NeedToLinkMesaSrc LinkSourceFile(hwlog.c, $(MESADRVSRCDIR)/common) LinkSourceFile(mm.c, $(MESADRVSRCDIR)/common) +LinkSourceFile(texmem.c, $(MESADRVSRCDIR)/common) +LinkSourceFile(utils.c, $(MESADRVSRCDIR)/common) +LinkSourceFile(vblank.c, $(MESADRVSRCDIR)/common) #endif diff --git a/xc/lib/GL/mesa/src/drv/common/texmem.c b/xc/lib/GL/mesa/src/drv/common/texmem.c new file mode 100644 index 000000000..4c652ed4a --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/common/texmem.c @@ -0,0 +1,1157 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * (c) Copyright IBM Corporation 2002 + * 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 + * VA LINUX SYSTEM, IBM 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: + * Ian Romanick <idr@us.ibm.com> + * Keith Whitwell <keithw@tungstengraphics.com> + * Kevin E. Martin <kem@users.sourceforge.net> + * Gareth Hughes <gareth@nvidia.com> + */ +/* $XFree86:$ */ + +/** \file texmem.c + * Implements all of the device-independent texture memory management. + * + * Currently, only a simple LRU texture memory management policy is + * implemented. In the (hopefully very near) future, better policies will be + * implemented. The idea is that the DRI should be able to run in one of two + * modes. In the default mode the DRI will dynamically attempt to discover + * the best texture management policy for the running application. In the + * other mode, the user (via some sort of as yet TBD mechanism) will select + * a texture management policy that is known to work well with the + * application. + */ + +#include "texmem.h" +#include "simple_list.h" +#include "imports.h" + +#include <assert.h> + + + +static unsigned dummy_swap_counter; + + +/** + * Calculate \f$\log_2\f$ of a value. This is a particularly poor + * implementation of this function. However, since system performance is in + * no way dependent on this function, the slowness of the implementation is + * irrelevent. + * + * \param n Value whose \f$\log_2\f$ is to be calculated + */ + +static unsigned +driLog2( unsigned n ) +{ + unsigned log2; + + + for ( log2 = 1 ; n > 1 ; log2++ ) { + n >>= 1; + } + + return log2; +} + + + + +/** + * Determine if a texture is resident in textureable memory. Depending on + * the driver, this may or may not be on-card memory. It could be AGP memory + * or anyother type of memory from which the hardware can directly read + * texels. + * + * This function is intended to be used as the \c IsTextureResident function + * in the device's \c dd_function_table. + * + * \param ctx GL context pointer (currently unused) + * \param texObj Texture object to be tested + */ + +GLboolean +driIsTextureResident( GLcontext * ctx, + struct gl_texture_object * texObj ) +{ + driTextureObject * t; + + + t = (driTextureObject *) texObj->DriverData; + return( (t != NULL) && (t->memBlock != NULL) ); +} + + + + +/** + * (Re)initialize the global circular LRU list. The last element + * in the array (\a heap->nrRegions) is the sentinal. Keeping it + * at the end of the array allows the other elements of the array + * to be addressed rationally when looking up objects at a particular + * location in texture memory. + * + * \param heap Texture heap to be reset + */ + +static void resetGlobalLRU( driTexHeap * heap ) +{ + drmTextureRegionPtr list = heap->global_regions; + unsigned sz = 1U << heap->logGranularity; + unsigned i; + + for (i = 0 ; (i+1) * sz <= heap->size ; i++) { + list[i].prev = i-1; + list[i].next = i+1; + list[i].age = 0; + } + + i--; + list[0].prev = heap->nrRegions; + list[i].prev = i-1; + list[i].next = heap->nrRegions; + list[heap->nrRegions].prev = i; + list[heap->nrRegions].next = 0; + heap->global_age[0] = 0; +} + +/** + * Print out debugging information about the local texture LRU. + * + * \param heap Texture heap to be printed + */ +static void printLocalLRU( driTexHeap * heap, const char *callername ) +{ + driTextureObject *t; + unsigned sz = 1U << heap->logGranularity; + + fprintf( stderr, "%s in %s:\nLocal LRU, heap %d:\n", + __FUNCTION__, callername, heap->heapId ); + + foreach ( t, &heap->texture_objects ) { + if (!t->memBlock) + continue; + if (!t->tObj) { + fprintf( stderr, "Placeholder (%p) %d at 0x%x sz 0x%x\n", + t, + t->memBlock->ofs / sz, + t->memBlock->ofs, + t->memBlock->size ); + } else { + fprintf( stderr, "Texture (%p) at 0x%x sz 0x%x\n", + t, + t->memBlock->ofs, + t->memBlock->size ); + } + } + foreach ( t, heap->swapped_objects ) { + if (!t->tObj) { + fprintf( stderr, "Swapped Placeholder (%p)\n", t ); + } else { + fprintf( stderr, "Swapped Texture (%p)\n", t ); + } + } + + fprintf( stderr, "\n" ); +} + +/** + * Print out debugging information about the global texture LRU. + * + * \param heap Texture heap to be printed + */ +static void printGlobalLRU( driTexHeap * heap, const char *callername ) +{ + drmTextureRegionPtr list = heap->global_regions; + int i, j; + + fprintf( stderr, "%s in %s:\nGlobal LRU, heap %d list %p:\n", + __FUNCTION__, callername, heap->heapId, list ); + + for ( i = 0, j = heap->nrRegions ; i < heap->nrRegions ; i++ ) { + fprintf( stderr, "list[%d] age %d next %d prev %d in_use %d\n", + j, list[j].age, list[j].next, list[j].prev, list[j].in_use ); + j = list[j].next; + if ( j == heap->nrRegions ) break; + } + + if ( j != heap->nrRegions ) { + fprintf( stderr, "Loop detected in global LRU\n" ); + for ( i = 0 ; i < heap->nrRegions ; i++ ) { + fprintf( stderr, "list[%d] age %d next %d prev %d in_use %d\n", + i, list[i].age, list[i].next, list[i].prev, list[i].in_use ); + } + } + + fprintf( stderr, "\n" ); +} + + +/** + * Called by the client whenever it touches a local texture. + * + * \param t Texture object that the client has accessed + */ + +void driUpdateTextureLRU( driTextureObject * t ) +{ + driTexHeap * heap; + drmTextureRegionPtr list; + unsigned shift; + unsigned start; + unsigned end; + unsigned i; + + + heap = t->heap; + if ( heap != NULL ) { + shift = heap->logGranularity; + start = t->memBlock->ofs >> shift; + end = (t->memBlock->ofs + t->memBlock->size - 1) >> shift; + + + heap->local_age = ++heap->global_age[0]; + list = heap->global_regions; + + + /* Update the context's local LRU + */ + + move_to_head( & heap->texture_objects, t ); + + + for (i = start ; i <= end ; i++) { + list[i].in_use = 1; + list[i].age = heap->local_age; + + /* 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 = heap->nrRegions; + list[i].next = list[heap->nrRegions].next; + list[(unsigned)list[heap->nrRegions].next].prev = i; + list[heap->nrRegions].next = i; + } + + if ( 0 ) { + printGlobalLRU( heap, __FUNCTION__ ); + printLocalLRU( heap, __FUNCTION__ ); + } + } +} + + + + +/** + * Keep track of swapped out texture objects. + * + * \param t Texture object to be "swapped" out of its texture heap + */ + +void driSwapOutTextureObject( driTextureObject * t ) +{ + unsigned face; + + + if ( t->memBlock != NULL ) { + assert( t->heap != NULL ); + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + + t->heap->texture_swaps[0]++; + move_to_tail( t->heap->swapped_objects, t ); + t->heap = NULL; + } + else { + assert( t->heap == NULL ); + } + + + for ( face = 0 ; face < 6 ; face++ ) { + t->dirty_images[face] = ~0; + } +} + + + + +/** + * Destroy hardware state associated with texture \a t. Calls the + * \a destroy_texture_object method associated with the heap from which + * \a t was allocated. + * + * \param t Texture object to be destroyed + */ + +void driDestroyTextureObject( driTextureObject * t ) +{ + driTexHeap * heap; + + + if ( 0 ) { + fprintf( stderr, "[%s:%d] freeing %p (tObj = %p, DriverData = %p)\n", + __FILE__, __LINE__, + t, + (t != NULL) ? t->tObj : NULL, + (t != NULL && t->tObj != NULL) ? t->tObj->DriverData : NULL ); + } + + if ( t != NULL ) { + if ( t->memBlock ) { + heap = t->heap; + assert( heap != NULL ); + + heap->texture_swaps[0]++; + + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + + heap->destroy_texture_object( heap->driverContext, t ); + t->heap = NULL; + } + + if ( t->tObj != NULL ) { + assert( t->tObj->DriverData == t ); + t->tObj->DriverData = NULL; + } + + remove_from_list( t ); + FREE( t ); + } + + if ( 0 ) { + fprintf( stderr, "[%s:%d] done freeing %p\n", __FILE__, __LINE__, t ); + } +} + + + + +/** + * Update the local heap's representation of texture memory based on + * data in the SAREA. This is done each time it is detected that some other + * direct rendering client has 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 \a tObj being \a NULL. + * + * \param heap Heap whose state is to be updated + * \param offset Byte offset in the heap that has been stolen + * \param size Size, in bytes, of the stolen block + * \param in_use Non-zero if the block is in-use by another context + */ + +static void driTexturesGone( driTexHeap * heap, int offset, int size, + int in_use ) +{ + driTextureObject * t; + driTextureObject * tmp; + + + foreach_s ( t, tmp, & heap->texture_objects ) { + if ( (t->memBlock->ofs < (offset + size)) + && ((t->memBlock->ofs + t->memBlock->size) > offset) ) { + /* It overlaps - kick it out. If the texture object is just a + * place holder, then destroy it all together. Otherwise, mark + * it as being swapped out. + */ + + if ( t->tObj != NULL ) { + driSwapOutTextureObject( t ); + } + else { + if ( in_use && + offset == t->memBlock->ofs && size == t->memBlock->size ) { + /* Matching placeholder already exists */ + return; + } else { + driDestroyTextureObject( t ); + } + } + } + } + + + if ( in_use ) { + t = (driTextureObject *) CALLOC( heap->texture_object_size ); + if ( t == NULL ) return; + + t->memBlock = mmAllocMem( heap->memory_heap, size, 0, offset ); + if ( t->memBlock == NULL ) { + fprintf( stderr, "Couldn't alloc placeholder: heap %u sz %x ofs %x\n", heap->heapId, + (int)size, (int)offset ); + mmDumpMemInfo( heap->memory_heap ); + return; + } + t->heap = heap; + insert_at_head( & heap->texture_objects, t ); + } +} + + + + +/** + * Called by the client on lock contention to determine whether textures have + * been stolen. If another client has modified a region in which we have + * textures, then we need to figure out which of our textures have been + * removed and update our global LRU. + * + * \param heap Texture heap to be updated + */ + +void driAgeTextures( driTexHeap * heap ) +{ + drmTextureRegionPtr list = heap->global_regions; + unsigned sz = 1U << (heap->logGranularity); + unsigned i, nr = 0; + + + /* Have to go right round from the back to ensure stuff ends up + * LRU in the local list... Fix with a cursor pointer. + */ + + for (i = list[heap->nrRegions].prev ; + i != heap->nrRegions && nr < heap->nrRegions ; + i = list[i].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 ( (i * sz) > heap->size ) { + nr = heap->nrRegions; + break; + } + + if (list[i].age > heap->local_age) + driTexturesGone( heap, i * sz, sz, list[i].in_use); + } + + /* Loop or uninitialized heap detected. Reset. + */ + + if (nr == heap->nrRegions) { + driTexturesGone( heap, 0, heap->size, 0); + resetGlobalLRU( heap ); + } + + if ( 0 ) { + printGlobalLRU( heap, __FUNCTION__ ); + printLocalLRU( heap, __FUNCTION__ ); + } + + heap->local_age = heap->global_age[0]; +} + + + + +/** + * Allocate memory from a texture heap to hold a texture object. This + * routine will attempt to allocate memory for the texture from the heaps + * specified by \c heap_array in order. That is, first it will try to + * allocate from \c heap_array[0], then \c heap_array[1], and so on. + * + * \param heap_array Array of pointers to texture heaps to use + * \param nr_heaps Number of heap pointer in \a heap_array + * \param t Texture object for which space is needed + * \return The ID of the heap from which memory was allocated, or -1 if + * memory could not be allocated. + * + * \bug The replacement policy implemented by this function is horrible. + */ + +int +driAllocateTexture( driTexHeap * const * heap_array, unsigned nr_heaps, + driTextureObject * t ) +{ + driTexHeap * heap; + driTextureObject * temp; + unsigned id; + + + /* In case it already has texture space, initialize heap. This also + * prevents GCC from issuing a warning that heap might be used + * uninitialized. + */ + + heap = t->heap; + + + /* Run through each of the existing heaps and try to allocate a buffer + * to hold the texture. + */ + + for ( id = 0 ; (t->memBlock == NULL) && (id < nr_heaps) ; id++ ) { + heap = heap_array[ id ]; + if ( heap != NULL ) { + t->memBlock = mmAllocMem( heap->memory_heap, t->totalSize, + heap->alignmentShift, 0 ); + } + } + + + /* Kick textures out until the requested texture fits. + */ + + if ( t->memBlock == NULL ) { + for ( id = 0 ; (t->memBlock == NULL) && (id < nr_heaps) ; id++ ) { + heap = heap_array[ id ]; + if ( t->totalSize <= heap->size ) { + while ( (t->memBlock == NULL) + && ! is_empty_list( & heap->texture_objects ) ) { + /* The the LRU element. If the texture is bound to one of + * the texture units, then we cannot kick it out. + */ + + temp = last_elem( & heap->texture_objects ); + if ( temp->bound != 0 ) { + break; + } + + /* If this is a placeholder, there's no need to keep it */ + if (temp->tObj) + driSwapOutTextureObject( temp ); + else + driDestroyTextureObject( temp ); + + t->memBlock = mmAllocMem( heap->memory_heap, t->totalSize, + heap->alignmentShift, 0 ); + } + } /* if ( t->totalSize <= heap->size ) ... */ + } + } + + + if ( t->memBlock != NULL ) { + /* id and heap->heapId may or may not be the same value here. + */ + + assert( heap != NULL ); + assert( (t->heap == NULL) || (t->heap == heap) ); + + t->heap = heap; + return heap->heapId; + } + else { + assert( t->heap == NULL ); + + fprintf( stderr, "[%s:%d] unable to allocate texture\n", + __FUNCTION__, __LINE__ ); + return -1; + } +} + + + + +/** + * Set the location where the texture-swap counter is stored. + */ + +void +driSetTextureSwapCounterLocation( driTexHeap * heap, unsigned * counter ) +{ + heap->texture_swaps = (counter == NULL) ? & dummy_swap_counter : counter; +} + + + + +/** + * Create a new heap for texture data. + * + * \param heap_id Device-dependent heap identifier. This value + * will returned by driAllocateTexture when memory + * is allocated from this heap. + * \param context Device-dependent driver context. This is + * supplied as the first parameter to the + * \c destroy_tex_obj function. + * \param size Size, in bytes, of the texture region + * \param alignmentShift Alignment requirement for textures. If textures + * must be allocated on a 4096 byte boundry, this + * would be 12. + * \param nr_regions Number of regions into which this texture space + * should be partitioned + * \param global_regions Array of \c drmTextureRegion structures in the SAREA + * \param global_age Pointer to the global texture age in the SAREA + * \param swapped_objects Pointer to the list of texture objects that are + * not in texture memory (i.e., have been swapped + * out). + * \param texture_object_size Size, in bytes, of a device-dependent texture + * object + * \param destroy_tex_obj Function used to destroy a device-dependent + * texture object + * + * \sa driDestroyTextureHeap + */ + +driTexHeap * +driCreateTextureHeap( unsigned heap_id, void * context, unsigned size, + unsigned alignmentShift, unsigned nr_regions, + drmTextureRegionPtr global_regions, unsigned * global_age, + driTextureObject * swapped_objects, + unsigned texture_object_size, + destroy_texture_object_t * destroy_tex_obj + ) +{ + driTexHeap * heap; + unsigned l; + + + if ( 0 ) + fprintf( stderr, "%s( %u, %p, %u, %u, %u )\n", + __FUNCTION__, + heap_id, context, size, alignmentShift, nr_regions ); + + heap = (driTexHeap *) CALLOC( sizeof( driTexHeap ) ); + if ( heap != NULL ) { + l = driLog2( (size - 1) / nr_regions ); + if ( l < alignmentShift ) + { + l = alignmentShift; + } + + heap->logGranularity = l; + heap->size = size & ~((1L << l) - 1); + + heap->memory_heap = mmInit( 0, heap->size ); + if ( heap->memory_heap != NULL ) { + heap->heapId = heap_id; + heap->driverContext = context; + + heap->alignmentShift = alignmentShift; + heap->nrRegions = nr_regions; + heap->global_regions = global_regions; + heap->global_age = global_age; + heap->swapped_objects = swapped_objects; + heap->texture_object_size = texture_object_size; + heap->destroy_texture_object = destroy_tex_obj; + + /* Force global heap init */ + if (heap->global_age == 0) + heap->local_age = ~0; + else + heap->local_age = 0; + + make_empty_list( & heap->texture_objects ); + driSetTextureSwapCounterLocation( heap, NULL ); + } + else { + FREE( heap ); + heap = NULL; + } + } + + + if ( 0 ) + fprintf( stderr, "%s returning %p\n", __FUNCTION__, heap ); + + return heap; +} + + + + +/** Destroys a texture heap + * + * \param heap Texture heap to be destroyed + */ + +void +driDestroyTextureHeap( driTexHeap * heap ) +{ + driTextureObject * t; + driTextureObject * temp; + + + if ( heap != NULL ) { + foreach_s( t, temp, & heap->texture_objects ) { + driDestroyTextureObject( t ); + } + foreach_s( t, temp, heap->swapped_objects ) { + driDestroyTextureObject( t ); + } + + mmDestroy( heap->memory_heap ); + FREE( heap ); + } +} + + + + +/****************************************************************************/ +/** + * Determine how many texels (including all mipmap levels) would be required + * for a texture map of size \f$2^^\c base_size_log2\f$ would require. + * + * \param base_size_log2 \f$log_2\f$ of the size of a side of the texture + * \param dimensions Number of dimensions of the texture. Either 2 or 3. + * \param faces Number of faces of the texture. Either 1 or 6 (for cube maps). + * \returns Number of texels + */ + +static unsigned +texels_this_map_size( int base_size_log2, unsigned dimensions, unsigned faces ) +{ + unsigned texels; + + + assert( (faces == 1) || (faces == 6) ); + assert( (dimensions == 2) || (dimensions == 3) ); + + texels = 0; + if ( base_size_log2 >= 0 ) { + texels = (1U << (dimensions * base_size_log2)); + + /* See http://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg03636.html + * for the complete explaination of why this formulation is used. + * Basically, the smaller mipmap levels sum to 0.333 the size of the + * level 0 map. The total size is therefore the size of the map + * multipled by 1.333. The +2 is there to round up. + */ + + texels = (texels * 4 * faces + 2) / 3; + } + + return texels; +} + + + + +struct maps_per_heap { + unsigned c[32]; +}; + +static void +fill_in_maximums( driTexHeap * const * heaps, unsigned nr_heaps, + unsigned max_bytes_per_texel, unsigned max_size, + unsigned mipmaps_at_once, unsigned dimensions, + unsigned faces, struct maps_per_heap * max_textures ) +{ + unsigned heap; + unsigned log2_size; + unsigned mask; + + + /* Determine how many textures of each size can be stored in each + * texture heap. + */ + + for ( heap = 0 ; heap < nr_heaps ; heap++ ) { + if ( heaps[ heap ] == NULL ) { + (void) memset( max_textures[ heap ].c, 0, + sizeof( max_textures[ heap ].c ) ); + continue; + } + + mask = (1U << heaps[ heap ]->logGranularity) - 1; + + if ( 0 ) { + fprintf( stderr, "[%s:%d] heap[%u] = %u bytes, mask = 0x%08x\n", + __FILE__, __LINE__, + heap, heaps[ heap ]->size, mask ); + } + + for ( log2_size = max_size ; log2_size > 0 ; log2_size-- ) { + unsigned total; + + + /* Determine the total number of bytes required by a texture of + * size log2_size. + */ + + total = texels_this_map_size( log2_size, dimensions, faces ) + - texels_this_map_size( log2_size - mipmaps_at_once, + dimensions, faces ); + total *= max_bytes_per_texel; + total = (total + mask) & ~mask; + + /* The number of textures of a given size that will fit in a heap + * is equal to the size of the heap divided by the size of the + * texture. + */ + + max_textures[ heap ].c[ log2_size ] = heaps[ heap ]->size / total; + + if ( 0 ) { + fprintf( stderr, "[%s:%d] max_textures[%u].c[%02u] " + "= 0x%08x / 0x%08x " + "= %u (%u)\n", + __FILE__, __LINE__, + heap, log2_size, + heaps[ heap ]->size, total, + heaps[ heap ]->size / total, + max_textures[ heap ].c[ log2_size ] ); + } + } + } +} + + +static unsigned +get_max_size( unsigned nr_heaps, + unsigned texture_units, + unsigned max_size, + int all_textures_one_heap, + struct maps_per_heap * max_textures ) +{ + unsigned heap; + unsigned log2_size; + + + /* Determine the largest texture size such that a texture of that size + * can be bound to each texture unit at the same time. Some hardware + * may require that all textures be in the same texture heap for + * multitexturing. + */ + + for ( log2_size = max_size ; log2_size > 0 ; log2_size-- ) { + unsigned total = 0; + + for ( heap = 0 ; heap < nr_heaps ; heap++ ) + { + total += max_textures[ heap ].c[ log2_size ]; + + if ( 0 ) { + fprintf( stderr, "[%s:%d] max_textures[%u].c[%02u] = %u, " + "total = %u\n", __FILE__, __LINE__, heap, log2_size, + max_textures[ heap ].c[ log2_size ], total ); + } + + if ( (max_textures[ heap ].c[ log2_size ] >= texture_units) + || (!all_textures_one_heap && (total >= texture_units)) ) { + /* The number of mipmap levels is the log-base-2 of the + * maximum texture size plus 1. If the maximum texture size + * is 1x1, the log-base-2 is 0 and 1 mipmap level (the base + * level) is available. + */ + + return log2_size + 1; + } + } + } + + /* This should NEVER happen. It should always be possible to have at + * *least* a 1x1 texture in memory! + */ + assert( log2_size != 0 ); + return 0; +} + +#define SET_MAX(f,v) \ + do { if ( max_sizes[v] != 0 ) { limits-> f = max_sizes[v]; } } while( 0 ) + +#define SET_MAX_RECT(f,v) \ + do { if ( max_sizes[v] != 0 ) { limits-> f = 1 << max_sizes[v]; } } while( 0 ) + + +/** + * Given the amount of texture memory, the number of texture units, and the + * maximum size of a texel, calculate the maximum texture size the driver can + * adverteise. + * + * \param heaps Texture heaps for this card + * \param nr_heap Number of texture heaps + * \param limits OpenGL contants. MaxTextureUnits must be set. + * \param max_bytes_per_texel Maximum size of a single texel, in bytes + * \param max_2D_size \f$\log_2\f$ of the maximum 2D texture size (i.e., + * 1024x1024 textures, this would be 10) + * \param max_3D_size \f$\log_2\f$ of the maximum 3D texture size (i.e., + * 1024x1024x1024 textures, this would be 10) + * \param max_cube_size \f$\log_2\f$ of the maximum cube texture size (i.e., + * 1024x1024 textures, this would be 10) + * \param max_rect_size \f$\log_2\f$ of the maximum texture rectangle size + * (i.e., 1024x1024 textures, this would be 10). This is a power-of-2 + * even though texture rectangles need not be a power-of-2. + * \param mipmaps_at_once Total number of mipmaps that can be used + * at one time. For most hardware this will be \f$\c max_size + 1\f$. + * For hardware that does not support mipmapping, this will be 1. + * \param all_textures_one_heap True if the hardware requires that all + * textures be in a single texture heap for multitexturing. + */ + +void +driCalculateMaxTextureLevels( driTexHeap * const * heaps, + unsigned nr_heaps, + struct gl_constants * limits, + unsigned max_bytes_per_texel, + unsigned max_2D_size, + unsigned max_3D_size, + unsigned max_cube_size, + unsigned max_rect_size, + unsigned mipmaps_at_once, + int all_textures_one_heap ) +{ + struct maps_per_heap max_textures[8]; + unsigned i; + const unsigned dimensions[4] = { 2, 3, 2, 2 }; + const unsigned faces[4] = { 1, 1, 6, 1 }; + unsigned max_sizes[4]; + unsigned mipmaps[4]; + + + max_sizes[0] = max_2D_size; + max_sizes[1] = max_3D_size; + max_sizes[2] = max_cube_size; + max_sizes[3] = max_rect_size; + + mipmaps[0] = mipmaps_at_once; + mipmaps[1] = mipmaps_at_once; + mipmaps[2] = 1; + mipmaps[3] = mipmaps_at_once; + + + /* Calculate the maximum number of texture levels in two passes. The + * first pass determines how many textures of each power-of-two size + * (including all mipmap levels for that size) can fit in each texture + * heap. The second pass finds the largest texture size that allows + * a texture of that size to be bound to every texture unit. + */ + + for ( i = 0 ; i < 4 ; i++ ) { + if ( max_sizes[ i ] != 0 ) { + fill_in_maximums( heaps, nr_heaps, max_bytes_per_texel, + max_sizes[ i ], mipmaps[ i ], + dimensions[ i ], faces[ i ], + max_textures ); + + max_sizes[ i ] = get_max_size( nr_heaps, + limits->MaxTextureUnits, + max_sizes[ i ], + all_textures_one_heap, + max_textures ); + } + } + + SET_MAX( MaxTextureLevels, 0 ); + SET_MAX( Max3DTextureLevels, 1 ); + SET_MAX( MaxCubeTextureLevels, 2 ); + SET_MAX_RECT( MaxTextureRectSize, 3 ); +} + + + + +/** + * Perform initial binding of default textures objects on a per unit, per + * texture target basis. + * + * \param ctx Current OpenGL context + * \param swapped List of swapped-out textures + * \param targets Bit-mask of value texture targets + */ + +void driInitTextureObjects( GLcontext *ctx, driTextureObject * swapped, + GLuint targets ) +{ + struct gl_texture_object *texObj; + GLuint tmp = ctx->Texture.CurrentUnit; + unsigned i; + + + for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { + ctx->Texture.CurrentUnit = i; + + if ( (targets & DRI_TEXMGR_DO_TEXTURE_1D) != 0 ) { + texObj = ctx->Texture.Unit[i].Current1D; + ctx->Driver.BindTexture( ctx, GL_TEXTURE_1D, texObj ); + move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); + } + + if ( (targets & DRI_TEXMGR_DO_TEXTURE_2D) != 0 ) { + texObj = ctx->Texture.Unit[i].Current2D; + ctx->Driver.BindTexture( ctx, GL_TEXTURE_2D, texObj ); + move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); + } + + if ( (targets & DRI_TEXMGR_DO_TEXTURE_3D) != 0 ) { + texObj = ctx->Texture.Unit[i].Current3D; + ctx->Driver.BindTexture( ctx, GL_TEXTURE_3D, texObj ); + move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); + } + + if ( (targets & DRI_TEXMGR_DO_TEXTURE_CUBE) != 0 ) { + texObj = ctx->Texture.Unit[i].CurrentCubeMap; + ctx->Driver.BindTexture( ctx, GL_TEXTURE_CUBE_MAP_ARB, texObj ); + move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); + } + + if ( (targets & DRI_TEXMGR_DO_TEXTURE_RECT) != 0 ) { + texObj = ctx->Texture.Unit[i].CurrentRect; + ctx->Driver.BindTexture( ctx, GL_TEXTURE_RECTANGLE_NV, texObj ); + move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); + } + } + + ctx->Texture.CurrentUnit = tmp; +} + + + + +/** + * Verify that the specified texture is in the specificed heap. + * + * \param tex Texture to be tested. + * \param heap Texture memory heap to be tested. + * \returns True if the texture is in the heap, false otherwise. + */ + +static GLboolean +check_in_heap( const driTextureObject * tex, const driTexHeap * heap ) +{ +#if 1 + return tex->heap == heap; +#else + driTextureObject * curr; + + foreach( curr, & heap->texture_objects ) { + if ( curr == tex ) { + break; + } + } + + return curr == tex; +#endif +} + + + +/****************************************************************************/ +/** + * Validate the consistency of a set of texture heaps. + * Original version by Keith Whitwell in r200/r200_sanity.c. + */ + +GLboolean +driValidateTextureHeaps( driTexHeap * const * texture_heaps, + unsigned nr_heaps, const driTextureObject * swapped ) +{ + driTextureObject *t; + unsigned i; + + for ( i = 0 ; i < nr_heaps ; i++ ) { + int last_end = 0; + unsigned textures_in_heap = 0; + unsigned blocks_in_mempool = 0; + const driTexHeap * heap = texture_heaps[i]; + const memHeap_t * p = heap->memory_heap; + + /* Check each texture object has a MemBlock, and is linked into + * the correct heap. + * + * Check the texobj base address corresponds to the MemBlock + * range. Check the texobj size (recalculate???) fits within + * the MemBlock. + * + * Count the number of texobj's using this heap. + */ + + foreach ( t, &heap->texture_objects ) { + if ( !check_in_heap( t, heap ) ) { + fprintf( stderr, "%s memory block for texture object @ %p not " + "found in heap #%d\n", + __FUNCTION__, t, i ); + return GL_FALSE; + } + + + if ( t->totalSize > t->memBlock->size ) { + fprintf( stderr, "%s: Memory block for texture object @ %p is " + "only %u bytes, but %u are required\n", + __FUNCTION__, t, t->totalSize, t->memBlock->size ); + return GL_FALSE; + } + + textures_in_heap++; + } + + /* Validate the contents of the heap: + * - Ordering + * - Overlaps + * - Bounds + */ + + while ( p != NULL ) { + if (p->reserved) { + fprintf( stderr, "%s: Block (%08x,%x), is reserved?!\n", + __FUNCTION__, p->ofs, p->size ); + return GL_FALSE; + } + + if (p->ofs != last_end) { + fprintf( stderr, "%s: blocks_in_mempool = %d, last_end = %d, p->ofs = %d\n", + __FUNCTION__, blocks_in_mempool, last_end, p->ofs ); + return GL_FALSE; + } + + if (!p->reserved && !p->free) { + blocks_in_mempool++; + } + + last_end = p->ofs + p->size; + p = p->next; + } + + if (textures_in_heap != blocks_in_mempool) { + fprintf( stderr, "%s: Different number of textures objects (%u) and " + "inuse memory blocks (%u)\n", + __FUNCTION__, textures_in_heap, blocks_in_mempool ); + return GL_FALSE; + } + +#if 0 + fprintf( stderr, "%s: textures_in_heap = %u\n", + __FUNCTION__, textures_in_heap ); +#endif + } + + + /* Check swapped texobj's have zero memblocks + */ + i = 0; + foreach ( t, swapped ) { + if ( t->memBlock != NULL ) { + fprintf( stderr, "%s: Swapped texobj %p has non-NULL memblock %p\n", + __FUNCTION__, t, t->memBlock ); + return GL_FALSE; + } + i++; + } + +#if 0 + fprintf( stderr, "%s: swapped texture count = %u\n", i ); +#endif + + return GL_TRUE; +} diff --git a/xc/lib/GL/mesa/src/drv/common/texmem.h b/xc/lib/GL/mesa/src/drv/common/texmem.h new file mode 100644 index 000000000..e4d944a0b --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/common/texmem.h @@ -0,0 +1,265 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * (c) Copyright IBM Corporation 2002 + * 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 + * VA LINUX SYSTEM, IBM 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: + * Ian Romanick <idr@us.ibm.com> + * Keith Whitwell <keithw@tungstengraphics.com> + * Kevin E. Martin <kem@users.sourceforge.net> + * Gareth Hughes <gareth@nvidia.com> + */ +/* $XFree86:$ */ + +/** \file texmem.h + * Public interface to the DRI texture memory management routines. + * + * \sa texmem.c + */ + +#ifndef DRI_TEXMEM_H +#define DRI_TEXMEM_H + +#include "mtypes.h" +#include "mm.h" +#include "xf86drm.h" + +struct dri_tex_heap; +typedef struct dri_tex_heap driTexHeap; + +struct dri_texture_object; +typedef struct dri_texture_object driTextureObject; + + +/** + * Base texture object type. Each driver will extend this type with its own + * private data members. + */ + +struct dri_texture_object { + struct dri_texture_object * next; + struct dri_texture_object * prev; + + driTexHeap * heap; /**< Texture heap currently stored in */ + struct gl_texture_object * tObj;/**< Pointer to Mesa texture object + * If NULL, this texture object is a + * "placeholder" object representing + * texture memory in use by another context. + * A placeholder should have a heap and a memBlock. + */ + PMemBlock memBlock; /**< Memory block containing texture */ + unsigned bound; /**< Texture unit currently bound to */ + + unsigned totalSize; /**< Total size of the texture, + * including all mipmap levels + */ + + unsigned dirty_images[6]; /**< Flags for whether or not images + * need to be uploaded to local or + * AGP texture space. One flag set + * for each cube face for cubic + * textures. + */ +}; + + +typedef void (destroy_texture_object_t)( void * driverContext, + driTextureObject * t ); + +/** + * Client-private representation of texture memory state. + * + * Clients will place one or more of these structs in their driver + * context struct to manage one or more global texture heaps. + */ + +struct dri_tex_heap { + + /** Client-supplied heap identifier + */ + unsigned heapId; + + /** Pointer to the client's private context + */ + void *driverContext; + + /** Total size of the heap, in bytes + */ + unsigned size; + + /** \brief \f$log_2\f$ of size of single heap region + * + * Each context takes memory from the global texture heap in + * \f$2^{logGranularity}\f$ byte blocks. The value of + * \a logGranularity is based on the amount of memory represented + * by the heap and the maximum number of regions in the SAREA. Given + * \a b bytes of texture memory an \a n regions in the SAREA, + * \a logGranularity will be \f$\lfloor\log_2( b / n )\rfloor\f$. + */ + unsigned logGranularity; + + /** \brief Required alignment of allocations in this heap + * + * The alignment shift is supplied to \a mmAllocMem when memory is + * allocated from this heap. The value of \a alignmentShift will + * typically reflect some require of the hardware. This value has + * \b no \b relation to \a logGranularity. \a alignmentShift is a + * per-context value. + * + * \sa mmAllocMem + */ + unsigned alignmentShift; + + /** Number of elements in global list (the SAREA). + */ + unsigned nrRegions; + + /** Pointer to SAREA \a driTexRegion array + */ + drmTextureRegionPtr global_regions; + + /** Pointer to the texture state age (generation number) in the SAREA + */ + unsigned * global_age; + + /** Local age (generation number) of texture state + */ + unsigned local_age; + + /** Memory heap used to manage texture memory represented by + * this texture heap. + */ + memHeap_t * memory_heap; + + /** List of objects that we currently believe to be in texture + * memory. + */ + driTextureObject texture_objects; + + /** Pointer to the list of texture objects that are not in + * texture memory. + */ + driTextureObject * swapped_objects; + + /** Size of the driver-speicific texture object. + */ + unsigned texture_object_size; + + + /** + * \brief Function to destroy driver-specific texture object data. + * + * This function is supplied by the driver so that the texture manager + * can release all resources associated with a texture object. This + * function should only release driver-specific data. That is, + * \a driDestroyTextureObject will release the texture memory + * associated with the texture object, it will release the memory + * for the texture object itself, and it will unlink the texture + * object from the texture object lists. + * + * \param driverContext Pointer to the driver supplied context + * \param t Texture object that is to be destroyed + * \sa driDestroyTextureObject + */ + + destroy_texture_object_t * destroy_texture_object; + + + /** + */ + unsigned * texture_swaps; +}; + + + + +/** + * Called by the client on lock contention to determine whether textures have + * been stolen. If another client has modified a region in which we have + * textures, then we need to figure out which of our textures have been + * removed and update our global LRU. + * + * \param heap Texture heap to be updated + * \hideinitializer + */ + +#define DRI_AGE_TEXTURES( heap ) \ + do { \ + if ( ((heap) != NULL) \ + && ((heap)->local_age != (heap)->global_age[0]) ) \ + driAgeTextures( heap ); \ + } while( 0 ) + + + + +/* This should be called whenever there has been contention on the hardware + * lock. driAgeTextures should not be called directly. Instead, clients + * should use DRI_AGE_TEXTURES, above. + */ + +void driAgeTextures( driTexHeap * heap ); + +void driUpdateTextureLRU( driTextureObject * t ); +void driSwapOutTextureObject( driTextureObject * t ); +void driDestroyTextureObject( driTextureObject * t ); +int driAllocateTexture( driTexHeap * const * heap_array, unsigned nr_heaps, + driTextureObject * t ); + +GLboolean driIsTextureResident( GLcontext * ctx, + struct gl_texture_object * texObj ); + +driTexHeap * driCreateTextureHeap( unsigned heap_id, void * context, + unsigned size, unsigned alignmentShift, unsigned nr_regions, + drmTextureRegionPtr global_regions, unsigned * global_age, + driTextureObject * swapped_objects, unsigned texture_object_size, + destroy_texture_object_t * destroy_tex_obj ); +void driDestroyTextureHeap( driTexHeap * heap ); + +void +driCalculateMaxTextureLevels( driTexHeap * const * heaps, + unsigned nr_heaps, + struct gl_constants * limits, + unsigned max_bytes_per_texel, + unsigned max_2D_size, + unsigned max_3D_size, + unsigned max_cube_size, + unsigned max_rect_size, + unsigned mipmaps_at_once, + int all_textures_one_heap ); + +void +driSetTextureSwapCounterLocation( driTexHeap * heap, unsigned * counter ); + +#define DRI_TEXMGR_DO_TEXTURE_1D 0x0001 +#define DRI_TEXMGR_DO_TEXTURE_2D 0x0002 +#define DRI_TEXMGR_DO_TEXTURE_3D 0x0004 +#define DRI_TEXMGR_DO_TEXTURE_CUBE 0x0008 +#define DRI_TEXMGR_DO_TEXTURE_RECT 0x0010 + +void driInitTextureObjects( GLcontext *ctx, driTextureObject * swapped, + GLuint targets ); + +GLboolean driValidateTextureHeaps( driTexHeap * const * texture_heaps, + unsigned nr_heaps, const driTextureObject * swapped ); + +#endif /* DRI_TEXMEM_H */ diff --git a/xc/lib/GL/mesa/src/drv/common/utils.c b/xc/lib/GL/mesa/src/drv/common/utils.c new file mode 100644 index 000000000..c94192a88 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/common/utils.c @@ -0,0 +1,173 @@ +/* + * (c) Copyright IBM Corporation 2002 + * 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 + * VA LINUX SYSTEM, IBM 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: + * Ian Romanick <idr@us.ibm.com> + */ +/* $XFree86:$ */ + +#include <string.h> +#include <stdlib.h> +#include "mtypes.h" +#include "extensions.h" +#include "utils.h" + +unsigned +driParseDebugString( const char * debug, + const struct dri_debug_control * control ) +{ + unsigned flag; + + + flag = 0; + if ( debug != NULL ) { + while( control->string != NULL ) { + if ( strstr( debug, control->string ) != NULL ) { + flag |= control->flag; + } + + control++; + } + } + + return flag; +} + + + + +unsigned +driGetRendererString( char * buffer, const char * hardware_name, + const char * driver_date, GLuint agp_mode ) +{ +#ifdef USE_X86_ASM + char * x86_str = ""; + char * mmx_str = ""; + char * tdnow_str = ""; + char * sse_str = ""; +#endif + unsigned offset; + + + offset = sprintf( buffer, "Mesa DRI %s %s", hardware_name, driver_date ); + + /* Append any AGP-specific information. + */ + switch ( agp_mode ) { + case 1: + case 2: + case 4: + case 8: + offset += sprintf( & buffer[ offset ], " AGP %ux", agp_mode ); + break; + + default: + break; + } + + /* Append any CPU-specific information. + */ +#ifdef USE_X86_ASM + if ( _mesa_x86_cpu_features ) { + x86_str = " x86"; + } +# ifdef USE_MMX_ASM + if ( cpu_has_mmx ) { + mmx_str = (cpu_has_mmxext) ? "/MMX+" : "/MMX"; + } +# endif +# ifdef USE_3DNOW_ASM + if ( cpu_has_3dnow ) { + tdnow_str = (cpu_has_3dnowext) ? "/3DNow!+" : "/3DNow!"; + } +# endif +# ifdef USE_SSE_ASM + if ( cpu_has_xmm ) { + sse_str = (cpu_has_xmm2) ? "/SSE2" : "/SSE"; + } +# endif + + offset += sprintf( & buffer[ offset ], "%s%s%s%s", + x86_str, mmx_str, tdnow_str, sse_str ); +#endif + + return offset; +} + + + + +void driInitExtensions( GLcontext * ctx, + const char * const extensions_to_enable[], + GLboolean enable_imaging ) +{ + unsigned i; + + if ( enable_imaging ) { + _mesa_enable_imaging_extensions( ctx ); + } + + for ( i = 0 ; extensions_to_enable[i] != NULL ; i++ ) { + _mesa_enable_extension( ctx, extensions_to_enable[i] ); + } +} + + + + +GLboolean +driCheckDriDdxDrmVersions(__DRIscreenPrivate *sPriv, + const char * driver_name, + int dri_major, int dri_minor, + int ddx_major, int ddx_minor, + int drm_major, int drm_minor) +{ + static const char format[] = "%s DRI driver expected %s version %d.%d.x " + "but got version %d.%d.%d"; + int major, minor, patch; + + /* Check the DRI version */ + if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { + if (major != dri_major || minor < dri_minor) { + __driUtilMessage(format, "DRI", driver_name, dri_major, dri_minor, + major, minor, patch); + return GL_FALSE; + } + } + + /* Check that the DDX driver version is compatible */ + if (sPriv->ddxMajor != ddx_major || sPriv->ddxMinor < ddx_minor) { + __driUtilMessage(format, "DDX", driver_name, ddx_major, ddx_minor, + sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch); + return GL_FALSE; + } + + /* Check that the DRM driver version is compatible */ + if (sPriv->drmMajor != drm_major || sPriv->drmMinor < drm_minor) { + __driUtilMessage(format, "DRM", driver_name, drm_major, drm_minor, + sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); + return GL_FALSE; + } + + return GL_TRUE; +} diff --git a/xc/lib/GL/mesa/src/drv/common/utils.h b/xc/lib/GL/mesa/src/drv/common/utils.h new file mode 100644 index 000000000..d6506c5b8 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/common/utils.h @@ -0,0 +1,54 @@ +/* + * (c) Copyright IBM Corporation 2002 + * 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 + * VA LINUX SYSTEM, IBM 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: + * Ian Romanick <idr@us.ibm.com> + */ +/* $XFree86:$ */ + +#ifndef DRI_DEBUG_H +#define DRI_DEBUG_H + +#include "context.h" +#include "dri_util.h" + +struct dri_debug_control +{ + const char * string; + unsigned flag; +}; + +extern unsigned driParseDebugString( const char * debug, + const struct dri_debug_control * control ); + +extern unsigned driGetRendererString( char * buffer, + const char * hardware_name, const char * driver_date, GLuint agp_mode ); + +extern void driInitExtensions( GLcontext * ctx, + const char * const card_extensions[], GLboolean enable_imaging ); + +extern GLboolean driCheckDriDdxDrmVersions( __DRIscreenPrivate *sPriv, + const char * driver_name, int dri_major, int dri_minor, + int ddx_major, int ddx_minor, int drm_major, int drm_minor ); + +#endif /* DRI_DEBUG_H */ diff --git a/xc/lib/GL/mesa/src/drv/common/vblank.c b/xc/lib/GL/mesa/src/drv/common/vblank.c new file mode 100644 index 000000000..09a7c43b7 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/common/vblank.c @@ -0,0 +1,265 @@ +/* + * (c) Copyright IBM Corporation 2002 + * 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 + * VA LINUX SYSTEM, IBM 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: + * Ian Romanick <idr@us.ibm.com> + */ +/* $XFree86:$ */ + +#include "glheader.h" +#include "xf86drm.h" +#include "mtypes.h" +#include "macros.h" +#include "dd.h" +#include "vblank.h" + +/****************************************************************************/ +/** + * Wait for a specified refresh count. This implements most of the + * functionality of \c glXWaitForMscOML from the GLX_OML_sync_control spec. + * Waits for the \c target_msc refresh. If that has already passed, it + * waits until \f$(MSC \bmod divisor)\f$ is equal to \c remainder. + * + * This function is actually something of a hack. The problem is that, at + * the time of this writing, none of the existing DRM modules support an + * ioctl that returns a 64-bit count (at least not on 32-bit platforms). + * However, this function exists to support a GLX function that requires + * the use of 64-bit counts. As such, there is a little bit of ugly + * hackery at the end of this function to make the 32-bit count act like + * a 64-bit count. There are still some cases where this will break, but + * I believe it catches the most common cases. + * + * The real solution is to provide an ioctl that uses a 64-bit count. + * + * \param dpy Pointer to the \c Display. + * \param priv Pointer to the DRI drawable private. + * \param target_msc Desired refresh count to wait for. + * \param divisor MSC divisor if \c target_msc is already reached. + * \param remainder Desired MSC remainder if \c target_msc is already + * reached. + * \param msc Buffer to hold MSC when done waiting. + * + * \returns Zero on success or \c GLX_BAD_CONTEXT on failure. + */ + +int driWaitForMSC32( __DRIdrawablePrivate *priv, + int64_t target_msc, int64_t divisor, int64_t remainder, + int64_t * msc ) +{ + drmVBlank vbl; + + + if ( divisor != 0 ) { + int next = target_msc; + int target = (int) target_msc; + int r; + + + do { + vbl.request.type = DRM_VBLANK_ABSOLUTE; + vbl.request.sequence = next; + + if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) { + /* FIXME: This doesn't seem like the right thing to return here. + */ + return GLX_BAD_CONTEXT; + } + + /* Assuming the wait-done test fails, the next refresh to wait for + * will be one that satisfies (MSC % divisor) == remainder. The + * value (MSC - (MSC % divisor) + remainder) is the previous refresh + * that would satisfy the equation. Adding divisor gives the value + * of the next refresh that will satisfy it. + */ + + r = (vbl.reply.sequence % divisor); + next = (vbl.reply.sequence - r) + (divisor + remainder); + + } while ( (vbl.reply.sequence != target) && (r != remainder) ); + } + else { + /* If the \c divisor is zero, just wait until the MSC is greater + * than or equal to \c target_msc. + */ + + vbl.request.type = DRM_VBLANK_ABSOLUTE; + vbl.request.sequence = target_msc; + + if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) { + /* FIXME: This doesn't seem like the right thing to return here. + */ + return GLX_BAD_CONTEXT; + } + } + + *msc = (target_msc & 0xffffffff00000000LL); + *msc |= vbl.reply.sequence; + if ( *msc < target_msc ) { + *msc += 0x0000000100000000LL; + } + + return 0; +} + + +/****************************************************************************/ +/** + * Gets a set of default vertical-blank-wait flags based on the internal GLX + * API version and several environment variables. + */ + +GLuint driGetDefaultVBlankFlags( void ) +{ + GLuint flags = 0; + + + flags |= (driCompareGLXAPIVersion( 20030317 ) >= 0) + ? VBLANK_FLAG_INTERVAL : 0; + flags |= (getenv("LIBGL_SYNC_REFRESH") != NULL) + ? VBLANK_FLAG_SYNC : 0; + flags |= (getenv("LIBGL_THROTTLE_REFRESH") != NULL) + ? VBLANK_FLAG_THROTTLE : 0; + + return flags; +} + + +/****************************************************************************/ +/** + * Wrapper to call \c drmWaitVBlank. The main purpose of this function is to + * wrap the error message logging. The error message should only be logged + * the first time the \c drmWaitVBlank fails. If \c drmWaitVBlank is + * successful, \c vbl_seq will be set the sequence value in the reply. + * + * \param vbl Pointer to drmVBlank packet desribing how to wait. + * \param vbl_seq Location to store the current refresh counter. + * \param fd File descriptor use to call into the DRM. + * \returns Zero on success or -1 on failure. + */ + +static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd ) +{ + int ret; + + + ret = drmWaitVBlank( fd, vbl ); + if ( ret != 0 ) { + static GLboolean first_time = GL_TRUE; + + if ( first_time ) { + fprintf(stderr, + "%s: drmWaitVBlank returned %d, IRQs don't seem to be" + " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH" + " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret); + first_time = GL_FALSE; + } + + return -1; + } + + *vbl_seq = vbl->reply.sequence; + return 0; +} + + +/****************************************************************************/ +/** + * Waits for the vertical blank for use with glXSwapBuffers. + * + * \param vbl_seq Vertical blank sequence number (MSC) after the last buffer + * swap. Updated after this wait. + * \param flags \c VBLANK_FLAG bits that control how long to wait. + * \param missed_deadline Set to \c GL_TRUE if the MSC after waiting is later + * than the "target" based on \c flags. The idea is that if + * \c missed_deadline is set, then the application is not + * achieving its desired framerate. + * \returns Zero on success, -1 on error. + */ + +int +driWaitForVBlank( GLuint * vbl_seq, GLuint flags, + GLboolean * missed_deadline ) +{ + drmVBlank vbl; + __GLXcontext *gc = __glXGetCurrentContext(); + __DRIcontextPrivate *priv = gc->driContext.private; + unsigned original_seq; + unsigned deadline; + unsigned interval; + + + *missed_deadline = GL_FALSE; + if ( (flags & VBLANK_FLAG_NO_IRQ) != 0 ) { + return 0; + } + + + /* VBLANK_FLAG_SYNC means to wait for at least one vertical blank. If + * that flag is not set, do a fake wait for zero vertical blanking + * periods so that we can get the current MSC. + * + * VBLANK_FLAG_INTERVAL and VBLANK_FLAG_THROTTLE mean to wait for at + * least one vertical blank since the last wait. Since do_wait modifies + * vbl_seq, we have to save the original value of vbl_seq for the + * VBLANK_FLAG_INTERVAL / VBLANK_FLAG_THROTTLE calculation later. + */ + + original_seq = *vbl_seq; + + vbl.request.sequence = ((flags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0; + vbl.request.type = DRM_VBLANK_RELATIVE; + + if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) { + return -1; + } + + + vbl.request.type = DRM_VBLANK_ABSOLUTE; + + if ( (flags & VBLANK_FLAG_INTERVAL) != 0 ) { + interval = gc->driContext.swap_interval; + } + else if ( (flags & VBLANK_FLAG_THROTTLE) != 0 ) { + interval = 1; + } + else { + interval = 0; + } + + + /* Wait until the next vertical blank. If the interval is zero, then + * the deadline is one vertical blank after the previous wait. + */ + + vbl.request.sequence = original_seq + interval; + if ( *vbl_seq < vbl.request.sequence ) { + if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) { + return -1; + } + } + + deadline = original_seq + ((interval == 0) ? 1 : interval); + *missed_deadline = ( *vbl_seq > deadline ); + + return 0; +} diff --git a/xc/lib/GL/mesa/src/drv/common/vblank.h b/xc/lib/GL/mesa/src/drv/common/vblank.h new file mode 100644 index 000000000..91c5d98ab --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/common/vblank.h @@ -0,0 +1,60 @@ +/* + * (c) Copyright IBM Corporation 2002 + * 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 + * VA LINUX SYSTEM, IBM 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: + * Ian Romanick <idr@us.ibm.com> + */ +/* $XFree86:$ */ + +#ifndef DRI_VBLANK_H +#define DRI_VBLANK_H + +#include "context.h" +#include "dri_util.h" + +#define VBLANK_FLAG_INTERVAL (1U << 0) /* Respect the swap_interval setting + */ +#define VBLANK_FLAG_THROTTLE (1U << 1) /* Wait 1 refresh since last call. + */ +#define VBLANK_FLAG_SYNC (1U << 2) /* Sync to the next refresh. + */ +#define VBLANK_FLAG_NO_IRQ (1U << 7) /* DRM has no IRQ to wait on. + */ + +extern int driWaitForMSC32( __DRIdrawablePrivate *priv, + int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc ); +extern GLuint driGetDefaultVBlankFlags( void ); +extern int driWaitForVBlank( GLuint * vbl_seq, GLuint flags, + GLboolean * missed_deadline ); + +#undef usleep +#include <unistd.h> /* for usleep() */ + +#define DO_USLEEP(nr) \ + do { \ + if (0) fprintf(stderr, "%s: usleep for %u\n", __FUNCTION__, nr ); \ + if (1) usleep( nr ); \ + sched_yield(); \ + } while( 0 ) + +#endif /* DRI_VBLANK_H */ diff --git a/xc/lib/GL/mesa/src/drv/mga/Imakefile.inc b/xc/lib/GL/mesa/src/drv/mga/Imakefile.inc index b43895ba7..1b8fd453e 100644 --- a/xc/lib/GL/mesa/src/drv/mga/Imakefile.inc +++ b/xc/lib/GL/mesa/src/drv/mga/Imakefile.inc @@ -34,78 +34,72 @@ MESA_INCLUDES = -I$(MESASRCDIR)/src \ -I$(MESADRVSRCDIR)/mga X_INCLUDES = -I$(XINCLUDESRC) -I$(EXTINCSRC) - MGASRCS = $(MESADRVMGABUILDDIR)mgabuffers.c \ - $(MESADRVMGABUILDDIR)mgadd.c \ + MGASRCS = $(MESADRVMGABUILDDIR)mgadd.c \ $(MESADRVMGABUILDDIR)mgarender.c \ $(MESADRVMGABUILDDIR)mgaioctl.c \ $(MESADRVMGABUILDDIR)mgapixel.c \ $(MESADRVMGABUILDDIR)mgaspan.c \ $(MESADRVMGABUILDDIR)mgastate.c \ $(MESADRVMGABUILDDIR)mgatex.c \ - $(MESADRVMGABUILDDIR)mgatexcnv.c \ $(MESADRVMGABUILDDIR)mgatexmem.c \ + $(MESADRVMGABUILDDIR)mga_texstate.c \ $(MESADRVMGABUILDDIR)mgatris.c \ $(MESADRVMGABUILDDIR)mgavb.c \ $(MESADRVMGABUILDDIR)mga_xmesa.c \ - MGAOBJS = $(MESADRVMGABUILDDIR)mgabuffers.o \ - $(MESADRVMGABUILDDIR)mgadd.o \ + MGAOBJS = $(MESADRVMGABUILDDIR)mgadd.o \ $(MESADRVMGABUILDDIR)mgarender.o \ $(MESADRVMGABUILDDIR)mgaioctl.o \ $(MESADRVMGABUILDDIR)mgapixel.o \ $(MESADRVMGABUILDDIR)mgaspan.o \ $(MESADRVMGABUILDDIR)mgastate.o \ $(MESADRVMGABUILDDIR)mgatex.o \ - $(MESADRVMGABUILDDIR)mgatexcnv.o \ $(MESADRVMGABUILDDIR)mgatexmem.o \ + $(MESADRVMGABUILDDIR)mga_texstate.o \ $(MESADRVMGABUILDDIR)mgatris.o \ $(MESADRVMGABUILDDIR)mgavb.o \ $(MESADRVMGABUILDDIR)mga_xmesa.o - MGAUOBJS = $(MESADRVMGABUILDDIR)unshared/mgabuffers.o \ - $(MESADRVMGABUILDDIR)unshared/mgadd.o \ + MGAUOBJS = $(MESADRVMGABUILDDIR)unshared/mgadd.o \ $(MESADRVMGABUILDDIR)unshared/mgarender.o \ $(MESADRVMGABUILDDIR)unshared/mgaioctl.o \ $(MESADRVMGABUILDDIR)unshared/mgapixel.o \ $(MESADRVMGABUILDDIR)unshared/mgaspan.o \ $(MESADRVMGABUILDDIR)unshared/mgastate.o \ $(MESADRVMGABUILDDIR)unshared/mgatex.o \ - $(MESADRVMGABUILDDIR)unshared/mgatexcnv.o \ $(MESADRVMGABUILDDIR)unshared/mgatexmem.o \ + $(MESADRVMGABUILDDIR)unshared/mga_texstate.o \ $(MESADRVMGABUILDDIR)unshared/mgatris.o \ $(MESADRVMGABUILDDIR)unshared/mgavb.o \ $(MESADRVMGABUILDDIR)unshared/mga_xmesa.o - MGADOBJS = $(MESADRVMGABUILDDIR)debugger/mgabuffers.o \ - $(MESADRVMGABUILDDIR)debugger/mgadd.o \ + MGADOBJS = $(MESADRVMGABUILDDIR)debugger/mgadd.o \ $(MESADRVMGABUILDDIR)debugger/mgarender.o \ $(MESADRVMGABUILDDIR)debugger/mgaioctl.o \ $(MESADRVMGABUILDDIR)debugger/mgapixel.o \ $(MESADRVMGABUILDDIR)debugger/mgaspan.o \ $(MESADRVMGABUILDDIR)debugger/mgastate.o \ $(MESADRVMGABUILDDIR)debugger/mgatex.o \ - $(MESADRVMGABUILDDIR)debugger/mgatexcnv.o \ $(MESADRVMGABUILDDIR)debugger/mgatexmem.o \ + $(MESADRVMGABUILDDIR)debugger/mga_texstate.o \ $(MESADRVMGABUILDDIR)debugger/mgatris.o \ $(MESADRVMGABUILDDIR)debugger/mgavb.o \ $(MESADRVMGABUILDDIR)debugger/mga_xmesa.o - MGAPOBJS = $(MESADRVMGABUILDDIR)profiled/mgabuffers.o \ - $(MESADRVMGABUILDDIR)profiled/mgadd.o \ + MGAPOBJS = $(MESADRVMGABUILDDIR)profiled/mgadd.o \ $(MESADRVMGABUILDDIR)profiled/mgarender.o \ $(MESADRVMGABUILDDIR)profiled/mgaioctl.o \ $(MESADRVMGABUILDDIR)profiled/mgapixel.o \ $(MESADRVMGABUILDDIR)profiled/mgaspan.o \ $(MESADRVMGABUILDDIR)profiled/mgastate.o \ $(MESADRVMGABUILDDIR)profiled/mgatex.o \ - $(MESADRVMGABUILDDIR)profiled/mgatexcnv.o \ $(MESADRVMGABUILDDIR)profiled/mgatexmem.o \ + $(MESADRVMGABUILDDIR)profiled/mga_texstate.o \ $(MESADRVMGABUILDDIR)profiled/mgatris.o \ $(MESADRVMGABUILDDIR)profiled/mgavb.o \ $(MESADRVMGABUILDDIR)profiled/mga_xmesa.o #ifdef NeedToLinkMesaSrc -LinkSourceFile(mgabuffers.c, $(MESADRVSRCDIR)/mga) LinkSourceFile(mgadd.c, $(MESADRVSRCDIR)/mga) LinkSourceFile(mgarender.c, $(MESADRVSRCDIR)/mga) LinkSourceFile(mgaioctl.c, $(MESADRVSRCDIR)/mga) @@ -113,8 +107,8 @@ LinkSourceFile(mgapixel.c, $(MESADRVSRCDIR)/mga) LinkSourceFile(mgaspan.c, $(MESADRVSRCDIR)/mga) LinkSourceFile(mgastate.c, $(MESADRVSRCDIR)/mga) LinkSourceFile(mgatex.c, $(MESADRVSRCDIR)/mga) -LinkSourceFile(mgatexcnv.c, $(MESADRVSRCDIR)/mga) LinkSourceFile(mgatexmem.c, $(MESADRVSRCDIR)/mga) +LinkSourceFile(mga_texstate.c, $(MESADRVSRCDIR)/mga) LinkSourceFile(mgatris.c, $(MESADRVSRCDIR)/mga) LinkSourceFile(mgavb.c, $(MESADRVSRCDIR)/mga) LinkSourceFile(mga_xmesa.c, $(MESADRVSRCDIR)/mga) diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_texstate.c b/xc/lib/GL/mesa/src/drv/mga/mga_texstate.c new file mode 100644 index 000000000..d7f795143 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/mga/mga_texstate.c @@ -0,0 +1,719 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * (c) Copyright IBM Corporation 2002 + * 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 + * VA LINUX SYSTEMS, IBM 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: + * Ian Romanick <idr@us.ibm.com> + * Keith Whitwell <keithw@tungstengraphics.com> + */ +/* $XFree86:$ */ + +#include "mm.h" +#include "mgacontext.h" +#include "mgatex.h" +#include "mgaregs.h" +#include "mgatris.h" +#include "mgaioctl.h" + +#include "context.h" +#include "enums.h" +#include "macros.h" +#include "imports.h" + +#include "simple_list.h" +#include "texformat.h" + + +#ifdef MGA_USE_TABLE_FOR_FORMAT +#define TMC_nr_tformat (MESA_FORMAT_CI8 + 1) +static const unsigned TMC_tformat[ TMC_nr_tformat ] = +{ + [MESA_FORMAT_ARGB8888] = TMC_tformat_tw32 | TMC_takey_1 | TMC_tamask_0, + [MESA_FORMAT_RGB565] = TMC_tformat_tw16 | TMC_takey_1 | TMC_tamask_0, + [MESA_FORMAT_ARGB4444] = TMC_tformat_tw12 | TMC_takey_1 | TMC_tamask_0, + [MESA_FORMAT_ARGB1555] = TMC_tformat_tw15 | TMC_takey_1 | TMC_tamask_0, + [MESA_FORMAT_CI8] = TMC_tformat_tw8 | TMC_takey_1 | TMC_tamask_0, +}; +#endif + +static void +mgaSetTexImages( mgaContextPtr mmesa, + const struct gl_texture_object * tObj ) +{ + mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData; + struct gl_texture_image *baseImage = tObj->Image[ tObj->BaseLevel ]; + GLint totalSize; + GLint width, height; + GLint i; + GLint lastLevel; + GLint log2Width, log2Height; + GLuint txformat = 0; + GLint ofs; + + /* Set the hardware texture format + */ +#ifndef MGA_USE_TABLE_FOR_FORMAT + switch (baseImage->TexFormat->MesaFormat) { + + case MESA_FORMAT_ARGB8888: txformat = TMC_tformat_tw32; break; + case MESA_FORMAT_RGB565: txformat = TMC_tformat_tw16; break; + case MESA_FORMAT_ARGB4444: txformat = TMC_tformat_tw12; break; + case MESA_FORMAT_ARGB1555: txformat = TMC_tformat_tw15; break; + case MESA_FORMAT_CI8: txformat = TMC_tformat_tw8; break; + + default: + _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); + return; + } +#else + if ( (baseImage->TexFormat->MesaFormat >= TMC_nr_tformat) + || (TMC_tformat[ baseImage->TexFormat->MesaFormat ] == 0) ) + { + _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); + return; + } + + txformat = TMC_tformat[ baseImage->TexFormat->MesaFormat ]; + +#endif + + /* We are going to upload all levels that are present, even if + * later levels wouldn't be used by the current filtering mode. This + * allows the filtering mode to change without forcing another upload + * of the images. + */ + + lastLevel = ((MGA_IS_G200(mmesa)) ? G200_TEX_MAXLEVELS : G400_TEX_MAXLEVELS) + - 1; + + totalSize = 0; + for ( i = 0 ; i <= lastLevel ; i++ ) { + const struct gl_texture_image *texImage; + + texImage = tObj->Image[i]; + if ( texImage == NULL ) { + lastLevel = i - 1; + break; + } + + t->offsets[i] = totalSize; + t->base.dirty_images[0] |= (1<<i); + + totalSize += ((MAX2( texImage->Width, 8 ) * + MAX2( texImage->Height, 8 ) * + baseImage->TexFormat->TexelBytes) + 31) & ~31; + } + + t->base.totalSize = totalSize; + t->lastLevel = lastLevel; + + + /* setup hardware register values */ + t->setup.texctl &= (TMC_tformat_MASK & TMC_tpitch_MASK + & TMC_tpitchext_MASK); + t->setup.texctl |= txformat; + + if ( baseImage->WidthLog2 >= 3 ) + t->setup.texctl |= ((baseImage->WidthLog2 - 3) << TMC_tpitch_SHIFT); + else + t->setup.texctl |= (TMC_tpitchlin_enable | + (baseImage->Width << TMC_tpitchext_SHIFT)); + + /* G400 specifies the number of mip levels in a strange way. Since there + * are up to 12 levels, it requires 4 bits. Three of the bits are at the + * high end of TEXFILTER. The other bit is in the middle. Weird. + */ + /* FIXME: Is this correct for G200? + */ + t->setup.texfilter &= TF_mapnb_MASK & ~(1U << 18) & ~(0x1ff00); + t->setup.texfilter |= ((lastLevel & 0x01e) << (TF_mapnb_SHIFT - 1)); + t->setup.texfilter |= ((lastLevel & 0x001) << 18); + + /* warp texture registers */ + ofs = MGA_IS_G200(mmesa) ? 28 : 11; + + width = baseImage->Width; + height = baseImage->Height; + + log2Width = baseImage->WidthLog2; + log2Height = baseImage->HeightLog2; + + t->setup.texwidth = (MGA_FIELD(TW_twmask, width - 1) | + MGA_FIELD(TW_rfw, (10 - log2Width - 8) & 63 ) | + MGA_FIELD(TW_tw, (log2Width + ofs ) | 0x40 )); + + t->setup.texheight = (MGA_FIELD(TH_thmask, height - 1) | + MGA_FIELD(TH_rfh, (10 - log2Height - 8) & 63 ) | + MGA_FIELD(TH_th, (log2Height + ofs ) | 0x40 )); + + mgaUploadTexImages( mmesa, t ); +} + + +/* ================================================================ + * Texture unit state management + */ + +static void mgaUpdateTextureEnvG200( GLcontext *ctx, GLuint unit ) +{ + struct gl_texture_object *tObj = ctx->Texture.Unit[0]._Current; + mgaTextureObjectPtr t; + + if (!tObj || !tObj->DriverData) + return; + + t = (mgaTextureObjectPtr)tObj->DriverData; + + t->setup.texctl2 &= ~TMC_decalblend_enable; + + switch (ctx->Texture.Unit[0].EnvMode) { + case GL_REPLACE: + t->setup.texctl &= ~TMC_tmodulate_enable; + break; + case GL_MODULATE: + t->setup.texctl |= TMC_tmodulate_enable; + break; + case GL_DECAL: + t->setup.texctl &= ~TMC_tmodulate_enable; + t->setup.texctl2 |= TMC_decalblend_enable; + break; + case GL_BLEND: + FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE ); + break; + default: + break; + } +} + + +#define MGA_DISABLE 0 +#define MGA_REPLACE 1 +#define MGA_MODULATE 2 +#define MGA_DECAL 3 +#define MGA_BLEND 4 +#define MGA_ADD 5 +#define MGA_MAX_COMBFUNC 6 + +static const GLuint g400_color_combine[][MGA_MAX_COMBFUNC] = +{ + /* Unit 0: + */ + { + /* Disable combiner stage + */ + (0), + + /* GL_REPLACE + */ + (TD0_color_sel_arg1 | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg2 ), + + /* GL_MODULATE + */ + (TD0_color_arg2_diffuse | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_mul), + + /* GL_DECAL + */ + (TD0_color_sel_arg1 | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg2), + + /* GL_BLEND + */ + (0), + + /* GL_ADD + */ + (TD0_color_arg2_diffuse | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_mul), + }, + + /* Unit 1: + */ + { + /* Disable combiner stage + */ + (0), + + /* GL_REPLACE + */ + (TD0_color_sel_arg1 | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg2 ), + + /* GL_MODULATE + */ + (TD0_color_arg2_prevstage | + TD0_color_alpha_prevstage | + TD0_color_sel_mul | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_mul), + + /* GL_DECAL + */ + (TD0_color_sel_arg1 | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2 ), + + /* GL_BLEND + */ + (0), + + /* GL_ADD + */ + (TD0_color_arg2_prevstage | + TD0_color_alpha_prevstage | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_mul), + }, +}; + +static const GLuint g400_alpha_combine[][MGA_MAX_COMBFUNC] = +{ + /* Unit 0: + */ + { + /* Disable combiner stage + */ + (0), + + /* GL_REPLACE + */ + (TD0_color_sel_arg2 | + TD0_color_arg2_diffuse | + TD0_alpha_sel_arg1 ), + + /* GL_MODULATE + * FIXME: Is this correct? + */ + (TD0_color_arg2_diffuse | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_mul), + + /* GL_DECAL + */ + (TD0_color_arg2_diffuse | + TD0_color_sel_arg2 | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg2), + + /* GL_BLEND + */ + (TD0_color_arg2_diffuse | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_mul), + + /* GL_ADD + */ + (TD0_color_arg2_diffuse | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_mul), + }, + + /* Unit 1: + */ + { + /* Disable combiner stage + */ + (0), + + /* GL_REPLACE + */ + (TD0_color_sel_arg2 | + TD0_color_arg2_diffuse | + TD0_alpha_sel_arg1 ), + + /* GL_MODULATE + * FIXME: Is this correct? + */ + (TD0_color_arg2_prevstage | + TD0_color_alpha_prevstage | + TD0_color_sel_mul | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_mul), + + /* GL_DECAL + */ + (TD0_color_arg2_prevstage | + TD0_color_sel_arg2 | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2), + + /* GL_BLEND + */ + (TD0_color_arg2_diffuse | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_mul), + + /* GL_ADD + */ + (TD0_color_arg2_prevstage | + TD0_color_sel_mul | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_mul), + }, +}; + +static void mgaUpdateTextureEnvG400( GLcontext *ctx, GLuint unit ) +{ + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + const int source = mmesa->tmu_source[unit]; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; + const struct gl_texture_object *tObj = texUnit->_Current; + GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit); + GLenum format; + + if ( tObj != ctx->Texture.Unit[source].Current2D || !tObj ) + return; + + format = tObj->Image[tObj->BaseLevel]->Format; + + switch (ctx->Texture.Unit[source].EnvMode) { + case GL_REPLACE: + if (format == GL_RGB || format == GL_LUMINANCE) { + *reg = g400_color_combine[unit][MGA_REPLACE]; + } + else if (format == GL_ALPHA) { + *reg = g400_alpha_combine[unit][MGA_REPLACE]; + } + else { + *reg = (TD0_color_sel_arg1 | + TD0_alpha_sel_arg1 ); + } + break; + + case GL_MODULATE: + *reg = g400_color_combine[unit][MGA_MODULATE]; + break; + case GL_DECAL: + if (format == GL_RGB) { + *reg = g400_color_combine[unit][MGA_DECAL]; + } + else if ( format == GL_RGBA ) { +#if 0 + if (unit == 0) { + /* this doesn't work */ + *reg = (TD0_color_arg2_diffuse | + TD0_color_alpha_currtex | + TD0_color_alpha2inv_enable | + TD0_color_arg2mul_alpha2 | + TD0_color_arg1mul_alpha1 | + TD0_color_blend_enable | + TD0_color_arg1add_mulout | + TD0_color_arg2add_mulout | + TD0_color_add_add | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg2 ); + } + else { + *reg = (TD0_color_arg2_prevstage | + TD0_color_alpha_currtex | + TD0_color_alpha2inv_enable | + TD0_color_arg2mul_alpha2 | + TD0_color_arg1mul_alpha1 | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2 ); + } +#else + /* s/w fallback, pretty sure we can't do in h/w */ + FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE ); + if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK ) + fprintf( stderr, "FALLBACK: GL_DECAL RGBA texture, unit=%d\n", + unit ); +#endif + } + else { + *reg = g400_alpha_combine[unit][MGA_DECAL]; + } + break; + + case GL_ADD: + if (format == GL_INTENSITY) { + if (unit == 0) { + *reg = ( TD0_color_arg2_diffuse | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_diffuse | + TD0_alpha_add_enable | + TD0_alpha_sel_add); + } + else { + *reg = ( TD0_color_arg2_prevstage | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_add_enable | + TD0_alpha_sel_add); + } + } + else if (format == GL_ALPHA) { + *reg = g400_alpha_combine[unit][MGA_ADD]; + } + else { + *reg = g400_color_combine[unit][MGA_ADD]; + } + break; + + case GL_BLEND: + if (format == GL_ALPHA) { + *reg = g400_alpha_combine[unit][MGA_BLEND]; + } + else { + FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE ); + if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK ) + fprintf( stderr, "FALLBACK: GL_BLEND envcolor=0x%08x\n", + mmesa->envcolor ); + + /* Do singletexture GL_BLEND with 'all ones' env-color + * by using both texture units. Multitexture gl_blend + * is a fallback. + */ + if (unit == 0) { + /* Part 1: R1 = Rf ( 1 - Rt ) + * A1 = Af At + */ + *reg = ( TD0_color_arg2_diffuse | + TD0_color_arg1_inv_enable | + TD0_color_sel_mul | + TD0_alpha_arg2_diffuse | + TD0_alpha_sel_arg1); + } else { + /* Part 2: R2 = R1 + Rt + * A2 = A1 + */ + *reg = ( TD0_color_arg2_prevstage | + TD0_color_add_add | + TD0_color_sel_add | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2); + } + } + break; + default: + break; + } +} + + +static void disable_tex( GLcontext *ctx, int unit ) +{ + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + + /* Texture unit disabled */ + + if ( mmesa->CurrentTexObj[unit] != NULL ) { + /* The old texture is no longer bound to this texture unit. + * Mark it as such. + */ + + mmesa->CurrentTexObj[unit]->base.bound &= ~(1UL << unit); + mmesa->CurrentTexObj[unit] = NULL; + } + + if ( unit != 0 ) { + mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0; + } + + if ( ctx->Texture._EnabledUnits == 0 ) { + mmesa->setup.dwgctl &= DC_opcod_MASK; + mmesa->setup.dwgctl |= DC_opcod_trap; + mmesa->hw.alpha_sel = AC_alphasel_diffused; + } + + mmesa->dirty |= MGA_UPLOAD_CONTEXT | (MGA_UPLOAD_TEX0 << unit); +} + +static GLboolean enable_tex_2d( GLcontext *ctx, int unit ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + const int source = mmesa->tmu_source[unit]; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; + const struct gl_texture_object *tObj = texUnit->_Current; + mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData; + + /* Upload teximages (not pipelined) + */ + if (t->base.dirty_images[0]) { + FLUSH_BATCH( mmesa ); + mgaSetTexImages( mmesa, tObj ); + if ( t->base.memBlock == NULL ) { + return GL_FALSE; + } + } + + return GL_TRUE; +} + +static GLboolean update_tex_common( GLcontext *ctx, int unit ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + const int source = mmesa->tmu_source[unit]; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; + struct gl_texture_object *tObj = texUnit->_Current; + mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData; + + /* Fallback if there's a texture border */ + if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) { + return GL_FALSE; + } + + + /* Update state if this is a different texture object to last + * time. + */ + if ( mmesa->CurrentTexObj[unit] != t ) { + if ( mmesa->CurrentTexObj[unit] != NULL ) { + /* The old texture is no longer bound to this texture unit. + * Mark it as such. + */ + + mmesa->CurrentTexObj[unit]->base.bound &= ~(1UL << unit); + } + + mmesa->CurrentTexObj[unit] = t; + t->base.bound |= (1UL << unit); + + driUpdateTextureLRU( (driTextureObject *) t ); /* done too often */ + } + + /* register setup */ + if ( unit == 1 ) { + mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0; + } + + t->setup.texctl2 &= TMC_dualtex_MASK; + if (ctx->Texture._EnabledUnits == 0x03) { + t->setup.texctl2 |= TMC_dualtex_enable; + } + + /* FIXME: The Radeon has some cached state so that it can avoid calling + * FIXME: UpdateTextureEnv in some cases. Is that possible here? + */ + if (MGA_IS_G400(mmesa)) { + /* G400: Regardless of texture env mode, we use the alpha from the + * texture unit (AC_alphasel_fromtex) since it will have already + * been modulated by the incoming fragment color, if needed. + * We don't want (AC_alphasel_modulate) since that'll effectively + * do the modulation twice. + */ + mmesa->hw.alpha_sel = AC_alphasel_fromtex; + + mgaUpdateTextureEnvG400( ctx, unit ); + } else { + mmesa->hw.alpha_sel = 0; + switch (ctx->Texture.Unit[0].EnvMode) { + case GL_DECAL: + mmesa->hw.alpha_sel |= AC_alphasel_diffused; + case GL_REPLACE: + mmesa->hw.alpha_sel |= AC_alphasel_fromtex; + break; + case GL_BLEND: + case GL_MODULATE: + mmesa->hw.alpha_sel |= AC_alphasel_modulated; + break; + default: + break; + } + + mgaUpdateTextureEnvG200( ctx, unit ); + } + + mmesa->setup.dwgctl &= DC_opcod_MASK; + mmesa->setup.dwgctl |= DC_opcod_texture_trap; + mmesa->dirty |= MGA_UPLOAD_CONTEXT | (MGA_UPLOAD_TEX0 << unit); + + return GL_TRUE; +} + + +static GLboolean updateTextureUnit( GLcontext *ctx, int unit ) +{ + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + const int source = mmesa->tmu_source[unit]; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; + + + if ( texUnit->_ReallyEnabled == TEXTURE_2D_BIT) { + return(enable_tex_2d( ctx, unit ) && + update_tex_common( ctx, unit )); + } + else if ( texUnit->_ReallyEnabled ) { + return GL_FALSE; + } + else { + disable_tex( ctx, unit ); + return GL_TRUE; + } +} + +/* The G400 is now programmed quite differently wrt texture environment. + */ +void mgaUpdateTextureState( GLcontext *ctx ) +{ + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + GLboolean ok; + unsigned i; + + + /* This works around a quirk with the MGA hardware. If only OpenGL + * TEXTURE1 is enabled, then the hardware TEXTURE0 must be used. The + * hardware TEXTURE1 can ONLY be used when hardware TEXTURE0 is also used. + */ + + mmesa->tmu_source[0] = 0; + mmesa->tmu_source[1] = 1; + + if ((ctx->Texture._EnabledUnits & 0x03) == 0x02) { + /* only texture 1 enabled */ + mmesa->tmu_source[0] = 1; + mmesa->tmu_source[1] = 0; + } + + for ( i = 0, ok = GL_TRUE + ; (i < ctx->Const.MaxTextureUnits) && ok + ; i++ ) { + ok = updateTextureUnit( ctx, i ); + } + + FALLBACK( ctx, MGA_FALLBACK_TEXTURE, !ok ); + + /* FIXME: I believe that ChooseVertexState should be called here instead of + * FIXME: in mgaDDValidateState. + */ +} diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c index ea454481a..7c349e91c 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c @@ -49,26 +49,20 @@ #include "mgaioctl.h" #include "mgatris.h" #include "mgavb.h" -#include "mgabuffers.h" #include "mgapixel.h" - #include "mga_xmesa.h" - #include "mga_dri.h" +#include "utils.h" +#include "vblank.h" +#include "glxextensions.h" + #ifndef MGA_DEBUG -int MGA_DEBUG = (0 -/* | DEBUG_ALWAYS_SYNC */ -/* | DEBUG_VERBOSE_MSG */ -/* | DEBUG_VERBOSE_LRU */ -/* | DEBUG_VERBOSE_DRI */ -/* | DEBUG_VERBOSE_IOCTL */ -/* | DEBUG_VERBOSE_2D */ -/* | DEBUG_VERBOSE_FALLBACK */ - ); +int MGA_DEBUG = 0; #endif +static int get_MSC( __DRIscreenPrivate * priv, int64_t * count ); static GLboolean mgaInitDriver(__DRIscreenPrivate *sPriv) @@ -76,31 +70,8 @@ mgaInitDriver(__DRIscreenPrivate *sPriv) mgaScreenPrivate *mgaScreen; MGADRIPtr serverInfo = (MGADRIPtr)sPriv->pDevPriv; - if (MGA_DEBUG&DEBUG_VERBOSE_DRI) - fprintf(stderr, "mgaInitDriver\n"); - - /* Check the DRI externsion version */ - if ( sPriv->driMajor != 4 || sPriv->driMinor < 0 ) { - __driUtilMessage( "MGA DRI driver expected DRI version 4.0.x " - "but got version %d.%d.%d", - sPriv->driMajor, sPriv->driMinor, sPriv->driPatch ); - return GL_FALSE; - } - - /* Check that the DDX driver version is compatible */ - if (sPriv->ddxMajor != 1 || - sPriv->ddxMinor < 0) { - __driUtilMessage("MGA DRI driver expected DDX driver version 1.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch); - return GL_FALSE; - } - - /* Check that the DRM driver version is compatible */ - if (sPriv->drmMajor != 3 || - sPriv->drmMinor < 0) { - __driUtilMessage("MGA DRI driver expected DRM driver version 3.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); + if ( ! driCheckDriDdxDrmVersions( sPriv, "MGA", 4, 0, 1, 0, 3, 0 ) ) return GL_FALSE; - } - /* Allocate the private area */ mgaScreen = (mgaScreenPrivate *)MALLOC(sizeof(mgaScreenPrivate)); @@ -129,6 +100,20 @@ mgaInitDriver(__DRIscreenPrivate *sPriv) } } + mgaScreen->linecomp_sane = (sPriv->ddxMajor > 1) || (sPriv->ddxMinor > 1) + || ((sPriv->ddxMinor == 1) && (sPriv->ddxPatch > 0)); + if ( ! mgaScreen->linecomp_sane ) { + PFNGLXDISABLEEXTENSIONPROC glx_disable_extension; + + glx_disable_extension = (PFNGLXDISABLEEXTENSIONPROC) + glXGetProcAddress( "__glXDisableExtension" ); + + if ( glx_disable_extension != NULL ) { + (*glx_disable_extension)( "GLX_SGI_swap_control" ); + (*glx_disable_extension)( "GLX_SGI_video_sync" ); + (*glx_disable_extension)( "GLX_MESA_swap_control" ); + } + } if (serverInfo->chipset != MGA_CARD_TYPE_G200 && serverInfo->chipset != MGA_CARD_TYPE_G400) { @@ -269,6 +254,52 @@ static const struct gl_pipeline_stage *mga_pipeline[] = { }; +static const char * const g400_extensions[] = +{ + "GL_ARB_multitexture", + "GL_ARB_texture_env_add", + "GL_EXT_texture_env_add", +#if defined (MESA_packed_depth_stencil) + "GL_MESA_packed_depth_stencil", +#endif + NULL +}; + +static const char * const card_extensions[] = +{ + "GL_ARB_multisample", + "GL_ARB_texture_compression", + "GL_EXT_fog_coord", + /* paletted_textures currently doesn't work, but we could fix them later */ +#if 0 + "GL_EXT_shared_texture_palette", + "GL_EXT_paletted_texture", +#endif + "GL_EXT_secondary_color", + "GL_EXT_stencil_wrap", + "GL_SGIS_generate_mipmap", + NULL +}; + +static const struct dri_debug_control debug_control[] = +{ + { "fall", DEBUG_VERBOSE_FALLBACK }, + { "tex", DEBUG_VERBOSE_TEXTURE }, + { "ioctl", DEBUG_VERBOSE_IOCTL }, + { "verb", DEBUG_VERBOSE_MSG }, + { "dri", DEBUG_VERBOSE_DRI }, + { NULL, 0 } +}; + + +static int +get_ust_nop( int64_t * ust ) +{ + *ust = 1; + return 0; +} + + static GLboolean mgaCreateContext( const __GLcontextModes *mesaVis, __DRIcontextPrivate *driContextPriv, @@ -313,13 +344,20 @@ mgaCreateContext( const __GLcontextModes *mesaVis, mmesa->sarea = (void *)saPriv; mmesa->glBuffer = NULL; - make_empty_list(&mmesa->SwappedOut); - - mmesa->lastTexHeap = mgaScreen->texVirtual[MGA_AGP_HEAP] ? 2 : 1; - - for (i = 0 ; i < mmesa->lastTexHeap ; i++) { - mmesa->texHeap[i] = mmInit( 0, mgaScreen->textureSize[i]); - make_empty_list(&mmesa->TexObjList[i]); + (void) memset( mmesa->texture_heaps, 0, sizeof( mmesa->texture_heaps ) ); + make_empty_list( & mmesa->swapped ); + + mmesa->nr_heaps = mgaScreen->texVirtual[MGA_AGP_HEAP] ? 2 : 1; + for ( i = 0 ; i < mmesa->nr_heaps ; i++ ) { + mmesa->texture_heaps[i] = driCreateTextureHeap( i, mmesa, + mgaScreen->textureSize[i], + 6, + MGA_NR_TEX_REGIONS, + mmesa->sarea->texList[i], + & mmesa->sarea->texAge[i], + & mmesa->swapped, + sizeof( mgaTextureObject_t ), + (destroy_texture_object_t *) mgaDestroyTexObj ); } /* Set the maximum texture size small enough that we can guarentee @@ -327,23 +365,34 @@ mgaCreateContext( const __GLcontextModes *mesaVis, * on the card at once. */ ctx = mmesa->glCtx; - { - int nr = 2; - - if (mgaScreen->chipset == MGA_CARD_TYPE_G200) - nr = 1; - - if (mgaScreen->textureSize[0] < nr*1024*1024) { - ctx->Const.MaxTextureLevels = 9; - } else if (mgaScreen->textureSize[0] < nr*4*1024*1024) { - ctx->Const.MaxTextureLevels = 10; - } else { - ctx->Const.MaxTextureLevels = 11; - } - - ctx->Const.MaxTextureUnits = nr; + if ( mgaScreen->chipset == MGA_CARD_TYPE_G200 ) { + ctx->Const.MaxTextureUnits = 1; + driCalculateMaxTextureLevels( mmesa->texture_heaps, + mmesa->nr_heaps, + & ctx->Const, + 4, + 10, /* max 2D texture size is 1024x1024 */ + 0, /* 3D textures unsupported. */ + 0, /* cube textures unsupported. */ + 0, /* texture rectangles unsupported. */ + G200_TEX_MAXLEVELS, + GL_FALSE ); + } + else { + ctx->Const.MaxTextureUnits = 2; + driCalculateMaxTextureLevels( mmesa->texture_heaps, + mmesa->nr_heaps, + & ctx->Const, + 4, + 11, /* max 2D texture size is 2048x2048 */ + 0, /* 3D textures unsupported. */ + 0, /* cube textures unsupported. */ + 0, /* texture rectangles unsupported. */ + G400_TEX_MAXLEVELS, + GL_FALSE ); } + ctx->Const.MinLineWidth = 1.0; ctx->Const.MinLineWidthAA = 1.0; ctx->Const.MaxLineWidth = 10.0; @@ -376,7 +425,6 @@ mgaCreateContext( const __GLcontextModes *mesaVis, mmesa->haveHwStipple = GL_FALSE; mmesa->RenderIndex = -1; /* impossible value */ - mmesa->new_state = ~0; mmesa->dirty = ~0; mmesa->vertex_format = 0; mmesa->CurrentTexObj[0] = 0; @@ -410,7 +458,11 @@ mgaCreateContext( const __GLcontextModes *mesaVis, ctx->DriverCtx = (void *) mmesa; mmesa->glCtx = ctx; - mgaDDExtensionsInit( ctx ); + driInitExtensions( ctx, card_extensions, GL_FALSE ); + + if (MGA_IS_G400(MGA_CONTEXT(ctx))) { + driInitExtensions( ctx, g400_extensions, GL_FALSE ); + } mgaDDInitStateFuncs( ctx ); mgaDDInitTextureFuncs( ctx ); @@ -425,6 +477,20 @@ mgaCreateContext( const __GLcontextModes *mesaVis, driContextPriv->driverPrivate = (void *) mmesa; +#if DO_DEBUG + MGA_DEBUG = driParseDebugString( getenv( "MGA_DEBUG" ), + debug_control ); +#endif + + mmesa->vblank_flags = ((mmesa->mgaScreen->irq == 0) + && mmesa->mgaScreen->linecomp_sane) + ? VBLANK_FLAG_NO_IRQ : driGetDefaultVBlankFlags(); + + mmesa->get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( "__glXGetUST" ); + if ( mmesa->get_ust == NULL ) { + mmesa->get_ust = get_ust_nop; + } + return GL_TRUE; } @@ -434,10 +500,15 @@ mgaDestroyContext(__DRIcontextPrivate *driContextPriv) mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate; if (MGA_DEBUG&DEBUG_VERBOSE_DRI) - fprintf(stderr, "mgaDestroyContext\n"); + fprintf( stderr, "[%s:%d] mgaDestroyContext start\n", + __FILE__, __LINE__ ); assert(mmesa); /* should never be null */ if (mmesa) { + GLboolean release_texture_heaps; + + + release_texture_heaps = (mmesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( mmesa->glCtx ); _tnl_DestroyContext( mmesa->glCtx ); _ac_DestroyContext( mmesa->glCtx ); @@ -448,9 +519,27 @@ mgaDestroyContext(__DRIcontextPrivate *driContextPriv) /* free the Mesa context */ mmesa->glCtx->DriverCtx = NULL; _mesa_destroy_context(mmesa->glCtx); - /* free the mga context */ + + if ( release_texture_heaps ) { + /* This share group is about to go away, free our private + * texture object data. + */ + int i; + + assert( is_empty_list( & mmesa->swapped ) ); + + for ( i = 0 ; i < mmesa->nr_heaps ; i++ ) { + driDestroyTextureHeap( mmesa->texture_heaps[ i ] ); + mmesa->texture_heaps[ i ] = NULL; + } + } + FREE(mmesa); } + + if (MGA_DEBUG&DEBUG_VERBOSE_DRI) + fprintf( stderr, "[%s:%d] mgaDestroyContext done\n", + __FILE__, __LINE__ ); } @@ -572,9 +661,9 @@ void mgaGetLock( mgaContextPtr mmesa, GLuint flags ) sarea->ctxOwner=me; } - for (i = 0 ; i < mmesa->lastTexHeap ; i++) - if (sarea->texAge[i] != mmesa->texAge[i]) - mgaAgeTextures( mmesa, i ); + for ( i = 0 ; i < mmesa->nr_heaps ; i++ ) { + DRI_AGE_TEXTURES( mmesa->texture_heaps[ i ] ); + } sarea->last_quiescent = -1; /* just kill it for now */ } @@ -592,7 +681,12 @@ static const struct __DriverAPIRec mgaAPI = { mgaMakeCurrent, mgaUnbindContext, mgaOpenFullScreen, - mgaCloseFullScreen + mgaCloseFullScreen, + + .GetMSC = get_MSC, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL }; @@ -611,5 +705,42 @@ void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, } +/* This function is called by libGL.so as soon as libGL.so is loaded. + * This is where we'd register new extension functions with the dispatcher. + */ +void +__driRegisterExtensions( void ) +{ + PFNGLXENABLEEXTENSIONPROC glx_enable_extension; + + if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) { + glx_enable_extension = (PFNGLXENABLEEXTENSIONPROC) + glXGetProcAddress( "__glXEnableExtension" ); + + if ( glx_enable_extension != NULL ) { + (*glx_enable_extension)( "GLX_SGI_swap_control", GL_FALSE ); + (*glx_enable_extension)( "GLX_SGI_video_sync", GL_FALSE ); + (*glx_enable_extension)( "GLX_MESA_swap_control", GL_FALSE ); + } + } +} + +static int +get_MSC( __DRIscreenPrivate * priv, int64_t * count ) +{ + drmVBlank vbl; + int ret; + + + /* Don't wait for anything. Just get the current frame count. */ + + vbl.request.type = DRM_VBLANK_ABSOLUTE; + vbl.request.sequence = 0; + + ret = drmWaitVBlank( priv->fd, &vbl ); + *count = vbl.reply.sequence; + + return ret; +} #endif diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h index 558ab274f..de349da08 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h +++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.h @@ -47,6 +47,9 @@ typedef struct mga_screen_private_s { int cpp; /* for front and back buffers */ GLint agpMode; unsigned int irq; /* IRQ number (0 means none) */ + GLboolean linecomp_sane; /* GL_TRUE if line comp. programmed correctly + * by the DDX driver. + */ unsigned int mAccess; diff --git a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c deleted file mode 100644 index f2657876b..000000000 --- a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright 2000-2001 VA Linux Systems, Inc. - * 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 - * VA LINUX SYSTEMS AND/OR ITS 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: - * Keith Whitwell <keith@tungstengraphics.com> - */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.c,v 1.13 2002/11/05 17:46:08 tsi Exp $ */ - -#include "mgacontext.h" -#include "mgabuffers.h" -#include "mgastate.h" -#include "mgaioctl.h" -#include "mgatris.h" -#include "swrast/swrast.h" -#include "imports.h" - -static void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa ) -{ - __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; - - if (driDrawable->numClipRects == 0) { - static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0}; - mmesa->numClipRects = 1; - mmesa->pClipRects = &zeroareacliprect; - } else { - mmesa->numClipRects = driDrawable->numClipRects; - mmesa->pClipRects = driDrawable->pClipRects; - } - mmesa->drawX = driDrawable->x; - mmesa->drawY = driDrawable->y; - - mmesa->setup.dstorg = mmesa->drawOffset; - mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS; -} - - -static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa ) -{ - __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; - - if (driDrawable->numBackClipRects == 0) - { - if (driDrawable->numClipRects == 0) { - static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0}; - mmesa->numClipRects = 1; - mmesa->pClipRects = &zeroareacliprect; - } else { - mmesa->numClipRects = driDrawable->numClipRects; - mmesa->pClipRects = driDrawable->pClipRects; - } - mmesa->drawX = driDrawable->x; - mmesa->drawY = driDrawable->y; - } else { - mmesa->numClipRects = driDrawable->numBackClipRects; - mmesa->pClipRects = driDrawable->pBackClipRects; - mmesa->drawX = driDrawable->backX; - mmesa->drawY = driDrawable->backY; - } - - mmesa->setup.dstorg = mmesa->drawOffset; - mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS; -} - - - -#if 0 -static void mgaUpdateRectsFromSarea( mgaContextPtr mmesa ) -{ - __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; - __DRIscreenPrivate *driScreen = mmesa->driScreen; - MGASAREAPrivPtr sarea = mmesa->sarea; - int i = 0, top = 0; - - - if (sarea->exported_buffers & MGA_BACK) { - - driDrawable->numBackClipRects = sarea->exported_nback; - driDrawable->pBackClipRects = mmesa->tmp_boxes[0]; - - top = sarea->exported_nback; - for (i = 0 ; i < top ; i++) - driDrawable->pBackClipRects[i] = - *(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]); - } - - - if (sarea->exported_buffers & MGA_FRONT) - { - int start = top; - - driDrawable->numClipRects = sarea->exported_nfront; - driDrawable->pClipRects = mmesa->tmp_boxes[1]; - - top += sarea->exported_nfront; - for ( ; i < top ; i++) - driDrawable->pClipRects[i-start] = - *(XF86DRIClipRectPtr)&(sarea->exported_boxes[i]); - - } - - - - driDrawable->index = sarea->exported_index; - driDrawable->lastStamp = sarea->exported_stamp; - driDrawable->x = sarea->exported_front_x; - driDrawable->y = sarea->exported_front_y; - driDrawable->backX = sarea->exported_back_x; - driDrawable->backY = sarea->exported_back_y; - driDrawable->w = sarea->exported_w; - driDrawable->h = sarea->exported_h; - driDrawable->pStamp = - &(driScreen->pSAREA->drawableTable[driDrawable->index].stamp); - - mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK) & ~(sarea->exported_buffers); -} -#endif - -#if 0 -static void printSareaRects( mgaContextPtr mmesa ) -{ - __DRIscreenPrivate *driScreen = mmesa->driScreen; - MGASAREAPrivPtr sarea = mmesa->sarea; - int i; - - fprintf(stderr, "sarea->exported: %d\n", sarea->exported_drawable); - fprintf(stderr, "sarea->exported_index: %d\n", sarea->exported_index); - fprintf(stderr, "sarea->exported_stamp: %d\n", sarea->exported_stamp); - fprintf(stderr, "sarea->exported_front_x: %d\n", sarea->exported_front_x); - fprintf(stderr, "sarea->exported_front_y: %d\n", sarea->exported_front_y); - fprintf(stderr, "sarea->exported_back_x: %d\n", sarea->exported_back_x); - fprintf(stderr, "sarea->exported_back_y: %d\n", sarea->exported_back_y); - fprintf(stderr, "sarea->exported_w: %d\n", sarea->exported_w); - fprintf(stderr, "sarea->exported_h: %d\n", sarea->exported_h); - fprintf(stderr, "sarea->exported_buffers: %d\n", sarea->exported_buffers); - fprintf(stderr, "sarea->exported_nfront: %d\n", sarea->exported_nfront); - fprintf(stderr, "sarea->exported_nback: %d\n", sarea->exported_nback); - - i = 0; - if (sarea->exported_buffers & MGA_BACK) - for ( ; i < sarea->exported_nback ; i++) - fprintf(stderr, "back %d: %d,%d-%d,%d\n", i, - sarea->exported_boxes[i].x1, sarea->exported_boxes[i].y1, - sarea->exported_boxes[i].x2, sarea->exported_boxes[i].y2); - - if (sarea->exported_buffers & MGA_FRONT) { - int start = i; - int top = i + sarea->exported_nfront; - for ( ; i < top ; i++) - fprintf(stderr, "front %d: %d,%d-%d,%d\n", - i - start, - sarea->exported_boxes[i].x1, sarea->exported_boxes[i].y1, - sarea->exported_boxes[i].x2, sarea->exported_boxes[i].y2); - } - - fprintf(stderr, "drawableTable[%d].stamp: %d\n", - sarea->exported_index, - driScreen->pSAREA->drawableTable[sarea->exported_index].stamp); -} - -static void printMmesaRects( mgaContextPtr mmesa ) -{ - __DRIscreenPrivate *driScreen = mmesa->driScreen; - __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; - int nr = mmesa->numClipRects; - int i; - - fprintf(stderr, "driDrawable->draw: %ld\n", driDrawable->draw); - fprintf(stderr, "driDrawable->index: %d\n", driDrawable->index); - fprintf(stderr, "driDrawable->lastStamp: %d\n", driDrawable->lastStamp); - fprintf(stderr, "mmesa->drawX: %d\n", mmesa->drawX); - fprintf(stderr, "mmesa->drawY: %d\n", mmesa->drawY); - fprintf(stderr, "driDrawable->w: %d\n", driDrawable->w); - fprintf(stderr, "driDrawable->h: %d\n", driDrawable->h); - - for (i = 0 ; i < nr ; i++) - fprintf(stderr, "box %d: %d,%d-%d,%d\n", i, - mmesa->pClipRects[i].x1, mmesa->pClipRects[i].y1, - mmesa->pClipRects[i].x2, mmesa->pClipRects[i].y2); - - fprintf(stderr, "mmesa->draw_buffer: %d\n", mmesa->draw_buffer); - fprintf(stderr, "drawableTable[%d].stamp: %d\n", - driDrawable->index, - driScreen->pSAREA->drawableTable[driDrawable->index].stamp); -} -#endif - - - -void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers ) -{ - __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; - MGASAREAPrivPtr sarea = mmesa->sarea; - -/* fprintf(stderr, "%s\n", __FUNCTION__); */ - - DRI_VALIDATE_DRAWABLE_INFO(mmesa->driScreen, driDrawable); - mmesa->dirty_cliprects = 0; - - if (mmesa->draw_buffer == MGA_FRONT) - mgaXMesaSetFrontClipRects( mmesa ); - else - mgaXMesaSetBackClipRects( mmesa ); - -#if 0 - printMmesaRects(mmesa); -#endif - - sarea->req_drawable = driDrawable->draw; - sarea->req_draw_buffer = mmesa->draw_buffer; - - mgaUpdateClipping( mmesa->glCtx ); - mgaCalcViewport( mmesa->glCtx ); - - mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; -} - - - -void mgaDDDrawBuffer(GLcontext *ctx, GLenum mode ) -{ - mgaContextPtr mmesa = MGA_CONTEXT(ctx); - - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - - /* - * _DrawDestMask is easier to cope with than <mode>. - */ - switch ( ctx->Color._DrawDestMask ) { - case FRONT_LEFT_BIT: - mmesa->setup.dstorg = mmesa->mgaScreen->frontOffset; - mmesa->dirty |= MGA_UPLOAD_CONTEXT; - mmesa->draw_buffer = MGA_FRONT; - mgaXMesaSetFrontClipRects( mmesa ); - FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE ); - break; - case BACK_LEFT_BIT: - mmesa->setup.dstorg = mmesa->mgaScreen->backOffset; - mmesa->draw_buffer = MGA_BACK; - mmesa->dirty |= MGA_UPLOAD_CONTEXT; - mgaXMesaSetBackClipRects( mmesa ); - FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE ); - break; - default: - /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ - FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE ); - return; - } - - /* We want to update the s/w rast state too so that r200SetBuffer() - * gets called. - */ - _swrast_DrawBuffer(ctx, mode); -} - - -void mgaDDReadBuffer(GLcontext *ctx, GLenum mode ) -{ - mgaContextPtr mmesa = MGA_CONTEXT(ctx); - - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - - switch (ctx->Pixel._ReadSrcMask) { - case FRONT_LEFT_BIT: - mmesa->read_buffer = MGA_FRONT; - break; - case BACK_LEFT_BIT: - mmesa->read_buffer = MGA_FRONT; - break; - default: - _mesa_problem(ctx, "bad mode in mgaDDReadBuffer"); - } -} diff --git a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.h b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.h deleted file mode 100644 index 76389415f..000000000 --- a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.h +++ /dev/null @@ -1,37 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.h,v 1.7 2002/10/30 12:51:35 alanh Exp $ */ -/* - * Copyright 2000-2001 VA Linux Systems, Inc. - * 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 - * VA LINUX SYSTEMS AND/OR ITS 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: - * Keith Whitwell <keith@tungstengraphics.com> - */ - -#ifndef MGA_BUFFERS_H -#define MGA_BUFFERS_H - -void mgaDDDrawBuffer(GLcontext *ctx, GLenum mode ); -void mgaDDReadBuffer(GLcontext *ctx, GLenum mode ); - -void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers ); - -#endif diff --git a/xc/lib/GL/mesa/src/drv/mga/mgacontext.h b/xc/lib/GL/mesa/src/drv/mga/mgacontext.h index 5c7826bc6..6770c59a1 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgacontext.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgacontext.h @@ -29,12 +29,14 @@ #ifndef MGALIB_INC #define MGALIB_INC +#include <stdint.h> #include "dri_util.h" #include "mtypes.h" #include "xf86drm.h" #include "mm.h" #include "mga_sarea.h" - +#include "texmem.h" +#include "macros.h" #define MGA_SET_FIELD(reg,mask,val) reg = ((reg) & (mask)) | ((val) & ~(mask)) #define MGA_FIELD(field,val) (((val) << (field ## _SHIFT)) & ~(field ## _MASK)) @@ -59,17 +61,6 @@ #define MGA_FALLBACK_DEPTH 0x40 -/* For mgaCtx->new_state. - */ -#define MGA_NEW_DEPTH 0x1 -#define MGA_NEW_ALPHA 0x2 -#define MGA_NEW_CLIP 0x8 -#define MGA_NEW_TEXTURE 0x20 -#define MGA_NEW_CULL 0x40 -#define MGA_NEW_WARP 0x80 -#define MGA_NEW_STENCIL 0x100 -#define MGA_NEW_CONTEXT 0x200 - /* Use the templated vertex formats: */ #define TAG(x) mga##x @@ -94,43 +85,98 @@ typedef void (*mga_point_func)( mgaContextPtr, mgaVertex * ); struct mga_texture_object_s; struct mga_screen_private_s; -#define MGA_TEX_MAXLEVELS 5 +#define G200_TEX_MAXLEVELS 5 +#define G400_TEX_MAXLEVELS 12 typedef struct mga_texture_object_s { - struct mga_texture_object_s *next; - struct mga_texture_object_s *prev; - struct gl_texture_object *tObj; - struct mga_context_t *ctx; - PMemBlock MemBlock; - GLuint offsets[MGA_TEX_MAXLEVELS]; - int lastLevel; - GLuint dirty_images; - GLuint totalSize; - int texelBytes; - GLuint age; - int bound; - int heap; /* agp or card */ + driTextureObject base; + + /* The G200 only has the ability to use 5 mipmap levels (including the + * base level). The G400 does not have this restriction, but it still + * only has 5 offset pointers in the hardware. The trick on the G400 is + * upto the first 4 offset pointers point to mipmap levels. The last + * offset pointer tells how large the preceeding mipmap is. This value is + * then used to determine where the remaining mipmaps are. + * + * For example, if the first offsets[0] through offsets[2] are used as + * pointers, then offset[3] will be the size of the mipmap pointed to by + * offsets[2]. So mipmap level 3 will be at (offsets[2]+offsets[3]). For + * each successive mipmap level, offsets[3] is divided by 4 and added to + * the previous address. So mipmap level 4 will be at + * (offsets[2]+offsets[3]+(offsets[3] / 4)). + * + * The last pointer is selected by setting TO_texorgoffsetsel in its + * pointer. In the previous example, offset[2] would have + * TO_texorgoffsetsel or'ed in before writing it to the hardware. + * + * In the current driver all of the mipmaps are packed together linearly + * with mipmap level 0. Therefore offsets[0] points to the base of the + * texture (and has TO_texorgoffsetsel or'ed in), and offsets[1] is the + * size of the base texture. + * + * There is a possible optimization available here. At times the driver + * may not be able to allocate a single block of memory for the complete + * texture without ejecting some other textures from memory. It may be + * possible to put some of the lower mipmap levels (i.e., the larger + * mipmaps) in memory separate from the higher levels. + * + * The implementation should be fairly obvious, but getting "right" would + * likely be non-trivial. A first allocation for the entire texture would + * be attempted with a flag that says "don't eject other textures." If + * that failed, an additional allocation would be attmpted for just the + * base map. The process would repeat with the block of lower maps. The + * tricky parts would be in detecting when some of the levels had been + * ejected from texture memory by other textures and preventing the + * 4th allocation (for all the smallest mipmap levels) from kicking out + * any of the first three. + * + * This array holds G400_TEX_MAXLEVELS pointers to remove an if-statement + * in a loop in mgaSetTexImages. Values past G200_TEX_MAXLEVELS are not + * used. + */ + GLuint offsets[G400_TEX_MAXLEVELS]; + + int lastLevel; + int texelBytes; + GLuint age; mga_texture_regs_t setup; } mgaTextureObject_t; +struct mga_hw_state { + GLuint specen; + GLuint cull; + GLuint cull_dualtex; + GLuint stencil; + GLuint stencilctl; + GLuint stencil_enable; + GLuint zmode; + GLuint rop; + GLuint alpha_func; + GLuint alpha_func_enable; + GLuint blend_func; + GLuint blend_func_enable; + GLuint alpha_sel; +}; + struct mga_context_t { GLcontext *glCtx; - unsigned int lastStamp; /* fullscreen breaks dpriv->laststamp, - * need to shadow it here. */ + unsigned int lastStamp; /* fullscreen breaks dpriv->laststamp, + * need to shadow it here. */ + + /* Hardware state management + */ + struct mga_hw_state hw; /* Bookkeeping for texturing */ - int lastTexHeap; - struct mga_texture_object_s TexObjList[MGA_NR_TEX_HEAPS]; - struct mga_texture_object_s SwappedOut; + unsigned nr_heaps; + driTexHeap * texture_heaps[ MGA_NR_TEX_HEAPS ]; + driTextureObject swapped; + struct mga_texture_object_s *CurrentTexObj[2]; - memHeap_t *texHeap[MGA_NR_TEX_HEAPS]; - int c_texupload; - int c_texusage; - int tex_thrash; /* Map GL texture units onto hardware. @@ -178,8 +224,7 @@ struct mga_context_t { /* Manage driver and hardware state */ - GLuint new_gl_state; - GLuint new_state; + GLuint NewGLState; GLuint dirty; mga_context_regs_t setup; @@ -203,13 +248,21 @@ struct mga_context_t { /* VBI */ GLuint vbl_seq; + GLuint vblank_flags; + + uint64_t swap_ust; + uint64_t swap_missed_ust; + + GLuint swap_count; + GLuint swap_missed_count; + + PFNGLXGETUSTPROC get_ust; /* Drawable, cliprect and scissor information */ int dirty_cliprects; /* which sets of cliprects are uptodate? */ int draw_buffer; /* which buffer are we rendering to */ unsigned int drawOffset; /* draw buffer address in space */ - int read_buffer; int readOffset; int drawX, drawY; /* origin of drawable in draw buffer */ int lastX, lastY; /* detect DSTORG bug */ @@ -243,51 +296,38 @@ struct mga_context_t { #define MGA_CONTEXT(ctx) ((mgaContextPtr)(ctx->DriverCtx)) -#define MGAPACKCOLOR555(r,g,b,a) \ - ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ - ((a) ? 0x8000 : 0)) -#define MGAPACKCOLOR565(r,g,b) \ - ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) -#define MGAPACKCOLOR88(l, a) \ - (((l) << 8) | (a)) - -#define MGAPACKCOLOR888(r,g,b) \ - (((r) << 16) | ((g) << 8) | (b)) - -#define MGAPACKCOLOR8888(r,g,b,a) \ - (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) - -#define MGAPACKCOLOR4444(r,g,b,a) \ - ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) +/* ================================================================ + * Debugging: + */ +#define DO_DEBUG 1 -#define MGA_DEBUG 0 -#ifndef MGA_DEBUG +#if DO_DEBUG extern int MGA_DEBUG; +#else +#define MGA_DEBUG 0 #endif -#define DEBUG_ALWAYS_SYNC 0x1 -#define DEBUG_VERBOSE_MSG 0x2 -#define DEBUG_VERBOSE_LRU 0x4 -#define DEBUG_VERBOSE_DRI 0x8 -#define DEBUG_VERBOSE_IOCTL 0x10 -#define DEBUG_VERBOSE_2D 0x20 -#define DEBUG_VERBOSE_FALLBACK 0x40 +#define DEBUG_VERBOSE_MSG 0x01 +#define DEBUG_VERBOSE_DRI 0x02 +#define DEBUG_VERBOSE_IOCTL 0x04 +#define DEBUG_VERBOSE_TEXTURE 0x08 +#define DEBUG_VERBOSE_FALLBACK 0x10 static __inline__ GLuint mgaPackColor(GLuint cpp, GLubyte r, GLubyte g, GLubyte b, GLubyte a) { - switch (cpp) { - case 2: - return MGAPACKCOLOR565(r,g,b); - case 4: - return MGAPACKCOLOR8888(r,g,b,a); - default: - return 0; - } + switch (cpp) { + case 2: + return PACK_COLOR_565( r, g, b ); + case 4: + return PACK_COLOR_8888( a, r, g, b ); + default: + return 0; + } } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadd.c b/xc/lib/GL/mesa/src/drv/mga/mgadd.c index 7e5c65790..bbbd9f41d 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgadd.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgadd.c @@ -39,11 +39,12 @@ #include "mgavb.h" #include "mga_xmesa.h" #include "extensions.h" +#include "utils.h" #if defined(USE_X86_ASM) #include "X86/common_x86_asm.h" #endif -#define MGA_DATE "20021125" +#define DRIVER_DATE "20030328" /*************************************** @@ -55,52 +56,19 @@ static const GLubyte *mgaDDGetString( GLcontext *ctx, GLenum name ) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); static char buffer[128]; + unsigned offset; switch ( name ) { case GL_VENDOR: return (GLubyte *) "VA Linux Systems Inc."; case GL_RENDERER: - sprintf( buffer, "Mesa DRI %s " MGA_DATE, - MGA_IS_G400(mmesa) ? "G400" : - MGA_IS_G200(mmesa) ? "G200" : "MGA" ); - - /* Append any AGP-specific information. - */ - switch ( mmesa->mgaScreen->agpMode ) { - case 1: - strncat( buffer, " AGP 1x", 7 ); - break; - case 2: - strncat( buffer, " AGP 2x", 7 ); - break; - case 4: - strncat( buffer, " AGP 4x", 7 ); - break; - } - - /* Append any CPU-specific information. - */ -#ifdef USE_X86_ASM - if ( _mesa_x86_cpu_features ) { - strncat( buffer, " x86", 4 ); - } -#endif -#ifdef USE_MMX_ASM - if ( cpu_has_mmx ) { - strncat( buffer, "/MMX", 4 ); - } -#endif -#ifdef USE_3DNOW_ASM - if ( cpu_has_3dnow ) { - strncat( buffer, "/3DNow!", 7 ); - } -#endif -#ifdef USE_SSE_ASM - if ( cpu_has_xmm ) { - strncat( buffer, "/SSE", 4 ); - } -#endif + offset = driGetRendererString( buffer, + MGA_IS_G400(mmesa) ? "G400" : + MGA_IS_G200(mmesa) ? "G200" : "MGA", + DRIVER_DATE, + mmesa->mgaScreen->agpMode ); + return (GLubyte *)buffer; default: @@ -125,40 +93,6 @@ static void mgaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height) UNLOCK_HARDWARE( mmesa ); } -void mgaDDExtensionsInit( GLcontext *ctx ) -{ - /* paletted_textures currently doesn't work, but we could fix them later */ - /* - _mesa_enable_extension( ctx, "GL_EXT_shared_texture_palette" ); - _mesa_enable_extension( ctx, "GL_EXT_paletted_texture" ); - */ - - _mesa_enable_extension( ctx, "GL_ARB_texture_compression" ); - _mesa_enable_extension( ctx, "GL_ARB_multisample" ); - - _mesa_enable_extension( ctx, "GL_SGIS_generate_mipmap" ); - - /* Turn on multitexture and texenv_add for the G400. - */ - if (MGA_IS_G400(MGA_CONTEXT(ctx))) { - _mesa_enable_extension( ctx, "GL_ARB_multitexture" ); - _mesa_enable_extension( ctx, "GL_ARB_texture_env_add" ); - - _mesa_enable_extension( ctx, "GL_EXT_texture_env_add" ); - -#if defined (MESA_packed_depth_stencil) - _mesa_enable_extension( ctx, "GL_MESA_packed_depth_stencil" ); -#endif - -#if defined (MESA_experimetal_agp_allocator) - if (!getenv("MGA_DISABLE_AGP_ALLOCATOR")) - _mesa_enable_extension( ctx, "GL_MESA_experimental_agp_allocator" ); -#endif - } -} - - - void mgaDDInitDriverFuncs( GLcontext *ctx ) { ctx->Driver.GetBufferSize = mgaBufferSize; diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadd.h b/xc/lib/GL/mesa/src/drv/mga/mgadd.h index 6072e6cfc..919fd742d 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgadd.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgadd.h @@ -32,6 +32,5 @@ #include "context.h" void mgaDDInitDriverFuncs( GLcontext *ctx ); -void mgaDDExtensionsInit( GLcontext *ctx ); #endif diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c index 2f28c2b58..fadaafe5b 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c @@ -40,9 +40,10 @@ #include "mgavb.h" #include "mgaioctl.h" #include "mgatris.h" -#include "mgabuffers.h" #include "mga_common.h" +#include "vblank.h" + static void mga_iload_dma_ioctl(mgaContextPtr mmesa, unsigned long dest, @@ -56,6 +57,13 @@ static void mga_iload_dma_ioctl(mgaContextPtr mmesa, fprintf(stderr, "DRM_IOCTL_MGA_ILOAD idx %d dst %x length %d\n", buf->idx, (int) dest, length); + if ( (length & MGA_ILOAD_MASK) != 0 ) { + UNLOCK_HARDWARE( mmesa ); + fprintf( stderr, "%s: Invalid ILOAD datasize (%d), must be " + "multiple of %u.\n", __FUNCTION__, length, MGA_ILOAD_ALIGN ); + exit( 1 ); + } + iload.idx = buf->idx; iload.dstorg = dest; iload.length = length; @@ -273,63 +281,11 @@ mgaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, } -int nrswaps; - - -void mgaWaitForVBlank( mgaContextPtr mmesa ) +static void mgaWaitForFrameCompletion( mgaContextPtr mmesa ) { - drmVBlank vbl; - int ret; - - if ( !mmesa->mgaScreen->irq ) - return; - - if ( getenv("LIBGL_SYNC_REFRESH") ) { - /* Wait for until the next vertical blank */ - vbl.request.type = DRM_VBLANK_RELATIVE; - vbl.request.sequence = 1; - } else if ( getenv("LIBGL_THROTTLE_REFRESH") ) { - /* Wait for at least one vertical blank since the last call */ - vbl.request.type = DRM_VBLANK_ABSOLUTE; - vbl.request.sequence = mmesa->vbl_seq + 1; - } else { - return; - } - - if ((ret = drmWaitVBlank( mmesa->driFd, &vbl ))) { - fprintf(stderr, "%s: drmWaitVBlank returned %d, IRQs don't seem to be" - " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH" - " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret); - exit(1); - } - - mmesa->vbl_seq = vbl.reply.sequence; -} - - -/* - * Copy the back buffer to the front buffer. - */ -void mgaSwapBuffers( __DRIdrawablePrivate *dPriv ) -{ - mgaContextPtr mmesa; - XF86DRIClipRectPtr pbox; - GLint nbox; - GLint ret, wait = 0; - GLint i; + unsigned wait = 0; GLuint last_frame, last_wrap; - assert(dPriv); - assert(dPriv->driContextPriv); - assert(dPriv->driContextPriv->driverPrivate); - - mmesa = (mgaContextPtr) dPriv->driContextPriv->driverPrivate; - - FLUSH_BATCH( mmesa ); - - mgaWaitForVBlank( mmesa ); - - LOCK_HARDWARE( mmesa ); last_frame = mmesa->sarea->last_frame.head; last_wrap = mmesa->sarea->last_frame.wrap; @@ -353,12 +309,45 @@ void mgaSwapBuffers( __DRIdrawablePrivate *dPriv ) } UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH ); - for ( i = 0 ; i < 1024 ; i++ ) { - /* Don't just hammer the register... */ - } + UNLOCK_HARDWARE( mmesa ); + DO_USLEEP( 1 ); + LOCK_HARDWARE( mmesa ); } if ( wait ) fprintf( stderr, "\n" ); +} + + +/* + * Copy the back buffer to the front buffer. + */ +void mgaSwapBuffers( __DRIdrawablePrivate *dPriv ) +{ + mgaContextPtr mmesa; + XF86DRIClipRectPtr pbox; + GLint nbox; + GLint ret; + GLint i; + GLboolean missed_target; + + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + mmesa = (mgaContextPtr) dPriv->driContextPriv->driverPrivate; + + FLUSH_BATCH( mmesa ); + + LOCK_HARDWARE( mmesa ); + mgaWaitForFrameCompletion( mmesa ); + UNLOCK_HARDWARE( mmesa ); + driWaitForVBlank( & mmesa->vbl_seq, mmesa->vblank_flags, & missed_target ); + if ( missed_target ) { + mmesa->swap_missed_count++; + (void) (*mmesa->get_ust)( & mmesa->swap_missed_ust ); + } + LOCK_HARDWARE( mmesa ); /* Use the frontbuffer cliprects */ @@ -392,6 +381,8 @@ void mgaSwapBuffers( __DRIdrawablePrivate *dPriv ) UNLOCK_HARDWARE( mmesa ); mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; + mmesa->swap_count++; + (void) (*mmesa->get_ust)( & mmesa->swap_ust ); } @@ -435,18 +426,17 @@ void mgaWaitAge( mgaContextPtr mmesa, int age ) } -static int intersect_rect( XF86DRIClipRectPtr out, - XF86DRIClipRectPtr a, - XF86DRIClipRectPtr b ) +static GLboolean intersect_rect( XF86DRIClipRectPtr out, + const XF86DRIClipRectPtr a, + const XF86DRIClipRectPtr b ) { *out = *a; if (b->x1 > out->x1) out->x1 = b->x1; if (b->y1 > out->y1) out->y1 = b->y1; if (b->x2 < out->x2) out->x2 = b->x2; if (b->y2 < out->y2) out->y2 = b->y2; - if (out->x1 > out->x2) return 0; - if (out->y1 > out->y2) return 0; - return 1; + + return ((out->x1 < out->x2) && (out->y1 < out->y2)); } @@ -552,7 +542,7 @@ void mgaFlushVerticesLocked( mgaContextPtr mmesa ) vertex.idx = buffer->idx; vertex.used = buffer->used; vertex.discard = discard; - drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX, + drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX, &vertex, sizeof(drmMGAVertex) ); age_mmesa(mmesa, mmesa->sarea->last_enqueue); diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h index ecf513dd7..2d959d824 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h @@ -104,8 +104,9 @@ do { \ if ( ret < 0 ) { \ drmCommandNone( mmesa->driFd, DRM_MGA_RESET ); \ UNLOCK_HARDWARE( mmesa ); \ - fprintf( stderr, "%s: flush ret=%d\n", __FUNCTION__, ret ); \ - /*fprintf( stderr, "drmMGAFlushDMA: return = %d\n", ret );*/ \ + fprintf( stderr, "%s: flush return = %s (%d), flags = 0x%08x\n", \ + __FUNCTION__, strerror( -ret ), -ret, \ + (unsigned)(flags) ); \ exit( 1 ); \ } \ } while (0) diff --git a/xc/lib/GL/mesa/src/drv/mga/mgapixel.c b/xc/lib/GL/mesa/src/drv/mga/mgapixel.c index b454ed72d..07e0c3a75 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgapixel.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgapixel.c @@ -35,7 +35,7 @@ #include "mgacontext.h" #include "mgaioctl.h" #include "mgapixel.h" -#include "mgabuffers.h" +#include "mgastate.h" #include "mga_common.h" @@ -639,42 +639,8 @@ mgaDDDrawPixels( GLcontext *ctx, * the same block of agp space which isn't used for anything else at * present. */ -#if defined(MESA_hacked_agp_allocator) -static void mgaDDFreeAgpMemory( GLcontext *ctx, void *ptr ) -{ - (void) ptr; -} - -static void *mgaDDAllocateAgpMemory( GLcontext *ctx, GLsizei size ) -{ - mgaContextPtr mmesa = MGA_CONTEXT(ctx); - - if (size < mmesa->mgaScreen->textureSize[MGA_AGP_HEAP]) - return mmesa->mgaScreen->texVirtual[MGA_AGP_HEAP]; - else - return 0; -} - -static GLint mgaDDGetAgpOffset( GLcontext *ctx, const void *ptr ) -{ - mgaContextPtr mmesa = MGA_CONTEXT(ctx); - - if (!IS_AGP_MEM(mmesa, ptr)) - return -1; - - return AGP_OFFSET(mmesa, ptr); -} -#endif - - void mgaDDInitPixelFuncs( GLcontext *ctx ) { -#if defined (MESA_experimetal_agp_allocator) - ctx->Driver.AllocateAgpMemory = mgaDDAllocateAgpMemory; - ctx->Driver.GetAgpOffset = mgaDDGetAgpOffset; - ctx->Driver.FreeAgpMemory = mgaDDFreeAgpMemory; -#endif - /* Pixel path fallbacks. */ ctx->Driver.Accum = _swrast_Accum; diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaregs.h b/xc/lib/GL/mesa/src/drv/mga/mgaregs.h index f07dc2de0..401913a5b 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaregs.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgaregs.h @@ -1377,5 +1377,11 @@ /**************** (END) AUTOMATICLY GENERATED REGISTER FILE ******************/ +/* Copied from mga_drv.h kernel file. + */ + +#define MGA_ILOAD_ALIGN 64 +#define MGA_ILOAD_MASK (MGA_ILOAD_ALIGN - 1) + #endif /* _MGAREGS_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c index 61aded398..684239865 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c @@ -116,7 +116,7 @@ #undef INIT_MONO_PIXEL #define INIT_MONO_PIXEL(p, color) \ - p = MGAPACKCOLOR565( color[0], color[1], color[2] ) + p = PACK_COLOR_565( color[0], color[1], color[2] ) #define WRITE_RGBA( _x, _y, r, g, b, a ) \ @@ -148,7 +148,7 @@ do { \ #undef INIT_MONO_PIXEL #define INIT_MONO_PIXEL(p, color) \ - p = MGAPACKCOLOR8888( color[0], color[1], color[2], color[3] ) + p = PACK_COLOR_8888( color[3], color[0], color[1], color[2] ) #define WRITE_RGBA(_x, _y, r, g, b, a) \ diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.c b/xc/lib/GL/mesa/src/drv/mga/mgastate.c index e6a52010d..bda711921 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgastate.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgastate.c @@ -40,18 +40,22 @@ #include "mgatris.h" #include "mgaioctl.h" #include "mgaregs.h" -#include "mgabuffers.h" #include "swrast/swrast.h" #include "array_cache/acache.h" #include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" +static void updateSpecularLighting( GLcontext *ctx ); + + /* Some outstanding problems with accelerating logic ops... */ #if defined(ACCEL_ROP) -static GLuint mgarop_NoBLK[16] = { +static const GLuint mgarop_NoBLK[16] = { DC_atype_rpl | 0x00000000, DC_atype_rstr | 0x00080000, DC_atype_rstr | 0x00040000, DC_atype_rpl | 0x000c0000, DC_atype_rstr | 0x00020000, DC_atype_rstr | 0x000a0000, @@ -64,221 +68,57 @@ static GLuint mgarop_NoBLK[16] = { #endif -static void mgaUpdateStencil(const GLcontext *ctx) -{ - mgaContextPtr mmesa = MGA_CONTEXT(ctx); - GLuint stencil = 0, stencilctl = 0; - - if (ctx->Stencil.Enabled) - { - stencil = ctx->Stencil.Ref[0] | - ( ctx->Stencil.ValueMask[0] << 8 ) | - ( ctx->Stencil.WriteMask[0] << 16 ); - - switch (ctx->Stencil.Function[0]) - { - case GL_NEVER: - MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_snever); - break; - case GL_LESS: - MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_slt); - break; - case GL_LEQUAL: - MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_slte); - break; - case GL_GREATER: - MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_sgt); - break; - case GL_GEQUAL: - MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_sgte); - break; - case GL_NOTEQUAL: - MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_sne); - break; - case GL_EQUAL: - MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_se); - break; - case GL_ALWAYS: - MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_salways); - default: - break; - } - - switch (ctx->Stencil.FailFunc[0]) - { - case GL_KEEP: - MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_keep); - break; - case GL_ZERO: - MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_zero); - break; - case GL_REPLACE: - MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_replace); - break; - case GL_INCR: - MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_incrsat); - break; - case GL_DECR: - MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_decrsat); - break; - case GL_INVERT: - MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_invert); - break; - default: - break; - } - - switch (ctx->Stencil.ZFailFunc[0]) - { - case GL_KEEP: - MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_keep); - break; - case GL_ZERO: - MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_zero); - break; - case GL_REPLACE: - MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_replace); - break; - case GL_INCR: - MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_incrsat); - break; - case GL_DECR: - MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_decrsat); - break; - case GL_INVERT: - MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_invert); - break; - default: - break; - } - - switch (ctx->Stencil.ZPassFunc[0]) - { - case GL_KEEP: - MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_keep); - break; - case GL_ZERO: - MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_zero); - break; - case GL_REPLACE: - MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_replace); - break; - case GL_INCR: - MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_incrsat); - break; - case GL_DECR: - MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_decrsat); - break; - case GL_INVERT: - MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_invert); - break; - default: - break; - } - } - - mmesa->setup.stencil = stencil; - mmesa->setup.stencilctl = stencilctl; - mmesa->dirty |= MGA_UPLOAD_CONTEXT; -} - -static void mgaDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref, - GLuint mask) -{ - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_STENCIL; -} - -static void mgaDDStencilMask(GLcontext *ctx, GLuint mask) -{ - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_STENCIL; -} - -static void mgaDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail, - GLenum zpass) -{ - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_STENCIL; -} +/* ============================================================= + * Alpha blending + */ -static void mgaDDClearDepth(GLcontext *ctx, GLclampd d) +static void mgaDDAlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); + GLubyte refByte; + GLuint a; - /* KW: should the ~ be there? */ - switch (mmesa->setup.maccess & ~MA_zwidth_MASK) { - case MA_zwidth_16: mmesa->ClearDepth = d * 0x0000ffff; break; - case MA_zwidth_24: mmesa->ClearDepth = d * 0xffffff00; break; - case MA_zwidth_32: mmesa->ClearDepth = d * 0xffffffff; break; - default: return; - } -} + CLAMPED_FLOAT_TO_UBYTE(refByte, ref); -static void mgaUpdateZMode(const GLcontext *ctx) -{ - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - int zmode = 0; - - if (ctx->Depth.Test) { - switch(ctx->Depth.Func) { - case GL_NEVER: - /* can't do this in h/w, we'll use a s/w fallback */ - zmode = DC_zmode_nozcmp; - break; - case GL_ALWAYS: - zmode = DC_zmode_nozcmp; break; - case GL_LESS: - zmode = DC_zmode_zlt; break; - case GL_LEQUAL: - zmode = DC_zmode_zlte; break; - case GL_EQUAL: - zmode = DC_zmode_ze; break; - case GL_GREATER: - zmode = DC_zmode_zgt; break; - case GL_GEQUAL: - zmode = DC_zmode_zgte; break; - case GL_NOTEQUAL: - zmode = DC_zmode_zne; break; - default: - break; - } - - if (ctx->Depth.Mask) - zmode |= DC_atype_zi; - else - zmode |= DC_atype_i; - } - else { - zmode |= DC_zmode_nozcmp; - zmode |= DC_atype_i; /* don't write to zbuffer */ + switch ( func ) { + case GL_NEVER: + a = AC_atmode_alt; + refByte = 0; + break; + case GL_LESS: + a = AC_atmode_alt; + break; + case GL_GEQUAL: + a = AC_atmode_agte; + break; + case GL_LEQUAL: + a = AC_atmode_alte; + break; + case GL_GREATER: + a = AC_atmode_agt; + break; + case GL_NOTEQUAL: + a = AC_atmode_ane; + break; + case GL_EQUAL: + a = AC_atmode_ae; + break; + case GL_ALWAYS: + a = AC_atmode_noacmp; + break; + default: + a = 0; + break; } -#if defined(ACCEL_ROP) - mmesa->setup.dwgctl &= DC_bop_MASK; - if (ctx->Color.ColorLogicOpEnabled) - zmode |= mgarop_NoBLK[(ctx->Color.LogicOp)&0xf]; - else - zmode |= mgarop_NoBLK[GL_COPY & 0xf]; -#endif - - mmesa->setup.dwgctl &= DC_zmode_MASK & DC_atype_MASK; - mmesa->setup.dwgctl |= zmode; + FLUSH_BATCH( mmesa ); + mmesa->hw.alpha_func = a | MGA_FIELD( AC_atref, refByte ); mmesa->dirty |= MGA_UPLOAD_CONTEXT; } - -static void mgaDDAlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) -{ - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA; -} - - static void mgaDDBlendEquation(GLcontext *ctx, GLenum mode) { FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA; /* BlendEquation sets ColorLogicOpEnabled in an unexpected * manner. @@ -290,247 +130,169 @@ static void mgaDDBlendEquation(GLcontext *ctx, GLenum mode) static void mgaDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) { - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA; + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; + GLuint src; + GLuint dst; + + switch (ctx->Color.BlendSrcRGB) { + case GL_ZERO: + src = AC_src_zero; break; + case GL_SRC_ALPHA: + src = AC_src_src_alpha; break; + case GL_ONE: + default: /* never happens */ + src = AC_src_one; break; + case GL_DST_COLOR: + src = AC_src_dst_color; break; + case GL_ONE_MINUS_DST_COLOR: + src = AC_src_om_dst_color; break; + case GL_ONE_MINUS_SRC_ALPHA: + src = AC_src_om_src_alpha; break; + case GL_DST_ALPHA: + src = (mgaScreen->cpp == 4) + ? AC_src_dst_alpha : AC_src_one; + break; + case GL_ONE_MINUS_DST_ALPHA: + src = (mgaScreen->cpp == 4) + ? AC_src_om_dst_alpha : AC_src_zero; + break; + case GL_SRC_ALPHA_SATURATE: + src = (ctx->Visual.alphaBits > 0) + ? AC_src_src_alpha_sat : AC_src_zero; + break; + } + + switch (ctx->Color.BlendDstRGB) { + case GL_SRC_ALPHA: + dst = AC_dst_src_alpha; break; + case GL_ONE_MINUS_SRC_ALPHA: + dst = AC_dst_om_src_alpha; break; + default: /* never happens */ + case GL_ZERO: + dst = AC_dst_zero; break; + case GL_ONE: + dst = AC_dst_one; break; + case GL_SRC_COLOR: + dst = AC_dst_src_color; break; + case GL_ONE_MINUS_SRC_COLOR: + dst = AC_dst_om_src_color; break; + case GL_DST_ALPHA: + dst = (mgaScreen->cpp == 4) + ? AC_dst_dst_alpha : AC_dst_one; + break; + case GL_ONE_MINUS_DST_ALPHA: + dst = (mgaScreen->cpp == 4) + ? AC_dst_om_dst_alpha : AC_dst_zero; + break; + } + + FLUSH_BATCH( mmesa ); + mmesa->hw.blend_func = (src | dst); + mmesa->dirty |= MGA_UPLOAD_CONTEXT; } static void mgaDDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA ) { - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA; + mgaDDBlendFunc( ctx, sfactorRGB, dfactorRGB ); } +/* ============================================================= + * Depth testing + */ -static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname, - const GLfloat *param) +static void mgaDDDepthFunc(GLcontext *ctx, GLenum func) { - if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + int zmode; + + switch (func) { + case GL_NEVER: + /* can't do this in h/w, we'll use a s/w fallback */ + FALLBACK (ctx, MGA_FALLBACK_DEPTH, ctx->Depth.Test); + + /* FALLTHROUGH */ + case GL_ALWAYS: + zmode = DC_zmode_nozcmp; break; + case GL_LESS: + zmode = DC_zmode_zlt; break; + case GL_LEQUAL: + zmode = DC_zmode_zlte; break; + case GL_EQUAL: + zmode = DC_zmode_ze; break; + case GL_GREATER: + zmode = DC_zmode_zgt; break; + case GL_GEQUAL: + zmode = DC_zmode_zgte; break; + case GL_NOTEQUAL: + zmode = DC_zmode_zne; break; + default: + zmode = 0; break; } -} - -static void mgaDDShadeModel(GLcontext *ctx, GLenum mode) -{ - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; -} - - -static void mgaDDDepthFunc(GLcontext *ctx, GLenum func) -{ - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH; + FLUSH_BATCH( mmesa ); + mmesa->hw.zmode &= DC_zmode_MASK; + mmesa->hw.zmode |= zmode; + mmesa->dirty |= MGA_UPLOAD_CONTEXT; } static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag) { - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH; -} + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); -#if defined(ACCEL_ROP) -static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode ) -{ - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH; -} -#else -static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode ) -{ - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - FALLBACK( ctx, MGA_FALLBACK_LOGICOP, - (ctx->Color.ColorLogicOpEnabled && opcode != GL_COPY) ); -} -#endif + FLUSH_BATCH( mmesa ); + mmesa->hw.zmode &= DC_atype_MASK; + mmesa->hw.zmode |= (flag) ? DC_atype_zi : DC_atype_i; + mmesa->dirty |= MGA_UPLOAD_CONTEXT; +} -static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) +static void mgaDDClearDepth(GLcontext *ctx, GLclampd d) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); - if (pname == GL_FOG_COLOR) { - GLuint color = MGAPACKCOLOR888((GLubyte)(ctx->Fog.Color[0]*255.0F), - (GLubyte)(ctx->Fog.Color[1]*255.0F), - (GLubyte)(ctx->Fog.Color[2]*255.0F)); - - MGA_STATECHANGE(mmesa, MGA_UPLOAD_CONTEXT); - mmesa->setup.fogcolor = color; + /* Select the Z depth. The ~ is used because the _MASK values in the + * MGA driver are used to mask OFF the selected bits. In this case, + * we want to mask off everything except the MA_zwidth bits. + */ + switch (mmesa->setup.maccess & ~MA_zwidth_MASK) { + case MA_zwidth_16: mmesa->ClearDepth = d * 0x0000ffff; break; + case MA_zwidth_24: mmesa->ClearDepth = d * 0xffffff00; break; + case MA_zwidth_32: mmesa->ClearDepth = d * 0xffffffff; break; + default: return; } } - - /* ============================================================= - * Alpha blending + * Fog */ -static void mgaUpdateAlphaMode(GLcontext *ctx) +static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; - int a = 0; - - /* determine source of alpha for blending and testing */ - if (ctx->Texture._EnabledUnits == 0) { - a |= AC_alphasel_diffused; - } - else { - /* G400: Regardless of texture env mode, we use the alpha from the - * texture unit (AC_alphasel_fromtex) since it will have already - * been modulated by the incoming fragment color, if needed. - * We don't want (AC_alphasel_modulate) since that'll effectively - * do the modulation twice. - */ - if (MGA_IS_G400(mmesa)) { - a |= AC_alphasel_fromtex; - } - else { - /* G200 */ - switch (ctx->Texture.Unit[0].EnvMode) { - case GL_DECAL: - a |= AC_alphasel_diffused; - case GL_REPLACE: - a |= AC_alphasel_fromtex; - break; - case GL_BLEND: - case GL_MODULATE: - a |= AC_alphasel_modulated; - break; - default: - break; - } - } - } - - - /* alpha test control. - */ - if (ctx->Color.AlphaEnabled) { - GLubyte ref = (GLint) (ctx->Color.AlphaRef * 255.0); - switch (ctx->Color.AlphaFunc) { - case GL_NEVER: - a |= AC_atmode_alt; - ref = 0; - break; - case GL_LESS: - a |= AC_atmode_alt; - break; - case GL_GEQUAL: - a |= AC_atmode_agte; - break; - case GL_LEQUAL: - a |= AC_atmode_alte; - break; - case GL_GREATER: - a |= AC_atmode_agt; - break; - case GL_NOTEQUAL: - a |= AC_atmode_ane; - break; - case GL_EQUAL: - a |= AC_atmode_ae; - break; - case GL_ALWAYS: - a |= AC_atmode_noacmp; - break; - default: - break; - } - a |= MGA_FIELD(AC_atref,ref); - } + mgaContextPtr mmesa = MGA_CONTEXT(ctx); - /* blending control */ - if (ctx->Color.BlendEnabled) { - switch (ctx->Color.BlendSrcRGB) { - case GL_ZERO: - a |= AC_src_zero; break; - case GL_SRC_ALPHA: - a |= AC_src_src_alpha; break; - case GL_ONE: - a |= AC_src_one; break; - case GL_DST_COLOR: - a |= AC_src_dst_color; break; - case GL_ONE_MINUS_DST_COLOR: - a |= AC_src_om_dst_color; break; - case GL_ONE_MINUS_SRC_ALPHA: - a |= AC_src_om_src_alpha; break; - case GL_DST_ALPHA: - if (mgaScreen->cpp == 4) - a |= AC_src_dst_alpha; - else - a |= AC_src_one; - break; - case GL_ONE_MINUS_DST_ALPHA: - if (mgaScreen->cpp == 4) - a |= AC_src_om_dst_alpha; - else - a |= AC_src_zero; - break; - case GL_SRC_ALPHA_SATURATE: - if (ctx->Visual.alphaBits > 0) - a |= AC_src_src_alpha_sat; - else - a |= AC_src_zero; - break; - default: /* never happens */ - break; - } + if (pname == GL_FOG_COLOR) { + GLuint color = PACK_COLOR_888((GLubyte)(ctx->Fog.Color[0]*255.0F), + (GLubyte)(ctx->Fog.Color[1]*255.0F), + (GLubyte)(ctx->Fog.Color[2]*255.0F)); - switch (ctx->Color.BlendDstRGB) { - case GL_SRC_ALPHA: - a |= AC_dst_src_alpha; break; - case GL_ONE_MINUS_SRC_ALPHA: - a |= AC_dst_om_src_alpha; break; - case GL_ZERO: - a |= AC_dst_zero; break; - case GL_ONE: - a |= AC_dst_one; break; - case GL_SRC_COLOR: - a |= AC_dst_src_color; break; - case GL_ONE_MINUS_SRC_COLOR: - a |= AC_dst_om_src_color; break; - case GL_DST_ALPHA: - if (mgaScreen->cpp == 4) - a |= AC_dst_dst_alpha; - else - a |= AC_dst_one; - break; - case GL_ONE_MINUS_DST_ALPHA: - if (mgaScreen->cpp == 4) - a |= AC_dst_om_dst_alpha; - else - a |= AC_dst_zero; - break; - default: /* never happens */ - break; - } - } else { - a |= AC_src_one|AC_dst_zero; + MGA_STATECHANGE(mmesa, MGA_UPLOAD_CONTEXT); + mmesa->setup.fogcolor = color; } - - mmesa->setup.alphactrl = (AC_amode_alpha_channel | - AC_astipple_disable | - AC_aten_disable | - AC_atmode_noacmp | - a); - - mmesa->dirty |= MGA_UPLOAD_CONTEXT; } - /* ============================================================= - * Hardware clipping + * Scissoring */ + void mgaUpdateClipping(const GLcontext *ctx) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); @@ -553,13 +315,6 @@ void mgaUpdateClipping(const GLcontext *ctx) mmesa->scissor_rect.x2 = x2; mmesa->scissor_rect.y2 = y2; - if (MGA_DEBUG&DEBUG_VERBOSE_2D) - fprintf(stderr, "SET SCISSOR %d,%d-%d,%d\n", - mmesa->scissor_rect.x1, - mmesa->scissor_rect.y1, - mmesa->scissor_rect.x2, - mmesa->scissor_rect.y2); - mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; } } @@ -568,23 +323,10 @@ void mgaUpdateClipping(const GLcontext *ctx) static void mgaDDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) { - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CLIP; -} - - -static void mgaDDClearColor(GLcontext *ctx, - const GLfloat color[4] ) -{ - mgaContextPtr mmesa = MGA_CONTEXT(ctx); - GLubyte c[4]; - CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]); - CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); - CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); - CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]); - - mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->cpp, - c[0], c[1], c[2], c[3]); + if ( ctx->Scissor.Enabled ) { + FLUSH_BATCH( MGA_CONTEXT(ctx) ); /* don't pipeline cliprect changes */ + mgaUpdateClipping( ctx ); + } } @@ -592,46 +334,42 @@ static void mgaDDClearColor(GLcontext *ctx, * Culling */ + #define _CULL_DISABLE 0 #define _CULL_NEGATIVE ((1<<11)|(1<<5)|(1<<16)) #define _CULL_POSITIVE (1<<11) - -void mgaUpdateCull( GLcontext *ctx ) +static void mgaDDCullFaceFrontFace(GLcontext *ctx, GLenum unused) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); - GLuint mode = _CULL_DISABLE; + + FLUSH_BATCH( mmesa ); if (ctx->Polygon.CullFlag && - mmesa->raster_primitive == GL_TRIANGLES && ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { - mode = _CULL_NEGATIVE; + mmesa->hw.cull = _CULL_NEGATIVE; + if (ctx->Polygon.CullFaceMode == GL_FRONT) - mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); + mmesa->hw.cull ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); + if (ctx->Polygon.FrontFace != GL_CCW) - mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); - if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT && - ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) - mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); /* warp bug? */ + mmesa->hw.cull ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); + + mmesa->hw.cull_dualtex = mmesa->hw.cull ^ + (_CULL_POSITIVE ^ _CULL_NEGATIVE); /* warp bug? */ + } + else { + mmesa->hw.cull = _CULL_DISABLE; + mmesa->hw.cull_dualtex = _CULL_DISABLE; } - mmesa->setup.wflag = mode; mmesa->dirty |= MGA_UPLOAD_CONTEXT; } -static void mgaDDCullFaceFrontFace(GLcontext *ctx, GLenum mode) -{ - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CULL; -} - - - - /* ============================================================= - * Color masks + * Masks */ static void mgaDDColorMask(GLcontext *ctx, @@ -657,15 +395,11 @@ static void mgaDDColorMask(GLcontext *ctx, } } + /* ============================================================= - * Polygon stipple - * - * The mga supports a subset of possible 4x4 stipples natively, GL - * wants 32x32. Fortunately stipple is usually a repeating pattern. - * - * Note: the fully opaque pattern (0xffff) has been disabled in order - * to work around a conformance issue. + * Polygon state */ + static int mgaStipples[16] = { 0xffff1, /* See above note */ 0xa5a5, @@ -685,6 +419,17 @@ static int mgaStipples[16] = { 0x0000 }; +/** + * The MGA supports a subset of possible 4x4 stipples natively, GL + * wants 32x32. Fortunately stipple is usually a repeating pattern. + * + * \param ctx GL rendering context to be affected + * \param mask Pointer to the 32x32 stipple mask + * + * \note the fully opaque pattern (0xffff) has been disabled in order + * to work around a conformance issue. + */ + static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); @@ -733,93 +478,216 @@ static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) } } + /* ============================================================= + * Rendering attributes + * + * We really don't want to recalculate all this every time we bind a + * texture. These things shouldn't change all that often, so it makes + * sense to break them out of the core texture state update routines. */ -static void mgaDDPrintDirty( const char *msg, GLuint state ) +static void updateSpecularLighting( GLcontext *ctx ) { - fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n", - msg, - (unsigned int) state, - (state & MGA_WAIT_AGE) ? "wait-age, " : "", - (state & MGA_UPLOAD_TEX0IMAGE) ? "upload-tex0-img, " : "", - (state & MGA_UPLOAD_TEX1IMAGE) ? "upload-tex1-img, " : "", - (state & MGA_UPLOAD_CONTEXT) ? "upload-ctx, " : "", - (state & MGA_UPLOAD_TEX0) ? "upload-tex0, " : "", - (state & MGA_UPLOAD_TEX1) ? "upload-tex1, " : "", - (state & MGA_UPLOAD_PIPE) ? "upload-pipe, " : "" - ); + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + unsigned int specen; + + specen = (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR && + ctx->Light.Enabled) ? TMC_specen_enable : 0; + + if ( specen != mmesa->hw.specen ) { + mmesa->hw.specen = specen; + mmesa->dirty |= MGA_UPLOAD_TEX0 | MGA_UPLOAD_TEX1; + + mgaChooseVertexState( ctx ); + } } -/* Push the state into the sarea and/or texture memory. + +/* ============================================================= + * Materials */ -void mgaEmitHwStateLocked( mgaContextPtr mmesa ) -{ - MGASAREAPrivPtr sarea = mmesa->sarea; - if (MGA_DEBUG & DEBUG_VERBOSE_MSG) - mgaDDPrintDirty( "mgaEmitHwStateLocked", mmesa->dirty ); - if ((mmesa->dirty & MGA_UPLOAD_TEX0IMAGE) && mmesa->CurrentTexObj[0]) - mgaUploadTexImages(mmesa, mmesa->CurrentTexObj[0]); +static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname, + const GLfloat *param) +{ + if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { + FLUSH_BATCH( MGA_CONTEXT(ctx) ); + updateSpecularLighting( ctx ); + } +} - if ((mmesa->dirty & MGA_UPLOAD_TEX1IMAGE) && mmesa->CurrentTexObj[1]) - mgaUploadTexImages(mmesa, mmesa->CurrentTexObj[1]); - if (mmesa->dirty & MGA_UPLOAD_CONTEXT) { - memcpy( &sarea->ContextState, &mmesa->setup, sizeof(mmesa->setup)); - } +static void mgaDDShadeModel(GLcontext *ctx, GLenum mode) +{ + /* FIXME: This used to FLUSH_BATCH and set MGA_NEW_TEXTURE in new_state, + * FIXME: so I'm not sure what to do here now. + */ +} - if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0]) { - memcpy(&sarea->TexState[0], - &mmesa->CurrentTexObj[0]->setup, - sizeof(sarea->TexState[0])); - } - if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1]) { - memcpy(&sarea->TexState[1], - &mmesa->CurrentTexObj[1]->setup, - sizeof(sarea->TexState[1])); - } +/* ============================================================= + * Stencil + */ - if (sarea->TexState[0].texctl2 != - sarea->TexState[1].texctl2) { - memcpy(&sarea->TexState[1], - &sarea->TexState[0], - sizeof(sarea->TexState[0])); - mmesa->dirty |= MGA_UPLOAD_TEX1|MGA_UPLOAD_TEX0; - } - if (mmesa->dirty & MGA_UPLOAD_PIPE) { -/* mmesa->sarea->wacceptseq = mmesa->hw_primitive; */ - mmesa->sarea->WarpPipe = mmesa->vertex_format; - mmesa->sarea->vertsize = mmesa->vertex_size; +static void mgaDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref, + GLuint mask) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + GLuint stencil; + GLuint stencilctl; + + stencil = (ref << S_sref_SHIFT) | (mask << S_smsk_SHIFT); + switch (func) + { + case GL_NEVER: + stencilctl = SC_smode_snever; + break; + case GL_LESS: + stencilctl = SC_smode_slt; + break; + case GL_LEQUAL: + stencilctl = SC_smode_slte; + break; + case GL_GREATER: + stencilctl = SC_smode_sgt; + break; + case GL_GEQUAL: + stencilctl = SC_smode_sgte; + break; + case GL_NOTEQUAL: + stencilctl = SC_smode_sne; + break; + case GL_EQUAL: + stencilctl = SC_smode_se; + break; + case GL_ALWAYS: + default: + stencilctl = SC_smode_salways; + break; } - mmesa->sarea->dirty |= mmesa->dirty; + FLUSH_BATCH( mmesa ); + mmesa->hw.stencil &= (S_sref_MASK & S_smsk_MASK); + mmesa->hw.stencil |= stencil; + mmesa->hw.stencilctl &= SC_smode_MASK; + mmesa->hw.stencilctl |= stencilctl; + mmesa->dirty |= MGA_UPLOAD_CONTEXT; +} - mmesa->dirty &= (MGA_UPLOAD_CLIPRECTS|MGA_WAIT_AGE); +static void mgaDDStencilMask(GLcontext *ctx, GLuint mask) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); - /* This is a bit of a hack but seems to be the best place to ensure - * that separate specular is disabled when not needed. - */ - if (mmesa->glCtx->Texture._EnabledUnits == 0 || - !mmesa->glCtx->Light.Enabled || - mmesa->glCtx->Light.Model.ColorControl == GL_SINGLE_COLOR) { - sarea->TexState[0].texctl2 &= ~TMC_specen_enable; - sarea->TexState[1].texctl2 &= ~TMC_specen_enable; - } + FLUSH_BATCH( mmesa ); + mmesa->hw.stencil &= S_swtmsk_MASK; + mmesa->hw.stencil |= (mask << S_swtmsk_SHIFT); + mmesa->dirty |= MGA_UPLOAD_CONTEXT; } -/* Fallback to swrast for select and feedback. - */ -static void mgaRenderMode( GLcontext *ctx, GLenum mode ) +static void mgaDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail, + GLenum zpass) { - FALLBACK( ctx, MGA_FALLBACK_RENDERMODE, (mode != GL_RENDER) ); + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + GLuint stencilctl; + + stencilctl = 0; + switch (ctx->Stencil.FailFunc[0]) + { + case GL_KEEP: + stencilctl |= SC_sfailop_keep; + break; + case GL_ZERO: + stencilctl |= SC_sfailop_zero; + break; + case GL_REPLACE: + stencilctl |= SC_sfailop_replace; + break; + case GL_INCR: + stencilctl |= SC_sfailop_incrsat; + break; + case GL_DECR: + stencilctl |= SC_sfailop_decrsat; + break; + case GL_INCR_WRAP: + stencilctl |= SC_sfailop_incr; + break; + case GL_DECR_WRAP: + stencilctl |= SC_sfailop_decr; + break; + case GL_INVERT: + stencilctl |= SC_sfailop_invert; + break; + default: + break; + } + + switch (ctx->Stencil.ZFailFunc[0]) + { + case GL_KEEP: + stencilctl |= SC_szfailop_keep; + break; + case GL_ZERO: + stencilctl |= SC_szfailop_zero; + break; + case GL_REPLACE: + stencilctl |= SC_szfailop_replace; + break; + case GL_INCR: + stencilctl |= SC_szfailop_incrsat; + break; + case GL_DECR: + stencilctl |= SC_szfailop_decrsat; + break; + case GL_INCR_WRAP: + stencilctl |= SC_szfailop_incr; + break; + case GL_DECR_WRAP: + stencilctl |= SC_szfailop_decr; + break; + case GL_INVERT: + stencilctl |= SC_szfailop_invert; + break; + default: + break; + } + + switch (ctx->Stencil.ZPassFunc[0]) + { + case GL_KEEP: + stencilctl |= SC_szpassop_keep; + break; + case GL_ZERO: + stencilctl |= SC_szpassop_zero; + break; + case GL_REPLACE: + stencilctl |= SC_szpassop_replace; + break; + case GL_INCR: + stencilctl |= SC_szpassop_incrsat; + break; + case GL_DECR: + stencilctl |= SC_szpassop_decrsat; + break; + case GL_INVERT: + stencilctl |= SC_szpassop_invert; + break; + default: + break; + } + + FLUSH_BATCH( mmesa ); + mmesa->hw.stencilctl &= (SC_sfailop_MASK & SC_szfailop_MASK + & SC_szpassop_MASK); + mmesa->hw.stencilctl |= stencilctl; + mmesa->dirty |= MGA_UPLOAD_CONTEXT; } /* ============================================================= + * Window position and viewport transformation */ void mgaCalcViewport( GLcontext *ctx ) @@ -853,8 +721,169 @@ static void mgaDepthRange( GLcontext *ctx, mgaCalcViewport( ctx ); } + /* ============================================================= + * Miscellaneous + */ + +static void mgaDDClearColor(GLcontext *ctx, + const GLfloat color[4] ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + GLubyte c[4]; + CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]); + + mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->cpp, + c[0], c[1], c[2], c[3]); +} + + +/* Fallback to swrast for select and feedback. */ +static void mgaRenderMode( GLcontext *ctx, GLenum mode ) +{ + FALLBACK( ctx, MGA_FALLBACK_RENDERMODE, (mode != GL_RENDER) ); +} + + +static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode ) +{ + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + + FLUSH_BATCH( mmesa ); +#if defined(ACCEL_ROP) + mmesa->hw.rop = mgarop_NoBLK[ opcode & 0x0f ]; + mmesa->dirty |= MGA_UPLOAD_CONTEXT; +#else + FALLBACK( ctx, MGA_FALLBACK_LOGICOP, + (ctx->Color.ColorLogicOpEnabled && opcode != GL_COPY) ); +#endif +} + + +static void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa ) +{ + __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; + + if (driDrawable->numClipRects == 0) { + static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0}; + mmesa->numClipRects = 1; + mmesa->pClipRects = &zeroareacliprect; + } else { + mmesa->numClipRects = driDrawable->numClipRects; + mmesa->pClipRects = driDrawable->pClipRects; + } + mmesa->drawX = driDrawable->x; + mmesa->drawY = driDrawable->y; + + mmesa->setup.dstorg = mmesa->drawOffset; + mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS; +} + + +static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa ) +{ + __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; + + if (driDrawable->numBackClipRects == 0) + { + if (driDrawable->numClipRects == 0) { + static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0}; + mmesa->numClipRects = 1; + mmesa->pClipRects = &zeroareacliprect; + } else { + mmesa->numClipRects = driDrawable->numClipRects; + mmesa->pClipRects = driDrawable->pClipRects; + } + mmesa->drawX = driDrawable->x; + mmesa->drawY = driDrawable->y; + } else { + mmesa->numClipRects = driDrawable->numBackClipRects; + mmesa->pClipRects = driDrawable->pBackClipRects; + mmesa->drawX = driDrawable->backX; + mmesa->drawY = driDrawable->backY; + } + + mmesa->setup.dstorg = mmesa->drawOffset; + mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS; +} + + +void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers ) +{ + __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; + MGASAREAPrivPtr sarea = mmesa->sarea; + + + DRI_VALIDATE_DRAWABLE_INFO(mmesa->driScreen, driDrawable); + mmesa->dirty_cliprects = 0; + + if (mmesa->draw_buffer == MGA_FRONT) + mgaXMesaSetFrontClipRects( mmesa ); + else + mgaXMesaSetBackClipRects( mmesa ); + + + sarea->req_drawable = driDrawable->draw; + sarea->req_draw_buffer = mmesa->draw_buffer; + + mgaUpdateClipping( mmesa->glCtx ); + mgaCalcViewport( mmesa->glCtx ); + + mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; +} + + +static void mgaDDDrawBuffer(GLcontext *ctx, GLenum mode ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + + FLUSH_BATCH( mmesa ); + + /* + * _DrawDestMask is easier to cope with than <mode>. + */ + switch ( ctx->Color._DrawDestMask ) { + case FRONT_LEFT_BIT: + mmesa->setup.dstorg = mmesa->mgaScreen->frontOffset; + mmesa->dirty |= MGA_UPLOAD_CONTEXT; + mmesa->draw_buffer = MGA_FRONT; + mgaXMesaSetFrontClipRects( mmesa ); + FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE ); + break; + case BACK_LEFT_BIT: + mmesa->setup.dstorg = mmesa->mgaScreen->backOffset; + mmesa->draw_buffer = MGA_BACK; + mmesa->dirty |= MGA_UPLOAD_CONTEXT; + mgaXMesaSetBackClipRects( mmesa ); + FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE ); + break; + default: + /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ + FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE ); + return; + } + + /* We want to update the s/w rast state too so that r200SetBuffer() + * gets called. + */ + _swrast_DrawBuffer(ctx, mode); +} + + +static void mgaDDReadBuffer(GLcontext *ctx, GLenum mode ) +{ + /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ +} + + +/* ============================================================= + * State enable/disable + */ + static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state) { @@ -863,11 +892,11 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state) switch(cap) { case GL_ALPHA_TEST: FLUSH_BATCH( mmesa ); - mmesa->new_state |= MGA_NEW_ALPHA; + mmesa->hw.alpha_func_enable = (state) ? ~0 : 0; break; case GL_BLEND: FLUSH_BATCH( mmesa ); - mmesa->new_state |= MGA_NEW_ALPHA; + mmesa->hw.blend_func_enable = (state) ? ~0 : 0; /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled. */ @@ -877,31 +906,31 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state) break; case GL_DEPTH_TEST: FLUSH_BATCH( mmesa ); - mmesa->new_state |= MGA_NEW_DEPTH; FALLBACK (ctx, MGA_FALLBACK_DEPTH, ctx->Depth.Func == GL_NEVER && ctx->Depth.Test); break; + case GL_SCISSOR_TEST: FLUSH_BATCH( mmesa ); mmesa->scissor = state; - mmesa->new_state |= MGA_NEW_CLIP; + mgaUpdateClipping( ctx ); break; + case GL_FOG: MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT ); if (ctx->Fog.Enabled) mmesa->setup.maccess |= MA_fogen_enable; else mmesa->setup.maccess &= ~MA_fogen_enable; + + mgaChooseVertexState( ctx ); break; case GL_CULL_FACE: - FLUSH_BATCH( mmesa ); - mmesa->new_state |= MGA_NEW_CULL; + mgaDDCullFaceFrontFace( ctx, 0 ); break; case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_3D: - FLUSH_BATCH( mmesa ); - mmesa->new_state |= (MGA_NEW_TEXTURE|MGA_NEW_ALPHA); break; case GL_POLYGON_STIPPLE: if (mmesa->haveHwStipple && mmesa->raster_primitive == GL_TRIANGLES) { @@ -917,16 +946,16 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state) #if !defined(ACCEL_ROP) FALLBACK( ctx, MGA_FALLBACK_LOGICOP, (state && ctx->Color.LogicOp != GL_COPY)); -#else - mmesa->new_state |= MGA_NEW_DEPTH; #endif break; case GL_STENCIL_TEST: FLUSH_BATCH( mmesa ); - if (mmesa->hw_stencil) - mmesa->new_state |= MGA_NEW_STENCIL; - else + if (mmesa->hw_stencil) { + mmesa->hw.stencil_enable = ( state ) ? ~0 : 0; + } + else { FALLBACK( ctx, MGA_FALLBACK_STENCIL, state ); + } default: break; } @@ -936,56 +965,148 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state) /* ============================================================= */ - - -/* ============================================================= - */ - -static void mgaDDPrintState( const char *msg, GLuint state ) +static void mgaDDPrintDirty( const char *msg, GLuint state ) { - fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s\n", + fprintf(stderr, "%s (0x%03x): %s%s%s%s%s%s%s\n", msg, - state, - (state & MGA_NEW_DEPTH) ? "depth, " : "", - (state & MGA_NEW_ALPHA) ? "alpha, " : "", - (state & MGA_NEW_CLIP) ? "clip, " : "", - (state & MGA_NEW_CULL) ? "cull, " : "", - (state & MGA_NEW_TEXTURE) ? "texture, " : "", - (state & MGA_NEW_CONTEXT) ? "context, " : ""); + (unsigned int) state, + (state & MGA_WAIT_AGE) ? "wait-age " : "", + (state & MGA_UPLOAD_TEX0IMAGE) ? "upload-tex0-img " : "", + (state & MGA_UPLOAD_TEX1IMAGE) ? "upload-tex1-img " : "", + (state & MGA_UPLOAD_CONTEXT) ? "upload-ctx " : "", + (state & MGA_UPLOAD_TEX0) ? "upload-tex0 " : "", + (state & MGA_UPLOAD_TEX1) ? "upload-tex1 " : "", + (state & MGA_UPLOAD_PIPE) ? "upload-pipe " : "" + ); } -void mgaDDUpdateHwState( GLcontext *ctx ) +/* Push the state into the sarea and/or texture memory. + */ +void mgaEmitHwStateLocked( mgaContextPtr mmesa ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - int new_state = mmesa->new_state; + MGASAREAPrivPtr sarea = mmesa->sarea; + GLcontext * ctx = mmesa->glCtx; - if (new_state) - { - FLUSH_BATCH( mmesa ); + if (MGA_DEBUG & DEBUG_VERBOSE_MSG) + mgaDDPrintDirty( __FUNCTION__, mmesa->dirty ); - mmesa->new_state = 0; + if (mmesa->dirty & MGA_UPLOAD_CONTEXT) { + mmesa->setup.wflag = _CULL_DISABLE; + if (mmesa->raster_primitive == GL_TRIANGLES) { + if ((ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT && + ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT)) { + mmesa->setup.wflag = mmesa->hw.cull_dualtex; + } + else { + mmesa->setup.wflag = mmesa->hw.cull; + } + } + + mmesa->setup.stencil = mmesa->hw.stencil + & mmesa->hw.stencil_enable; + mmesa->setup.stencilctl = mmesa->hw.stencilctl + & mmesa->hw.stencil_enable; + + /* If depth testing is not enabled, then use the no Z-compare / no + * Z-write mode. Otherwise, use whatever is set in hw.zmode. + */ + mmesa->setup.dwgctl &= (DC_zmode_MASK & DC_atype_MASK); + mmesa->setup.dwgctl |= (ctx->Depth.Test) + ? mmesa->hw.zmode : (DC_zmode_nozcmp | DC_atype_i); + +#if defined(ACCEL_ROP) + mmesa->setup.dwgctl &= DC_bop_MASK; + mmesa->setup.dwgctl |= (ctx->Color.ColorLogicOpEnabled) + ? mmesa->hw.rop : mgarop_NoBLK[ GL_COPY & 0x0f ]; +#endif + + mmesa->setup.alphactrl &= AC_src_MASK & AC_dst_MASK & AC_atmode_MASK + & AC_atref_MASK; + mmesa->setup.alphactrl |= + ((mmesa->hw.alpha_func & mmesa->hw.alpha_func_enable) + | ((mmesa->hw.blend_func & mmesa->hw.blend_func_enable) + | ((AC_src_one | AC_dst_zero) & ~mmesa->hw.blend_func_enable)) + | mmesa->hw.alpha_sel + | (AC_amode_alpha_channel + | AC_astipple_disable + | AC_aten_disable + | AC_atmode_noacmp)); + + memcpy( &sarea->ContextState, &mmesa->setup, sizeof(mmesa->setup)); + } + + if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0]) { + mmesa->CurrentTexObj[0]->setup.texctl2 &= ~TMC_specen_enable; + mmesa->CurrentTexObj[0]->setup.texctl2 |= mmesa->hw.specen; + + memcpy(&sarea->TexState[0], + &mmesa->CurrentTexObj[0]->setup, + sizeof(sarea->TexState[0])); + } + + if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1]) { + mmesa->CurrentTexObj[1]->setup.texctl2 &= ~TMC_specen_enable; + mmesa->CurrentTexObj[1]->setup.texctl2 |= mmesa->hw.specen; + + memcpy(&sarea->TexState[1], + &mmesa->CurrentTexObj[1]->setup, + sizeof(sarea->TexState[1])); + } + + if (sarea->TexState[0].texctl2 != + sarea->TexState[1].texctl2) { + memcpy(&sarea->TexState[1], + &sarea->TexState[0], + sizeof(sarea->TexState[0])); + mmesa->dirty |= MGA_UPLOAD_TEX1|MGA_UPLOAD_TEX0; + } + + if (mmesa->dirty & MGA_UPLOAD_PIPE) { +/* mmesa->sarea->wacceptseq = mmesa->hw_primitive; */ + mmesa->sarea->WarpPipe = mmesa->vertex_format; + mmesa->sarea->vertsize = mmesa->vertex_size; + } + + mmesa->sarea->dirty |= mmesa->dirty; + mmesa->dirty &= MGA_UPLOAD_CLIPRECTS; + + /* This is a bit of a hack but seems to be the best place to ensure + * that separate specular is disabled when not needed. + */ + if (ctx->Texture._EnabledUnits == 0 || + !ctx->Light.Enabled || + ctx->Light.Model.ColorControl == GL_SINGLE_COLOR) { + sarea->TexState[0].texctl2 &= ~TMC_specen_enable; + sarea->TexState[1].texctl2 &= ~TMC_specen_enable; + } +} + + +/* ============================================================= + */ - if (MESA_VERBOSE&VERBOSE_DRIVER) - mgaDDPrintState("UpdateHwState", new_state); - if (new_state & MGA_NEW_DEPTH) - mgaUpdateZMode(ctx); +static void mgaDDValidateState( GLcontext *ctx ) +{ + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + int new_state = mmesa->NewGLState; - if (new_state & MGA_NEW_ALPHA) - mgaUpdateAlphaMode(ctx); - if (new_state & MGA_NEW_CLIP) - mgaUpdateClipping(ctx); + FLUSH_BATCH( mmesa ); - if (new_state & MGA_NEW_STENCIL) - mgaUpdateStencil(ctx); + if (mmesa->NewGLState & _MGA_NEW_RASTERSETUP) { + mgaChooseVertexState( ctx ); + } - if (new_state & (MGA_NEW_WARP|MGA_NEW_CULL)) - mgaUpdateCull(ctx); + if (mmesa->NewGLState & _MGA_NEW_RENDERSTATE) { + mgaChooseRenderState( ctx ); + } - if (new_state & (MGA_NEW_WARP|MGA_NEW_TEXTURE)) - mgaUpdateTextureState(ctx); + if (new_state & _NEW_TEXTURE) { + mgaUpdateTextureState(ctx); } + + mmesa->NewGLState = 0; } @@ -995,10 +1116,25 @@ static void mgaDDInvalidateState( GLcontext *ctx, GLuint new_state ) _swsetup_InvalidateState( ctx, new_state ); _ac_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); - MGA_CONTEXT(ctx)->new_gl_state |= new_state; + MGA_CONTEXT(ctx)->NewGLState |= new_state; } +static void mgaRunPipeline( GLcontext *ctx ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + + if (mmesa->NewGLState) { + mgaDDValidateState( ctx ); + } + + if (mmesa->dirty) { + mgaEmitHwStateLocked( mmesa ); + } + + _tnl_run_pipeline( ctx ); +} + void mgaInitState( mgaContextPtr mmesa ) { @@ -1008,14 +1144,12 @@ void mgaInitState( mgaContextPtr mmesa ) if (ctx->Visual.doubleBufferMode) { /* use back buffer by default */ mmesa->draw_buffer = MGA_BACK; - mmesa->read_buffer = MGA_BACK; mmesa->drawOffset = mmesa->mgaScreen->backOffset; mmesa->readOffset = mmesa->mgaScreen->backOffset; mmesa->setup.dstorg = mgaScreen->backOffset; } else { /* use front buffer by default */ mmesa->draw_buffer = MGA_FRONT; - mmesa->read_buffer = MGA_FRONT; mmesa->drawOffset = mmesa->mgaScreen->frontOffset; mmesa->readOffset = mmesa->mgaScreen->frontOffset; mmesa->setup.dstorg = mgaScreen->frontOffset; @@ -1048,14 +1182,21 @@ void mgaInitState( mgaContextPtr mmesa ) mmesa->setup.maccess |= MA_zwidth_24; break; case 32: - mmesa->setup.maccess |= MA_pwidth_32; + mmesa->setup.maccess |= MA_zwidth_32; break; } + mmesa->hw.zmode = DC_zmode_zlt | DC_atype_zi; + mmesa->hw.stencil = (0x0ff << S_smsk_SHIFT) | (0x0ff << S_swtmsk_SHIFT); + mmesa->hw.stencilctl = SC_smode_salways | SC_sfailop_keep + | SC_szfailop_keep | SC_szpassop_keep; + mmesa->hw.stencil_enable = 0; + mmesa->hw.cull = _CULL_NEGATIVE; + mmesa->hw.cull_dualtex = _CULL_POSITIVE; + mmesa->hw.specen = 0; + mmesa->setup.dwgctl = (DC_opcod_trap | - DC_atype_i | DC_linear_xy | - DC_zmode_nozcmp | DC_solid_disable | DC_arzero_disable | DC_sgnzero_disable | @@ -1077,16 +1218,15 @@ void mgaInitState( mgaContextPtr mmesa ) AC_atmode_noacmp | AC_alphasel_fromtex ); - mmesa->setup.fogcolor = - MGAPACKCOLOR888((GLubyte)(ctx->Fog.Color[0]*255.0F), - (GLubyte)(ctx->Fog.Color[1]*255.0F), - (GLubyte)(ctx->Fog.Color[2]*255.0F)); + mmesa->setup.fogcolor = PACK_COLOR_888((GLubyte)(ctx->Fog.Color[0]*255.0F), + (GLubyte)(ctx->Fog.Color[1]*255.0F), + (GLubyte)(ctx->Fog.Color[2]*255.0F)); mmesa->setup.wflag = 0; mmesa->setup.tdualstage0 = 0; mmesa->setup.tdualstage1 = 0; mmesa->setup.fcol = 0; - mmesa->new_state = ~0; + mmesa->dirty |= MGA_UPLOAD_CONTEXT; } @@ -1133,4 +1273,6 @@ void mgaDDInitStateFuncs( GLcontext *ctx ) ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; + + TNL_CONTEXT(ctx)->Driver.RunPipeline = mgaRunPipeline; } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.h b/xc/lib/GL/mesa/src/drv/mga/mgastate.h index a9f1039d7..afbe0aaf9 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgastate.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgastate.h @@ -29,14 +29,11 @@ #ifndef _MGA_STATE_H #define _MGA_STATE_H - extern void mgaInitState( mgaContextPtr mmesa ); extern void mgaDDInitStateFuncs(GLcontext *ctx); -extern void mgaDDUpdateHwState( GLcontext *ctx ); extern void mgaUpdateClipping(const GLcontext *ctx); extern void mgaUpdateCull( GLcontext *ctx ); extern void mgaCalcViewport( GLcontext *ctx ); - - +extern void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers ); #endif diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.c b/xc/lib/GL/mesa/src/drv/mga/mgatex.c index 3dc0b1d89..6f47b4a87 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatex.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.c @@ -34,6 +34,8 @@ #include "mgatris.h" #include "mgaioctl.h" +#include "colormac.h" +#include "context.h" #include "enums.h" #include "simple_list.h" #include "imports.h" @@ -43,67 +45,41 @@ #include "swrast/swrast.h" -#define TEX_0 1 -#define TEX_1 2 - -/* - * mgaDestroyTexObj - * Free all memory associated with a texture and NULL any pointers - * to it. +/** + * Set the texture wrap modes. + * Currently, only \c GL_REPEAT and \c GL_CLAMP are supported. + * + * \param t Texture object whose wrap modes are to be set + * \param swrap Wrap mode for the \a s texture coordinate + * \param twrap Wrap mode for the \a t texture coordinate */ -void -mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t ) -{ - if ( !t ) return; - - /* free the texture memory */ - if (t->MemBlock) { - mmFreeMem( t->MemBlock ); - t->MemBlock = 0; - - if (mmesa && t->age > mmesa->dirtyAge) - mmesa->dirtyAge = t->age; - } - /* free mesa's link */ - if (t->tObj) - t->tObj->DriverData = NULL; - - /* see if it was the driver's current object */ - if (mmesa) { - if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0; - if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0; - } - - remove_from_list(t); - FREE( t ); -} - - -/* - * mgaSetTexWrappings - */ -static void mgaSetTexWrapping( mgaTextureObjectPtr t, - GLenum sWrap, - GLenum tWrap ) +static void +mgaSetTexWrapping( mgaTextureObjectPtr t, GLenum swrap, GLenum twrap ) { GLuint val = 0; - if (sWrap != GL_REPEAT) + if (swrap != GL_REPEAT) val |= TMC_clampu_enable; - if (tWrap != GL_REPEAT) + if (twrap != GL_REPEAT) val |= TMC_clampv_enable; - t->setup.texctl &= ~(TMC_clampu_enable|TMC_clampv_enable); + t->setup.texctl &= (TMC_clampu_MASK & TMC_clampv_MASK); t->setup.texctl |= val; } -/* - * mgaSetTexFilter +/** + * Set the texture magnification and minification modes. + * + * \param t Texture whose filter modes are to be set + * \param minf Texture minification mode + * \param magf Texture magnification mode */ -static void mgaSetTexFilter(mgaTextureObjectPtr t, GLenum minf, GLenum magf) + +static void +mgaSetTexFilter( mgaTextureObjectPtr t, GLenum minf, GLenum magf ) { GLuint val = 0; @@ -132,123 +108,79 @@ static void mgaSetTexFilter(mgaTextureObjectPtr t, GLenum minf, GLenum magf) } - t->setup.texfilter &= (TF_minfilter_MASK | - TF_magfilter_MASK | + /* Mask off the bits for the fields we are setting. Remember, the MGA mask + * defines have 0s for the bits in the named fields. This is the opposite + * of most of the other drivers. + */ + + t->setup.texfilter &= (TF_minfilter_MASK & + TF_magfilter_MASK & TF_fthres_MASK); t->setup.texfilter |= val; } -/* - * mgaSetTexBorderColor - */ static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4]) { - t->setup.texbordercol = MGAPACKCOLOR8888(color[0],color[1], - color[2],color[3]); + t->setup.texbordercol = PACK_COLOR_8888(color[3], color[0], + color[1], color[2] ); } -static GLint mgaChooseTexFormat( mgaContextPtr mmesa, - struct gl_texture_image *texImage, - GLenum format, GLenum type ) +static const struct gl_texture_format * +mgaChooseTextureFormat( GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type ) { + mgaContextPtr mmesa = MGA_CONTEXT(ctx); const GLboolean do32bpt = mmesa->default32BitTextures; - const struct gl_texture_format *texFormat; - GLint ret; - - if ( 0 ) - fprintf( stderr, "internal=%s format=%s type=%s\n", - texImage->IntFormat == 3 ? "GL_RGB (3)" : - texImage->IntFormat == 4 ? "GL_RGBA (4)" : - _mesa_lookup_enum_by_nr( texImage->IntFormat ), - _mesa_lookup_enum_by_nr( format ), - _mesa_lookup_enum_by_nr( type ) ); - -#define SET_FORMAT( r, gl ) \ - do { \ - ret = (r); \ - texFormat = &(gl); \ - } while (0) - -#define SET_FORMAT_32BPT( r32, gl32, r16, gl16 ) \ - do { \ - if ( do32bpt ) { \ - ret = (r32); \ - texFormat = &(gl32); \ - } else { \ - ret = (r16); \ - texFormat = &(gl16); \ - } \ - } while (0) - - switch ( texImage->IntFormat ) { - /* GH: Bias towards GL_RGB, GL_RGBA texture formats. This has - * got to be better than sticking them way down the end of this - * huge list. - */ + + switch ( internalFormat ) { case 4: case GL_RGBA: case GL_COMPRESSED_RGBA: if ( format == GL_BGRA ) { if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) { - SET_FORMAT( TMC_tformat_tw32, _mesa_texformat_argb8888 ); - break; - } else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) { - SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); - break; - } else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) { - SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 ); - break; + return &_mesa_texformat_argb8888; + } + else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) { + return &_mesa_texformat_argb4444; + } + else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) { + return &_mesa_texformat_argb1555; } } - SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888, - TMC_tformat_tw12, _mesa_texformat_argb4444 ); - break; + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; case 3: case GL_RGB: case GL_COMPRESSED_RGB: if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { - SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 ); - break; + return &_mesa_texformat_rgb565; } - SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888, - TMC_tformat_tw16, _mesa_texformat_rgb565 ); - break; + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; - /* GH: Okay, keep checking as normal. Still test for GL_RGB, - * GL_RGBA formats first. - */ case GL_RGBA8: case GL_RGB10_A2: case GL_RGBA12: case GL_RGBA16: - SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888, - TMC_tformat_tw12, _mesa_texformat_argb4444 ); - break; + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; case GL_RGBA4: case GL_RGBA2: - SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); - break; + return &_mesa_texformat_argb4444; case GL_RGB5_A1: - SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 ); - break; + return &_mesa_texformat_argb1555; case GL_RGB8: case GL_RGB10: case GL_RGB12: case GL_RGB16: - SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888, - TMC_tformat_tw16, _mesa_texformat_rgb565 ); - break; + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; case GL_RGB5: case GL_RGB4: case GL_R3_G3_B2: - SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 ); - break; + return &_mesa_texformat_rgb565; case GL_ALPHA: case GL_ALPHA4: @@ -257,8 +189,7 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa, case GL_ALPHA16: case GL_COMPRESSED_ALPHA: /* FIXME: This will report incorrect component sizes... */ - SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); - break; + return &_mesa_texformat_argb4444; case 1: case GL_LUMINANCE: @@ -268,8 +199,7 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa, case GL_LUMINANCE16: case GL_COMPRESSED_LUMINANCE: /* FIXME: This will report incorrect component sizes... */ - SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 ); - break; + return &_mesa_texformat_rgb565; case 2: case GL_LUMINANCE_ALPHA: @@ -281,8 +211,7 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa, case GL_LUMINANCE16_ALPHA16: case GL_COMPRESSED_LUMINANCE_ALPHA: /* FIXME: This will report incorrect component sizes... */ - SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); - break; + return &_mesa_texformat_argb4444; case GL_INTENSITY: case GL_INTENSITY4: @@ -291,8 +220,7 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa, case GL_INTENSITY16: case GL_COMPRESSED_INTENSITY: /* FIXME: This will report incorrect component sizes... */ - SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); - break; + return &_mesa_texformat_argb4444; case GL_COLOR_INDEX: case GL_COLOR_INDEX1_EXT: @@ -301,503 +229,75 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa, case GL_COLOR_INDEX8_EXT: case GL_COLOR_INDEX12_EXT: case GL_COLOR_INDEX16_EXT: - SET_FORMAT( TMC_tformat_tw8, _mesa_texformat_ci8 ); - break; + return &_mesa_texformat_ci8; default: - fprintf( stderr, "bad texture format in mgaChooseTexFormat() %d", - texImage->IntFormat ); - return -1; + _mesa_problem( ctx, "unexpected texture format in %s", __FUNCTION__ ); + return NULL; } - texImage->TexFormat = texFormat; - - return ret; + return NULL; /* never get here */ } -/* - * mgaCreateTexObj + + +/** * Allocate space for and load the mesa images into the texture memory block. * This will happen before drawing with a new texture, or drawing with a * texture after it was swapped out or teximaged again. */ -static void mgaCreateTexObj(mgaContextPtr mmesa, - struct gl_texture_object *tObj) -{ - const GLint baseLevel = tObj->BaseLevel; - struct gl_texture_image *image = tObj->Image[baseLevel]; - mgaTextureObjectPtr t; - int i, ofs; - int LastLevel; - int s, s2; - int tformat; - - if (!image) return; - - tObj->DriverData = t = CALLOC( sizeof( *t ) ); - if (!t) { - fprintf(stderr, "mgaCreateTexObj: Failed to malloc mgaTextureObject\n" ); - return; - } - /* FIXME: Use the real DD interface... - */ - tformat = mgaChooseTexFormat( mmesa, image, image->Format, - GL_UNSIGNED_BYTE ); - t->texelBytes = image->TexFormat->TexelBytes; - - /* We are going to upload all levels that are present, even if - * later levels wouldn't be used by the current filtering mode. This - * allows the filtering mode to change without forcing another upload - * of the images. - */ - LastLevel = MGA_TEX_MAXLEVELS-1; - - ofs = 0; - for ( i = 0 ; i <= LastLevel ; i++ ) { - if ( !tObj->Image[i] ) { - LastLevel = i - 1; - break; - } - - t->offsets[i] = ofs; - t->dirty_images |= (1<<i); - - ofs += ((MAX2( tObj->Image[i]->Width, 8 ) * - MAX2( tObj->Image[i]->Height, 8 ) * - t->texelBytes) + 31) & ~31; - } - t->totalSize = ofs; - t->lastLevel = LastLevel; - t->tObj = tObj; - t->ctx = mmesa; - t->age = 0; - t->bound = 0; - t->MemBlock = 0; - - insert_at_tail(&(mmesa->SwappedOut), t); - - - /* setup hardware register values */ - t->setup.texctl = TMC_takey_1 | TMC_tamask_0 | tformat; - - if (image->WidthLog2 >= 3) - t->setup.texctl |= ((image->WidthLog2 - 3) << TMC_tpitch_SHIFT); - else - t->setup.texctl |= (TMC_tpitchlin_enable | - (image->Width << TMC_tpitchext_SHIFT)); - - - t->setup.texctl2 = TMC_ckstransdis_enable; - - if ( mmesa->glCtx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) - t->setup.texctl2 |= TMC_specen_enable; - - - t->setup.texfilter = (TF_minfilter_nrst | - TF_magfilter_nrst | - TF_filteralpha_enable | - (0x10 << TF_fthres_SHIFT) | - (LastLevel << TF_mapnb_SHIFT)); - - /* warp texture registers */ - ofs = MGA_IS_G200(mmesa) ? 28 : 11; - s = image->Width; - s2 = image->WidthLog2; - t->setup.texwidth = (MGA_FIELD(TW_twmask, s - 1) | - MGA_FIELD(TW_rfw, (10 - s2 - 8) & 63 ) | - MGA_FIELD(TW_tw, (s2 + ofs ) | 0x40 )); - - - s = image->Height; - s2 = image->HeightLog2; - t->setup.texheight = (MGA_FIELD(TH_thmask, s - 1) | - MGA_FIELD(TH_rfh, (10 - s2 - 8) & 63 ) | - MGA_FIELD(TH_th, (s2 + ofs ) | 0x40 )); - - - /* set all the register values for filtering, border, etc */ - mgaSetTexWrapping( t, tObj->WrapS, tObj->WrapT ); - mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); - mgaSetTexBorderColor( t, tObj->_BorderChan ); -} - - - - -static void mgaUpdateTextureEnvG200( GLcontext *ctx ) +static mgaTextureObjectPtr +mgaAllocTexObj( struct gl_texture_object *tObj ) { - struct gl_texture_object *tObj = ctx->Texture.Unit[0]._Current; mgaTextureObjectPtr t; - if (!tObj || !tObj->DriverData) - return; - - t = (mgaTextureObjectPtr)tObj->DriverData; - - t->setup.texctl2 &= ~TMC_decalblend_enable; - - switch (ctx->Texture.Unit[0].EnvMode) { - case GL_REPLACE: - t->setup.texctl &= ~TMC_tmodulate_enable; - break; - case GL_MODULATE: - t->setup.texctl |= TMC_tmodulate_enable; - break; - case GL_DECAL: - t->setup.texctl &= ~TMC_tmodulate_enable; - t->setup.texctl2 |= TMC_decalblend_enable; - break; - case GL_BLEND: - FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE ); - break; - default: - break; - } -} - -static void mgaUpdateTextureEnvG400( GLcontext *ctx, int unit ) -{ - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit); - GLuint source = mmesa->tmu_source[unit]; - struct gl_texture_object *tObj = ctx->Texture.Unit[source]._Current; - GLenum format; - - if ( tObj != ctx->Texture.Unit[source].Current2D || !tObj ) - return; - - format = tObj->Image[tObj->BaseLevel]->Format; - - switch (ctx->Texture.Unit[source].EnvMode) { - case GL_REPLACE: - if (format == GL_RGB || format == GL_LUMINANCE) { - *reg = (TD0_color_sel_arg1 | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_arg2 ); - } - else if (format == GL_ALPHA) { - *reg = (TD0_color_sel_arg2 | - TD0_color_arg2_diffuse | - TD0_alpha_sel_arg1 ); - } - else { - *reg = (TD0_color_sel_arg1 | - TD0_alpha_sel_arg1 ); - } - break; - case GL_MODULATE: - if (unit == 0) { - *reg = ( TD0_color_arg2_diffuse | - TD0_color_sel_mul | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_mul); - } - else { - *reg = ( TD0_color_arg2_prevstage | - TD0_color_alpha_prevstage | - TD0_color_sel_mul | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_mul); - } - break; - case GL_DECAL: - if (format == GL_RGB) { - if (unit == 0) { - *reg = (TD0_color_sel_arg1 | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_arg2 ); - } - else { - *reg = (TD0_color_sel_arg1 | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_arg2 ); - } - } - else if ( format == GL_RGBA ) { -#if 0 - if (unit == 0) { - /* this doesn't work */ - *reg = (TD0_color_arg2_diffuse | - TD0_color_alpha_currtex | - TD0_color_alpha2inv_enable | - TD0_color_arg2mul_alpha2 | - TD0_color_arg1mul_alpha1 | - TD0_color_blend_enable | - TD0_color_arg1add_mulout | - TD0_color_arg2add_mulout | - TD0_color_add_add | - TD0_color_sel_mul | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_arg2 ); - } - else { - *reg = (TD0_color_arg2_prevstage | - TD0_color_alpha_currtex | - TD0_color_alpha2inv_enable | - TD0_color_arg2mul_alpha2 | - TD0_color_arg1mul_alpha1 | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_arg2 ); - } -#else - /* s/w fallback, pretty sure we can't do in h/w */ - FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE ); - if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK ) - fprintf( stderr, "FALLBACK: GL_DECAL RGBA texture, unit=%d\n", - unit ); -#endif - } - else { - if (unit == 0) { - *reg = ( TD0_color_arg2_diffuse | - TD0_color_sel_arg2 | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_arg2); - } - else { - *reg = ( TD0_color_arg2_prevstage | - TD0_color_sel_arg2 | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_arg2); - } - } - break; - - case GL_ADD: - if (unit == 0) { - if (format == GL_INTENSITY) - *reg = ( TD0_color_arg2_diffuse | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_diffuse | - TD0_alpha_add_enable | - TD0_alpha_sel_add); - else if (format == GL_ALPHA) - *reg = ( TD0_color_arg2_diffuse | - TD0_color_sel_mul | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_mul); - else - *reg = ( TD0_color_arg2_diffuse | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_mul); - } - else { - if (format == GL_INTENSITY) { - *reg = ( TD0_color_arg2_prevstage | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_prevstage | - TD0_alpha_add_enable | - TD0_alpha_sel_add); - } - else if (format == GL_ALPHA) { - *reg = ( TD0_color_arg2_prevstage | - TD0_color_sel_mul | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_mul); - } - else { - *reg = ( TD0_color_arg2_prevstage | - TD0_color_alpha_prevstage | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_mul); - } - } - break; - - case GL_BLEND: - if (format == GL_ALPHA) { - *reg = ( TD0_color_arg2_diffuse | - TD0_color_sel_mul | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_mul); - } - else { - FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE ); - if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK ) - fprintf( stderr, "FALLBACK: GL_BLEND envcolor=0x%08x\n", - mmesa->envcolor ); - - /* Do singletexture GL_BLEND with 'all ones' env-color - * by using both texture units. Multitexture gl_blend - * is a fallback. - */ - if (unit == 0) { - /* Part 1: R1 = Rf ( 1 - Rt ) - * A1 = Af At - */ - *reg = ( TD0_color_arg2_diffuse | - TD0_color_arg1_inv_enable | - TD0_color_sel_mul | - TD0_alpha_arg2_diffuse | - TD0_alpha_sel_arg1); - } else { - /* Part 2: R2 = R1 + Rt - * A2 = A1 - */ - *reg = ( TD0_color_arg2_prevstage | - TD0_color_add_add | - TD0_color_sel_add | - TD0_alpha_arg2_prevstage | - TD0_alpha_sel_arg2); - } - } - break; - default: - break; - } -} - - - -static void mgaUpdateTextureObject( GLcontext *ctx, int hw_unit ) -{ - mgaTextureObjectPtr t; - struct gl_texture_object *tObj; - GLuint enabled; - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - GLuint gl_unit = mmesa->tmu_source[hw_unit]; - - - enabled = ctx->Texture.Unit[gl_unit]._ReallyEnabled; - tObj = ctx->Texture.Unit[gl_unit]._Current; - - if (enabled != TEXTURE_2D_BIT) { - if (enabled) - FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE ); - return; - } - - if (tObj->Image[tObj->BaseLevel]->Border > 0) { - FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE ); - if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK ) - fprintf( stderr, "FALLBACK: texture border\n" ); - return; - } - - if ( !tObj->DriverData ) { - mgaCreateTexObj( mmesa, tObj ); - if ( !tObj->DriverData ) { - FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE ); - return; - } - } - - t = (mgaTextureObjectPtr)tObj->DriverData; - - if (t->dirty_images) - mmesa->dirty |= (MGA_UPLOAD_TEX0IMAGE << hw_unit); - - mmesa->CurrentTexObj[hw_unit] = t; - t->bound |= hw_unit+1; - -/* if (t->MemBlock) */ -/* mgaUpdateTexLRU( mmesa, t ); */ - - t->setup.texctl2 &= ~TMC_dualtex_enable; - if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT && - ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) - t->setup.texctl2 |= TMC_dualtex_enable; - - t->setup.texctl2 &= ~TMC_specen_enable; - if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) - t->setup.texctl2 |= TMC_specen_enable; -} - - - - - - -/* The G400 is now programmed quite differently wrt texture environment. - */ -void mgaUpdateTextureState( GLcontext *ctx ) -{ - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_FALSE ); - - if (mmesa->CurrentTexObj[0]) { - mmesa->CurrentTexObj[0]->bound = 0; - mmesa->CurrentTexObj[0] = 0; - } + t = CALLOC( sizeof( *t ) ); + tObj->DriverData = t; + if ( t != NULL ) { + /* Initialize non-image-dependent parts of the state: + */ + t->base.tObj = tObj; - if (mmesa->CurrentTexObj[1]) { - mmesa->CurrentTexObj[1]->bound = 0; - mmesa->CurrentTexObj[1] = 0; - } + t->setup.texctl = TMC_takey_1 | TMC_tamask_0; + t->setup.texctl2 = TMC_ckstransdis_enable; + t->setup.texfilter = (TF_minfilter_nrst + | TF_magfilter_nrst + | TF_filteralpha_enable); - if (ctx->Texture.Unit[0]._ReallyEnabled == 0 && - ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) { - mmesa->tmu_source[0] = 1; - } else { - mmesa->tmu_source[0] = 0; - } + make_empty_list( & t->base ); - if (MGA_IS_G400(mmesa)) { - mgaUpdateTextureObject( ctx, 0 ); - mgaUpdateTextureEnvG400( ctx, 0 ); - - mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0; - - if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT && - ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) { - mgaUpdateTextureObject( ctx, 1 ); - mgaUpdateTextureEnvG400( ctx, 1 ); - mmesa->dirty |= MGA_UPLOAD_TEX1; - } - } else { - mgaUpdateTextureObject( ctx, 0 ); - mgaUpdateTextureEnvG200( ctx ); + mgaSetTexWrapping( t, tObj->WrapS, tObj->WrapT ); + mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); + mgaSetTexBorderColor( t, tObj->_BorderChan ); } - mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_TEX0; - - mmesa->setup.dwgctl &= DC_opcod_MASK; - mmesa->setup.dwgctl |= (ctx->Texture._EnabledUnits - ? DC_opcod_texture_trap - : DC_opcod_trap); + return( t ); } - - static void mgaDDTexEnv( GLcontext *ctx, GLenum target, GLenum pname, const GLfloat *param ) { + GLuint unit = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; mgaContextPtr mmesa = MGA_CONTEXT(ctx); - if (pname == GL_TEXTURE_ENV_MODE) { - /* force the texture state to be updated */ - FLUSH_BATCH( MGA_CONTEXT(ctx) ); - MGA_CONTEXT(ctx)->new_state |= (MGA_NEW_TEXTURE | - MGA_NEW_ALPHA); - } - else if (pname == GL_TEXTURE_ENV_COLOR) - { - struct gl_texture_unit *texUnit = - &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - GLfloat *fc = texUnit->EnvColor; + switch( pname ) { + case GL_TEXTURE_ENV_COLOR: { GLubyte c[4]; - GLuint col; + GLuint envColor; - COPY_4V(c, fc); - col = mgaPackColor( mmesa->mgaScreen->cpp, c[0], c[1], c[2], c[3] ); - mmesa->envcolor = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]); + UNCLAMPED_FLOAT_TO_RGBA_CHAN( c, texUnit->EnvColor ); + envColor = mgaPackColor( mmesa->mgaScreen->cpp, c[0], c[1], c[2], c[3] ); + mmesa->envcolor = PACK_COLOR_8888( c[3], c[0], c[1], c[2] ); - if (mmesa->setup.fcol != col) { + if (mmesa->setup.fcol != envColor) { FLUSH_BATCH(mmesa); - mmesa->setup.fcol = col; + mmesa->setup.fcol = envColor; mmesa->dirty |= MGA_UPLOAD_CONTEXT; mmesa->blend_flags &= ~MGA_BLEND_ENV_COLOR; @@ -811,6 +311,8 @@ static void mgaDDTexEnv( GLcontext *ctx, GLenum target, if (mmesa->envcolor != 0x0 && mmesa->envcolor != 0xffffffff) mmesa->blend_flags |= MGA_BLEND_ENV_COLOR; } + break; + } } } @@ -823,14 +325,24 @@ static void mgaTexImage2D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - mgaTextureObjectPtr t = (mgaTextureObjectPtr) texObj->DriverData; - if (t) { - mgaDestroyTexObj( MGA_CONTEXT(ctx), t ); - texObj->DriverData = 0; + driTextureObject * t = (driTextureObject *) texObj->DriverData; + + + if ( t != NULL ) { + driSwapOutTextureObject( t ); + } + else { + t = (driTextureObject *) mgaAllocTexObj( texObj ); + if ( t == NULL ) { + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glTexImage2D" ); + return; + } } + _mesa_store_teximage2d( ctx, target, level, internalFormat, width, height, border, format, type, pixels, packing, texObj, texImage ); + t->dirty_images[0] |= (1UL << level); } static void mgaTexSubImage2D( GLcontext *ctx, @@ -844,39 +356,50 @@ static void mgaTexSubImage2D( GLcontext *ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - mgaTextureObjectPtr t = (mgaTextureObjectPtr) texObj->DriverData; - if (t) { - mgaDestroyTexObj( MGA_CONTEXT(ctx), t ); - texObj->DriverData = 0; + driTextureObject * t = (driTextureObject *) texObj->DriverData; + + + assert( t != NULL ); /* this _should_ be true */ + if ( t != NULL ) { + driSwapOutTextureObject( t ); + } + else { + t = (driTextureObject *) mgaAllocTexObj( texObj ); + if ( t == NULL ) { + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glTexImage2D" ); + return; + } } + _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, height, format, type, pixels, packing, texObj, texImage); - + t->dirty_images[0] |= (1UL << level); } - - -/* - * mgaTexParameter - * This just changes variables and flags for a state update, which - * will happen at the next mgaUpdateTextureState +/** + * Changes variables and flags for a state update, which will happen at the + * next UpdateTextureState */ + static void mgaDDTexParameter( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLenum pname, const GLfloat *params ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); + mgaContextPtr mmesa = MGA_CONTEXT( ctx ); mgaTextureObjectPtr t; t = (mgaTextureObjectPtr) tObj->DriverData; - /* if we don't have a hardware texture, it will be automatically - created with current state before it is used, so we don't have - to do anything now */ - if ( !t || !t->bound || target != GL_TEXTURE_2D ) { + /* If we don't have a hardware texture, it will be automatically + * created with current state before it is used, so we don't have + * to do anything now + */ + + if ( (t == NULL) + || (target != GL_TEXTURE_2D) ) { return; } @@ -901,8 +424,6 @@ mgaDDTexParameter( GLcontext *ctx, GLenum target, default: return; } - - mmesa->new_state |= MGA_NEW_TEXTURE; } @@ -910,19 +431,11 @@ static void mgaDDBindTexture( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj ) { - mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - int unit = ctx->Texture.CurrentUnit; - - FLUSH_BATCH(mmesa); - - if (mmesa->CurrentTexObj[unit]) { - mmesa->CurrentTexObj[unit]->bound &= ~(unit+1); - mmesa->CurrentTexObj[unit] = 0; + if ( target == GL_TEXTURE_2D ) { + if ( tObj->DriverData == NULL ) { + mgaAllocTexObj( tObj ); + } } - - /* force the texture state to be updated - */ - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; } @@ -930,53 +443,48 @@ static void mgaDDDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaTextureObjectPtr t = (mgaTextureObjectPtr)tObj->DriverData; + driTextureObject * t = (driTextureObject *) tObj->DriverData; if ( t ) { - if (mmesa) { - if (t->bound) { - FLUSH_BATCH(mmesa); - if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0; - if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0; - } - mmesa->new_state |= MGA_NEW_TEXTURE; + if ( mmesa ) { + FLUSH_BATCH( mmesa ); } - mgaDestroyTexObj( mmesa, t ); + driDestroyTextureObject( t ); } } -static GLboolean -mgaDDIsTextureResident( GLcontext *ctx, struct gl_texture_object *t ) -{ - mgaTextureObjectPtr mt = (mgaTextureObjectPtr)t->DriverData; - return mt && mt->MemBlock; -} - - void mgaDDInitTextureFuncs( GLcontext *ctx ) { - ctx->Driver.TexEnv = mgaDDTexEnv; - - ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format; - ctx->Driver.TexImage1D = _mesa_store_teximage1d; - ctx->Driver.TexImage2D = mgaTexImage2D; - ctx->Driver.TexImage3D = _mesa_store_teximage3d; - ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; - ctx->Driver.TexSubImage2D = mgaTexSubImage2D; - ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; - ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; - ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; - ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; - ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; - ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; - ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; - - ctx->Driver.BindTexture = mgaDDBindTexture; - ctx->Driver.DeleteTexture = mgaDDDeleteTexture; - ctx->Driver.TexParameter = mgaDDTexParameter; - ctx->Driver.UpdateTexturePalette = 0; - ctx->Driver.IsTextureResident = mgaDDIsTextureResident; + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + + + ctx->Driver.ChooseTextureFormat = mgaChooseTextureFormat; + ctx->Driver.TexImage1D = _mesa_store_teximage1d; + ctx->Driver.TexImage2D = mgaTexImage2D; + ctx->Driver.TexImage3D = _mesa_store_teximage3d; + ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; + ctx->Driver.TexSubImage2D = mgaTexSubImage2D; + ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; + ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; + ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; + ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; + ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; + ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; + ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + + ctx->Driver.BindTexture = mgaDDBindTexture; + ctx->Driver.CreateTexture = NULL; /* FIXME: Is this used??? */ + ctx->Driver.DeleteTexture = mgaDDDeleteTexture; + ctx->Driver.IsTextureResident = driIsTextureResident; + ctx->Driver.PrioritizeTexture = NULL; + ctx->Driver.ActiveTexture = NULL; + ctx->Driver.UpdateTexturePalette = NULL; + + ctx->Driver.TexEnv = mgaDDTexEnv; + ctx->Driver.TexParameter = mgaDDTexParameter; + + driInitTextureObjects( ctx, & mmesa->swapped, DRI_TEXMGR_DO_TEXTURE_2D ); } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.h b/xc/lib/GL/mesa/src/drv/mga/mgatex.h index c9f87d997..282577e9f 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatex.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.h @@ -40,23 +40,10 @@ typedef struct mga_texture_object_s *mgaTextureObjectPtr; */ void mgaUpdateTextureState( GLcontext *ctx ); -void mgaConvertTexture( GLuint *dest, int texelBytes, - struct gl_texture_image *image, - int x, int y, int width, int height ); - - -void mgaUploadSubImageLocked( mgaContextPtr mmesa, - mgaTextureObjectPtr t, - int level, - int x, int y, int width, int height ); - int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t ); void mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t ); -void mgaAgeTextures( mgaContextPtr mmesa, int heap ); - void mgaDDInitTextureFuncs( GLcontext *ctx ); - #endif diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c b/xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c deleted file mode 100644 index f9e9a79ff..000000000 --- a/xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c +++ /dev/null @@ -1,253 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexcnv.c,v 1.3 2002/10/30 12:51:36 alanh Exp $ */ -/* - * Copyright 2000-2001 VA Linux Systems, Inc. - * 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 - * VA LINUX SYSTEMS AND/OR ITS 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: - * Keith Whitwell <keith@tungstengraphics.com> - */ - -#include <GL/gl.h> - -#include "mm.h" -#include "mgacontext.h" -#include "mgatex.h" - - -/* - * mgaConvertTexture - * Converts a mesa format texture to the apropriate hardware format - * Note that sometimes width may be larger than the texture, like 64x1 - * for an 8x8 texture. This happens when we have to crutch the pitch - * limits of the mga by uploading a block of texels as a single line. - */ -void mgaConvertTexture( GLuint *destPtr, int texelBytes, - struct gl_texture_image *image, - int x, int y, int width, int height ) -{ - register int i, j; - GLubyte *src; - int stride; - - if (0) - fprintf(stderr, "texture image %p\n", image->Data); - - if (image->Data == 0) - return; - - /* FIXME: g400 luminance_alpha internal format */ - switch (texelBytes) { - case 1: - switch (image->Format) { - case GL_COLOR_INDEX: - case GL_INTENSITY: - case GL_LUMINANCE: - case GL_ALPHA: - src = (GLubyte *)image->Data + ( y * image->Width + x ); - stride = (image->Width - width); - for ( i = height ; i ; i-- ) { - for ( j = width >> 2 ; j ; j-- ) { - - *destPtr++ = src[0] | ( src[1] << 8 ) | ( src[2] << 16 ) | ( src[3] << 24 ); - src += 4; - } - src += stride; - } - break; - default: - goto format_error; - } - break; - case 2: - switch (image->Format) { - case GL_RGB: - src = (GLubyte *)image->Data + ( y * image->Width + x ) * 3; - stride = (image->Width - width) * 3; - for ( i = height ; i ; i-- ) { - for ( j = width >> 1 ; j ; j-- ) { - - *destPtr++ = MGAPACKCOLOR565(src[0],src[1],src[2]) | - ( MGAPACKCOLOR565(src[3],src[4],src[5]) << 16 ); - src += 6; - } - src += stride; - } - break; - case GL_RGBA: - src = (GLubyte *)image->Data + ( y * image->Width + x ) * 4; - stride = (image->Width - width) * 4; - for ( i = height ; i ; i-- ) { - for ( j = width >> 1 ; j ; j-- ) { - - *destPtr++ = MGAPACKCOLOR4444(src[0],src[1],src[2],src[3]) | - ( MGAPACKCOLOR4444(src[4],src[5],src[6],src[7]) << 16 ); - src += 8; - } - src += stride; - } - break; - case GL_LUMINANCE: - src = (GLubyte *)image->Data + ( y * image->Width + x ); - stride = (image->Width - width); - for ( i = height ; i ; i-- ) { - for ( j = width >> 1 ; j ; j-- ) { - /* FIXME: should probably use 555 texture to get true grey */ - *destPtr++ = MGAPACKCOLOR565(src[0],src[0],src[0]) | - ( MGAPACKCOLOR565(src[1],src[1],src[1]) << 16 ); - src += 2; - } - src += stride; - } - break; - case GL_INTENSITY: - src = (GLubyte *)image->Data + ( y * image->Width + x ); - stride = (image->Width - width); - for ( i = height ; i ; i-- ) { - for ( j = width >> 1 ; j ; j-- ) { - - *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[0]) | - ( MGAPACKCOLOR4444(src[1],src[1],src[1],src[1]) << 16 ); - src += 2; - } - src += stride; - } - break; - case GL_ALPHA: - src = (GLubyte *)image->Data + ( y * image->Width + x ); - stride = (image->Width - width); - for ( i = height ; i ; i-- ) { - for ( j = width >> 1 ; j ; j-- ) { - - *destPtr++ = MGAPACKCOLOR4444(255,255,255,src[0]) | - ( MGAPACKCOLOR4444(255,255,255,src[1]) << 16 ); - src += 2; - } - src += stride; - } - break; - case GL_LUMINANCE_ALPHA: - src = (GLubyte *)image->Data + ( y * image->Width + x ) * 2; - stride = (image->Width - width) * 2; - for ( i = height ; i ; i-- ) { - for ( j = width >> 1 ; j ; j-- ) { - - *destPtr++ = MGAPACKCOLOR4444(src[0],src[0],src[0],src[1]) | - ( MGAPACKCOLOR4444(src[2],src[2],src[2],src[3]) << 16 ); - src += 4; - } - src += stride; - } - break; - default: - goto format_error; - } - break; - case 4: - switch (image->Format) { - case GL_RGB: - src = (GLubyte *)image->Data + ( y * image->Width + x ) * 3; - stride = (image->Width - width) * 3; - for ( i = height ; i ; i-- ) { - for ( j = width ; j ; j-- ) { - - *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2], 255); - src += 3; - } - src += stride; - } - break; - case GL_RGBA: - src = (GLubyte *)image->Data + ( y * image->Width + x ) * 4; - stride = (image->Width - width) * 4; - for ( i = height ; i ; i-- ) { - for ( j = width ; j ; j-- ) { - - *destPtr++ = MGAPACKCOLOR8888(src[0],src[1],src[2],src[3]); - src += 4; - } - src += stride; - } - break; - case GL_LUMINANCE: - src = (GLubyte *)image->Data + ( y * image->Width + x ); - stride = (image->Width - width); - for ( i = height ; i ; i-- ) { - for ( j = width ; j ; j-- ) { - - *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0], 255); - src += 1; - } - src += stride; - } - break; - case GL_INTENSITY: - src = (GLubyte *)image->Data + ( y * image->Width + x ); - stride = (image->Width - width); - for ( i = height ; i ; i-- ) { - for ( j = width ; j ; j-- ) { - - *destPtr++ = MGAPACKCOLOR8888(src[0],src[0],src[0],src[0]); - src += 1; - } - src += stride; - } - break; - case GL_ALPHA: - src = (GLubyte *)image->Data + ( y * image->Width + x ); - stride = (image->Width - width); - for ( i = height ; i ; i-- ) { - for ( j = width ; j ; j-- ) { - - *destPtr++ = MGAPACKCOLOR8888(255,255,255,src[0]); - src += 1; - } - src += stride; - } - break; - case GL_LUMINANCE_ALPHA: - src = (GLubyte *)image->Data + ( y * image->Width + x ) * 2; - stride = (image->Width - width) * 2; - for ( i = height ; i ; i-- ) { - for ( j = width ; j ; j-- ) { - - *destPtr++ = MGAPACKCOLOR8888(src[0],src[0], - src[0],src[1]); - src += 2; - } - src += stride; - } - break; - default: - goto format_error; - } - break; - default: - goto format_error; - } - - return; - - format_error: - - fprintf(stderr, "Unsupported texelBytes %i, image->Format %i\n", - (int)texelBytes, (int)image->Format ); -} diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatexmem.c b/xc/lib/GL/mesa/src/drv/mga/mgatexmem.c index cc0313baa..bd32ebbda 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatexmem.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatexmem.c @@ -33,530 +33,247 @@ #include "mgatex.h" #include "mgaregs.h" #include "mgaioctl.h" +#include "mga_xmesa.h" #include "imports.h" #include "simple_list.h" -static void -mgaSwapOutTexObj(mgaContextPtr mmesa, mgaTextureObjectPtr t) -{ - if (t->MemBlock) { - mmFreeMem(t->MemBlock); - t->MemBlock = 0; - - if (t->age > mmesa->dirtyAge) - mmesa->dirtyAge = t->age; - } - - t->dirty_images = ~0; - move_to_tail(&(mmesa->SwappedOut), t); -} - -static void -mgaPrintLocalLRU( mgaContextPtr mmesa, int heap ) -{ - mgaTextureObjectPtr t; - int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]); - - fprintf(stderr, "\nLocal LRU, heap %d:\n", heap); - - foreach( t, &(mmesa->TexObjList[heap]) ) { - if (!t->tObj) - 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); - } - - fprintf(stderr, "\n\n"); -} - -static void -mgaPrintGlobalLRU( mgaContextPtr mmesa, int heap ) +/** + * Destroy any device-dependent state associated with the texture. This may + * include NULLing out hardware state that points to the texture. + */ +void +mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t ) { - int i, j; - drmTextureRegion *list = mmesa->sarea->texList[heap]; + unsigned i; - fprintf(stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list); - for (i = 0, j = MGA_NR_TEX_REGIONS ; i < MGA_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 == MGA_NR_TEX_REGIONS) break; - } + /* See if it was the driver's current object. + */ - if (j != MGA_NR_TEX_REGIONS) { - fprintf(stderr, "Loop detected in global LRU\n\n\n"); - for (i = 0 ; i < MGA_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); - } - } + if ( mmesa != NULL ) + { + if ( t->age > mmesa->dirtyAge ) + mmesa->dirtyAge = t->age; - fprintf(stderr, "\n\n"); + for ( i = 0 ; i < mmesa->glCtx->Const.MaxTextureUnits ; i++ ) + { + if ( t == mmesa->CurrentTexObj[ i ] ) { + mmesa->CurrentTexObj[ i ] = NULL; + } + } + } } -static void mgaResetGlobalLRU( mgaContextPtr mmesa, GLuint heap ) +/** + * Upload a texture image from system memory to either on-card or AGP + * memory. Uploads to on-card memory are performed using an ILOAD operation. + * This is used for both initial loading of the entire image, and texSubImage + * updates. + * + * Performed with the hardware lock held. + * + * Even though this function is named "upload subimage," the entire image + * is uploaded. + * + * \param mmesa Driver context. + * \param t Texture to be uploaded. + * \param level Mipmap level of the texture to be uploaded. + * + * \bug As mentioned above, this fuction actually copies the entier mipmap + * level. There should be a version of this function that performs + * sub-rectangle uploads. This will perform quite a bit better if only + * a small portion of a larger texture has been updated. Care would + * need to be take with such an implementation once glCopyTexImage has + * been hardware accelerated. + */ +static void mgaUploadSubImage( mgaContextPtr mmesa, + mgaTextureObjectPtr t, GLint level ) { - drmTextureRegion *list = mmesa->sarea->texList[heap]; - int sz = 1 << mmesa->mgaScreen->logTextureGranularity[heap]; - int i; + struct gl_texture_image * texImage; + unsigned offset; + unsigned texelBytes; + unsigned length; - mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap]; - if (0) fprintf(stderr, "mgaResetGlobalLRU %d\n", (int)heap); - - /* (Re)initialize the global circular LRU list. The last element - * in the array (MGA_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->mgaScreen->textureSize[heap] ; i++) { - list[i].prev = i-1; - list[i].next = i+1; - list[i].age = mmesa->sarea->texAge[heap]; + if ( (level < 0) + || (level >= (MGA_IS_G200(mmesa) + ? G200_TEX_MAXLEVELS : G400_TEX_MAXLEVELS)) ) { + fprintf( stderr, "[%s:%d] level = %d\n", __FILE__, __LINE__, level ); + return; } - i--; - list[0].prev = MGA_NR_TEX_REGIONS; - list[i].prev = i-1; - list[i].next = MGA_NR_TEX_REGIONS; - list[MGA_NR_TEX_REGIONS].prev = i; - list[MGA_NR_TEX_REGIONS].next = 0; - -} - - -static void mgaUpdateTexLRU( mgaContextPtr mmesa, mgaTextureObjectPtr t ) -{ - int i; - int heap = t->heap; - int logsz = mmesa->mgaScreen->logTextureGranularity[heap]; - int start = t->MemBlock->ofs >> logsz; - int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; - drmTextureRegion *list = mmesa->sarea->texList[heap]; - - mmesa->texAge[heap] = ++mmesa->sarea->texAge[heap]; - - if (!t->MemBlock) { - fprintf(stderr, "no memblock\n\n"); + texImage = t->base.tObj->Image[level]; + if ( texImage == NULL ) { + fprintf( stderr, "[%s:%d] Image[%d] = NULL\n", __FILE__, __LINE__, + level ); return; } - /* Update our local LRU - */ - move_to_head( &(mmesa->TexObjList[heap]), t ); - - - if (0) - fprintf(stderr, "mgaUpdateTexLRU heap %d list %p\n", heap, list); - - /* Update the global LRU - */ - for (i = start ; i <= end ; i++) { - - list[i].in_use = 1; - list[i].age = mmesa->texAge[heap]; - - /* 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 = MGA_NR_TEX_REGIONS; - list[i].next = list[MGA_NR_TEX_REGIONS].next; - list[(unsigned)list[MGA_NR_TEX_REGIONS].next].prev = i; - list[MGA_NR_TEX_REGIONS].next = i; - } - - if (0) { - mgaPrintGlobalLRU(mmesa, t->heap); - mgaPrintLocalLRU(mmesa, t->heap); + if (texImage->Data == NULL) { + fprintf(stderr, "null texture image data tObj %p level %d\n", + t->base.tObj, level); + return; } -} - -/* 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. - */ -static void mgaTexturesGone( mgaContextPtr mmesa, - GLuint heap, - GLuint offset, - GLuint size, - GLuint in_use ) -{ - mgaTextureObjectPtr 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 off. Need to hold onto the currently bound - * objects, however. - */ - if (t->bound) - mgaSwapOutTexObj( mmesa, t ); - else - mgaDestroyTexObj( mmesa, t ); + /* find the proper destination offset for this level */ + if ( MGA_IS_G200(mmesa) ) { + offset = (t->base.memBlock->ofs + t->offsets[level]); } + else { + unsigned i; - - if (in_use) { - t = (mgaTextureObjectPtr) CALLOC(sizeof(*t)); - if (!t) return; - - t->heap = heap; - 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; + offset = t->base.memBlock->ofs; + for ( i = 0 ; i < level ; i++ ) { + offset += (t->offsets[1] >> (i * 2)); } - insert_at_head( &(mmesa->TexObjList[heap]), t ); - } -} - -void mgaAgeTextures( mgaContextPtr mmesa, int heap ) -{ - MGASAREAPrivPtr sarea = mmesa->sarea; - int sz = 1 << (mmesa->mgaScreen->logTextureGranularity[heap]); - int idx, nr = 0; - - /* 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->texList[heap][MGA_NR_TEX_REGIONS].prev ; - idx != MGA_NR_TEX_REGIONS && nr < MGA_NR_TEX_REGIONS ; - idx = sarea->texList[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. + /* Each mipmap must be DWORD aligned. */ - if ( idx * sz > mmesa->mgaScreen->textureSize[heap] ) { - nr = MGA_NR_TEX_REGIONS; - break; - } - - if (sarea->texList[heap][idx].age > mmesa->texAge[heap]) { - mgaTexturesGone(mmesa, heap, idx * sz, sz, - sarea->texList[heap][idx].in_use); - } + offset &= ~0x03; } - if (nr == MGA_NR_TEX_REGIONS) { - mgaTexturesGone(mmesa, heap, 0, - mmesa->mgaScreen->textureSize[heap], 0); - mgaResetGlobalLRU( mmesa, heap ); - } + /* Copy the texture from system memory to a memory space that can be + * directly used by the hardware for texturing. + */ - if (0) { - mgaPrintGlobalLRU( mmesa, heap ); - mgaPrintLocalLRU( mmesa, heap ); - } - - mmesa->texAge[heap] = sarea->texAge[heap]; - mmesa->dirty |= MGA_UPLOAD_TEX0IMAGE | MGA_UPLOAD_TEX1IMAGE; -} - -/* - * mgaUploadSubImageLocked - * - * Perform an iload based update of a resident buffer. This is used for - * both initial loading of the entire image, and texSubImage updates. - * - * Performed with the hardware lock held. - */ -void mgaUploadSubImageLocked( mgaContextPtr mmesa, - mgaTextureObjectPtr t, - int level, - int x, int y, int width, int height ) -{ - int x2; - int dwords; - int offset; - struct gl_texture_image *image; - int texelBytes, texelsPerDword, texelMaccess, length; - - if ( level < 0 || level >= MGA_TEX_MAXLEVELS ) - return; - - image = t->tObj->Image[level]; - if ( !image ) return; + texelBytes = texImage->TexFormat->TexelBytes; + length = texImage->Width * texImage->Height * texelBytes; + if ( t->base.heap->heapId == MGA_CARD_HEAP ) { + unsigned tex_offset = 0; + unsigned to_copy; - if (image->Data == 0) { - fprintf(stderr, "null texture image data tObj %p level %d\n", - t->tObj, level); - return; - } + /* We may not be able to upload the entire texture in one batch due to + * register limits or dma buffer limits. Split the copy up into maximum + * sized chunks. + */ + offset += mmesa->mgaScreen->textureOffset[ t->base.heap->heapId ]; + while ( length != 0 ) { + mgaGetILoadBufferLocked( mmesa ); - /* find the proper destination offset for this level */ - offset = (t->MemBlock->ofs + - t->offsets[level]); - - - texelBytes = t->texelBytes; - switch( texelBytes ) { - case 1: - texelsPerDword = 4; - texelMaccess = 0; - break; - case 2: - texelsPerDword = 2; - texelMaccess = 1; - break; - case 4: - texelsPerDword = 1; - texelMaccess = 2; - break; - default: - return; - } + /* The kernel ILOAD ioctl requires that the lenght be an even multiple + * of MGA_ILOAD_ALIGN. + */ + length = ((length) + MGA_ILOAD_MASK) & ~MGA_ILOAD_MASK; + to_copy = MIN2( length, MGA_BUFFER_SIZE ); + (void) memcpy( mmesa->iload_buffer->address, + (GLubyte *) texImage->Data + tex_offset, to_copy ); - /* We can't do a subimage update if pitch is < 32 texels due - * to hardware XY addressing limits, so we will need to - * linearly upload all modified rows. - */ - if ( image->Width < 32 ) { - x = 0; - width = image->Width * height; - height = 1; - - /* Assume that 1x1 textures aren't going to cause a - * bus error if we read up to four texels from that - * location: - */ -/* if ( width < texelsPerDword ) { */ -/* width = texelsPerDword; */ -/* } */ - } else { - /* pad the size out to dwords. The image is a pointer - to the entire image, so we can safely reference - outside the x,y,width,height bounds if we need to */ - x2 = x + width; - x2 = (x2 + (texelsPerDword-1)) & ~(texelsPerDword-1); - x = (x + (texelsPerDword-1)) & ~(texelsPerDword-1); - width = x2 - x; - } + if ( MGA_DEBUG & DEBUG_VERBOSE_TEXTURE ) + fprintf(stderr, "[%s:%d] address/size = 0x%08lx/%d\n", + __FILE__, __LINE__, + (long) (offset + tex_offset), + to_copy ); - /* we may not be able to upload the entire texture in one - batch due to register limits or dma buffer limits. - Recursively split it up. */ - while ( 1 ) { - dwords = height * width / texelsPerDword; - if ( dwords * 4 <= MGA_BUFFER_SIZE ) { - break; + mgaFireILoadLocked( mmesa, offset + tex_offset, to_copy ); + tex_offset += to_copy; + length -= to_copy; } - - mgaUploadSubImageLocked( mmesa, t, level, x, y, - width, height >> 1 ); - y += ( height >> 1 ); - height -= ( height >> 1 ); - } - - length = dwords * 4; - - /* Fill in the secondary buffer with properly converted texels - * from the mesa buffer. */ - /* FIXME: the sync for direct copy reduces speed.. */ - if(t->heap == MGA_CARD_HEAP ) { - mgaGetILoadBufferLocked( mmesa ); - mgaConvertTexture( (GLuint *)mmesa->iload_buffer->address, - texelBytes, image, x, y, width, height ); - if(length < 64) length = 64; - - if (0) - fprintf(stderr, "TexelBytes : %d, offset: %d, length : %d\n", - texelBytes, - mmesa->mgaScreen->textureOffset[t->heap] + - offset + - y * width * 4/texelsPerDword, - length); - - mgaFireILoadLocked( mmesa, - mmesa->mgaScreen->textureOffset[t->heap] + - offset + - y * width * 4/texelsPerDword, - length); } else { + /* FIXME: the sync for direct copy reduces speed.. */ /* This works, is slower for uploads to card space and needs * additional synchronization with the dma stream. */ UPDATE_LOCK(mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT); - mgaConvertTexture( (GLuint *) - (mmesa->mgaScreen->texVirtual[t->heap] + - offset + - y * width * 4/texelsPerDword), - texelBytes, image, x, y, width, height ); - } -} - - -static void mgaUploadTexLevel( mgaContextPtr mmesa, - mgaTextureObjectPtr t, - int l ) -{ - mgaUploadSubImageLocked( mmesa, - t, - l, - 0, 0, - t->tObj->Image[l]->Width, - t->tObj->Image[l]->Height); -} - - - -#if 0 -static void mgaMigrateTexture( mgaContextPtr mmesa, mgaTextureObjectPtr t ) -{ - /* NOT DONE */ -} -#endif - - -static int mgaChooseTexHeap( mgaContextPtr mmesa, mgaTextureObjectPtr t ) -{ - int freeagp, freecard; - int fitincard, fitinagp; - int totalcard, totalagp; - TMemBlock *b; - - totalcard = totalagp = fitincard = fitinagp = freeagp = freecard = 0; - - b = mmesa->texHeap[0]; - while(b) - { - totalcard += b->size; - if(b->free) if(t->totalSize <= b->size)fitincard = 1; - b = b->next; - } - - b = mmesa->texHeap[1]; - while(b) - { - totalagp += b->size; - if(b->free) if(t->totalSize <= b->size)fitinagp = 1; - b = b->next; - } + memcpy( mmesa->mgaScreen->texVirtual[t->base.heap->heapId] + offset, + texImage->Data, length ); - if(fitincard)return 0; - if(fitinagp)return 1; - - if(totalcard && totalagp) - { - int ages; - int ratio = (totalcard > totalagp) ? totalcard / totalagp : totalagp / totalcard; - ages = mmesa->sarea->texAge[0] + mmesa->sarea->texAge[1]; - if( (ages % ratio) == 0)return totalcard > totalagp ? 1 : 0; - else return totalcard > totalagp ? 0 : 1; + if ( MGA_DEBUG & DEBUG_VERBOSE_TEXTURE ) + fprintf(stderr, "[%s:%d] address/size = 0x%08lx/%d\n", + __FILE__, __LINE__, + (long) (mmesa->mgaScreen->texVirtual[t->base.heap->heapId] + + offset), + length); } - - if(totalagp) return 1; - return 0; } +/** + * Upload the texture images associated with texture \a t. This might + * require the allocation of texture memory. + * + * \param mmesa Context pointer + * \param t Texture to be uploaded + */ + int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t ) { - int heap; int i; int ofs; - heap = t->heap = mgaChooseTexHeap( mmesa, t ); - /* Do we need to eject LRU texture objects? - */ - if (!t->MemBlock) { - while (1) - { - mgaTextureObjectPtr tmp = mmesa->TexObjList[heap].prev; - - t->MemBlock = mmAllocMem( mmesa->texHeap[heap], - t->totalSize, - 6, 0 ); - if (t->MemBlock) - break; - - if (mmesa->TexObjList[heap].prev->bound) { - fprintf(stderr, "Hit bound texture in upload\n"); - return -1; - } + if ( (t == NULL) || (t->base.totalSize == 0) ) + return 0; - if (mmesa->TexObjList[heap].prev == - &(mmesa->TexObjList[heap])) - { - fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize); - mmDumpMemInfo( mmesa->texHeap[heap] ); - return -1; - } + LOCK_HARDWARE( mmesa ); + + if (t->base.memBlock == NULL ) { + int heap; - mgaDestroyTexObj( mmesa, tmp ); + heap = driAllocateTexture( mmesa->texture_heaps, mmesa->nr_heaps, + (driTextureObject *) t ); + if ( heap == -1 ) { + UNLOCK_HARDWARE( mmesa ); + return -1; } - ofs = t->MemBlock->ofs - + mmesa->mgaScreen->textureOffset[heap] - ; + ofs = mmesa->mgaScreen->textureOffset[ heap ] + + t->base.memBlock->ofs; - t->setup.texorg = ofs; - t->setup.texorg1 = ofs + t->offsets[1]; - t->setup.texorg2 = ofs + t->offsets[2]; - t->setup.texorg3 = ofs + t->offsets[3]; - t->setup.texorg4 = ofs + t->offsets[4]; + if ( MGA_IS_G200(mmesa) ) { + t->setup.texorg = ofs; + t->setup.texorg1 = ofs + t->offsets[1]; + t->setup.texorg2 = ofs + t->offsets[2]; + t->setup.texorg3 = ofs + t->offsets[3]; + t->setup.texorg4 = ofs + t->offsets[4]; + } + else { + t->setup.texorg = ofs | TO_texorgoffsetsel; + t->setup.texorg1 = t->offsets[1]; + t->setup.texorg2 = 0; + t->setup.texorg3 = 0; + t->setup.texorg4 = 0; + } mmesa->dirty |= MGA_UPLOAD_CONTEXT; } /* Let the world know we've used this memory recently. */ - mgaUpdateTexLRU( mmesa, t ); + driUpdateTextureLRU( (driTextureObject *) t ); - - if (MGA_DEBUG&DEBUG_VERBOSE_LRU) - fprintf(stderr, "dispatch age: %d age freed memory: %d\n", + if (MGA_DEBUG&DEBUG_VERBOSE_TEXTURE) + fprintf(stderr, "[%s:%d] dispatch age: %d age freed memory: %d\n", + __FILE__, __LINE__, GET_DISPATCH_AGE(mmesa), mmesa->dirtyAge); if (mmesa->dirtyAge >= GET_DISPATCH_AGE(mmesa)) mgaWaitAgeLocked( mmesa, mmesa->dirtyAge ); - if (t->dirty_images) { - if (MGA_DEBUG&DEBUG_VERBOSE_LRU) - fprintf(stderr, "*"); + if (t->base.dirty_images[0]) { + if (MGA_DEBUG&DEBUG_VERBOSE_TEXTURE) + fprintf(stderr, "[%s:%d] dirty_images[0] = 0x%04x\n", + __FILE__, __LINE__, t->base.dirty_images[0] ); - for (i = 0 ; i <= t->lastLevel ; i++) - if (t->dirty_images & (1<<i)) - mgaUploadTexLevel( mmesa, t, i ); + for (i = 0 ; i <= t->lastLevel ; i++) { + if ( (t->base.dirty_images[0] & (1U << i)) != 0 ) { + mgaUploadSubImage( mmesa, t, i ); + } + } + t->base.dirty_images[0] = 0; } - t->dirty_images = 0; + UNLOCK_HARDWARE( mmesa ); + return 0; } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.c b/xc/lib/GL/mesa/src/drv/mga/mgatris.c index d82f24507..949482f47 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatris.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.c @@ -673,15 +673,6 @@ static void mgaFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, /**********************************************************************/ - -#define _MGA_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \ - _DD_NEW_TRI_UNFILLED | \ - _DD_NEW_TRI_LIGHT_TWOSIDE | \ - _DD_NEW_TRI_OFFSET | \ - _DD_NEW_TRI_STIPPLE | \ - _NEW_POLYGONSTIPPLE) - - #define POINT_FALLBACK (DD_POINT_SMOOTH) #define LINE_FALLBACK (DD_LINE_SMOOTH | DD_LINE_STIPPLE) #define TRI_FALLBACK (DD_TRI_SMOOTH | DD_TRI_UNFILLED) @@ -690,7 +681,7 @@ static void mgaFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, #define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET| \ DD_TRI_UNFILLED) -static void mgaChooseRenderState(GLcontext *ctx) +void mgaChooseRenderState(GLcontext *ctx) { TNLcontext *tnl = TNL_CONTEXT(ctx); mgaContextPtr mmesa = MGA_CONTEXT(ctx); @@ -756,36 +747,6 @@ static void mgaChooseRenderState(GLcontext *ctx) /**********************************************************************/ -static void mgaRunPipeline( GLcontext *ctx ) -{ - mgaContextPtr mmesa = MGA_CONTEXT(ctx); - - if (mmesa->new_state) { - mgaDDUpdateHwState( ctx ); - } - - if (!mmesa->Fallback && mmesa->new_gl_state) { - if (mmesa->new_gl_state & _MGA_NEW_RASTERSETUP) - mgaChooseVertexState( ctx ); - - if (mmesa->new_gl_state & _MGA_NEW_RENDERSTATE) - mgaChooseRenderState( ctx ); - - mmesa->new_gl_state = 0; - - /* Circularity: mgaDDUpdateHwState can affect mmesa->Fallback, - * but mgaChooseVertexState can affect mmesa->new_state. Hence - * the second check. (Fix this...) - */ - if (mmesa->new_state) { - mgaDDUpdateHwState( ctx ); - } - } - - _tnl_run_pipeline( ctx ); -} - - static GLenum reduced_prim[GL_POLYGON+1] = { GL_POINTS, GL_LINES, @@ -812,7 +773,6 @@ void mgaRasterPrimitive( GLcontext *ctx, GLenum prim, GLuint hwprim ) mmesa->raster_primitive = prim; /* mmesa->hw_primitive = hwprim; */ mmesa->hw_primitive = MGA_WA_TRIANGLES; /* disable mgarender.c for now */ - mgaUpdateCull(ctx); if (ctx->Polygon.StippleFlag && mmesa->haveHwStipple) { @@ -883,8 +843,8 @@ void mgaFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) tnl->Driver.Render.PrimitiveNotify = mgaRenderPrimitive; tnl->Driver.Render.Finish = mgaRenderFinish; tnl->Driver.Render.BuildVertices = mgaBuildVertices; - mmesa->new_gl_state |= (_MGA_NEW_RENDERSTATE | - _MGA_NEW_RASTERSETUP); + mmesa->NewGLState |= (_MGA_NEW_RENDERSTATE | + _MGA_NEW_RASTERSETUP); } } } @@ -902,7 +862,6 @@ void mgaDDInitTriFuncs( GLcontext *ctx ) mmesa->RenderIndex = ~0; - tnl->Driver.RunPipeline = mgaRunPipeline; tnl->Driver.Render.Start = mgaCheckTexSizes; tnl->Driver.Render.Finish = mgaRenderFinish; tnl->Driver.Render.PrimitiveNotify = mgaRenderPrimitive; diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.h b/xc/lib/GL/mesa/src/drv/mga/mgatris.h index 88eda91e1..a8c0b8936 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatris.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.h @@ -32,12 +32,17 @@ #include "mtypes.h" extern void mgaDDInitTriFuncs( GLcontext *ctx ); - +extern void mgaChooseRenderState( GLcontext *ctx ); extern void mgaRasterPrimitive( GLcontext *ctx, GLenum prim, GLuint hwprim ); extern void mgaFallback( GLcontext *ctx, GLuint bit, GLboolean mode ); #define FALLBACK( ctx, bit, mode ) mgaFallback( ctx, bit, mode ) - +#define _MGA_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _DD_NEW_TRI_OFFSET | \ + _DD_NEW_TRI_STIPPLE | \ + _NEW_POLYGONSTIPPLE) #endif diff --git a/xc/lib/GL/mesa/src/drv/mga/mgavb.c b/xc/lib/GL/mesa/src/drv/mga/mgavb.c index 576c6bf9f..04cd93ec9 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgavb.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.c @@ -430,7 +430,6 @@ void mgaChooseVertexState( GLcontext *ctx ) if (setup_tab[ind].vertex_format != mmesa->vertex_format) { FLUSH_BATCH(mmesa); - mmesa->new_state |= MGA_NEW_WARP; mmesa->dirty |= MGA_UPLOAD_PIPE; mmesa->vertex_format = setup_tab[ind].vertex_format; mmesa->vertex_size = setup_tab[ind].vertex_size; @@ -467,7 +466,6 @@ void mgaInitVB( GLcontext *ctx ) } } - mmesa->new_state |= MGA_NEW_WARP; mmesa->dirty |= MGA_UPLOAD_PIPE; mmesa->vertex_format = setup_tab[0].vertex_format; mmesa->vertex_size = setup_tab[0].vertex_size; diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.c b/xc/lib/GL/mesa/src/drv/r128/r128_context.c index 5c2a7371e..0f4875f2a 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_context.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.c @@ -55,18 +55,36 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_tris.h" #include "r128_vb.h" +#include "vblank.h" +#include "utils.h" +#include "texmem.h" + #ifndef R128_DEBUG -int R128_DEBUG = (0 -/* | DEBUG_ALWAYS_SYNC */ -/* | DEBUG_VERBOSE_API */ -/* | DEBUG_VERBOSE_MSG */ -/* | DEBUG_VERBOSE_LRU */ -/* | DEBUG_VERBOSE_DRI */ -/* | DEBUG_VERBOSE_IOCTL */ -/* | DEBUG_VERBOSE_2D */ - ); +int R128_DEBUG = 0; #endif +static const char * const card_extensions[] = +{ + "GL_ARB_multitexture", + "GL_ARB_texture_env_add", + "GL_ARB_texture_mirrored_repeat", + "GL_EXT_texture_env_add", + "GL_IBM_texture_mirrored_repeat", + "GL_SGIS_generate_mipmap", + NULL +}; + +static const struct dri_debug_control debug_control[] = +{ + { "ioctl", DEBUG_VERBOSE_IOCTL }, + { "verb", DEBUG_VERBOSE_MSG }, + { "dri", DEBUG_VERBOSE_DRI }, + { "2d", DEBUG_VERBOSE_2D }, + { "sync", DEBUG_ALWAYS_SYNC }, + { "api", DEBUG_VERBOSE_API }, + { NULL, 0 } +}; + /* Create the device specific context. */ GLboolean r128CreateContext( const __GLcontextModes *glVisual, @@ -112,34 +130,48 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual, rmesa->CurrentTexObj[0] = NULL; rmesa->CurrentTexObj[1] = NULL; - make_empty_list( &rmesa->SwappedOut ); - - for ( i = 0 ; i < r128scrn->numTexHeaps ; i++ ) { - make_empty_list( &rmesa->TexObjList[i] ); - rmesa->texHeap[i] = mmInit( 0, r128scrn->texSize[i] ); - rmesa->lastTexAge[i] = -1; + (void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) ); + make_empty_list( & rmesa->swapped ); + + rmesa->nr_heaps = r128scrn->numTexHeaps; + for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { + rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa, + r128scrn->texSize[i], + 12, + R128_NR_TEX_REGIONS, + rmesa->sarea->texList[i], + & rmesa->sarea->texAge[i], + & rmesa->swapped, + sizeof( r128TexObj ), + (destroy_texture_object_t *) r128DestroyTexObj ); + + driSetTextureSwapCounterLocation( rmesa->texture_heaps[i], + & rmesa->c_textureSwaps ); } - rmesa->lastTexHeap = r128scrn->numTexHeaps; + rmesa->RenderIndex = -1; /* Impossible value */ rmesa->vert_buf = NULL; rmesa->num_verts = 0; - /* KW: Set the maximum texture size small enough that we can - * guarentee that both texture units can bind a maximal texture - * and have them both in on-card memory at once. (Kevin or - * Gareth: Please check these numbers are OK) + /* Set the maximum texture size small enough that we can guarentee that + * all texture units can bind a maximal texture and have them both in + * texturable memory at once. */ - if ( r128scrn->texSize[0] < 2*1024*1024 ) { - ctx->Const.MaxTextureLevels = 9; - } else if ( r128scrn->texSize[0] < 8*1024*1024 ) { - ctx->Const.MaxTextureLevels = 10; - } else { - ctx->Const.MaxTextureLevels = 11; - } ctx->Const.MaxTextureUnits = 2; + driCalculateMaxTextureLevels( rmesa->texture_heaps, + rmesa->nr_heaps, + & ctx->Const, + 4, + 10, /* max 2D texture size is 1024x1024 */ + 0, /* 3D textures unsupported. */ + 0, /* cube textures unsupported. */ + 0, /* texture rectangles unsupported. */ + 11, + GL_FALSE ); + /* No wide points. */ ctx->Const.MinPointSize = 1.0; @@ -156,11 +188,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual, ctx->Const.LineWidthGranularity = 1.0; #if ENABLE_PERF_BOXES - if ( getenv( "LIBGL_PERFORMANCE_BOXES" ) ) { - rmesa->boxes = 1; - } else { - rmesa->boxes = 0; - } + rmesa->boxes = (getenv( "LIBGL_PERFORMANCE_BOXES" ) != NULL); #endif /* Initialize the software rasterizer and helper modules. @@ -180,9 +208,9 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual, _swrast_allow_pixel_fog( ctx, GL_FALSE ); _swrast_allow_vertex_fog( ctx, GL_TRUE ); + driInitExtensions( ctx, card_extensions, GL_TRUE ); r128InitVB( ctx ); r128InitTriFuncs( ctx ); - r128DDInitExtensions( ctx ); r128DDInitDriverFuncs( ctx ); r128DDInitIoctlFuncs( ctx ); r128DDInitStateFuncs( ctx ); @@ -190,8 +218,18 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual, r128DDInitTextureFuncs( ctx ); r128DDInitState( rmesa ); + rmesa->do_irqs = (rmesa->r128Screen->irq && !getenv("R128_NO_IRQS")); + + rmesa->vblank_flags = (rmesa->do_irqs) + ? driGetDefaultVBlankFlags() : VBLANK_FLAG_NO_IRQ; + driContextPriv->driverPrivate = (void *)rmesa; +#if DO_DEBUG + R128_DEBUG = driParseDebugString( getenv( "R128_DEBUG" ), + debug_control ); +#endif + return GL_TRUE; } @@ -203,25 +241,10 @@ void r128DestroyContext( __DRIcontextPrivate *driContextPriv ) assert(rmesa); /* should never be null */ if ( rmesa ) { - if (rmesa->glCtx->Shared->RefCount == 1) { - /* This share group is about to go away, free our private - * texture object data. - */ - r128TexObjPtr t, next_t; - int i; + GLboolean release_texture_heaps; - for ( i = 0 ; i < rmesa->r128Screen->numTexHeaps ; i++ ) { - foreach_s ( t, next_t, &rmesa->TexObjList[i] ) { - r128DestroyTexObj( rmesa, t ); - } - mmDestroy( rmesa->texHeap[i] ); - rmesa->texHeap[i] = NULL; - } - foreach_s ( t, next_t, &rmesa->SwappedOut ) { - r128DestroyTexObj( rmesa, t ); - } - } + release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( rmesa->glCtx ); _tnl_DestroyContext( rmesa->glCtx ); @@ -234,6 +257,20 @@ void r128DestroyContext( __DRIcontextPrivate *driContextPriv ) rmesa->glCtx->DriverCtx = NULL; _mesa_destroy_context(rmesa->glCtx); + if ( release_texture_heaps ) { + /* This share group is about to go away, free our private + * texture object data. + */ + int i; + + assert( is_empty_list( & rmesa->swapped ) ); + + for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { + driDestroyTextureHeap( rmesa->texture_heaps[ i ] ); + rmesa->texture_heaps[ i ] = NULL; + } + } + FREE( rmesa ); } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.h b/xc/lib/GL/mesa/src/drv/r128/r128_context.h index e27c84e3b..be9c210ac 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_context.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.h @@ -47,6 +47,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_reg.h" +#include "texmem.h" + struct r128_context; typedef struct r128_context r128ContextRec; typedef struct r128_context *r128ContextPtr; @@ -65,9 +67,8 @@ typedef struct r128_context *r128ContextPtr; #define R128_NEW_MASKS 0x0020 #define R128_NEW_RENDER_NOT 0x0040 #define R128_NEW_WINDOW 0x0080 -#define R128_NEW_TEXTURE 0x0100 -#define R128_NEW_CONTEXT 0x0200 -#define R128_NEW_ALL 0x03ff +#define R128_NEW_CONTEXT 0x0100 +#define R128_NEW_ALL 0x01ff /* Flags for software fallback cases: */ @@ -154,12 +155,11 @@ struct r128_context { /* Texture object bookkeeping */ + unsigned nr_heaps; + driTexHeap * texture_heaps[ R128_NR_TEX_HEAPS ]; + driTextureObject swapped; + r128TexObjPtr CurrentTexObj[2]; - r128TexObj TexObjList[R128_NR_TEX_HEAPS]; - r128TexObj SwappedOut; - memHeap_t *texHeap[R128_NR_TEX_HEAPS]; - GLint lastTexAge[R128_NR_TEX_HEAPS]; - GLint lastTexHeap; /* Fallback rasterization functions */ @@ -179,6 +179,10 @@ struct r128_context { GLuint doPageFlip; GLuint currentPage; + /* Busy waiting + */ + GLuint do_irqs; + /* Drawable, cliprect and scissor information */ GLint drawOffset, drawPitch; @@ -218,6 +222,7 @@ struct r128_context { /* VBI */ GLuint vbl_seq; + GLuint vblank_flags; }; #define R128_CONTEXT(ctx) ((r128ContextPtr)(ctx->DriverCtx)) diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c index c22ad5c7a..d6b47efcc 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c @@ -41,11 +41,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "context.h" #include "extensions.h" +#include "utils.h" #if defined(USE_X86_ASM) #include "X86/common_x86_asm.h" #endif -#define R128_DATE "20021125" +#define DRIVER_DATE "20030328" /* Return the width and height of the current color buffer. @@ -68,59 +69,26 @@ static const GLubyte *r128DDGetString( GLcontext *ctx, GLenum name ) { r128ContextPtr rmesa = R128_CONTEXT(ctx); static char buffer[128]; + unsigned offset; + const char * card_name = "Rage 128"; switch ( name ) { case GL_VENDOR: return (GLubyte *)"VA Linux Systems, Inc."; case GL_RENDERER: - sprintf( buffer, "Mesa DRI Rage128 " R128_DATE ); - - /* Append any chipset-specific information. + /* Select the spefic chipset. */ if ( R128_IS_PRO( rmesa ) ) { - strncat( buffer, " Pro", 4 ); + card_name = "Rage 128 Pro"; } - if ( R128_IS_MOBILITY( rmesa ) ) { - strncat( buffer, " M3", 3 ); + else if ( R128_IS_MOBILITY( rmesa ) ) { + card_name = "Rage 128 Mobility"; } - /* Append any AGP-specific information. - */ - switch ( rmesa->r128Screen->AGPMode ) { - case 1: - strncat( buffer, " AGP 1x", 7 ); - break; - case 2: - strncat( buffer, " AGP 2x", 7 ); - break; - case 4: - strncat( buffer, " AGP 4x", 7 ); - break; - } + offset = driGetRendererString( buffer, card_name, DRIVER_DATE, + rmesa->r128Screen->AGPMode ); - /* Append any CPU-specific information. - */ -#ifdef USE_X86_ASM - if ( _mesa_x86_cpu_features ) { - strncat( buffer, " x86", 4 ); - } -#ifdef USE_MMX_ASM - if ( cpu_has_mmx ) { - strncat( buffer, "/MMX", 4 ); - } -#endif -#ifdef USE_3DNOW_ASM - if ( cpu_has_3dnow ) { - strncat( buffer, "/3DNow!", 7 ); - } -#endif -#ifdef USE_SSE_ASM - if ( cpu_has_xmm ) { - strncat( buffer, "/SSE", 4 ); - } -#endif -#endif return (GLubyte *)buffer; default: @@ -168,16 +136,6 @@ static void r128DDFinish( GLcontext *ctx ) } -/* Initialize the extensions supported by this driver. - */ -void r128DDInitExtensions( GLcontext *ctx ) -{ - _mesa_enable_extension( ctx, "GL_ARB_multitexture" ); - _mesa_enable_extension( ctx, "GL_ARB_texture_env_add" ); - _mesa_enable_extension( ctx, "GL_EXT_texture_env_add" ); - _mesa_enable_imaging_extensions( ctx ); -} - /* Initialize the driver's misc functions. */ void r128DDInitDriverFuncs( GLcontext *ctx ) diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_dd.h b/xc/lib/GL/mesa/src/drv/r128/r128_dd.h index 17061f332..b8fc7ad9b 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_dd.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.h @@ -38,7 +38,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef GLX_DIRECT_RENDERING -extern void r128DDInitExtensions( GLcontext *ctx ); extern void r128DDInitDriverFuncs( GLcontext *ctx ); #endif diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c index 69f75257b..0fc76e13a 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c @@ -41,6 +41,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" +#include "vblank.h" + #define R128_TIMEOUT 2048 #define R128_IDLE_RETRY 32 @@ -247,6 +249,7 @@ void r128CopyBuffer( const __DRIdrawablePrivate *dPriv ) { r128ContextPtr rmesa; GLint nbox, i, ret; + GLboolean missed_target; assert(dPriv); assert(dPriv->driContextPriv); @@ -276,7 +279,9 @@ void r128CopyBuffer( const __DRIdrawablePrivate *dPriv ) rmesa->hardwareWentIdle = 0; } - r128WaitForVBlank( rmesa ); + UNLOCK_HARDWARE( rmesa ); + driWaitForVBlank( &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target ); + LOCK_HARDWARE( rmesa ); nbox = dPriv->numClipRects; @@ -325,6 +330,7 @@ void r128PageFlip( const __DRIdrawablePrivate *dPriv ) { r128ContextPtr rmesa; GLint ret; + GLboolean missed_target; assert(dPriv); assert(dPriv->driContextPriv); @@ -350,7 +356,9 @@ void r128PageFlip( const __DRIdrawablePrivate *dPriv ) rmesa->hardwareWentIdle = 0; } - r128WaitForVBlank( rmesa ); + UNLOCK_HARDWARE( rmesa ); + driWaitForVBlank( &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target ); + LOCK_HARDWARE( rmesa ); /* The kernel will have been initialized to perform page flipping * on a swapbuffers ioctl. @@ -800,40 +808,6 @@ void r128WaitForIdleLocked( r128ContextPtr rmesa ) } } -void r128WaitForVBlank( r128ContextPtr rmesa ) -{ - drmVBlank vbl; - int ret; - - if ( !rmesa->r128Screen->irq ) - return; - - if ( getenv("LIBGL_SYNC_REFRESH") ) { - /* Wait for until the next vertical blank */ - vbl.request.type = DRM_VBLANK_RELATIVE; - vbl.request.sequence = 1; - } else if ( getenv("LIBGL_THROTTLE_REFRESH") ) { - /* Wait for at least one vertical blank since the last call */ - vbl.request.type = DRM_VBLANK_ABSOLUTE; - vbl.request.sequence = rmesa->vbl_seq + 1; - } else { - return; - } - - UNLOCK_HARDWARE( rmesa ); - - if ((ret = drmWaitVBlank( rmesa->driFd, &vbl ))) { - fprintf(stderr, "%s: drmWaitVBlank returned %d, IRQs don't seem to be" - " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH" - " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret); - exit(1); - } - - rmesa->vbl_seq = vbl.reply.sequence; - - LOCK_HARDWARE( rmesa ); -} - void r128DDInitIoctlFuncs( GLcontext *ctx ) { ctx->Driver.Clear = r128DDClear; diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_lock.c b/xc/lib/GL/mesa/src/drv/r128/r128_lock.c index d735416b1..7f819cdf7 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_lock.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_lock.c @@ -85,9 +85,7 @@ void r128GetLock( r128ContextPtr rmesa, GLuint flags ) rmesa->dirty = R128_UPLOAD_ALL; } - for ( i = 0 ; i < rmesa->lastTexHeap ; i++ ) { - if ( rmesa->texHeap[i] && sarea->texAge[i] != rmesa->lastTexAge[i] ) { - r128AgeTextures( rmesa, i ); - } + for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { + DRI_AGE_TEXTURES( rmesa->texture_heaps[i] ); } } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c index 432d5407c..e8b8c731a 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c @@ -308,7 +308,7 @@ r128SwapBuffers(__DRIdrawablePrivate *dPriv) } else { /* XXX this shouldn't be an error but we can't handle it for now */ - _mesa_problem(NULL, "r128SwapBuffers: drawable has no context!\n"); + _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__); } } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.c b/xc/lib/GL/mesa/src/drv/r128/r128_state.c index 33ad025e4..b4a2b7f3f 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_state.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.c @@ -852,7 +852,6 @@ static void r128DDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) case GL_TEXTURE_2D: case GL_TEXTURE_3D: FLUSH_BATCH( rmesa ); - rmesa->new_state |= R128_NEW_TEXTURE; break; case GL_POLYGON_STIPPLE: @@ -884,7 +883,7 @@ static void r128DDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) static void r128DDPrintDirty( const char *msg, GLuint state ) { fprintf( stderr, - "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s\n", + "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", msg, state, (state & R128_UPLOAD_CORE) ? "core, " : "", @@ -892,8 +891,6 @@ static void r128DDPrintDirty( const char *msg, GLuint state ) (state & R128_UPLOAD_SETUP) ? "setup, " : "", (state & R128_UPLOAD_TEX0) ? "tex0, " : "", (state & R128_UPLOAD_TEX1) ? "tex1, " : "", - (state & R128_UPLOAD_TEX0IMAGES) ? "tex0 images, " : "", - (state & R128_UPLOAD_TEX1IMAGES) ? "tex1 images, " : "", (state & R128_UPLOAD_MASKS) ? "masks, " : "", (state & R128_UPLOAD_WINDOW) ? "window, " : "", (state & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "", @@ -922,21 +919,11 @@ void r128EmitHwStateLocked( r128ContextPtr rmesa ) r128DDPrintDirty( "r128EmitHwStateLocked", rmesa->dirty ); } - if ( rmesa->dirty & R128_UPLOAD_TEX0IMAGES ) { - if ( t0 ) r128UploadTexImages( rmesa, t0 ); - rmesa->dirty &= ~R128_UPLOAD_TEX0IMAGES; - } - if ( rmesa->dirty & R128_UPLOAD_TEX1IMAGES ) { - if ( t1 ) r128UploadTexImages( rmesa, t1 ); - rmesa->dirty &= ~R128_UPLOAD_TEX1IMAGES; - } - if ( rmesa->dirty & (R128_UPLOAD_CONTEXT | R128_UPLOAD_SETUP | R128_UPLOAD_MASKS | R128_UPLOAD_WINDOW | - R128_UPLOAD_CORE | - R128_UPLOAD_TEX0) ) { + R128_UPLOAD_CORE) ) { memcpy( &sarea->ContextState, regs, sizeof(sarea->ContextState) ); } @@ -975,7 +962,7 @@ void r128EmitHwStateLocked( r128ContextPtr rmesa ) static void r128DDPrintState( const char *msg, GLuint flags ) { fprintf( stderr, - "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", + "%s: (0x%x) %s%s%s%s%s%s%s%s\n", msg, flags, (flags & R128_NEW_CONTEXT) ? "context, " : "", @@ -983,7 +970,6 @@ static void r128DDPrintState( const char *msg, GLuint flags ) (flags & R128_NEW_DEPTH) ? "depth, " : "", (flags & R128_NEW_FOG) ? "fog, " : "", (flags & R128_NEW_CLIP) ? "clip, " : "", - (flags & R128_NEW_TEXTURE) ? "texture, " : "", (flags & R128_NEW_CULL) ? "cull, " : "", (flags & R128_NEW_MASKS) ? "masks, " : "", (flags & R128_NEW_WINDOW) ? "window, " : "" ); @@ -994,7 +980,7 @@ void r128DDUpdateHWState( GLcontext *ctx ) r128ContextPtr rmesa = R128_CONTEXT(ctx); int new_state = rmesa->new_state; - if ( new_state ) + if ( new_state || rmesa->NewGLState & _NEW_TEXTURE ) { FLUSH_BATCH( rmesa ); @@ -1026,8 +1012,9 @@ void r128DDUpdateHWState( GLcontext *ctx ) if ( new_state & R128_NEW_WINDOW ) r128UpdateWindow( ctx ); - if ( new_state & R128_NEW_TEXTURE ) + if ( rmesa->NewGLState & _NEW_TEXTURE ) { r128UpdateTextureState( ctx ); + } } } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c index a7574859c..df7fa5c6e 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c @@ -68,6 +68,12 @@ static void r128SetTexWrap( r128TexObjPtr t, GLenum swrap, GLenum twrap ) case GL_REPEAT: t->setup.tex_cntl |= R128_TEX_CLAMP_S_WRAP; break; + case GL_CLAMP_TO_BORDER: + t->setup.tex_cntl |= R128_TEX_CLAMP_S_BORDER_COLOR; + break; + case GL_MIRRORED_REPEAT: + t->setup.tex_cntl |= R128_TEX_CLAMP_S_MIRROR; + break; } switch ( twrap ) { @@ -80,6 +86,12 @@ static void r128SetTexWrap( r128TexObjPtr t, GLenum swrap, GLenum twrap ) case GL_REPEAT: t->setup.tex_cntl |= R128_TEX_CLAMP_T_WRAP; break; + case GL_CLAMP_TO_BORDER: + t->setup.tex_cntl |= R128_TEX_CLAMP_T_BORDER_COLOR; + break; + case GL_MIRRORED_REPEAT: + t->setup.tex_cntl |= R128_TEX_CLAMP_T_MIRROR; + break; } } @@ -133,20 +145,23 @@ static r128TexObjPtr r128AllocTexObj( struct gl_texture_object *texObj ) } t = (r128TexObjPtr) CALLOC_STRUCT( r128_tex_obj ); - if (!t) - return NULL; + texObj->DriverData = t; + if ( t != NULL ) { - /* Initialize non-image-dependent parts of the state: - */ - t->tObj = texObj; - t->dirty_images = ~0; + /* Initialize non-image-dependent parts of the state: + */ + t->base.tObj = texObj; - make_empty_list( t ); + /* FIXME Something here to set initial values for other parts of + * FIXME t->setup? + */ + + make_empty_list( (driTextureObject *) t ); - r128SetTexWrap( t, texObj->WrapS, texObj->WrapT ); - /*r128SetTexMaxAnisotropy( t, texObj->MaxAnisotropy );*/ - r128SetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); - r128SetTexBorderColor( t, texObj->_BorderChan ); + r128SetTexWrap( t, texObj->WrapS, texObj->WrapT ); + r128SetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); + r128SetTexBorderColor( t, texObj->_BorderChan ); + } return t; } @@ -167,6 +182,7 @@ r128ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_ALPHA8: case GL_ALPHA12: case GL_ALPHA16: + case GL_COMPRESSED_ALPHA: case 2: case GL_LUMINANCE_ALPHA: case GL_LUMINANCE4_ALPHA4: @@ -175,8 +191,10 @@ r128ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_LUMINANCE12_ALPHA4: case GL_LUMINANCE12_ALPHA12: case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: case 4: case GL_RGBA: + case GL_COMPRESSED_RGBA: case GL_RGBA2: case GL_RGB5_A1: case GL_RGBA8: @@ -192,6 +210,7 @@ r128ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case 3: case GL_RGB: + case GL_COMPRESSED_RGB: case GL_R3_G3_B2: case GL_RGB4: case GL_RGB5: @@ -210,6 +229,7 @@ r128ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_LUMINANCE8: case GL_LUMINANCE12: case GL_LUMINANCE16: + case GL_COMPRESSED_LUMINANCE: if (rmesa->r128Screen->cpp == 4) return &_mesa_texformat_argb8888; /* inefficient but accurate */ else @@ -221,6 +241,7 @@ r128ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_INTENSITY8: case GL_INTENSITY12: case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: if (rmesa->r128Screen->cpp == 4) return &_mesa_texformat_argb8888; /* inefficient but accurate */ else @@ -236,7 +257,7 @@ r128ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, return &_mesa_texformat_ci8; default: - _mesa_problem( ctx, "unexpected format in r128ChooseTextureFormat" ); + _mesa_problem( ctx, "unexpected format in %s", __FUNCTION__ ); return NULL; } } @@ -250,19 +271,17 @@ static void r128TexImage1D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - r128ContextPtr rmesa = R128_CONTEXT(ctx); - r128TexObjPtr t = (r128TexObjPtr) texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; if ( t ) { - r128SwapOutTexObj( R128_CONTEXT(ctx), t ); + driSwapOutTextureObject( t ); } else { - t = r128AllocTexObj(texObj); + t = (driTextureObject *) r128AllocTexObj(texObj); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); return; } - texObj->DriverData = t; } /* Note, this will call r128ChooseTextureFormat */ @@ -270,8 +289,7 @@ static void r128TexImage1D( GLcontext *ctx, GLenum target, GLint level, width, border, format, type, pixels, packing, texObj, texImage ); - t->dirty_images |= (1 << level); - rmesa->new_state |= R128_NEW_TEXTURE; + t->dirty_images[0] |= (1 << level); } @@ -286,29 +304,25 @@ static void r128TexSubImage1D( GLcontext *ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - r128ContextPtr rmesa = R128_CONTEXT(ctx); - r128TexObjPtr t = (r128TexObjPtr) texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; assert( t ); /* this _should_ be true */ if ( t ) { - r128SwapOutTexObj( R128_CONTEXT(ctx), t ); - t->dirty_images |= (1 << level); + driSwapOutTextureObject( t ); } else { - t = r128AllocTexObj(texObj); + t = (driTextureObject *) r128AllocTexObj(texObj); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); return; } - texObj->DriverData = t; } _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, format, type, pixels, packing, texObj, texImage); - t->dirty_images |= (1 << level); - rmesa->new_state |= R128_NEW_TEXTURE; + t->dirty_images[0] |= (1 << level); } @@ -320,19 +334,17 @@ static void r128TexImage2D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - r128ContextPtr rmesa = R128_CONTEXT(ctx); - r128TexObjPtr t = (r128TexObjPtr) texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; if ( t ) { - r128SwapOutTexObj( R128_CONTEXT(ctx), t ); + driSwapOutTextureObject( (driTextureObject *) t ); } else { - t = r128AllocTexObj(texObj); + t = (driTextureObject *) r128AllocTexObj(texObj); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; } - texObj->DriverData = t; } /* Note, this will call r128ChooseTextureFormat */ @@ -340,8 +352,7 @@ static void r128TexImage2D( GLcontext *ctx, GLenum target, GLint level, width, height, border, format, type, pixels, &ctx->Unpack, texObj, texImage); - t->dirty_images |= (1 << level); - rmesa->new_state |= R128_NEW_TEXTURE; + t->dirty_images[0] |= (1 << level); } @@ -356,27 +367,24 @@ static void r128TexSubImage2D( GLcontext *ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - r128ContextPtr rmesa = R128_CONTEXT(ctx); - r128TexObjPtr t = (r128TexObjPtr) texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; assert( t ); /* this _should_ be true */ if ( t ) { - r128SwapOutTexObj( R128_CONTEXT(ctx), t ); + driSwapOutTextureObject( t ); } else { - t = r128AllocTexObj(texObj); + t = (driTextureObject *) r128AllocTexObj(texObj); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; } - texObj->DriverData = t; } _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, height, format, type, pixels, packing, texObj, texImage); - t->dirty_images |= (1 << level); - rmesa->new_state |= R128_NEW_TEXTURE; + t->dirty_images[0] |= (1 << level); } @@ -395,7 +403,7 @@ static void r128DDTexEnv( GLcontext *ctx, GLenum target, switch ( pname ) { case GL_TEXTURE_ENV_MODE: FLUSH_BATCH( rmesa ); - rmesa->new_state |= R128_NEW_TEXTURE | R128_NEW_ALPHA; + rmesa->new_state |= R128_NEW_ALPHA; break; case GL_TEXTURE_ENV_COLOR: @@ -409,8 +417,6 @@ static void r128DDTexEnv( GLcontext *ctx, GLenum target, FLUSH_BATCH( rmesa ); rmesa->setup.constant_color_c = rmesa->env_color; - rmesa->new_state |= R128_NEW_TEXTURE; - /* More complex multitexture/multipass fallbacks for GL_BLEND * can be done later, but this allows a single pass GL_BLEND * in some cases (ie. Performer town demo). This is only @@ -485,30 +491,21 @@ static void r128DDTexParameter( GLcontext *ctx, GLenum target, if ( ( target != GL_TEXTURE_2D ) && ( target != GL_TEXTURE_1D ) ) return; - if (!t) { - t = r128AllocTexObj(tObj); - if (!t) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexParameter"); - return; - } - tObj->DriverData = t; - } - switch ( pname ) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: - if ( t->bound ) FLUSH_BATCH( rmesa ); + if ( t->base.bound ) FLUSH_BATCH( rmesa ); r128SetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); break; case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: - if ( t->bound ) FLUSH_BATCH( rmesa ); + if ( t->base.bound ) FLUSH_BATCH( rmesa ); r128SetTexWrap( t, tObj->WrapS, tObj->WrapT ); break; case GL_TEXTURE_BORDER_COLOR: - if ( t->bound ) FLUSH_BATCH( rmesa ); + if ( t->base.bound ) FLUSH_BATCH( rmesa ); r128SetTexBorderColor( t, tObj->_BorderChan ); break; @@ -521,70 +518,50 @@ static void r128DDTexParameter( GLcontext *ctx, GLenum target, * we just have to rely on loading the right subset of mipmap levels * to simulate a clamped LOD. */ - if ( t->bound ) FLUSH_BATCH( rmesa ); - r128SwapOutTexObj( rmesa, t ); + if ( t->base.bound ) FLUSH_BATCH( rmesa ); + driSwapOutTextureObject( (driTextureObject *) t ); break; default: return; } - - rmesa->new_state |= R128_NEW_TEXTURE; } static void r128DDBindTexture( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj ) { - r128ContextPtr rmesa = R128_CONTEXT(ctx); - GLint unit = ctx->Texture.CurrentUnit; - if ( R128_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p ) unit=%d\n", - __FUNCTION__, tObj, unit ); + fprintf( stderr, "%s( %p ) unit=%d\n", __FUNCTION__, tObj, + ctx->Texture.CurrentUnit ); } - FLUSH_BATCH( rmesa ); - - if ( rmesa->CurrentTexObj[unit] ) { - rmesa->CurrentTexObj[unit]->bound &= ~(1 << unit); - rmesa->CurrentTexObj[unit] = NULL; + if ( target == GL_TEXTURE_2D || target == GL_TEXTURE_1D ) { + if ( tObj->DriverData == NULL ) { + r128AllocTexObj( tObj ); + } } - - rmesa->new_state |= R128_NEW_TEXTURE; } static void r128DDDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) { r128ContextPtr rmesa = R128_CONTEXT(ctx); - r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; + driTextureObject * t = (driTextureObject *) tObj->DriverData; if ( t ) { if ( t->bound ) { FLUSH_BATCH( rmesa ); - - if ( t->bound & TEX_0 ) rmesa->CurrentTexObj[0] = NULL; - if ( t->bound & TEX_1 ) rmesa->CurrentTexObj[1] = NULL; - rmesa->new_state |= R128_NEW_TEXTURE; } - r128DestroyTexObj( rmesa, t ); - tObj->DriverData = NULL; + driDestroyTextureObject( t ); } } -static GLboolean r128DDIsTextureResident( GLcontext *ctx, - struct gl_texture_object *tObj ) +void r128DDInitTextureFuncs( GLcontext *ctx ) { - r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; - - return ( t && t->memBlock ); -} - + r128ContextPtr rmesa = R128_CONTEXT(ctx); -void r128DDInitTextureFuncs( GLcontext *ctx ) -{ ctx->Driver.TexEnv = r128DDTexEnv; ctx->Driver.ChooseTextureFormat = r128ChooseTextureFormat; ctx->Driver.TexImage1D = r128TexImage1D; @@ -604,6 +581,10 @@ void r128DDInitTextureFuncs( GLcontext *ctx ) ctx->Driver.DeleteTexture = r128DDDeleteTexture; ctx->Driver.UpdateTexturePalette = NULL; ctx->Driver.ActiveTexture = NULL; - ctx->Driver.IsTextureResident = r128DDIsTextureResident; + ctx->Driver.IsTextureResident = driIsTextureResident; ctx->Driver.PrioritizeTexture = NULL; + + driInitTextureObjects( ctx, & rmesa->swapped, + DRI_TEXMGR_DO_TEXTURE_1D + | DRI_TEXMGR_DO_TEXTURE_2D ); } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_texmem.c b/xc/lib/GL/mesa/src/drv/r128/r128_texmem.c index 1a0fb754b..e29f40129 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_texmem.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_texmem.c @@ -54,272 +54,32 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ void r128DestroyTexObj( r128ContextPtr rmesa, r128TexObjPtr t ) { -#if ENABLE_PERF_BOXES - /* Bump the performace counter */ - rmesa->c_textureSwaps++; -#endif - if ( !t ) return; - - if ( t->memBlock ) { - mmFreeMem( t->memBlock ); - t->memBlock = NULL; - } - - if ( t->tObj ) - t->tObj->DriverData = NULL; - - if ( t->bound & TEX_0 ) rmesa->CurrentTexObj[0] = NULL; - if ( t->bound & TEX_1 ) rmesa->CurrentTexObj[1] = NULL; - - remove_from_list( t ); - FREE( t ); -} - -/* Keep track of swapped out texture objects. - */ -void r128SwapOutTexObj( r128ContextPtr rmesa, r128TexObjPtr t ) -{ -#if ENABLE_PERF_BOXES - /* Bump the performace counter */ - rmesa->c_textureSwaps++; -#endif - if ( t->memBlock ) { - mmFreeMem( t->memBlock ); - t->memBlock = NULL; - } - - t->dirty_images = ~0; - move_to_tail( &rmesa->SwappedOut, t ); -} - -/* Print out debugging information about texture LRU. - */ -void r128PrintLocalLRU( r128ContextPtr rmesa, int heap ) -{ - r128TexObjPtr t; - int sz = 1 << (rmesa->r128Screen->logTexGranularity[heap]); - - fprintf( stderr, "\nLocal LRU, heap %d:\n", heap ); - - foreach ( t, &rmesa->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 r128PrintGlobalLRU( r128ContextPtr rmesa, int heap ) -{ - r128_tex_region_t *list = rmesa->sarea->texList[heap]; - int i, j; - - fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list ); - - for ( i = 0, j = R128_NR_TEX_REGIONS ; i < R128_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 == R128_NR_TEX_REGIONS ) break; - } - - if ( j != R128_NR_TEX_REGIONS ) { - fprintf( stderr, "Loop detected in global LRU\n" ); - for ( i = 0 ; i < R128_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 ); - } - } - - fprintf( stderr, "\n" ); -} + unsigned i; -/* Reset the global texture LRU. - */ -static void r128ResetGlobalLRU( r128ContextPtr rmesa, int heap ) -{ - r128_tex_region_t *list = rmesa->sarea->texList[heap]; - int sz = 1 << rmesa->r128Screen->logTexGranularity[heap]; - int i; - - /* (Re)initialize the global circular LRU list. The last element in - * the array (R128_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 <= rmesa->r128Screen->texSize[heap] ; i++ ) { - list[i].prev = i-1; - list[i].next = i+1; - list[i].age = 0; - } - - i--; - list[0].prev = R128_NR_TEX_REGIONS; - list[i].prev = i-1; - list[i].next = R128_NR_TEX_REGIONS; - list[R128_NR_TEX_REGIONS].prev = i; - list[R128_NR_TEX_REGIONS].next = 0; - rmesa->sarea->texAge[heap] = 0; -} - -/* Update the local and glock texture LRUs. - */ -void r128UpdateTexLRU( r128ContextPtr rmesa, r128TexObjPtr t ) -{ - int heap = t->heap; - r128_tex_region_t *list = rmesa->sarea->texList[heap]; - int log2sz = rmesa->r128Screen->logTexGranularity[heap]; - int start = t->memBlock->ofs >> log2sz; - int end = (t->memBlock->ofs + t->memBlock->size - 1) >> log2sz; - int i; - - rmesa->lastTexAge[heap] = ++rmesa->sarea->texAge[heap]; - - if ( !t->memBlock ) { - fprintf( stderr, "no memblock\n\n" ); - return; - } - /* Update our local LRU */ - move_to_head( &rmesa->TexObjList[heap], t ); + /* See if it was the driver's current object. + */ - /* Update the global LRU */ - for ( i = start ; i <= end ; i++ ) { - list[i].in_use = 1; - list[i].age = rmesa->lastTexAge[heap]; - - /* remove_from_list(i) */ - list[(CARD32)list[i].next].prev = list[i].prev; - list[(CARD32)list[i].prev].next = list[i].next; - - /* insert_at_head(list, i) */ - list[i].prev = R128_NR_TEX_REGIONS; - list[i].next = list[R128_NR_TEX_REGIONS].next; - list[(CARD32)list[R128_NR_TEX_REGIONS].next].prev = i; - list[R128_NR_TEX_REGIONS].next = i; - } - - if ( 0 ) { - r128PrintGlobalLRU( rmesa, t->heap ); - r128PrintLocalLRU( rmesa, 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). - */ -static void r128TexturesGone( r128ContextPtr rmesa, int heap, - int offset, int size, int in_use ) -{ - r128TexObjPtr t, tmp; - - foreach_s ( t, tmp, &rmesa->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 ) { - r128SwapOutTexObj( rmesa, t ); - } else { - r128DestroyTexObj( rmesa, t ); - } - } - - if ( in_use ) { - t = (r128TexObjPtr) CALLOC( sizeof(*t) ); - if ( !t ) return; - - t->memBlock = mmAllocMem( rmesa->texHeap[heap], size, 0, offset ); - if ( !t->memBlock ) { - fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n", - (int)size, (int)offset ); - mmDumpMemInfo( rmesa->texHeap[heap] ); - return; - } - insert_at_head( &rmesa->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 r128AgeTextures( r128ContextPtr rmesa, int heap ) -{ - R128SAREAPrivPtr sarea = rmesa->sarea; - - if ( sarea->texAge[heap] != rmesa->lastTexAge[heap] ) { - int sz = 1 << rmesa->r128Screen->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->texList[heap][R128_NR_TEX_REGIONS].prev ; - idx != R128_NR_TEX_REGIONS && nr < R128_NR_TEX_REGIONS ; - idx = sarea->texList[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 > rmesa->r128Screen->texSize[heap] ) { - nr = R128_NR_TEX_REGIONS; - break; - } - - if ( sarea->texList[heap][idx].age > rmesa->lastTexAge[heap] ) { - r128TexturesGone( rmesa, heap, idx * sz, sz, - sarea->texList[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 == R128_NR_TEX_REGIONS ) { - r128TexturesGone( rmesa, heap, 0, - rmesa->r128Screen->texSize[heap], 0 ); - r128ResetGlobalLRU( rmesa, heap ); - } - - if ( 0 ) { - r128PrintGlobalLRU( rmesa, heap ); - r128PrintLocalLRU( rmesa, heap ); - } - - rmesa->dirty |= (R128_UPLOAD_CONTEXT | - R128_UPLOAD_TEX0IMAGES | - R128_UPLOAD_TEX1IMAGES); - rmesa->lastTexAge[heap] = sarea->texAge[heap]; - } + if ( rmesa != NULL ) + { + for ( i = 0 ; i < rmesa->glCtx->Const.MaxTextureUnits ; i++ ) + { + if ( t == rmesa->CurrentTexObj[ i ] ) { + assert( t->base.bound & (1 << i) ); + rmesa->CurrentTexObj[ i ] = NULL; + } + } + } } -/* Upload the texture image associated with texture `t' at level `level' - * at the address relative to `start'. +/** + * Upload the texture image associated with texture \a t at the specified + * level at the address relative to \a start. */ -static void r128UploadSubImage( r128ContextPtr rmesa, - r128TexObjPtr t, int level, - int x, int y, int width, int height ) +static void uploadSubImage( r128ContextPtr rmesa, r128TexObjPtr t, + GLint level, + GLint x, GLint y, GLint width, GLint height ) { struct gl_texture_image *image; int texelsPerDword = 0; @@ -333,7 +93,7 @@ static void r128UploadSubImage( r128ContextPtr rmesa, if ( ( level < 0 ) || ( level > R128_MAX_TEXTURE_LEVELS ) ) return; - image = t->tObj->Image[level]; + image = t->base.tObj->Image[level]; if ( !image ) return; @@ -445,15 +205,16 @@ static void r128UploadSubImage( r128ContextPtr rmesa, CARD32 *dst; drmBufPtr buffer; + assert(image->Data); + height = MIN2(remaining, rows); /* Grab the indirect buffer for the texture blit */ + LOCK_HARDWARE( rmesa ); buffer = r128GetBufferLocked( rmesa ); dst = (CARD32 *)((char *)buffer->address + R128_HOSTDATA_BLIT_OFFSET); - assert(image->Data); - /* Copy the next chunck of the texture image into the blit buffer */ { const GLubyte *src = (const GLubyte *) image->Data + @@ -465,6 +226,7 @@ static void r128UploadSubImage( r128ContextPtr rmesa, r128FireBlitLocked( rmesa, buffer, offset, pitch, format, x, y, width, height ); + UNLOCK_HARDWARE( rmesa ); } rmesa->new_state |= R128_NEW_CONTEXT; @@ -476,11 +238,10 @@ static void r128UploadSubImage( r128ContextPtr rmesa, * require removing our own and/or other client's texture objects to * make room for these images. */ -/* NOTE: This function is only called while holding the hardware lock */ void r128UploadTexImages( r128ContextPtr rmesa, r128TexObjPtr t ) { const GLint numLevels = t->lastLevel - t->firstLevel + 1; - GLint i, heap; + GLint i; if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s( %p, %p )\n", @@ -489,60 +250,22 @@ void r128UploadTexImages( r128ContextPtr rmesa, r128TexObjPtr t ) assert(t); - /* Choose the heap appropriately */ - heap = t->heap = R128_CARD_HEAP; - if ( !rmesa->r128Screen->IsPCI && - t->totalSize > rmesa->r128Screen->texSize[heap] ) { - heap = t->heap = R128_AGP_HEAP; - } - - /* Do we need to eject LRU texture objects? */ - if ( !t->memBlock ) { - /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */ - t->memBlock = mmAllocMem( rmesa->texHeap[heap], t->totalSize, 12, 0 ); + LOCK_HARDWARE( rmesa ); - /* Try AGP before kicking anything out of local mem */ - if ( !t->memBlock && heap == R128_CARD_HEAP ) { - t->memBlock = mmAllocMem( rmesa->texHeap[R128_AGP_HEAP], - t->totalSize, 12, 0 ); + if ( !t->base.memBlock ) { + int heap; - if ( t->memBlock ) - heap = t->heap = R128_AGP_HEAP; - } - /* Kick out textures until the requested texture fits */ - while ( !t->memBlock ) { - if ( rmesa->TexObjList[heap].prev->bound ) { - fprintf( stderr, - "r128UploadTexImages: ran into bound texture\n" ); - return; - } - if ( rmesa->TexObjList[heap].prev == &rmesa->TexObjList[heap] ) { - if ( rmesa->r128Screen->IsPCI ) { - fprintf( stderr, "r128UploadTexImages: upload texture " - "failure on local texture heaps, sz=%d\n", - t->totalSize ); - return; - } else if ( heap == R128_CARD_HEAP ) { - heap = t->heap = R128_AGP_HEAP; - continue; - } else { - fprintf( stderr, "r128UploadTexImages: upload texture " - "failure on both local and AGP texture heaps, " - "sz=%d\n", - t->totalSize ); - return; - } - } - - r128SwapOutTexObj( rmesa, rmesa->TexObjList[heap].prev ); - - t->memBlock = mmAllocMem( rmesa->texHeap[heap], - t->totalSize, 12, 0 ); + heap = driAllocateTexture( rmesa->texture_heaps, rmesa->nr_heaps, + (driTextureObject *) t ); + if ( heap == -1 ) { + UNLOCK_HARDWARE( rmesa ); + return; } /* Set the base offset of the texture image */ - t->bufAddr = rmesa->r128Screen->texOffset[heap] + t->memBlock->ofs; + t->bufAddr = rmesa->r128Screen->texOffset[heap] + + t->base.memBlock->ofs; /* Set texture offsets for each mipmap level */ if ( t->setup.tex_cntl & R128_MIP_MAP_DISABLE ) { @@ -555,37 +278,25 @@ void r128UploadTexImages( r128ContextPtr rmesa, r128TexObjPtr t ) t->setup.tex_offset[j] = t->bufAddr + t->image[i].offset; } } - - /* Force loading the new state into the hardware */ - switch ( t->bound ) { - case 1: - rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_TEX0; - break; - - case 2: - rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_TEX1; - break; - - default: - return; - } } - /* Let the world know we've used this memory recently */ - r128UpdateTexLRU( rmesa, t ); + /* Let the world know we've used this memory recently. + */ + driUpdateTextureLRU( (driTextureObject *) t ); + UNLOCK_HARDWARE( rmesa ); /* Upload any images that are new */ - if ( t->dirty_images ) { + if ( t->base.dirty_images[0] ) { for ( i = 0 ; i < numLevels; i++ ) { const GLint j = t->firstLevel + i; /* the texObj's level */ - if ( t->dirty_images & (1 << j) ) { - r128UploadSubImage( rmesa, t, j, 0, 0, - t->image[i].width, t->image[i].height ); + if ( t->base.dirty_images[0] & (1 << j) ) { + uploadSubImage( rmesa, t, j, 0, 0, + t->image[i].width, t->image[i].height ); } } rmesa->setup.tex_cntl_c |= R128_TEX_CACHE_FLUSH; rmesa->dirty |= R128_UPLOAD_CONTEXT; - t->dirty_images = 0; + t->base.dirty_images[0] = 0; } } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h index 37a0a98a9..41fed0ab1 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h @@ -52,26 +52,15 @@ typedef struct r128_tex_obj r128TexObj, *r128TexObjPtr; /* Texture object in locally shared texture space. */ struct r128_tex_obj { - r128TexObjPtr next, prev; + driTextureObject base; - struct gl_texture_object *tObj; /* Mesa texture object */ - - PMemBlock memBlock; /* Memory block containing texture */ CARD32 bufAddr; /* Offset to start of locally shared texture block */ - CARD32 dirty_images; /* Flags for whether or not - images need to be uploaded to - local or AGP texture space */ - GLuint age; - GLint bound; /* Texture unit currently bound to */ - GLint heap; /* Texture heap currently stored in */ r128TexImage image[R128_MAX_TEXTURE_LEVELS]; /* Image data for all mipmap levels */ - GLint totalSize; /* Total size of the texture - including all mipmap levels */ CARD32 textureFormat; /* Actual hardware format */ r128_texture_regs_t setup; /* Setup regs for texture */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_texstate.c b/xc/lib/GL/mesa/src/drv/r128/r128_texstate.c index 33e2d2120..45c805a19 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_texstate.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_texstate.c @@ -80,7 +80,7 @@ static void r128SetTexImages( r128ContextPtr rmesa, t->textureFormat = R128_DATATYPE_CI8; break; default: - _mesa_problem(rmesa->glCtx, "Bad texture format in r128SetTexImages"); + _mesa_problem(rmesa->glCtx, "Bad texture format in %s", __FUNCTION__); }; /* Compute which mipmap levels we really want to send to the hardware. @@ -101,7 +101,7 @@ static void r128SetTexImages( r128ContextPtr rmesa, log2Size = MAX2(log2Pitch, log2Height); log2MinSize = log2Size; - t->dirty_images = 0; + t->base.dirty_images[0] = 0; totalSize = 0; for ( i = firstLevel; i <= lastLevel; i++ ) { const struct gl_texture_image *texImage; @@ -118,7 +118,7 @@ static void r128SetTexImages( r128ContextPtr rmesa, t->image[i - firstLevel].width = tObj->Image[i]->Width; t->image[i - firstLevel].height = tObj->Image[i]->Height; - t->dirty_images |= (1 << i); + t->base.dirty_images[0] |= (1 << i); totalSize += (tObj->Image[i]->Height * tObj->Image[i]->Width * @@ -128,7 +128,7 @@ static void r128SetTexImages( r128ContextPtr rmesa, totalSize = (totalSize + 31) & ~31; } - t->totalSize = totalSize; + t->base.totalSize = totalSize; t->firstLevel = firstLevel; t->lastLevel = lastLevel; @@ -152,9 +152,7 @@ static void r128SetTexImages( r128ContextPtr rmesa, else t->setup.tex_cntl &= ~R128_MIP_MAP_DISABLE; - /* XXX this is done in r128EmitHwStateLocked(): - r128UploadTexImages( rmesa, t ); - */ + /* FYI: r128UploadTexImages( rmesa, t ); used to be called here */ } @@ -195,7 +193,7 @@ static void r128SetTexImages( r128ContextPtr rmesa, #define INPUT_PREVIOUS (R128_INPUT_FACTOR_PREV_COLOR | \ R128_INP_FACTOR_A_PREV_ALPHA) -static void r128UpdateTextureEnv( GLcontext *ctx, int unit ) +static GLboolean r128UpdateTextureEnv( GLcontext *ctx, int unit ) { r128ContextPtr rmesa = R128_CONTEXT(ctx); GLint source = rmesa->tmu_source[unit]; @@ -236,7 +234,7 @@ static void r128UpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; @@ -259,7 +257,7 @@ static void r128UpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; @@ -283,7 +281,7 @@ static void r128UpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; @@ -319,14 +317,13 @@ static void r128UpdateTextureEnv( GLcontext *ctx, int unit ) default: combine |= (COLOR_COMB_MODULATE | /* C = fallback */ ALPHA_COMB_MODULATE); /* A = fallback */ - FALLBACK( rmesa, R128_FALLBACK_TEXTURE, GL_TRUE ); - break; + return GL_FALSE; } break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; } @@ -335,7 +332,7 @@ static void r128UpdateTextureEnv( GLcontext *ctx, int unit ) * to software rendering. */ if ( rmesa->blend_flags ) { - FALLBACK( rmesa, R128_FALLBACK_TEXTURE, GL_TRUE ); + return GL_FALSE; } switch ( format ) { case GL_RGBA: @@ -360,8 +357,7 @@ static void r128UpdateTextureEnv( GLcontext *ctx, int unit ) default: combine |= (COLOR_COMB_MODULATE | /* C = fallback */ ALPHA_COMB_MODULATE); /* A = fallback */ - FALLBACK( rmesa, R128_FALLBACK_TEXTURE, GL_TRUE ); - break; + return GL_FALSE; } break; case GL_RGB: @@ -386,8 +382,7 @@ static void r128UpdateTextureEnv( GLcontext *ctx, int unit ) default: combine |= (COLOR_COMB_MODULATE | /* C = fallback */ ALPHA_COMB_COPY_INPUT); /* A = fallback */ - FALLBACK( rmesa, R128_FALLBACK_TEXTURE, GL_TRUE ); - break; + return GL_FALSE; } break; case GL_ALPHA: @@ -417,8 +412,7 @@ static void r128UpdateTextureEnv( GLcontext *ctx, int unit ) default: combine |= (COLOR_COMB_MODULATE | /* C = fallback */ ALPHA_COMB_MODULATE); /* A = fallback */ - FALLBACK( rmesa, R128_FALLBACK_TEXTURE, GL_TRUE ); - break; + return GL_FALSE; } switch ( rmesa->env_color & 0xff000000 ) { case 0x00000000: @@ -437,13 +431,12 @@ static void r128UpdateTextureEnv( GLcontext *ctx, int unit ) default: combine |= (COLOR_COMB_MODULATE | /* C = fallback */ ALPHA_COMB_MODULATE); /* A = fallback */ - FALLBACK( rmesa, R128_FALLBACK_TEXTURE, GL_TRUE ); - break; + return GL_FALSE; } break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; @@ -469,132 +462,185 @@ static void r128UpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; default: - return; + return GL_FALSE; } - rmesa->tex_combine[unit] = combine; + if ( rmesa->tex_combine[unit] != combine ) { + rmesa->tex_combine[unit] = combine; + rmesa->dirty |= R128_UPLOAD_TEX0 << unit; + } + return GL_TRUE; } -static void r128UpdateTextureUnit( GLcontext *ctx, int unit ) +static void disable_tex( GLcontext *ctx, int unit ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + + if ( rmesa->CurrentTexObj[unit] ) { + rmesa->CurrentTexObj[unit]->base.bound &= ~(1 << unit); + rmesa->CurrentTexObj[unit] = NULL; + } + + rmesa->setup.tex_cntl_c &= ~(R128_TEXMAP_ENABLE << unit); + rmesa->setup.tex_size_pitch_c &= ~(R128_TEX_SIZE_PITCH_MASK << + (R128_SEC_TEX_SIZE_PITCH_SHIFT * unit)); + rmesa->dirty |= R128_UPLOAD_CONTEXT; + + /* If either texture unit is disabled, then multitexturing is not + * happening. + */ + + rmesa->blend_flags &= ~R128_BLEND_MULTITEX; +} + +static GLboolean enable_tex_2d( GLcontext *ctx, int unit ) { r128ContextPtr rmesa = R128_CONTEXT(ctx); const int source = rmesa->tmu_source[unit]; const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; - const struct gl_texture_object *tObj = ctx->Texture.Unit[source]._Current; - r128TexObjPtr t = tObj->DriverData; + const struct gl_texture_object *tObj = texUnit->_Current; + r128TexObjPtr t = (r128TexObjPtr) tObj->DriverData; - assert(unit == 0 || unit == 1); /* only two tex units */ + /* Need to load the 2d images associated with this unit. + */ + if ( t->base.dirty_images[0] ) { + /* FIXME: For Radeon, RADEON_FIREVERTICES is called here. Should + * FIXME: something similar be done for R128? + */ + /* FLUSH_BATCH( rmesa ); */ - if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) { + r128SetTexImages( rmesa, tObj ); + r128UploadTexImages( rmesa, t ); + if ( !t->base.memBlock ) + return GL_FALSE; + } - assert(t); /* should have driver tex data by now */ + return GL_TRUE; +} - /* Fallback if there's a texture border */ - if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) { - FALLBACK( rmesa, R128_FALLBACK_TEXTURE, GL_TRUE ); - return; - } +static GLboolean update_tex_common( GLcontext *ctx, int unit ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + const int source = rmesa->tmu_source[unit]; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; + const struct gl_texture_object *tObj = texUnit->_Current; + r128TexObjPtr t = (r128TexObjPtr) tObj->DriverData; - /* Upload teximages */ - if (t->dirty_images) { - r128SetTexImages( rmesa, tObj ); - } - /* Bind to the given texture unit */ - rmesa->CurrentTexObj[unit] = t; - t->bound |= (1 << unit); + /* Fallback if there's a texture border */ + if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) { + return GL_FALSE; + } - if ( t->memBlock ) - r128UpdateTexLRU( rmesa, t ); - /* register setup */ - if ( unit == 0 ) { - rmesa->setup.tex_cntl_c |= R128_TEXMAP_ENABLE; - rmesa->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 0; - rmesa->setup.scale_3d_cntl &= ~R128_TEX_CACHE_SPLIT; - t->setup.tex_cntl &= ~R128_SEC_SELECT_SEC_ST; - } - else { - rmesa->setup.tex_cntl_c |= R128_SEC_TEXMAP_ENABLE; - rmesa->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 16; - rmesa->setup.scale_3d_cntl |= R128_TEX_CACHE_SPLIT; - t->setup.tex_cntl |= R128_SEC_SELECT_SEC_ST; + /* Update state if this is a different texture object to last + * time. + */ + if ( rmesa->CurrentTexObj[unit] != t ) { + if ( rmesa->CurrentTexObj[unit] != NULL ) { + /* The old texture is no longer bound to this texture unit. + * Mark it as such. + */ + + rmesa->CurrentTexObj[unit]->base.bound &= + ~(1UL << unit); } + + rmesa->CurrentTexObj[unit] = t; + t->base.bound |= (1UL << unit); + rmesa->dirty |= R128_UPLOAD_TEX0 << unit; + + driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */ } - else if (texUnit->_ReallyEnabled) { - /* 3D or cube map texture enabled - fallback */ - FALLBACK( rmesa, R128_FALLBACK_TEXTURE, GL_TRUE ); + + /* FIXME: We need to update the texture unit if any texture parameters have + * changed, but this texture was already bound. This could be changed to + * work like the Radeon driver where the texture object has it's own + * dirty state flags + */ + rmesa->dirty |= R128_UPLOAD_TEX0 << unit; + + /* register setup */ + rmesa->setup.tex_size_pitch_c &= ~(R128_TEX_SIZE_PITCH_MASK << + (R128_SEC_TEX_SIZE_PITCH_SHIFT * unit)); + + if ( unit == 0 ) { + rmesa->setup.tex_cntl_c |= R128_TEXMAP_ENABLE; + rmesa->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 0; + rmesa->setup.scale_3d_cntl &= ~R128_TEX_CACHE_SPLIT; + t->setup.tex_cntl &= ~R128_SEC_SELECT_SEC_ST; } else { - /* texture unit disabled */ + rmesa->setup.tex_cntl_c |= R128_SEC_TEXMAP_ENABLE; + rmesa->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 16; + rmesa->setup.scale_3d_cntl |= R128_TEX_CACHE_SPLIT; + t->setup.tex_cntl |= R128_SEC_SELECT_SEC_ST; + + /* If the second TMU is enabled, then multitexturing is happening. + */ + if ( R128_IS_PLAIN( rmesa ) ) + rmesa->blend_flags |= R128_BLEND_MULTITEX; } -} + rmesa->dirty |= R128_UPLOAD_CONTEXT; -void r128UpdateTextureState( GLcontext *ctx ) + + /* FIXME: The Radeon has some cached state so that it can avoid calling + * FIXME: UpdateTextureEnv in some cases. Is that possible here? + */ + return r128UpdateTextureEnv( ctx, unit ); +} + +static GLboolean updateTextureUnit( GLcontext *ctx, int unit ) { r128ContextPtr rmesa = R128_CONTEXT(ctx); + const int source = rmesa->tmu_source[unit]; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; - if ( R128_DEBUG & DEBUG_VERBOSE_API ) { - fprintf( stderr, "%s( %p ) enabled=0x%x 0x%x\n", - __FUNCTION__, ctx, ctx->Texture.Unit[0]._ReallyEnabled, - ctx->Texture.Unit[1]._ReallyEnabled ); + + if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) { + return (enable_tex_2d( ctx, unit ) && + update_tex_common( ctx, unit )); + } + else if ( texUnit->_ReallyEnabled ) { + return GL_FALSE; } + else { + disable_tex( ctx, unit ); + return GL_TRUE; + } +} - /* Clear any texturing fallbacks */ - FALLBACK( rmesa, R128_FALLBACK_TEXTURE, GL_FALSE ); - /* Unbind any currently bound textures */ - if ( rmesa->CurrentTexObj[0] ) rmesa->CurrentTexObj[0]->bound = 0; - if ( rmesa->CurrentTexObj[1] ) rmesa->CurrentTexObj[1]->bound = 0; - rmesa->CurrentTexObj[0] = NULL; - rmesa->CurrentTexObj[1] = NULL; +void r128UpdateTextureState( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLboolean ok; - /* Disable all texturing until it is known to be good */ - rmesa->setup.tex_cntl_c &= ~(R128_TEXMAP_ENABLE | - R128_SEC_TEXMAP_ENABLE); - rmesa->setup.tex_size_pitch_c = 0x00000000; - /* - * Now examine texture enable state to do rest of setup. + /* This works around a quirk with the R128 hardware. If only OpenGL + * TEXTURE1 is enabled, then the hardware TEXTURE0 must be used. The + * hardware TEXTURE1 can ONLY be used when hardware TEXTURE0 is also used. */ + rmesa->tmu_source[0] = 0; rmesa->tmu_source[1] = 1; - rmesa->blend_flags &= ~R128_BLEND_MULTITEX; - if (ctx->Texture._EnabledUnits & 0x2) { - /* unit 1 enabled */ - if (ctx->Texture._EnabledUnits & 0x1) { - /* both texture 0 and 1 enabled */ - if ( R128_IS_PLAIN( rmesa ) ) - rmesa->blend_flags |= R128_BLEND_MULTITEX; - r128UpdateTextureUnit( ctx, 0 ); - r128UpdateTextureEnv( ctx, 0 ); - r128UpdateTextureUnit( ctx, 1 ); - r128UpdateTextureEnv( ctx, 1 ); - rmesa->dirty |= (R128_UPLOAD_TEX0IMAGES | R128_UPLOAD_TEX0 | - R128_UPLOAD_TEX1IMAGES | R128_UPLOAD_TEX1); - } - else { - /* only texture 1 enabled */ - rmesa->tmu_source[0] = 1; - rmesa->tmu_source[1] = 0; - r128UpdateTextureUnit( ctx, 0 ); - r128UpdateTextureEnv( ctx, 0 ); - rmesa->dirty |= (R128_UPLOAD_TEX0IMAGES | R128_UPLOAD_TEX0); - } - } - else if (ctx->Texture._EnabledUnits & 0x1) { - /* only texture 0 enabled */ - r128UpdateTextureUnit( ctx, 0 ); - r128UpdateTextureEnv( ctx, 0 ); - rmesa->dirty |= (R128_UPLOAD_TEX0IMAGES | R128_UPLOAD_TEX0); + if ((ctx->Texture._EnabledUnits & 0x03) == 0x02) { + /* only texture 1 enabled */ + rmesa->tmu_source[0] = 1; + rmesa->tmu_source[1] = 0; } - rmesa->dirty |= R128_UPLOAD_CONTEXT; + ok = (updateTextureUnit( ctx, 0 ) && + updateTextureUnit( ctx, 1 )); + + FALLBACK( rmesa, R128_FALLBACK_TEXTURE, !ok ); } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c index baad131d7..4e2860288 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c @@ -583,7 +583,7 @@ static void r128RunPipeline( GLcontext *ctx ) { r128ContextPtr rmesa = R128_CONTEXT(ctx); - if (rmesa->new_state) + if (rmesa->new_state || rmesa->NewGLState & _NEW_TEXTURE) r128DDUpdateHWState( ctx ); if (!rmesa->Fallback && rmesa->NewGLState) { @@ -699,6 +699,7 @@ void r128Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ) void r128InitTriFuncs( GLcontext *ctx ) { + r128ContextPtr rmesa = R128_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); static int firsttime = 1; @@ -713,6 +714,8 @@ void r128InitTriFuncs( GLcontext *ctx ) tnl->Driver.Render.PrimitiveNotify = r128RenderPrimitive; tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; tnl->Driver.Render.BuildVertices = r128BuildVertices; + rmesa->NewGLState |= (_R128_NEW_RENDER_STATE| + _R128_NEW_VERTEX_STATE); /* r128Fallback( ctx, 0x100000, 1 ); */ } diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_cmdbuf.c b/xc/lib/GL/mesa/src/drv/r200/r200_cmdbuf.c index 3e6b628b1..a64b32d91 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_cmdbuf.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_cmdbuf.c @@ -132,13 +132,6 @@ extern void r200EmitVbufPrim( r200ContextPtr rmesa, R200_VF_PRIM_WALK_LIST | R200_VF_COLOR_ORDER_RGBA | (vertex_nr << R200_VF_VERTEX_NUMBER_SHIFT)); - - - if (R200_DEBUG & DEBUG_SYNC) { - fprintf(stderr, "\nSyncing\n\n"); - R200_FIREVERTICES( rmesa ); - r200Finish( rmesa->glCtx ); - } } @@ -163,8 +156,7 @@ void r200FlushElts( r200ContextPtr rmesa ) cmd[2] |= nr << R200_VF_VERTEX_NUMBER_SHIFT; if (R200_DEBUG & DEBUG_SYNC) { - fprintf(stderr, "\nSyncing in %s\n\n", __FUNCTION__); - R200_FIREVERTICES( rmesa ); + fprintf(stderr, "%s: Syncing\n", __FUNCTION__); r200Finish( rmesa->glCtx ); } } diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_context.c b/xc/lib/GL/mesa/src/drv/r200/r200_context.c index bbfe4bd95..01678a790 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_context.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_context.c @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -38,7 +40,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "simple_list.h" #include "imports.h" #include "matrix.h" -#include "state.h" #include "extensions.h" #include "state.h" @@ -64,8 +65,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "X86/common_x86_asm.h" #endif -#define R200_DATE "20021125" +#define DRIVER_DATE "20030328" +#include "vblank.h" +#include "utils.h" #ifndef R200_DEBUG int R200_DEBUG = (0); #endif @@ -92,60 +95,19 @@ static const GLubyte *r200GetString( GLcontext *ctx, GLenum name ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); static char buffer[128]; + unsigned offset; switch ( name ) { case GL_VENDOR: return (GLubyte *)"Tungsten Graphics, Inc."; case GL_RENDERER: - sprintf( buffer, "Mesa DRI R200 " R200_DATE); - - /* Append any chipset-specific information. None yet. - */ - - /* Append any AGP-specific information. - */ - switch ( rmesa->r200Screen->AGPMode ) { - case 1: - strncat( buffer, " AGP 1x", 7 ); - break; - case 2: - strncat( buffer, " AGP 2x", 7 ); - break; - case 4: - strncat( buffer, " AGP 4x", 7 ); - break; - } - - /* Append any CPU-specific information. - */ -#ifdef USE_X86_ASM - if ( _mesa_x86_cpu_features ) { - strncat( buffer, " x86", 4 ); - } -#ifdef USE_MMX_ASM - if ( cpu_has_mmx ) { - strncat( buffer, "/MMX", 4 ); - } -#endif -#ifdef USE_3DNOW_ASM - if ( cpu_has_3dnow ) { - strncat( buffer, "/3DNow!", 7 ); - } -#endif -#ifdef USE_SSE_ASM - if ( cpu_has_xmm ) { - strncat( buffer, "/SSE", 4 ); - } -#endif -#endif + offset = driGetRendererString( buffer, "R200", DRIVER_DATE, + rmesa->r200Screen->AGPMode ); - if ( !(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE) ) { - strncat( buffer, " TCL", 4 ); - } - else { - strncat( buffer, " NO-TCL", 7 ); - } + sprintf( & buffer[ offset ], " %sTCL", + !(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE) + ? "" : "NO-" ); return (GLubyte *)buffer; @@ -155,44 +117,41 @@ static const GLubyte *r200GetString( GLcontext *ctx, GLenum name ) } - -/* Initialize the extensions supported by this driver. +/* Extension strings exported by the R200 driver. */ -static void r200InitExtensions( GLcontext *ctx, r200ScreenPtr r200Screen ) +static const char * const card_extensions[] = { - _mesa_enable_imaging_extensions( ctx ); - - _mesa_enable_extension( ctx, "GL_ARB_multitexture" ); - if (r200Screen->drmSupportsCubeMaps) - _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" ); - _mesa_enable_extension( ctx, "GL_ARB_texture_env_add" ); - _mesa_enable_extension( ctx, "GL_ARB_texture_env_combine" ); - _mesa_enable_extension( ctx, "GL_ARB_texture_env_dot3" ); - _mesa_enable_extension( ctx, "GL_ARB_texture_mirrored_repeat" ); - _mesa_enable_extension( ctx, "GL_ARB_texture_border_clamp" ); - - _mesa_enable_extension( ctx, "GL_ATI_texture_env_combine3" ); - _mesa_enable_extension( ctx, "GL_ATI_texture_mirror_once" ); - - _mesa_enable_extension( ctx, "GL_EXT_blend_logic_op" ); - /*_mesa_enable_extension( ctx, "GL_EXT_fog_coord" );*/ - _mesa_enable_extension( ctx, "GL_EXT_stencil_wrap" ); - _mesa_enable_extension( ctx, "GL_EXT_texture_edge_clamp" ); - _mesa_enable_extension( ctx, "GL_EXT_texture_env_add" ); - _mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" ); - _mesa_enable_extension( ctx, "GL_EXT_texture_env_dot3" ); - _mesa_enable_extension( ctx, "GL_EXT_texture_filter_anisotropic" ); - _mesa_enable_extension( ctx, "GL_EXT_texture_lod_bias" ); - _mesa_enable_extension( ctx, "GL_EXT_secondary_color" ); - _mesa_enable_extension( ctx, "GL_EXT_blend_subtract" ); - _mesa_enable_extension( ctx, "GL_EXT_blend_minmax" ); - -/* _mesa_enable_extension( ctx, "GL_EXT_fog_coord" ); */ - - _mesa_enable_extension( ctx, "GL_MESA_pack_invert" ); - _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" ); - _mesa_enable_extension( ctx, "GL_NV_texture_rectangle" ); -} + "GL_ARB_multisample", + "GL_ARB_multitexture", + "GL_ARB_texture_border_clamp", + "GL_ARB_texture_compression", + "GL_ARB_texture_env_add", + "GL_ARB_texture_env_combine", + "GL_ARB_texture_env_dot3", + "GL_ARB_texture_mirrored_repeat", + "GL_EXT_blend_logic_op", + "GL_EXT_blend_minmax", + "GL_EXT_blend_subtract", + "GL_EXT_secondary_color", + "GL_EXT_stencil_wrap", + "GL_EXT_texture_edge_clamp", + "GL_EXT_texture_env_add", + "GL_EXT_texture_env_combine", + "GL_EXT_texture_env_dot3", + "GL_EXT_texture_filter_anisotropic", + "GL_EXT_texture_lod_bias", + "GL_ATI_texture_env_combine3", + "GL_ATI_texture_mirror_once", + "GL_IBM_texture_mirrored_repeat", + "GL_MESA_pack_invert", + "GL_MESA_ycbcr_texture", + "GL_NV_blend_square", + "GL_NV_texture_rectangle", + "GL_SGIS_generate_mipmap", + "GL_SGIS_texture_border_clamp", + "GL_SGIS_texture_edge_clamp", + NULL +}; extern const struct gl_pipeline_stage _r200_render_stage; extern const struct gl_pipeline_stage _r200_tcl_stage; @@ -244,54 +203,36 @@ static void r200InitDriverFuncs( GLcontext *ctx ) ctx->Driver.Bitmap = NULL; } -static void add_debug_flags( const char *debug ) +static const struct dri_debug_control debug_control[] = { - if (strstr(debug, "fall")) - R200_DEBUG |= DEBUG_FALLBACKS; - - if (strstr(debug, "tex")) - R200_DEBUG |= DEBUG_TEXTURE; - - if (strstr(debug, "ioctl")) - R200_DEBUG |= DEBUG_IOCTL; - - if (strstr(debug, "prim")) - R200_DEBUG |= DEBUG_PRIMS; - - if (strstr(debug, "vert")) - R200_DEBUG |= DEBUG_VERTS; - - if (strstr(debug, "state")) - R200_DEBUG |= DEBUG_STATE; - - if (strstr(debug, "code")) - R200_DEBUG |= DEBUG_CODEGEN; - - if (strstr(debug, "vfmt") || strstr(debug, "vtxf")) - R200_DEBUG |= DEBUG_VFMT; - - if (strstr(debug, "verb")) - R200_DEBUG |= DEBUG_VERBOSE; - - if (strstr(debug, "dri")) - R200_DEBUG |= DEBUG_DRI; - - if (strstr(debug, "dma")) - R200_DEBUG |= DEBUG_DMA; - - if (strstr(debug, "san")) - R200_DEBUG |= DEBUG_SANITY; - - if (strstr(debug, "sync")) - R200_DEBUG |= DEBUG_SYNC; + { "fall", DEBUG_FALLBACKS }, + { "tex", DEBUG_TEXTURE }, + { "ioctl", DEBUG_IOCTL }, + { "prim", DEBUG_PRIMS }, + { "vert", DEBUG_VERTS }, + { "state", DEBUG_STATE }, + { "code", DEBUG_CODEGEN }, + { "vfmt", DEBUG_VFMT }, + { "vtxf", DEBUG_VFMT }, + { "verb", DEBUG_VERBOSE }, + { "dri", DEBUG_DRI }, + { "dma", DEBUG_DMA }, + { "san", DEBUG_SANITY }, + { "sync", DEBUG_SYNC }, + { "pix", DEBUG_PIXEL }, + { "mem", DEBUG_MEMORY }, + { NULL, 0 } +}; - if (strstr(debug, "pix")) - R200_DEBUG |= DEBUG_PIXEL; - if (strstr(debug, "mem")) - R200_DEBUG |= DEBUG_MEMORY; +static int +get_ust_nop( int64_t * ust ) +{ + *ust = 1; + return 0; } + /* Create the device specific context. */ GLboolean r200CreateContext( const __GLcontextModes *glVisual, @@ -299,14 +240,14 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, void *sharedContextPrivate) { __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - r200ScreenPtr r200Screen = (r200ScreenPtr)(sPriv->private); + r200ScreenPtr screen = (r200ScreenPtr)(sPriv->private); r200ContextPtr rmesa; GLcontext *ctx, *shareCtx; - int i, memPerUnit; + int i; assert(glVisual); assert(driContextPriv); - assert(r200Screen); + assert(screen); /* Allocate the R200 context */ rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) ); @@ -334,78 +275,55 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, rmesa->dri.fd = sPriv->fd; rmesa->dri.drmMinor = sPriv->drmMinor; - rmesa->r200Screen = r200Screen; + rmesa->r200Screen = screen; rmesa->sarea = (RADEONSAREAPrivPtr)((GLubyte *)sPriv->pSAREA + - r200Screen->sarea_priv_offset); + screen->sarea_priv_offset); rmesa->dma.buf0_address = rmesa->r200Screen->buffers->list[0].address; - for ( i = 0 ; i < r200Screen->numTexHeaps ; i++ ) { - make_empty_list( &rmesa->texture.objects[i] ); - rmesa->texture.heap[i] = mmInit( 0, r200Screen->texSize[i] ); - rmesa->texture.age[i] = -1; + (void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) ); + make_empty_list( & rmesa->swapped ); + + rmesa->nr_heaps = 1 /* screen->numTexHeaps */ ; + for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { + rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa, + screen->texSize[i], + 12, + RADEON_NR_TEX_REGIONS, + rmesa->sarea->texList[i], + & rmesa->sarea->texAge[i], + & rmesa->swapped, + sizeof( r200TexObj ), + (destroy_texture_object_t *) r200DestroyTexObj ); } - rmesa->texture.numHeaps = r200Screen->numTexHeaps; - make_empty_list( &rmesa->texture.swapped ); rmesa->swtcl.RenderIndex = ~0; rmesa->lost_context = 1; - /* KW: Set the maximum texture size small enough that we can - * guarentee that both texture units can bind a maximal texture - * and have them both in on-card memory at once. - * Test for 2 textures * 4 bytes/texel * size * size. + /* Set the maximum texture size small enough that we can guarentee that + * all texture units can bind a maximal texture and have them both in + * texturable memory at once. */ - ctx = rmesa->glCtx; - memPerUnit = r200Screen->texSize[RADEON_CARD_HEAP] / 2; - /* XXX the following code could go into a utility file */ - if (memPerUnit >= 4 * 2048 * 2048) { - ctx->Const.MaxTextureLevels = 12; /* 2048x2048 */ - } - else if (memPerUnit >= 4 * 1024 * 1024) { - ctx->Const.MaxTextureLevels = 11; /* 1024x1024 */ - } - else if (memPerUnit >= 4 * 512 * 512) { - ctx->Const.MaxTextureLevels = 10; /* 512x512 */ - } - else { - ctx->Const.MaxTextureLevels = 9; /* 256x256 */ - } + ctx = rmesa->glCtx; + ctx->Const.MaxTextureUnits = 2; + driCalculateMaxTextureLevels( rmesa->texture_heaps, + rmesa->nr_heaps, + & ctx->Const, + 4, + 11, /* max 2D texture size is 2048x2048 */ #if ENABLE_HW_3D_TEXTURE - if (memPerUnit >= 4 * 256 * 256 * 256) { - ctx->Const.Max3DTextureLevels = 9; /* 256x256x256 */ - } - else if (memPerUnit >= 4 * 64 * 64 * 64) { - ctx->Const.Max3DTextureLevels = 8; /* 128x128x128 */ - } - else if (memPerUnit >= 4 * 32 * 32 * 32) { - ctx->Const.Max3DTextureLevels = 7; /* 64x64x64 */ - } - else { /* 256KBytes */ - ctx->Const.Max3DTextureLevels = 6; /* 32x32x32 */ - } + 8, /* max 3D texture size is 256^3 */ +#else + 0, /* 3D textures unsupported */ #endif + 11, /* max cube texture size is 2048x2048 */ + 11, /* max texture rectangle size is 2048x2048 */ + 12, + GL_FALSE ); - if (memPerUnit >= 4 * 6 * 2048 * 2048) { - ctx->Const.MaxCubeTextureLevels = 12; /* 2048x2048 */ - } - if (memPerUnit >= 4 * 6 * 1024 * 1024) { - ctx->Const.MaxCubeTextureLevels = 11; /* 1024x1024 */ - } - else if (memPerUnit >= 4 * 6 * 512 * 512) { - ctx->Const.MaxCubeTextureLevels = 10; /* 512x512 */ - } - else if (memPerUnit >= 4 * 6 * 256 * 256) { - ctx->Const.MaxCubeTextureLevels = 9; /* 256x256 */ - } - else { /* 393216 bytes */ - ctx->Const.MaxCubeTextureLevels = 8; /* 128x128 */ - } - - ctx->Const.MaxTextureUnits = 2; ctx->Const.MaxTextureMaxAnisotropy = 16.0; /* No wide points. @@ -453,7 +371,10 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, _math_matrix_set_identity( &rmesa->TexGenMatrix[1] ); _math_matrix_set_identity( &rmesa->tmpmat ); - r200InitExtensions( ctx, r200Screen ); + driInitExtensions( ctx, card_extensions, GL_TRUE ); + if (rmesa->r200Screen->drmSupportsCubeMaps) + _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" ); + r200InitDriverFuncs( ctx ); r200InitIoctlFuncs( ctx ); r200InitStateFuncs( ctx ); @@ -478,15 +399,23 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, rmesa->do_usleeps = !getenv("R200_NO_USLEEPS"); + + rmesa->vblank_flags = (rmesa->do_irqs) + ? driGetDefaultVBlankFlags() : VBLANK_FLAG_NO_IRQ; + rmesa->prefer_agp_client_texturing = (getenv("R200_AGP_CLIENT_TEXTURES") != 0); - + rmesa->get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( "__glXGetUST" ); + if ( rmesa->get_ust == NULL ) { + rmesa->get_ust = get_ust_nop; + } + #if DO_DEBUG - if (getenv("R200_DEBUG")) - add_debug_flags( getenv("R200_DEBUG") ); - if (getenv("RADEON_DEBUG")) - add_debug_flags( getenv("RADEON_DEBUG") ); + R200_DEBUG = driParseDebugString( getenv( "R200_DEBUG" ), + debug_control ); + R200_DEBUG |= driParseDebugString( getenv( "RADEON_DEBUG" ), + debug_control ); #endif if (getenv("R200_NO_RAST")) { @@ -526,33 +455,16 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv ) /* Free r200 context resources */ assert(rmesa); /* should never be null */ if ( rmesa ) { - if (rmesa->glCtx->Shared->RefCount == 1) { - /* This share group is about to go away, free our private - * texture object data. - */ - r200TexObjPtr t, next_t; - int i; - - for ( i = 0 ; i < rmesa->texture.numHeaps ; i++ ) { - foreach_s ( t, next_t, &rmesa->texture.objects[i] ) { - r200DestroyTexObj( rmesa, t ); - } - mmDestroy( rmesa->texture.heap[i] ); - rmesa->texture.heap[i] = NULL; - } + GLboolean release_texture_heaps; - foreach_s ( t, next_t, &rmesa->texture.swapped ) { - r200DestroyTexObj( rmesa, t ); - } - } + release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( rmesa->glCtx ); _tnl_DestroyContext( rmesa->glCtx ); _ac_DestroyContext( rmesa->glCtx ); _swrast_DestroyContext( rmesa->glCtx ); r200DestroySwtcl( rmesa->glCtx ); - r200ReleaseArrays( rmesa->glCtx, ~0 ); if (rmesa->dma.current.buf) { @@ -573,6 +485,20 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv ) rmesa->state.scissor.pClipRects = 0; } + if ( release_texture_heaps ) { + /* This share group is about to go away, free our private + * texture object data. + */ + int i; + + assert( is_empty_list( & rmesa->swapped ) ); + + for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { + driDestroyTextureHeap( rmesa->texture_heaps[ i ] ); + rmesa->texture_heaps[ i ] = NULL; + } + } + FREE( rmesa ); } } @@ -600,7 +526,7 @@ r200SwapBuffers( __DRIdrawablePrivate *dPriv ) } else { /* XXX this shouldn't be an error but we can't handle it for now */ - _mesa_problem(NULL, "r200SwapBuffers: drawable has no context!\n"); + _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__); } } @@ -614,32 +540,32 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv, __DRIdrawablePrivate *driReadPriv ) { if ( driContextPriv ) { - r200ContextPtr newR200Ctx = + r200ContextPtr newCtx = (r200ContextPtr) driContextPriv->driverPrivate; if (R200_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s ctx %p\n", __FUNCTION__, newR200Ctx->glCtx); + fprintf(stderr, "%s ctx %p\n", __FUNCTION__, newCtx->glCtx); - if ( newR200Ctx->dri.drawable != driDrawPriv ) { - newR200Ctx->dri.drawable = driDrawPriv; - r200UpdateWindow( newR200Ctx->glCtx ); - r200UpdateViewportOffset( newR200Ctx->glCtx ); + if ( newCtx->dri.drawable != driDrawPriv ) { + newCtx->dri.drawable = driDrawPriv; + r200UpdateWindow( newCtx->glCtx ); + r200UpdateViewportOffset( newCtx->glCtx ); } - _mesa_make_current2( newR200Ctx->glCtx, + _mesa_make_current2( newCtx->glCtx, (GLframebuffer *) driDrawPriv->driverPrivate, (GLframebuffer *) driReadPriv->driverPrivate ); - if ( !newR200Ctx->glCtx->Viewport.Width ) { - _mesa_set_viewport( newR200Ctx->glCtx, 0, 0, + if ( !newCtx->glCtx->Viewport.Width ) { + _mesa_set_viewport( newCtx->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h ); } - if (newR200Ctx->vb.enabled) - r200VtxfmtMakeCurrent( newR200Ctx->glCtx ); + if (newCtx->vb.enabled) + r200VtxfmtMakeCurrent( newCtx->glCtx ); - _mesa_update_state( newR200Ctx->glCtx ); - r200ValidateState( newR200Ctx->glCtx ); + _mesa_update_state( newCtx->glCtx ); + r200ValidateState( newCtx->glCtx ); } else { if (R200_DEBUG & DEBUG_DRI) @@ -665,9 +591,3 @@ r200UnbindContext( __DRIcontextPrivate *driContextPriv ) r200VtxfmtUnbindContext( rmesa->glCtx ); return GL_TRUE; } - - - - - - diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_context.h b/xc/lib/GL/mesa/src/drv/r200/r200_context.h index b5853960f..3c04c0cd8 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_context.h +++ b/xc/lib/GL/mesa/src/drv/r200/r200_context.h @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -37,8 +39,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef GLX_DIRECT_RENDERING +#include <stdint.h> #include "dri_util.h" #include "radeon_common.h" +#include "texmem.h" #include "macros.h" #include "mtypes.h" @@ -132,19 +136,11 @@ typedef struct r200_tex_obj r200TexObj, *r200TexObjPtr; /* Texture object in locally shared texture space. */ struct r200_tex_obj { - r200TexObjPtr next, prev; - - struct gl_texture_object *tObj; /* Mesa texture object */ + driTextureObject base; - PMemBlock memBlock; /* Memory block containing texture */ GLuint bufAddr; /* Offset to start of locally shared texture block */ - GLuint dirty_images[6]; /* Flags for whether or not - images need to be uploaded to - local or AGP texture space. - Six cube faces. */ - GLuint dirty_state; /* Flags (1 per texunit) for whether or not this texobj has dirty hardware state @@ -152,15 +148,9 @@ struct r200_tex_obj { brought into the texunit. */ - GLint heap; /* Texture heap currently stored in */ - drmRadeonTexImage image[6][RADEON_MAX_TEXTURE_LEVELS]; /* Six, for the cube faces */ - GLint totalSize; /* Total size of the texture - including all mipmap levels, - and all six cube faces */ - GLuint pp_txfilter; /* hardware register values */ GLuint pp_txformat; GLuint pp_txformat_x; @@ -205,8 +195,8 @@ struct r200_state_atom { /* Trying to keep these relatively short as the variables are becoming - * extravagently long. Drop the R200_ off the front of everything - - * I think we know we're in the r200 driver by now, and keep the + * extravagently long. Drop the driver name prefix off the front of + * everything - I think we know which driver we're in by now, and keep the * prefix to 3 letters unless absolutely impossible. */ @@ -538,16 +528,6 @@ struct r200_state { struct r200_texture_state texture; }; -struct r200_texture { - r200TexObj objects[R200_NR_TEX_HEAPS]; - r200TexObj swapped; - - memHeap_t *heap[R200_NR_TEX_HEAPS]; - GLint age[R200_NR_TEX_HEAPS]; - - GLint numHeaps; -}; - /* Need refcounting on dma buffers: */ struct r200_dma_buffer { @@ -768,7 +748,7 @@ struct r200_vbinfo { GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */ GLuint primflags; - GLboolean enabled; /* R200_NO_VTXFMT//R200_NO_TCL env vars */ + GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */ GLboolean installed; GLboolean fell_back; GLboolean recheck; @@ -799,7 +779,9 @@ struct r200_context { /* Texture object bookkeeping */ - struct r200_texture texture; + unsigned nr_heaps; + driTexHeap * texture_heaps[ R200_NR_TEX_HEAPS ]; + driTextureObject swapped; /* Rasterization and vertex state: @@ -856,9 +838,18 @@ struct r200_context { GLuint TexGenCompSel; GLmatrix tmpmat; - /* VBI + /* VBI / buffer swap */ GLuint vbl_seq; + GLuint vblank_flags; + + uint64_t swap_ust; + uint64_t swap_missed_ust; + + GLuint swap_count; + GLuint swap_missed_count; + + PFNGLXGETUSTPROC get_ust; /* r200_tcl.c */ diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.c b/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.c index bf56c3e34..dba458931 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.c @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -45,20 +47,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_sanity.h" #include "radeon_reg.h" -#include <unistd.h> /* for usleep() */ +#include "vblank.h" #define R200_TIMEOUT 512 #define R200_IDLE_RETRY 16 -static void do_usleep( int nr, const char *caller ) -{ - if (1) fprintf(stderr, "sleep %d in %s\n", nr, caller ); - if (1) usleep( nr ); - sched_yield(); -} - static void r200WaitForIdle( r200ContextPtr rmesa ); @@ -98,8 +93,10 @@ int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller ) if (R200_DEBUG & DEBUG_MEMORY) { - if (!r200ValidateTexObjs( rmesa )) { - fprintf(stderr, " -- tex memory is inconsistent - expect mangled textures\n"); + if (! driValidateTextureHeaps( rmesa->texture_heaps, rmesa->nr_heaps, + & rmesa->swapped ) ) { + fprintf( stderr, "%s: texture memory is inconsistent - expect " + "mangled textures\n", __FUNCTION__ ); } } @@ -133,7 +130,6 @@ int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller ) rmesa->store.statenr = 0; rmesa->store.cmd_used = 0; rmesa->dma.nr_released_bufs = 0; -/* rmesa->lost_context = 0; */ rmesa->lost_context = 1; return ret; } @@ -207,10 +203,10 @@ void r200RefillCurrentDmaRegion( r200ContextPtr rmesa ) if (rmesa->dma.nr_released_bufs) { r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); } - + if (rmesa->do_usleeps) { UNLOCK_HARDWARE( rmesa ); - do_usleep(1, __FUNCTION__); + DO_USLEEP( 1 ); LOCK_HARDWARE( rmesa ); } } @@ -297,6 +293,8 @@ void r200AllocDmaRegion( r200ContextPtr rmesa, rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */ rmesa->dma.current.start = rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7; + + assert( rmesa->dma.current.ptr <= rmesa->dma.current.end ); } void r200AllocDmaRegionVerts( r200ContextPtr rmesa, @@ -388,7 +386,7 @@ static void r200WaitForFrameCompletion( r200ContextPtr rmesa ) while (r200GetLastFrame (rmesa) < sarea->last_frame) { UNLOCK_HARDWARE( rmesa ); if (rmesa->do_usleeps) - do_usleep(1, __FUNCTION__); + DO_USLEEP( 1 ); LOCK_HARDWARE( rmesa ); } } @@ -402,6 +400,8 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv ) { r200ContextPtr rmesa; GLint nbox, i, ret; + GLboolean missed_target; + int64_t ust; assert(dPriv); assert(dPriv->driContextPriv); @@ -422,8 +422,9 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv ) * request at a time. */ r200WaitForFrameCompletion( rmesa ); - - r200WaitForVBlank( rmesa ); + UNLOCK_HARDWARE( rmesa ); + driWaitForVBlank( & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target ); + LOCK_HARDWARE( rmesa ); nbox = rmesa->dri.drawable->numClipRects; /* must be in locked region */ @@ -450,13 +451,24 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv ) UNLOCK_HARDWARE( rmesa ); rmesa->lost_context = 1; - sched_yield(); /* Try and give other threads a shot */ + + rmesa->swap_count++; + (*rmesa->get_ust)( & ust ); + if ( missed_target ) { + rmesa->swap_missed_count++; + rmesa->swap_missed_ust = ust - rmesa->swap_ust; + } + + rmesa->swap_ust = ust; + + sched_yield(); } void r200PageFlip( const __DRIdrawablePrivate *dPriv ) { r200ContextPtr rmesa; GLint ret; + GLboolean missed_target; assert(dPriv); assert(dPriv->driContextPriv); @@ -491,18 +503,26 @@ void r200PageFlip( const __DRIdrawablePrivate *dPriv ) * request at a time. */ r200WaitForFrameCompletion( rmesa ); - - r200WaitForVBlank( rmesa ); + UNLOCK_HARDWARE( rmesa ); + driWaitForVBlank( & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target ); + if ( missed_target ) { + rmesa->swap_missed_count++; + (void) (*rmesa->get_ust)( & rmesa->swap_missed_ust ); + } + LOCK_HARDWARE( rmesa ); ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP ); UNLOCK_HARDWARE( rmesa ); if ( ret ) { - fprintf( stderr, "DRM_R200_FLIP: return = %d\n", ret ); + fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret ); exit( 1 ); } + rmesa->swap_count++; + (void) (*rmesa->get_ust)( & rmesa->swap_ust ); + if ( rmesa->sarea->pfCurrentPage == 1 ) { rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset; rmesa->state.color.drawPitch = rmesa->r200Screen->frontPitch; @@ -610,7 +630,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, if (rmesa->do_usleeps) { UNLOCK_HARDWARE( rmesa ); - do_usleep(1, __FUNCTION__); + DO_USLEEP( 1 ); LOCK_HARDWARE( rmesa ); } } @@ -695,7 +715,7 @@ void r200WaitForIdleLocked( r200ContextPtr rmesa ) do { ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_CP_IDLE); if (ret) - do_usleep( 1, __FUNCTION__ ); + DO_USLEEP( 1 ); } while (ret && ++i < 100); if ( ret < 0 ) { @@ -705,6 +725,7 @@ void r200WaitForIdleLocked( r200ContextPtr rmesa ) } } + static void r200WaitForIdle( r200ContextPtr rmesa ) { LOCK_HARDWARE(rmesa); @@ -713,41 +734,6 @@ static void r200WaitForIdle( r200ContextPtr rmesa ) } -void r200WaitForVBlank( r200ContextPtr rmesa ) -{ - drmVBlank vbl; - int ret; - - if ( !rmesa->r200Screen->irq ) - return; - - if ( getenv("LIBGL_SYNC_REFRESH") ) { - /* Wait for until the next vertical blank */ - vbl.request.type = DRM_VBLANK_RELATIVE; - vbl.request.sequence = 1; - } else if ( getenv("LIBGL_THROTTLE_REFRESH") ) { - /* Wait for at least one vertical blank since the last call */ - vbl.request.type = DRM_VBLANK_ABSOLUTE; - vbl.request.sequence = rmesa->vbl_seq + 1; - } else { - return; - } - - UNLOCK_HARDWARE( rmesa ); - - if ((ret = drmWaitVBlank( rmesa->dri.fd, &vbl ))) { - fprintf(stderr, "%s: drmWaitVBlank returned %d, IRQs don't seem to be" - " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH" - " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret); - exit(1); - } else if (R200_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s: drmWaitVBlank returned %d\n", __FUNCTION__, ret); - - rmesa->vbl_seq = vbl.reply.sequence; - - LOCK_HARDWARE( rmesa ); -} - void r200Flush( GLcontext *ctx ) { r200ContextPtr rmesa = R200_CONTEXT( ctx ); diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.h b/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.h index f4fec414a..5025c1d23 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.h +++ b/xc/lib/GL/mesa/src/drv/r200/r200_ioctl.h @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -171,14 +173,15 @@ do { \ static __inline char *r200AllocCmdBuf( r200ContextPtr rmesa, int bytes, const char *where ) { + char * head; + if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ) - r200FlushCmdBuf( rmesa, __FUNCTION__ ); - - { - char *head = rmesa->store.cmd_buf + rmesa->store.cmd_used; - rmesa->store.cmd_used += bytes; - return head; - } + r200FlushCmdBuf( rmesa, where ); + + head = rmesa->store.cmd_buf + rmesa->store.cmd_used; + rmesa->store.cmd_used += bytes; + assert( rmesa->store.cmd_used <= R200_CMD_BUF_SZ ); + return head; } diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_lock.c b/xc/lib/GL/mesa/src/drv/r200/r200_lock.c index 22b8b3af2..029142c59 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_lock.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_lock.c @@ -1,5 +1,5 @@ /* $XFree86$ */ -/* +/************************************************************************** Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +25,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -110,9 +111,7 @@ void r200GetLock( r200ContextPtr rmesa, GLuint flags ) sarea->ctxOwner = rmesa->dri.hwContext; } - for ( i = 0 ; i < rmesa->texture.numHeaps ; i++ ) { - if ( sarea->texAge[i] != rmesa->texture.age[i] ) { - r200AgeTextures( rmesa, i ); - } + for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { + DRI_AGE_TEXTURES( rmesa->texture_heaps[ i ] ); } } diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_lock.h b/xc/lib/GL/mesa/src/drv/r200/r200_lock.h index d0b20bf8a..59bc1d656 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_lock.h +++ b/xc/lib/GL/mesa/src/drv/r200/r200_lock.h @@ -1,5 +1,5 @@ /* $XFree86$ */ -/* +/************************************************************************** Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +25,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_maos.h b/xc/lib/GL/mesa/src/drv/r200/r200_maos.h index 1f7b1faa5..0dfcc5c3f 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_maos.h +++ b/xc/lib/GL/mesa/src/drv/r200/r200_maos.h @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_maos_arrays.c b/xc/lib/GL/mesa/src/drv/r200/r200_maos_arrays.c index b05a4cade..f2abaff3a 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_maos_arrays.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_maos_arrays.c @@ -1,5 +1,5 @@ /* $XFree86$ */ -/* +/************************************************************************** Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +25,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -445,9 +446,6 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1; } - -/* fprintf(stderr, "VTXFMT_0: %x VTXFMT_1: %x\n", vfmt0, vfmt1); */ - rmesa->tcl.nr_aos_components = nr; rmesa->tcl.vertex_format = vfmt0; } diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_maos_verts.c b/xc/lib/GL/mesa/src/drv/r200/r200_maos_verts.c index cc1d10f4d..cd866f661 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_maos_verts.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_maos_verts.c @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_sanity.c b/xc/lib/GL/mesa/src/drv/r200/r200_sanity.c index ec0de7ddd..a333ba81e 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_sanity.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_sanity.c @@ -1322,114 +1322,3 @@ int r200SanityCmdBuffer( r200ContextPtr rmesa, return 0; } - -static int check_in_heap( TMemBlock *p, TMemBlock *heap ) -{ -#if 1 - return p->heap == heap; -#else - while (heap && heap != p) - heap = heap->next; - - return heap && heap == p; -#endif -} - -int r200ValidateTexObjs( r200ContextPtr rmesa ) -{ - r200TexObjPtr t, next_t; - int i; - - for ( i = 0 ; i < rmesa->texture.numHeaps ; i++ ) { - int nr = 0, nr2 = 0; - TMemBlock *heap = (TMemBlock *)rmesa->texture.heap[i]; - - /* Check each texture object has a MemBlock, and is linked into - * the correct heap. - * - * Check the texobj base address corresponds to the MemBlock - * range. Check the texobj size (recalculate???) fits within - * the MemBlock. - * - * Count the number of texobj's using this heap. - */ - foreach_s ( t, next_t, &rmesa->texture.objects[i] ) { - int ofs = rmesa->r200Screen->texOffset[i] + t->memBlock->ofs; - - if (!check_in_heap( t->memBlock, heap )) { - fprintf(stderr, "memblock for texobj %p not found in heap %d\n", - t, i); - return GL_FALSE; - } - - if (t->tObj && (t->pp_txoffset != ofs || t->bufAddr != ofs)) { - fprintf(stderr, "Offsets mismatch: %x %x %x\n", - t->pp_txoffset, t->bufAddr, ofs ); - abort(); - return GL_FALSE; - } - - if (t->totalSize > t->memBlock->size) { - fprintf(stderr, "Memblock not large enough: %d %d\n", - t->totalSize, t->memBlock->size); - return GL_FALSE; - } - - - nr++; - } - - /* Validate the contents of the heap: - * - Ordering - * - Overlaps - * - Bounds - */ - { - TMemBlock *p = heap; - int last_end = 0; - - while (p) { - if (p->reserved) { - fprintf(stderr, " Block (%08x,%x), is reserved?!\n", - p->ofs, p->size); - return GL_FALSE; - } - if (p->ofs != last_end) { - fprintf(stderr, "nr2: %d last_end: %d p->ofs: %d\n", - nr2, last_end, p->ofs); - return GL_FALSE; - } - if (!p->reserved && !p->free) - nr2++; - last_end = p->ofs + p->size; - p = p->next; - } - } - - if (nr != nr2) { - fprintf(stderr, - "Different number of texobj's (%d) and inuse memblocks (%d)\n", - nr, nr2); - return GL_FALSE; - } - - if (0) fprintf(stderr, "nr: %d\n", nr); - } - - - /* Check swapped texobj's have zero memblocks - */ - i = 0; - foreach_s ( t, next_t, &rmesa->texture.swapped ) { - if (t->memBlock) { - fprintf(stderr, "Swapped texobj %p has non-zero memblock %p\n", - t, t->memBlock); - return GL_FALSE; - } - i++; - } - - if (0) fprintf(stderr, "nr_swapped: %d\n", i); - - return GL_TRUE; -} diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_sanity.h b/xc/lib/GL/mesa/src/drv/r200/r200_sanity.h index d52e08b4d..10260f211 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_sanity.h +++ b/xc/lib/GL/mesa/src/drv/r200/r200_sanity.h @@ -5,7 +5,4 @@ extern int r200SanityCmdBuffer( r200ContextPtr rmesa, int nbox, XF86DRIClipRectRec *boxes ); - -extern int r200ValidateTexObjs( r200ContextPtr rmesa ); - #endif diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_screen.c b/xc/lib/GL/mesa/src/drv/r200/r200_screen.c index 9997a7821..83747689b 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_screen.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_screen.c @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -42,6 +44,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_context.h" #include "r200_ioctl.h" +#include "utils.h" +#include "vblank.h" + +#include "glxextensions.h" #if 1 /* Including xf86PciInfo.h introduces a bunch of errors... @@ -55,62 +61,34 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define PCI_CHIP_R200_LW 0x4C57 #define PCI_CHIP_R200_LY 0x4C59 #define PCI_CHIP_R200_LZ 0x4C5A -#define PCI_CHIP_RV200_QW 0x5157 +#define PCI_CHIP_RV200_QW 0x5157 /* Radeon 7500 - not an R200 at all */ #endif static r200ScreenPtr __r200Screen; +static int get_MSC( __DRIscreenPrivate * priv, int64_t * count ); +static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ); + /* Create the device specific screen private data struct. */ static r200ScreenPtr r200CreateScreen( __DRIscreenPrivate *sPriv ) { - r200ScreenPtr r200Screen; - RADEONDRIPtr r200DRIPriv = (RADEONDRIPtr)sPriv->pDevPriv; - - /* Check the DRI extension version */ - if ( sPriv->driMajor != 4 || sPriv->driMinor < 0 ) { - __driUtilMessage( "R200 DRI driver expected DRI version 4.0.x " - "but got version %d.%d.%d", - sPriv->driMajor, sPriv->driMinor, sPriv->driPatch ); - return NULL; - } - - /* Check that the DDX driver version is compatible */ - if ( sPriv->ddxMajor != 4 || - sPriv->ddxMinor < 0 ) { - __driUtilMessage( "R200 DRI driver expected DDX driver version 4.0.x " - "but got version %d.%d.%d", - sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); - return NULL; - } + r200ScreenPtr screen; + RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv; - /* Check that the DRM driver version is compatible - * -- R200 support added at 1.5.0. - */ - if ( sPriv->drmMajor != 1 || - sPriv->drmMinor < 5) { - __driUtilMessage( "R200 DRI driver expected DRM driver version 1.5.x " - "but got version %d.%d.%d", - sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); + if ( ! driCheckDriDdxDrmVersions( sPriv, "R200", 4, 0, 4, 0, 1, 5 ) ) return NULL; - } /* Allocate the private area */ - r200Screen = (r200ScreenPtr) CALLOC( sizeof(*r200Screen) ); - if ( !r200Screen ) { - __driUtilMessage("%s: CALLOC r200Screen struct failed", + screen = (r200ScreenPtr) CALLOC( sizeof(*screen) ); + if ( !screen ) { + __driUtilMessage("%s: Could not allocate memory for screen structure", __FUNCTION__); return NULL; } - /* Check if kernel module is new enough to support cube maps */ - if (sPriv->drmMajor * 100 + sPriv->drmMinor >= 107) - r200Screen->drmSupportsCubeMaps = GL_TRUE; - else - r200Screen->drmSupportsCubeMaps = GL_FALSE; - - switch ( r200DRIPriv->deviceID ) { + switch ( dri_priv->deviceID ) { case PCI_CHIP_R200_QD: case PCI_CHIP_R200_QE: case PCI_CHIP_R200_QF: @@ -122,10 +100,10 @@ r200CreateScreen( __DRIscreenPrivate *sPriv ) case PCI_CHIP_R200_LY: case PCI_CHIP_R200_LZ: __driUtilMessage("r200CreateScreen(): Device isn't an r200!\n"); - FREE( r200Screen ); + FREE( screen ); return NULL; default: - r200Screen->chipset = R200_CHIPSET_R200; + screen->chipset = R200_CHIPSET_R200; break; } @@ -133,140 +111,140 @@ r200CreateScreen( __DRIscreenPrivate *sPriv ) /* This is first since which regions we map depends on whether or * not we are using a PCI card. */ - r200Screen->IsPCI = r200DRIPriv->IsPCI; + screen->IsPCI = dri_priv->IsPCI; { int ret; drmRadeonGetParam gp; gp.param = RADEON_PARAM_AGP_BUFFER_OFFSET; - gp.value = &r200Screen->agp_buffer_offset; + gp.value = &screen->agp_buffer_offset; ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); if (ret) { - FREE( r200Screen ); - fprintf(stderr, "drmR200GetParam: %d\n", ret); + FREE( screen ); + fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_AGP_BUFFER_OFFSET): %d\n", ret); return NULL; } - r200Screen->agp_texture_offset = - r200Screen->agp_buffer_offset + 2*1024*1024; + screen->agp_texture_offset = + screen->agp_buffer_offset + 2*1024*1024; if (sPriv->drmMinor >= 6) { gp.param = RADEON_PARAM_AGP_BASE; - gp.value = &r200Screen->agp_base; + gp.value = &screen->agp_base; ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); if (ret) { - FREE( r200Screen ); - fprintf(stderr, "drmR200GetParam (RADEON_PARAM_AGP_BUFFER_OFFSET): %d\n", ret); + FREE( screen ); + fprintf(stderr, "drmR200GetParam (RADEON_PARAM_AGP_BASE): %d\n", ret); return NULL; } - } - if (sPriv->drmMinor >= 6) { + gp.param = RADEON_PARAM_IRQ_NR; - gp.value = &r200Screen->irq; + gp.value = &screen->irq; ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); if (ret) { - FREE( r200Screen ); - fprintf(stderr, "drmR200GetParam (RADEON_PARAM_IRQ_NR): %d\n", ret); + FREE( screen ); + fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n", ret); return NULL; } - } + /* Check if kernel module is new enough to support cube maps */ + screen->drmSupportsCubeMaps = (sPriv->drmMinor >= 7); + } } - r200Screen->mmio.handle = r200DRIPriv->registerHandle; - r200Screen->mmio.size = r200DRIPriv->registerSize; + screen->mmio.handle = dri_priv->registerHandle; + screen->mmio.size = dri_priv->registerSize; if ( drmMap( sPriv->fd, - r200Screen->mmio.handle, - r200Screen->mmio.size, - &r200Screen->mmio.map ) ) { - FREE( r200Screen ); - __driUtilMessage("r200CreateScreen(): drmMap failed\n"); + screen->mmio.handle, + screen->mmio.size, + &screen->mmio.map ) ) { + FREE( screen ); + __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ ); return NULL; } - r200Screen->status.handle = r200DRIPriv->statusHandle; - r200Screen->status.size = r200DRIPriv->statusSize; + screen->status.handle = dri_priv->statusHandle; + screen->status.size = dri_priv->statusSize; if ( drmMap( sPriv->fd, - r200Screen->status.handle, - r200Screen->status.size, - &r200Screen->status.map ) ) { - drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size ); - FREE( r200Screen ); - __driUtilMessage("r200CreateScreen(): drmMap (2) failed\n"); + screen->status.handle, + screen->status.size, + &screen->status.map ) ) { + drmUnmap( screen->mmio.map, screen->mmio.size ); + FREE( screen ); + __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ ); return NULL; } - r200Screen->scratch = (__volatile__ CARD32 *) - ((GLubyte *)r200Screen->status.map + RADEON_SCRATCH_REG_OFFSET); - - r200Screen->buffers = drmMapBufs( sPriv->fd ); - if ( !r200Screen->buffers ) { - drmUnmap( r200Screen->status.map, r200Screen->status.size ); - drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size ); - FREE( r200Screen ); - __driUtilMessage("r200CreateScreen(): drmMapBufs failed\n"); + screen->scratch = (__volatile__ CARD32 *) + ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET); + + screen->buffers = drmMapBufs( sPriv->fd ); + if ( !screen->buffers ) { + drmUnmap( screen->status.map, screen->status.size ); + drmUnmap( screen->mmio.map, screen->mmio.size ); + FREE( screen ); + __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ ); return NULL; } - if ( !r200Screen->IsPCI ) { - r200Screen->agpTextures.handle = r200DRIPriv->agpTexHandle; - r200Screen->agpTextures.size = r200DRIPriv->agpTexMapSize; + if ( !screen->IsPCI ) { + screen->agpTextures.handle = dri_priv->agpTexHandle; + screen->agpTextures.size = dri_priv->agpTexMapSize; if ( drmMap( sPriv->fd, - r200Screen->agpTextures.handle, - r200Screen->agpTextures.size, - (drmAddressPtr)&r200Screen->agpTextures.map ) ) { - drmUnmapBufs( r200Screen->buffers ); - drmUnmap( r200Screen->status.map, r200Screen->status.size ); - drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size ); - FREE( r200Screen ); - __driUtilMessage("r200CreateScreen(): IsPCI failed\n"); + screen->agpTextures.handle, + screen->agpTextures.size, + (drmAddressPtr)&screen->agpTextures.map ) ) { + drmUnmapBufs( screen->buffers ); + drmUnmap( screen->status.map, screen->status.size ); + drmUnmap( screen->mmio.map, screen->mmio.size ); + FREE( screen ); + __driUtilMessage("%s: IsPCI failed\n", __FUNCTION__); return NULL; } } - r200Screen->cpp = r200DRIPriv->bpp / 8; - r200Screen->AGPMode = r200DRIPriv->AGPMode; + screen->cpp = dri_priv->bpp / 8; + screen->AGPMode = dri_priv->AGPMode; - r200Screen->frontOffset = r200DRIPriv->frontOffset; - r200Screen->frontPitch = r200DRIPriv->frontPitch; - r200Screen->backOffset = r200DRIPriv->backOffset; - r200Screen->backPitch = r200DRIPriv->backPitch; - r200Screen->depthOffset = r200DRIPriv->depthOffset; - r200Screen->depthPitch = r200DRIPriv->depthPitch; + screen->frontOffset = dri_priv->frontOffset; + screen->frontPitch = dri_priv->frontPitch; + screen->backOffset = dri_priv->backOffset; + screen->backPitch = dri_priv->backPitch; + screen->depthOffset = dri_priv->depthOffset; + screen->depthPitch = dri_priv->depthPitch; - r200Screen->texOffset[RADEON_CARD_HEAP] = r200DRIPriv->textureOffset; - r200Screen->texSize[RADEON_CARD_HEAP] = r200DRIPriv->textureSize; - r200Screen->logTexGranularity[RADEON_CARD_HEAP] = - r200DRIPriv->log2TexGran; + screen->texOffset[RADEON_CARD_HEAP] = dri_priv->textureOffset; + screen->texSize[RADEON_CARD_HEAP] = dri_priv->textureSize; + screen->logTexGranularity[RADEON_CARD_HEAP] = + dri_priv->log2TexGran; - if ( r200Screen->IsPCI ) { - r200Screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1; - r200Screen->texOffset[RADEON_AGP_HEAP] = 0; - r200Screen->texSize[RADEON_AGP_HEAP] = 0; - r200Screen->logTexGranularity[RADEON_AGP_HEAP] = 0; + if ( screen->IsPCI ) { + screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1; + screen->texOffset[RADEON_AGP_HEAP] = 0; + screen->texSize[RADEON_AGP_HEAP] = 0; + screen->logTexGranularity[RADEON_AGP_HEAP] = 0; } else { - r200Screen->numTexHeaps = RADEON_NR_TEX_HEAPS; - r200Screen->texOffset[RADEON_AGP_HEAP] = - r200DRIPriv->agpTexOffset + R200_AGP_TEX_OFFSET; - r200Screen->texSize[RADEON_AGP_HEAP] = r200DRIPriv->agpTexMapSize; - r200Screen->logTexGranularity[RADEON_AGP_HEAP] = - r200DRIPriv->log2AGPTexGran; + screen->numTexHeaps = RADEON_NR_TEX_HEAPS; + screen->texOffset[RADEON_AGP_HEAP] = + dri_priv->agpTexOffset + R200_AGP_TEX_OFFSET; + screen->texSize[RADEON_AGP_HEAP] = dri_priv->agpTexMapSize; + screen->logTexGranularity[RADEON_AGP_HEAP] = + dri_priv->log2AGPTexGran; } - - r200Screen->driScreen = sPriv; - r200Screen->sarea_priv_offset = r200DRIPriv->sarea_priv_offset; - return r200Screen; + screen->driScreen = sPriv; + screen->sarea_priv_offset = dri_priv->sarea_priv_offset; + return screen; } /* Destroy the device specific screen private data struct. @@ -274,20 +252,20 @@ r200CreateScreen( __DRIscreenPrivate *sPriv ) static void r200DestroyScreen( __DRIscreenPrivate *sPriv ) { - r200ScreenPtr r200Screen = (r200ScreenPtr)sPriv->private; + r200ScreenPtr screen = (r200ScreenPtr)sPriv->private; - if (!r200Screen) + if (!screen) return; - if ( !r200Screen->IsPCI ) { - drmUnmap( r200Screen->agpTextures.map, - r200Screen->agpTextures.size ); + if ( !screen->IsPCI ) { + drmUnmap( screen->agpTextures.map, + screen->agpTextures.size ); } - drmUnmapBufs( r200Screen->buffers ); - drmUnmap( r200Screen->status.map, r200Screen->status.size ); - drmUnmap( r200Screen->mmio.map, r200Screen->mmio.size ); + drmUnmapBufs( screen->buffers ); + drmUnmap( screen->status.map, screen->status.size ); + drmUnmap( screen->mmio.map, screen->mmio.size ); - FREE( r200Screen ); + FREE( screen ); sPriv->private = NULL; } @@ -368,7 +346,13 @@ static struct __DriverAPIRec r200API = { r200MakeCurrent, r200UnbindContext, r200OpenCloseFullScreen, - r200OpenCloseFullScreen + r200OpenCloseFullScreen, + + .GetSwapInfo = getSwapInfo, + .GetMSC = get_MSC, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL }; @@ -396,39 +380,119 @@ void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, void __driRegisterExtensions( void ) { - /* dlopen ourself */ - void *dll = dlopen(NULL, RTLD_GLOBAL); - if (dll) { - typedef void *(*registerFunc)(const char *funcName, void *funcAddr); - typedef void (*registerString)(const char *extName); - - /* Get pointers to libGL's __glXRegisterGLXFunction - * and __glXRegisterGLXExtensionString, if they exist. - */ - registerFunc regFunc = (registerFunc) dlsym(dll, "__glXRegisterGLXFunction"); - registerString regString = (registerString) dlsym(dll, "__glXRegisterGLXExtensionString"); - - if (regFunc) { - /* register our GLX extensions with libGL */ - void *p; - p = regFunc("glXAllocateMemoryNV", (void *) r200AllocateMemoryNV); - if (p) - ; /* XXX already registered - what to do, wrap? */ - - p = regFunc("glXFreeMemoryNV", (void *) r200FreeMemoryNV); - if (p) - ; /* XXX already registered - what to do, wrap? */ - - p = regFunc("glXGetAGPOffsetMESA", (void *) r200GetAGPOffset); - if (p) - ; /* XXX already registered - what to do, wrap? */ - } + PFNGLXENABLEEXTENSIONPROC glx_enable_extension; + typedef void *(*registerFunc)(const char *funcName, void *funcAddr); + registerFunc regFunc; + + + if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) { + glx_enable_extension = (PFNGLXENABLEEXTENSIONPROC) + glXGetProcAddress( "__glXEnableExtension" ); + + if ( glx_enable_extension != NULL ) { + glx_enable_extension( "GLX_SGI_swap_control", GL_FALSE ); + glx_enable_extension( "GLX_SGI_video_sync", GL_FALSE ); + glx_enable_extension( "GLX_MESA_swap_control", GL_FALSE ); + + + /* Get pointers to libGL's __glXRegisterGLXFunction + * and __glXRegisterGLXExtensionString, if they exist. + */ + regFunc = (registerFunc) glXGetProcAddress( "__glXRegisterGLXFunction" ); + + if (regFunc) { + /* register our GLX extensions with libGL */ + void *p; + p = regFunc("glXAllocateMemoryNV", (void *) r200AllocateMemoryNV); + if (p) + ; /* XXX already registered - what to do, wrap? */ + + p = regFunc("glXFreeMemoryNV", (void *) r200FreeMemoryNV); + if (p) + ; /* XXX already registered - what to do, wrap? */ - if (regString) { - regString("GLX_NV_vertex_array_range"); - regString("GLX_MESA_agp_offset"); + p = regFunc("glXGetAGPOffsetMESA", (void *) r200GetAGPOffset); + if (p) + ; /* XXX already registered - what to do, wrap? */ + + glx_enable_extension( "GLX_NV_vertex_array_range", GL_TRUE ); + glx_enable_extension( "GLX_MESA_agp_offset", GL_TRUE ); + } } + } +} + + + + +/** + * Get the current MSC. + * + * Stores the 64-bit count of vertical refreshes since some (arbitrary) + * point in time in \c count. Unless the value wraps around, which it + * may, it will never decrease. + * + * \param priv Pointer to the private screen structure. + * \param count Storage to hold the MSC. + * \return Zero is returned on success. A negative errno value + * is returned on failure. + */ +static int +get_MSC( __DRIscreenPrivate * priv, int64_t * count ) +{ + drmRadeonGetParam gp; + int frame; + int ret; + + if ( priv->drmMinor >= 4 ) { + gp.param = RADEON_PARAM_LAST_FRAME; + gp.value = &frame; + ret = drmCommandWriteRead( priv->fd, DRM_RADEON_GETPARAM, + &gp, sizeof(gp) ); + } + else { + ret = -EINVAL; + } + +#if 0 + if ( ret == -EINVAL ) { + unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map; + + frame = INREG( RADEON_LAST_FRAME_REG ); + ret = 0; + } +#endif + + if ( ret == 0 ) { + *count = frame; + } + + return ret; +} - dlclose(dll); + +/** + * Get information about previous buffer swaps. + */ +static int +getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ) +{ + r200ContextPtr rmesa; + + if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL) + || (dPriv->driContextPriv->driverPrivate == NULL) + || (sInfo == NULL) ) { + return -1; } + + rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate; + sInfo->swap_count = rmesa->swap_count; + sInfo->swap_ust = rmesa->swap_ust; + sInfo->swap_missed_count = rmesa->swap_missed_count; + + sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0) + ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust ) + : 0.0; + + return 0; } diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_screen.h b/xc/lib/GL/mesa/src/drv/r200/r200_screen.h index fd0ff7ab6..1e1f125b0 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_screen.h +++ b/xc/lib/GL/mesa/src/drv/r200/r200_screen.h @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_span.c b/xc/lib/GL/mesa/src/drv/r200/r200_span.c index c75e3f92a..b469aec42 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_span.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_span.c @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -182,7 +184,7 @@ do { \ * Depth buffer */ -/* The R200 has depth tiling on all the time, so we have to convert +/* The Radeon family has depth tiling on all the time, so we have to convert * the x,y coordinates into the memory bus address (mba) in the same * manner as the engine. In each case, the linear block address (ba) * is calculated, and then wired with x and y to produce the final @@ -327,7 +329,7 @@ static void r200SetBuffer( GLcontext *ctx, } break; default: - _mesa_problem(ctx, "Bad bufferBit in r200SetBuffer()"); + _mesa_problem(ctx, "Bad bufferBit in %s", __FUNCTION__); break; } } diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_span.h b/xc/lib/GL/mesa/src/drv/r200/r200_span.h index 4931d924f..269ac0593 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_span.h +++ b/xc/lib/GL/mesa/src/drv/r200/r200_span.h @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_state.c b/xc/lib/GL/mesa/src/drv/r200/r200_state.c index 4b2358774..f025a8847 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_state.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_state.c @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -97,7 +99,7 @@ static void r200AlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref ) pp_misc |= R200_ALPHA_TEST_PASS; break; } - + rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc; } @@ -107,24 +109,24 @@ static void r200BlendEquation( GLcontext *ctx, GLenum mode ) GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & ~R200_COMB_FCN_MASK; switch ( mode ) { - case GL_FUNC_ADD_EXT: + case GL_FUNC_ADD: case GL_LOGIC_OP: b |= R200_COMB_FCN_ADD_CLAMP; break; - case GL_FUNC_SUBTRACT_EXT: + case GL_FUNC_SUBTRACT: b |= R200_COMB_FCN_SUB_CLAMP; break; - case GL_FUNC_REVERSE_SUBTRACT_EXT: + case GL_FUNC_REVERSE_SUBTRACT: b |= R200_COMB_FCN_RSUB_CLAMP; break; - case GL_MIN_EXT: + case GL_MIN: b |= R200_COMB_FCN_MIN; break; - case GL_MAX_EXT: + case GL_MAX: b |= R200_COMB_FCN_MAX; break; @@ -160,6 +162,12 @@ static void r200BlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) case GL_ONE_MINUS_DST_COLOR: b |= R200_SRC_BLEND_GL_ONE_MINUS_DST_COLOR; break; + case GL_SRC_COLOR: + b |= R200_SRC_BLEND_GL_SRC_COLOR; + break; + case GL_ONE_MINUS_SRC_COLOR: + b |= R200_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR; + break; case GL_SRC_ALPHA: b |= R200_SRC_BLEND_GL_SRC_ALPHA; break; @@ -210,6 +218,12 @@ static void r200BlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) case GL_ONE_MINUS_SRC_ALPHA: b |= R200_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA; break; + case GL_DST_COLOR: + b |= R200_DST_BLEND_GL_DST_COLOR; + break; + case GL_ONE_MINUS_DST_COLOR: + b |= R200_DST_BLEND_GL_ONE_MINUS_DST_COLOR; + break; case GL_DST_ALPHA: b |= R200_DST_BLEND_GL_DST_ALPHA; break; @@ -251,7 +265,7 @@ static void r200BlendFuncSeparate( GLcontext *ctx, static void r200DepthFunc( GLcontext *ctx, GLenum func ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); - + R200_STATECHANGE( rmesa, ctx ); rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_Z_TEST_MASK; @@ -706,6 +720,7 @@ static void r200UpdateSpecular( GLcontext *ctx ) rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_0; rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_1; rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LIGHTING_ENABLE; + p &= ~R200_SPECULAR_ENABLE; rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_DIFFUSE_SPECULAR_COMBINE; @@ -739,9 +754,9 @@ static void r200UpdateSpecular( GLcontext *ctx ) } if (ctx->Fog.Enabled) { - rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= - ((R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT)); - rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1; + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= + ((R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT)); + rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1; } if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) { @@ -1002,7 +1017,6 @@ static void update_light( GLcontext *ctx ) } -/* R200_STATECHANGE( rmesa, glt ); */ if (ctx->Light.Enabled) { GLint p; diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_state.h b/xc/lib/GL/mesa/src/drv/r200/r200_state.h index 4eefa1838..fe2a7dc09 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_state.h +++ b/xc/lib/GL/mesa/src/drv/r200/r200_state.h @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_state_init.c b/xc/lib/GL/mesa/src/drv/r200/r200_state_init.c index 4ced8c03d..ba445d501 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_state_init.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_state_init.c @@ -470,7 +470,7 @@ void r200InitState( r200ContextPtr rmesa ) rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = 0x00000000; rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = 0x00000000; - for (i = 0; i < 2; i++) { /* 2 texture units for now */ + for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] = R200_BORDER_MODE_OGL; rmesa->hw.tex[i].cmd[TEX_PP_TXFORMAT] = ((i << R200_TXFORMAT_ST_ROUTE_SHIFT) | /* <-- note i */ diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_swtcl.c b/xc/lib/GL/mesa/src/drv/r200/r200_swtcl.c index e344b3ca7..fa23a27cc 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_swtcl.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_swtcl.c @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -276,7 +278,7 @@ static void r200SetVertexFormat( GLcontext *ctx, GLuint ind ) TNLcontext *tnl = TNL_CONTEXT(ctx); rmesa->swtcl.SetupIndex = ind; - + if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { tnl->Driver.Render.Interp = r200_interp_extras; tnl->Driver.Render.CopyPV = r200_copy_pv_extras; @@ -860,6 +862,7 @@ static struct { #define RASTERIZE(x) r200RasterPrimitive( ctx, reduced_hw_prim[x] ) #define RENDER_PRIMITIVE rmesa->swtcl.render_primitive +#undef TAG #define TAG(x) x #include "tnl_dd/t_dd_unfilled.h" #undef IND diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_tcl.c b/xc/lib/GL/mesa/src/drv/r200/r200_tcl.c index afcb770bf..359337f1f 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_tcl.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_tcl.c @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -334,13 +336,6 @@ static void r200_check_tcl_render( GLcontext *ctx, if (rmesa->NewGLState) r200ValidateState( ctx ); - if (0) - fprintf(stderr, "%s: RE %d TGE %d NN %d\n", - __FUNCTION__, - ctx->Texture.Unit[0]._ReallyEnabled, - ctx->Texture.Unit[0].TexGenEnabled, - rmesa->TexGenNeedNormals[0]); - if (ctx->RenderMode == GL_RENDER) { /* Make all this event-driven: */ diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_tcl.h b/xc/lib/GL/mesa/src/drv/r200/r200_tcl.h index b0f4386ee..a2db2e18a 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_tcl.h +++ b/xc/lib/GL/mesa/src/drv/r200/r200_tcl.h @@ -1,5 +1,5 @@ /* $XFree86$ */ -/* +/************************************************************************** Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +25,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_tex.c b/xc/lib/GL/mesa/src/drv/r200/r200_tex.c index 419a2e426..048108188 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_tex.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_tex.c @@ -42,6 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "texformat.h" #include "texstore.h" #include "texutil.h" +#include "texmem.h" #include "r200_context.h" #include "r200_state.h" @@ -50,8 +51,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_tex.h" -/* ============================================================= - * Utility functions: + +/** + * Set the texture wrap modes. + * + * \param t Texture object whose wrap modes are to be set + * \param swrap Wrap mode for the \a s texture coordinate + * \param twrap Wrap mode for the \a t texture coordinate */ static void r200SetTexWrap( r200TexObjPtr t, GLenum swrap, GLenum twrap, GLenum rwrap ) @@ -71,7 +77,7 @@ static void r200SetTexWrap( r200TexObjPtr t, GLenum swrap, GLenum twrap, GLenum case GL_CLAMP_TO_BORDER: t->pp_txfilter |= R200_CLAMP_S_CLAMP_BORDER; break; - case GL_MIRRORED_REPEAT_ARB: + case GL_MIRRORED_REPEAT: t->pp_txfilter |= R200_CLAMP_S_MIRROR; break; case GL_MIRROR_CLAMP_ATI: @@ -81,7 +87,7 @@ static void r200SetTexWrap( r200TexObjPtr t, GLenum swrap, GLenum twrap, GLenum t->pp_txfilter |= R200_CLAMP_S_MIRROR_CLAMP_LAST; break; default: - _mesa_problem(NULL, "bad S wrap mode in r200SetTexWrap"); + _mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__); } switch ( twrap ) { @@ -97,7 +103,7 @@ static void r200SetTexWrap( r200TexObjPtr t, GLenum swrap, GLenum twrap, GLenum case GL_CLAMP_TO_BORDER: t->pp_txfilter |= R200_CLAMP_T_CLAMP_BORDER; break; - case GL_MIRRORED_REPEAT_ARB: + case GL_MIRRORED_REPEAT: t->pp_txfilter |= R200_CLAMP_T_MIRROR; break; case GL_MIRROR_CLAMP_ATI: @@ -107,7 +113,7 @@ static void r200SetTexWrap( r200TexObjPtr t, GLenum swrap, GLenum twrap, GLenum t->pp_txfilter |= R200_CLAMP_T_MIRROR_CLAMP_LAST; break; default: - _mesa_problem(NULL, "bad S wrap mode in r200SetTexWrap"); + _mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__); } t->pp_txformat_x &= ~R200_CLAMP_Q_MASK; @@ -125,7 +131,7 @@ static void r200SetTexWrap( r200TexObjPtr t, GLenum swrap, GLenum twrap, GLenum case GL_CLAMP_TO_BORDER: t->pp_txformat_x |= R200_CLAMP_Q_CLAMP_BORDER; break; - case GL_MIRRORED_REPEAT_ARB: + case GL_MIRRORED_REPEAT: t->pp_txformat_x |= R200_CLAMP_Q_MIRROR; break; case GL_MIRROR_CLAMP_ATI: @@ -135,7 +141,7 @@ static void r200SetTexWrap( r200TexObjPtr t, GLenum swrap, GLenum twrap, GLenum t->pp_txformat_x |= R200_CLAMP_Q_MIRROR_CLAMP_LAST; break; default: - _mesa_problem(NULL, "bad R wrap mode in r200SetTexWrap"); + _mesa_problem(NULL, "bad R wrap mode in %s", __FUNCTION__); } } @@ -156,6 +162,14 @@ static void r200SetTexMaxAnisotropy( r200TexObjPtr t, GLfloat max ) } } +/** + * Set the texture magnification and minification modes. + * + * \param t Texture whose filter modes are to be set + * \param minf Texture minification mode + * \param magf Texture magnification mode + */ + static void r200SetTexFilter( r200TexObjPtr t, GLenum minf, GLenum magf ) { GLuint anisotropy = (t->pp_txfilter & R200_MAX_ANISO_MASK); @@ -224,27 +238,35 @@ static void r200SetTexBorderColor( r200TexObjPtr t, GLubyte c[4] ) } +/** + * Allocate space for and load the mesa images into the texture memory block. + * This will happen before drawing with a new texture, or drawing with a + * texture after it was swapped out or teximaged again. + */ + static r200TexObjPtr r200AllocTexObj( struct gl_texture_object *texObj ) { r200TexObjPtr t; t = CALLOC_STRUCT( r200_tex_obj ); - if (!t) - return NULL; + texObj->DriverData = t; + if ( t != NULL ) { + if ( R200_DEBUG & DEBUG_TEXTURE ) { + fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, texObj, t ); + } - if ( R200_DEBUG & DEBUG_TEXTURE ) { - fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, texObj, t ); - } + /* Initialize non-image-dependent parts of the state: + */ + t->base.tObj = texObj; - t->tObj = texObj; - make_empty_list( t ); + make_empty_list( & t->base ); + + r200SetTexWrap( t, texObj->WrapS, texObj->WrapT, texObj->WrapR ); + r200SetTexMaxAnisotropy( t, texObj->MaxAnisotropy ); + r200SetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); + r200SetTexBorderColor( t, texObj->_BorderChan ); + } - /* Initialize non-image-dependent parts of the state: - */ - r200SetTexWrap( t, texObj->WrapS, texObj->WrapT, texObj->WrapR ); - r200SetTexMaxAnisotropy( t, texObj->MaxAnisotropy ); - r200SetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); - r200SetTexBorderColor( t, texObj->_BorderChan ); return t; } @@ -259,6 +281,7 @@ r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, switch ( internalFormat ) { case 4: case GL_RGBA: + case GL_COMPRESSED_RGBA: if ( format == GL_BGRA ) { if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) { return &_mesa_texformat_argb8888; @@ -274,6 +297,7 @@ r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case 3: case GL_RGB: + case GL_COMPRESSED_RGB: if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { return &_mesa_texformat_rgb565; } @@ -308,6 +332,7 @@ r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_ALPHA8: case GL_ALPHA12: case GL_ALPHA16: + case GL_COMPRESSED_ALPHA: return &_mesa_texformat_al88; case 1: @@ -316,6 +341,7 @@ r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_LUMINANCE8: case GL_LUMINANCE12: case GL_LUMINANCE16: + case GL_COMPRESSED_LUMINANCE: return &_mesa_texformat_al88; case 2: @@ -326,6 +352,7 @@ r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_LUMINANCE12_ALPHA4: case GL_LUMINANCE12_ALPHA12: case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: return &_mesa_texformat_al88; case GL_INTENSITY: @@ -333,6 +360,7 @@ r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_INTENSITY8: case GL_INTENSITY12: case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: /* At the moment, glean & conform both fail using the i8 internal * format. */ @@ -347,7 +375,7 @@ r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, return &_mesa_texformat_ycbcr_rev; default: - _mesa_problem(ctx, "unexpected texture format in r200ChoosTexFormat"); + _mesa_problem(ctx, "unexpected texture format in %s", __FUNCTION__); return NULL; } @@ -464,22 +492,20 @@ static void r200TexImage1D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; if ( t ) { - r200SwapOutTexObj( rmesa, t ); + driSwapOutTextureObject( t ); } else { - t = r200AllocTexObj( texObj ); + t = (driTextureObject *) r200AllocTexObj( texObj ); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); return; } - texObj->DriverData = t; } - /* Note, this will call r200ChooseTextureFormat */ + /* Note, this will call ChooseTextureFormat */ _mesa_store_teximage1d(ctx, target, level, internalFormat, width, border, format, type, pixels, &ctx->Unpack, texObj, texImage); @@ -497,21 +523,18 @@ static void r200TexSubImage1D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200TexObjPtr t = (r200TexObjPtr)texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; assert( t ); /* this _should_ be true */ if ( t ) { - r200SwapOutTexObj( rmesa, t ); - t->dirty_images[0] |= (1 << level); + driSwapOutTextureObject( t ); } else { - t = r200AllocTexObj(texObj); + t = (driTextureObject *) r200AllocTexObj( texObj ); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); return; } - texObj->DriverData = t; } _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, @@ -530,8 +553,7 @@ static void r200TexImage2D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200TexObjPtr t = (r200TexObjPtr)texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; GLuint face; /* which cube face or ordinary 2D image */ @@ -549,16 +571,15 @@ static void r200TexImage2D( GLcontext *ctx, GLenum target, GLint level, face = 0; } - if ( t ) { - r200SwapOutTexObj( rmesa, t ); + if ( t != NULL ) { + driSwapOutTextureObject( t ); } else { - t = r200AllocTexObj( texObj ); + t = (driTextureObject *) r200AllocTexObj( texObj ); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; } - texObj->DriverData = t; } texImage->IsClientData = GL_FALSE; @@ -599,11 +620,9 @@ static void r200TexSubImage2D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; GLuint face; -/* fprintf(stderr, "%s\n", __FUNCTION__); */ /* which cube face or ordinary 2D image */ switch (target) { @@ -622,15 +641,14 @@ static void r200TexSubImage2D( GLcontext *ctx, GLenum target, GLint level, assert( t ); /* this _should_ be true */ if ( t ) { - r200SwapOutTexObj( rmesa, t ); + driSwapOutTextureObject( t ); } else { - t = r200AllocTexObj(texObj); + t = (driTextureObject *) r200AllocTexObj( texObj ); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); return; } - texObj->DriverData = t; } _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, @@ -641,6 +659,7 @@ static void r200TexSubImage2D( GLcontext *ctx, GLenum target, GLint level, } +#if ENABLE_HW_3D_TEXTURE static void r200TexImage3D( GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint depth, @@ -650,11 +669,10 @@ static void r200TexImage3D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200TexObjPtr t = (r200TexObjPtr)texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; if ( t ) { - r200SwapOutTexObj( rmesa, t ); + driSwapOutTextureObject( t ); } else { t = r200AllocTexObj( texObj ); @@ -662,7 +680,6 @@ static void r200TexImage3D( GLcontext *ctx, GLenum target, GLint level, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); return; } - texObj->DriverData = t; } texImage->IsClientData = GL_FALSE; @@ -696,8 +713,10 @@ static void r200TexImage3D( GLcontext *ctx, GLenum target, GLint level, t->dirty_images[0] |= (1 << level); } } +#endif +#if ENABLE_HW_3D_TEXTURE static void r200TexSubImage3D( GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, @@ -708,14 +727,13 @@ r200TexSubImage3D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; /* fprintf(stderr, "%s\n", __FUNCTION__); */ assert( t ); /* this _should_ be true */ if ( t ) { - r200SwapOutTexObj( rmesa, t ); + driSwapOutTextureObject( t ); } else { t = r200AllocTexObj(texObj); @@ -732,6 +750,7 @@ r200TexSubImage3D( GLcontext *ctx, GLenum target, GLint level, t->dirty_images[0] |= (1 << level); } +#endif @@ -791,11 +810,16 @@ static void r200TexEnv( GLcontext *ctx, GLenum target, } } + +/** + * Changes variables and flags for a state update, which will happen at the + * next UpdateTextureState + */ + static void r200TexParameter( GLcontext *ctx, GLenum target, struct gl_texture_object *texObj, GLenum pname, const GLfloat *params ) { - r200ContextPtr rmesa = R200_CONTEXT(ctx); r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { @@ -803,7 +827,8 @@ static void r200TexParameter( GLcontext *ctx, GLenum target, _mesa_lookup_enum_by_nr( pname ) ); } - if (!t) + if ( ( target != GL_TEXTURE_2D ) && + ( target != GL_TEXTURE_1D ) ) return; switch ( pname ) { @@ -829,11 +854,11 @@ static void r200TexParameter( GLcontext *ctx, GLenum target, case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: /* This isn't the most efficient solution but there doesn't appear to - * be a nice alternative for R200. Since there's no LOD clamping, + * be a nice alternative. Since there's no LOD clamping, * we just have to rely on loading the right subset of mipmap levels * to simulate a clamped LOD. */ - r200SwapOutTexObj( rmesa, t ); + driSwapOutTextureObject( (driTextureObject *) t ); break; default: @@ -850,17 +875,14 @@ static void r200TexParameter( GLcontext *ctx, GLenum target, static void r200BindTexture( GLcontext *ctx, GLenum target, struct gl_texture_object *texObj ) { - r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; - GLuint unit = ctx->Texture.CurrentUnit; - if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { - fprintf( stderr, "%s( %p ) unit=%d\n", __FUNCTION__, texObj, unit ); + fprintf( stderr, "%s( %p ) unit=%d\n", __FUNCTION__, texObj, + ctx->Texture.CurrentUnit ); } if ( target == GL_TEXTURE_2D || target == GL_TEXTURE_1D ) { - if ( !t ) { - t = r200AllocTexObj( texObj ); - texObj->DriverData = t; + if ( texObj->DriverData == NULL ) { + r200AllocTexObj( texObj ); } } } @@ -869,61 +891,20 @@ static void r200DeleteTexture( GLcontext *ctx, struct gl_texture_object *texObj ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { - fprintf( stderr, "%s( %p )\n", __FUNCTION__, texObj ); + fprintf( stderr, "%s( %p (target = %s) )\n", __FUNCTION__, texObj, + _mesa_lookup_enum_by_nr( texObj->Target ) ); } - if ( t ) { + if ( t != NULL ) { if ( rmesa ) { R200_FIREVERTICES( rmesa ); } - r200DestroyTexObj( rmesa, t ); - texObj->DriverData = NULL; - } -} -static GLboolean r200IsTextureResident( GLcontext *ctx, - struct gl_texture_object *texObj ) -{ - r200TexObjPtr t = (r200TexObjPtr) texObj->DriverData; - - return ( t && t->memBlock ); -} - - -static void r200InitTextureObjects( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - struct gl_texture_object *texObj; - GLuint tmp = ctx->Texture.CurrentUnit; - - ctx->Texture.CurrentUnit = 0; - - texObj = ctx->Texture.Unit[0].Current1D; - r200BindTexture( ctx, GL_TEXTURE_1D, texObj ); - move_to_tail( &rmesa->texture.swapped, - (r200TexObjPtr)texObj->DriverData ); - - texObj = ctx->Texture.Unit[0].Current2D; - r200BindTexture( ctx, GL_TEXTURE_2D, texObj ); - move_to_tail( &rmesa->texture.swapped, - (r200TexObjPtr)texObj->DriverData ); - - ctx->Texture.CurrentUnit = 1; - - texObj = ctx->Texture.Unit[1].Current1D; - r200BindTexture( ctx, GL_TEXTURE_1D, texObj ); - move_to_tail( &rmesa->texture.swapped, - (r200TexObjPtr)texObj->DriverData ); - - texObj = ctx->Texture.Unit[1].Current2D; - r200BindTexture( ctx, GL_TEXTURE_2D, texObj ); - move_to_tail( &rmesa->texture.swapped, - (r200TexObjPtr)texObj->DriverData ); - - ctx->Texture.CurrentUnit = tmp; + driDestroyTextureObject( t ); + } } /* Need: @@ -949,6 +930,9 @@ static void r200TexGen( GLcontext *ctx, void r200InitTextureFuncs( GLcontext *ctx ) { + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + ctx->Driver.ChooseTextureFormat = r200ChooseTextureFormat; ctx->Driver.TexImage1D = r200TexImage1D; ctx->Driver.TexImage2D = r200TexImage2D; @@ -974,7 +958,7 @@ void r200InitTextureFuncs( GLcontext *ctx ) ctx->Driver.BindTexture = r200BindTexture; ctx->Driver.CreateTexture = NULL; /* FIXME: Is this used??? */ ctx->Driver.DeleteTexture = r200DeleteTexture; - ctx->Driver.IsTextureResident = r200IsTextureResident; + ctx->Driver.IsTextureResident = driIsTextureResident; ctx->Driver.PrioritizeTexture = NULL; ctx->Driver.ActiveTexture = NULL; ctx->Driver.UpdateTexturePalette = NULL; @@ -983,5 +967,7 @@ void r200InitTextureFuncs( GLcontext *ctx ) ctx->Driver.TexParameter = r200TexParameter; ctx->Driver.TexGen = r200TexGen; - r200InitTextureObjects( ctx ); + driInitTextureObjects( ctx, & rmesa->swapped, + DRI_TEXMGR_DO_TEXTURE_1D + | DRI_TEXMGR_DO_TEXTURE_2D ); } diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_tex.h b/xc/lib/GL/mesa/src/drv/r200/r200_tex.h index 17230ae99..9013de6d7 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_tex.h +++ b/xc/lib/GL/mesa/src/drv/r200/r200_tex.h @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -41,13 +43,7 @@ extern void r200UpdateTextureState( GLcontext *ctx ); extern int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t, GLuint face ); -extern void r200AgeTextures( r200ContextPtr rmesa, int heap ); extern void r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t ); -extern void r200SwapOutTexObj( r200ContextPtr rmesa, r200TexObjPtr t ); - -extern void r200PrintLocalLRU( r200ContextPtr rmesa, int heap ); -extern void r200PrintGlobalLRU( r200ContextPtr rmesa, int heap ); -extern void r200UpdateTexLRU( r200ContextPtr rmesa, r200TexObjPtr t ); extern void r200InitTextureFuncs( GLcontext *ctx ); diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_texmem.c b/xc/lib/GL/mesa/src/drv/r200/r200_texmem.c index b2b1ed2c0..63dc38ffa 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_texmem.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_texmem.c @@ -52,279 +52,30 @@ SOFTWARE. #include <unistd.h> /* for usleep() */ -/* Destroy hardware state associated with texture `t'. +/** + * Destroy any device-dependent state associated with the texture. This may + * include NULLing out hardware state that points to the texture. */ -void r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t ) +void +r200DestroyTexObj( r200ContextPtr rmesa, r200TexObjPtr t ) { - if ( !t ) - return; - if ( R200_DEBUG & DEBUG_TEXTURE ) { - fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj ); - } - - if ( t->memBlock ) { - mmFreeMem( t->memBlock ); - t->memBlock = NULL; - } - - if ( t->tObj ) - t->tObj->DriverData = NULL; - - if ( rmesa ) { - if ( t == rmesa->state.texture.unit[0].texobj ) { - rmesa->state.texture.unit[0].texobj = NULL; - remove_from_list( &rmesa->hw.tex[0] ); - make_empty_list( &rmesa->hw.tex[0] ); - remove_from_list( &rmesa->hw.cube[0] ); - make_empty_list( &rmesa->hw.cube[0] ); - } - - if ( t == rmesa->state.texture.unit[1].texobj ) { - rmesa->state.texture.unit[1].texobj = NULL; - remove_from_list( &rmesa->hw.tex[1] ); - make_empty_list( &rmesa->hw.tex[1] ); - remove_from_list( &rmesa->hw.cube[1] ); - make_empty_list( &rmesa->hw.cube[1] ); - } - } - - remove_from_list( t ); - FREE( t ); -} - - -/* Keep track of swapped out texture objects. - */ -void r200SwapOutTexObj( r200ContextPtr rmesa, r200TexObjPtr t ) -{ - GLuint face; - - if ( R200_DEBUG & DEBUG_TEXTURE ) { - fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj ); - } - - if (t->memBlock) { - mmFreeMem( t->memBlock ); - t->memBlock = NULL; - } - - if (!t->tObj) { - remove_from_list( t ); - FREE( t ); - } - else { - for (face = 0; face < 6; face++) - t->dirty_images[face] = ~0; - move_to_tail( &rmesa->texture.swapped, t ); - } -} - -/* Print out debugging information about texture LRU. - */ -void r200PrintLocalLRU( r200ContextPtr rmesa, int heap ) -{ - r200TexObjPtr t; - int sz = 1 << (rmesa->r200Screen->logTexGranularity[heap]); - - fprintf( stderr, "\nLocal LRU, heap %d:\n", heap ); - - foreach ( t, &rmesa->texture.objects[heap] ) { - if (!t->memBlock) - continue; - 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 at 0x%x sz 0x%x\n", - t->memBlock->ofs, - t->memBlock->size ); - } - } - - fprintf( stderr, "\n" ); -} - -void r200PrintGlobalLRU( r200ContextPtr rmesa, int heap ) -{ - radeon_tex_region_t *list = rmesa->sarea->texList[heap]; - int i, j; - - fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list ); - - for ( i = 0, j = RADEON_NR_TEX_REGIONS ; i < RADEON_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 == RADEON_NR_TEX_REGIONS ) break; - } - - if ( j != RADEON_NR_TEX_REGIONS ) { - fprintf( stderr, "Loop detected in global LRU\n" ); - for ( i = 0 ; i < RADEON_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 ); - } - } - - fprintf( stderr, "\n" ); -} - -/* Reset the global texture LRU. - */ -static void r200ResetGlobalLRU( r200ContextPtr rmesa, int heap ) -{ - radeon_tex_region_t *list = rmesa->sarea->texList[heap]; - int sz = 1 << rmesa->r200Screen->logTexGranularity[heap]; - int i; - - /* - * (Re)initialize the global circular LRU list. The last element in - * the array (RADEON_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 <= rmesa->r200Screen->texSize[heap] ; i++ ) { - list[i].prev = i-1; - list[i].next = i+1; - list[i].age = 0; - } - - i--; - list[0].prev = RADEON_NR_TEX_REGIONS; - list[i].prev = i-1; - list[i].next = RADEON_NR_TEX_REGIONS; - list[RADEON_NR_TEX_REGIONS].prev = i; - list[RADEON_NR_TEX_REGIONS].next = 0; - rmesa->sarea->texAge[heap] = 0; -} - -/* Update the local and glock texture LRUs. - */ -void r200UpdateTexLRU(r200ContextPtr rmesa, r200TexObjPtr t ) -{ - int heap = t->heap; - radeon_tex_region_t *list = rmesa->sarea->texList[heap]; - int sz = rmesa->r200Screen->logTexGranularity[heap]; - int i, start, end; - - rmesa->texture.age[heap] = ++rmesa->sarea->texAge[heap]; - - if ( !t->memBlock ) - return; - - start = t->memBlock->ofs >> sz; - end = (t->memBlock->ofs + t->memBlock->size-1) >> sz; - - /* Update our local LRU */ - move_to_head( &rmesa->texture.objects[heap], t ); - - /* Update the global LRU */ - for ( i = start ; i <= end ; i++ ) { - list[i].in_use = 1; - list[i].age = rmesa->texture.age[heap]; - - /* remove_from_list(i) */ - list[(CARD32)list[i].next].prev = list[i].prev; - list[(CARD32)list[i].prev].next = list[i].next; - - /* insert_at_head(list, i) */ - list[i].prev = RADEON_NR_TEX_REGIONS; - list[i].next = list[RADEON_NR_TEX_REGIONS].next; - list[(CARD32)list[RADEON_NR_TEX_REGIONS].next].prev = i; - list[RADEON_NR_TEX_REGIONS].next = i; + fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->base.tObj ); } - if ( 0 ) { - r200PrintGlobalLRU( rmesa, t->heap ); - r200PrintLocalLRU( rmesa, 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). - */ -static void r200TexturesGone( r200ContextPtr rmesa, int heap, - int offset, int size, int in_use ) -{ - r200TexObjPtr t, tmp; - - foreach_s ( t, tmp, &rmesa->texture.objects[heap] ) { - if ( !t->memBlock || - 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. - */ - r200SwapOutTexObj( rmesa, t ); - } + if ( rmesa != NULL ) { + unsigned i; - if ( in_use ) { - t = (r200TexObjPtr) CALLOC( sizeof(*t) ); - if ( !t ) return; - t->memBlock = mmAllocMem( rmesa->texture.heap[heap], size, 0, offset ); - if ( !t->memBlock ) { - fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n", - (int)size, (int)offset ); - mmDumpMemInfo( rmesa->texture.heap[heap] ); - return; - } - insert_at_head( &rmesa->texture.objects[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 r200AgeTextures( r200ContextPtr rmesa, int heap ) -{ - RADEONSAREAPrivPtr sarea = rmesa->sarea; - - if ( R200_DEBUG & DEBUG_TEXTURE ) { - fprintf(stderr, "%s %d\n", __FUNCTION__, heap); - } - - if ( sarea->texAge[heap] != rmesa->texture.age[heap] ) { - int sz = 1 << rmesa->r200Screen->logTexGranularity[heap]; - int nr = 0; - int idx; - - for ( idx = sarea->texList[heap][RADEON_NR_TEX_REGIONS].prev ; - idx != RADEON_NR_TEX_REGIONS && nr < RADEON_NR_TEX_REGIONS ; - idx = sarea->texList[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 > rmesa->r200Screen->texSize[heap] ) { - nr = RADEON_NR_TEX_REGIONS; - break; + for ( i = 0 ; i < rmesa->glCtx->Const.MaxTextureUnits ; i++ ) { + if ( t == rmesa->state.texture.unit[i].texobj ) { + rmesa->state.texture.unit[i].texobj = NULL; + remove_from_list( &rmesa->hw.tex[i] ); + make_empty_list( &rmesa->hw.tex[i] ); + remove_from_list( &rmesa->hw.cube[i] ); + make_empty_list( &rmesa->hw.cube[i] ); } - - if ( sarea->texList[heap][idx].age > rmesa->texture.age[heap] ) { - r200TexturesGone( rmesa, heap, idx * sz, sz, - sarea->texList[heap][idx].in_use ); - } - } - - if ( nr == RADEON_NR_TEX_REGIONS ) { - r200TexturesGone( rmesa, heap, 0, - rmesa->r200Screen->texSize[heap], 0 ); - r200ResetGlobalLRU( rmesa, heap ); } - - rmesa->texture.age[heap] = sarea->texAge[heap]; } } @@ -442,11 +193,12 @@ static void r200UploadRectSubImage( r200ContextPtr rmesa, /* Release FB memory allocated for this image: */ - if ( t->memBlock ) { - mmFreeMem( t->memBlock ); - t->memBlock = NULL; + /* FIXME This may not be correct as driSwapOutTextureObject sets + * FIXME dirty_images. It may be fine, though. + */ + if ( t->base.memBlock ) { + driSwapOutTextureObject( (driTextureObject *) t ); } - } else if (texImage->IsClientData) { /* Data already in agp memory, with usable pitch. @@ -518,56 +270,54 @@ static void r200UploadRectSubImage( r200ContextPtr rmesa, } -/* Upload the texture image associated with texture `t' at level `level' - * at the address relative to `start'. +/** + * Upload the texture image associated with texture \a t at the specified + * level at the address relative to \a start. */ -static void r200UploadSubImage( r200ContextPtr rmesa, - r200TexObjPtr t, - GLint hwlevel, - GLint x, GLint y, GLint width, GLint height, - GLuint face ) +static void uploadSubImage( r200ContextPtr rmesa, r200TexObjPtr t, + GLint hwlevel, + GLint x, GLint y, GLint width, GLint height, + GLuint face ) { struct gl_texture_image *texImage = NULL; - const struct gl_texture_format *texFormat; - GLint texelsPerDword = 0; - GLuint format, pitch, offset; + GLuint offset; GLint imageWidth, imageHeight; GLint ret; drmRadeonTexture tex; drmRadeonTexImage tmp; - int level = hwlevel + t->firstLevel; + const int level = hwlevel + t->firstLevel; if ( R200_DEBUG & DEBUG_TEXTURE ) { - fprintf( stderr, "%s level %d %dx%d\n", __FUNCTION__, - level, width, height); + fprintf( stderr, "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n", + __FUNCTION__, t, t->base.tObj, level, width, height, face ); } ASSERT(face < 6); /* Ensure we have a valid texture to upload */ if ( ( hwlevel < 0 ) || ( hwlevel >= RADEON_MAX_TEXTURE_LEVELS ) ) { - _mesa_problem(NULL, "bad texture level in r200UploadSubimage"); + _mesa_problem(NULL, "bad texture level in %s", __FUNCTION__); return; } switch (face) { case 0: - texImage = t->tObj->Image[level]; + texImage = t->base.tObj->Image[level]; break; case 1: - texImage = t->tObj->NegX[level]; + texImage = t->base.tObj->NegX[level]; break; case 2: - texImage = t->tObj->PosY[level]; + texImage = t->base.tObj->PosY[level]; break; case 3: - texImage = t->tObj->NegY[level]; + texImage = t->base.tObj->NegY[level]; break; case 4: - texImage = t->tObj->PosZ[level]; + texImage = t->base.tObj->PosZ[level]; break; case 5: - texImage = t->tObj->NegZ[level]; + texImage = t->base.tObj->NegZ[level]; break; } @@ -583,7 +333,7 @@ static void r200UploadSubImage( r200ContextPtr rmesa, } - if (t->tObj->Target == GL_TEXTURE_RECTANGLE_NV) { + if (t->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) { assert(level == 0); assert(hwlevel == 0); if ( R200_DEBUG & DEBUG_TEXTURE ) @@ -604,35 +354,12 @@ static void r200UploadSubImage( r200ContextPtr rmesa, __FUNCTION__); - texFormat = texImage->TexFormat; - - switch ( texFormat->TexelBytes ) { - case 1: - texelsPerDword = 4; - break; - case 2: - texelsPerDword = 2; - break; - case 4: - texelsPerDword = 1; - break; - } - - format = t->pp_txformat & R200_TXFORMAT_FORMAT_MASK; - imageWidth = texImage->Width; imageHeight = texImage->Height; offset = t->bufAddr; - if (texFormat->TexelBytes == 0) - pitch = (t->image[face][0].width * 1) / 64; - else - pitch = (t->image[face][0].width * texFormat->TexelBytes) / 64; - - - if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) - { + if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) { GLint imageX = 0; GLint imageY = 0; GLint blitX = t->image[face][hwlevel].x; @@ -643,9 +370,8 @@ static void r200UploadSubImage( r200ContextPtr rmesa, imageWidth, imageHeight, imageX, imageY ); fprintf( stderr, " upload blit: %d,%d at %d,%d\n", blitWidth, blitHeight, blitX, blitY ); - fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x " - "level: %d/%d format: %x\n", - (GLuint)offset, (GLuint)pitch, hwlevel, level, format ); + fprintf( stderr, " blit ofs: 0x%07x level: %d/%d\n", + (GLuint)offset, hwlevel, level ); } t->image[face][hwlevel].data = texImage->Data; @@ -688,9 +414,9 @@ static void r200UploadSubImage( r200ContextPtr rmesa, UNLOCK_HARDWARE( rmesa ); if ( ret ) { - fprintf( stderr, "DRM_R200_TEXTURE: return = %d\n", ret ); - fprintf( stderr, " offset=0x%08x pitch=0x%x format=%d\n", - offset, pitch, format ); + fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret ); + fprintf( stderr, " offset=0x%08x\n", + offset ); fprintf( stderr, " image width=%d height=%d\n", imageWidth, imageHeight ); fprintf( stderr, " blit width=%d height=%d data=%p\n", @@ -701,108 +427,76 @@ static void r200UploadSubImage( r200ContextPtr rmesa, } - -/* 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. +/** + * Upload the texture images associated with texture \a t. This might + * require the allocation of texture memory. + * + * \param rmesa Context pointer + * \param t Texture to be uploaded + * \param face Cube map face to be uploaded. Zero for non-cube maps. */ + int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t, GLuint face ) { const int numLevels = t->lastLevel - t->firstLevel + 1; - int heap; - r200TexObjPtr t0 = rmesa->state.texture.unit[0].texobj; - r200TexObjPtr t1 = rmesa->state.texture.unit[1].texobj; if ( R200_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) { fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__, - rmesa->glCtx, t->tObj, t->totalSize, + rmesa->glCtx, t->base.tObj, t->base.totalSize, t->firstLevel, t->lastLevel ); } - if ( !t || t->totalSize == 0 ) + if ( !t || t->base.totalSize == 0 ) return 0; if (R200_DEBUG & DEBUG_SYNC) { - fprintf(stderr, "\nSyncing\n\n"); - R200_FIREVERTICES( rmesa ); + fprintf(stderr, "%s: Syncing\n", __FUNCTION__ ); r200Finish( rmesa->glCtx ); } LOCK_HARDWARE( rmesa ); - /* Choose the heap appropriately */ - heap = t->heap = RADEON_CARD_HEAP; - - /* Do we need to eject LRU texture objects? */ - if ( !t->memBlock ) { - /* Allocate a memory block on a 1k boundary (1<<10 == 1024) */ - t->memBlock = mmAllocMem( rmesa->texture.heap[heap], - t->totalSize, 10, 0 ); - + if ( t->base.memBlock == NULL ) { + int heap; - /* Kick out textures until the requested texture fits */ - while ( !t->memBlock ) { - if ( rmesa->texture.objects[heap].prev == t0 || - rmesa->texture.objects[heap].prev == t1 ) { - fprintf( stderr, - "r200UploadTexImages: ran into bound texture\n" ); - UNLOCK_HARDWARE( rmesa ); - return -1; - } - if ( rmesa->texture.objects[heap].prev == - &rmesa->texture.objects[heap] ) { - if ( rmesa->r200Screen->IsPCI ) { - fprintf( stderr, "r200UploadTexImages: upload texture " - "failure on local texture heaps, sz=%d\n", - t->totalSize ); - UNLOCK_HARDWARE( rmesa ); - return -1; - } else { - fprintf( stderr, "r200UploadTexImages: upload texture " - "failure on both local and AGP texture heaps, " - "sz=%d\n", - t->totalSize ); - UNLOCK_HARDWARE( rmesa ); - return -1; - } - } - - r200SwapOutTexObj( rmesa, rmesa->texture.objects[heap].prev ); - - t->memBlock = mmAllocMem( rmesa->texture.heap[heap], - t->totalSize, 12, 0 ); + heap = driAllocateTexture( rmesa->texture_heaps, rmesa->nr_heaps, + (driTextureObject *) t ); + if ( heap == -1 ) { + UNLOCK_HARDWARE( rmesa ); + return -1; } /* Set the base offset of the texture image */ - t->bufAddr = rmesa->r200Screen->texOffset[heap] + t->memBlock->ofs; + t->bufAddr = rmesa->r200Screen->texOffset[heap] + + t->base.memBlock->ofs; t->pp_txoffset = t->bufAddr; + /* Mark this texobj as dirty on all units: */ t->dirty_state = TEX_ALL; } - /* Let the world know we've used this memory recently */ - r200UpdateTexLRU( rmesa, t ); + /* Let the world know we've used this memory recently. + */ + driUpdateTextureLRU( (driTextureObject *) t ); UNLOCK_HARDWARE( rmesa ); /* Upload any images that are new */ - if (t->dirty_images[face]) { - int hwlevel; - for ( hwlevel = 0 ; hwlevel < numLevels ; hwlevel++ ) { - if ( t->dirty_images[face] & (1 << (hwlevel+t->firstLevel)) ) { - r200UploadSubImage( rmesa, t, hwlevel, - 0, 0, - t->image[face][hwlevel].width, - t->image[face][hwlevel].height, face ); + if (t->base.dirty_images[face]) { + int i; + for ( i = 0 ; i < numLevels ; i++ ) { + if ( (t->base.dirty_images[face] & (1 << (i+t->firstLevel))) != 0 ) { + uploadSubImage( rmesa, t, i, 0, 0, t->image[face][i].width, + t->image[face][i].height, face ); } } - t->dirty_images[face] = 0; + t->base.dirty_images[face] = 0; } if (R200_DEBUG & DEBUG_SYNC) { - fprintf(stderr, "\nSyncing\n\n"); + fprintf(stderr, "%s: Syncing\n", __FUNCTION__ ); r200Finish( rmesa->glCtx ); } diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_texstate.c b/xc/lib/GL/mesa/src/drv/r200/r200_texstate.c index ee5e8009f..a6e8034ff 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_texstate.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_texstate.c @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -47,6 +49,45 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_tcl.h" +#define R200_TXFORMAT_AL88 R200_TXFORMAT_AI88 +#define R200_TXFORMAT_YCBCR R200_TXFORMAT_YVYU422 +#define R200_TXFORMAT_YCBCR_REV R200_TXFORMAT_VYUY422 + +#define _COLOR(f) \ + [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, 0 } +#define _ALPHA(f) \ + [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 } +#define _YUV(f) \ + [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, R200_YUV_TO_RGB } +#define _INVALID(f) \ + [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 } +#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_YCBCR_REV) \ + && (tx_table[f].format != 0xffffffff) ) + +static const struct { + GLuint format, filter; +} +tx_table[] = +{ + _ALPHA(RGBA8888), + _ALPHA(ARGB8888), + _INVALID(RGB888), + _COLOR(RGB565), + _ALPHA(ARGB4444), + _ALPHA(ARGB1555), + _ALPHA(AL88), + _INVALID(A8), + _INVALID(L8), + _COLOR(I8), + _INVALID(CI8), + _YUV(YCBCR), + _YUV(YCBCR_REV), +}; + +#undef _COLOR +#undef _ALPHA +#undef _INVALID + /** * This function computes the number of bytes of storage needed for * the given texture object (all mipmap levels, all cube faces). @@ -67,59 +108,25 @@ static void r200SetTexImages( r200ContextPtr rmesa, GLint i; GLint firstLevel=0, lastLevel=0, numLevels; GLint log2Width, log2Height, log2Depth; - GLuint txformat = 0; - - t->pp_txfilter &= ~R200_YUV_TO_RGB; /* Set the hardware texture format */ - switch (baseImage->TexFormat->MesaFormat) { - case MESA_FORMAT_I8: - txformat = R200_TXFORMAT_I8; - break; - case MESA_FORMAT_AL88: - txformat = R200_TXFORMAT_AI88; - break; - case MESA_FORMAT_RGBA8888: - txformat = R200_TXFORMAT_RGBA8888; - break; - case MESA_FORMAT_ARGB8888: - txformat = R200_TXFORMAT_ARGB8888; - break; - case MESA_FORMAT_RGB565: - txformat = R200_TXFORMAT_RGB565; - break; - case MESA_FORMAT_ARGB1555: - txformat = R200_TXFORMAT_ARGB1555; - break; - case MESA_FORMAT_ARGB4444: - txformat = R200_TXFORMAT_ARGB4444; - break; - case MESA_FORMAT_YCBCR: - txformat = R200_TXFORMAT_YVYU422; - t->pp_txfilter |= R200_YUV_TO_RGB; - break; - case MESA_FORMAT_YCBCR_REV: - txformat = R200_TXFORMAT_VYUY422; - t->pp_txfilter |= R200_YUV_TO_RGB; - break; - default: - _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); - return; - } t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK | R200_TXFORMAT_ALPHA_IN_MAP); - t->pp_txformat |= txformat; - - if ( txformat == R200_TXFORMAT_RGBA8888 || - txformat == R200_TXFORMAT_ARGB8888 || - txformat == R200_TXFORMAT_ARGB4444 || - txformat == R200_TXFORMAT_ARGB1555 || - txformat == R200_TXFORMAT_AI88) { - t->pp_txformat |= R200_TXFORMAT_ALPHA_IN_MAP; + t->pp_txfilter &= ~R200_YUV_TO_RGB; + + if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) { + t->pp_txformat |= tx_table[ baseImage->TexFormat->MesaFormat ].format; + t->pp_txfilter |= tx_table[ baseImage->TexFormat->MesaFormat ].filter; + } + else { + _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); + return; } + + /* Compute which mipmap levels we really want to send to the hardware. * This depends on the base image size, GL_TEXTURE_MIN_LOD, * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. @@ -228,7 +235,6 @@ static void r200SetTexImages( r200ContextPtr rmesa, assert(t->image[0][i].x == 0 || (size < BLIT_WIDTH_BYTES && t->image[0][i].height == 1)); #endif - curOffset += size; if (0) fprintf(stderr, @@ -236,16 +242,19 @@ static void r200SetTexImages( r200ContextPtr rmesa, i, texImage->Width, texImage->Height, t->image[0][i].x, t->image[0][i].y, t->image[0][i].width, t->image[0][i].height, size, curOffset); + + curOffset += size; + } /* Align the total size of texture memory block. */ - t->totalSize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; + t->base.totalSize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; /* Setup remaining cube face blits, if needed */ if (tObj->Target == GL_TEXTURE_CUBE_MAP) { /* Round totalSize up to multiple of BLIT_WIDTH_BYTES */ - const GLuint faceSize = (t->totalSize + BLIT_WIDTH_BYTES - 1) + const GLuint faceSize = (t->base.totalSize + BLIT_WIDTH_BYTES - 1) & ~(BLIT_WIDTH_BYTES-1); const GLuint lines = faceSize / BLIT_WIDTH_BYTES; GLuint face; @@ -258,7 +267,7 @@ static void r200SetTexImages( r200ContextPtr rmesa, t->image[face][i].height = t->image[0][i].height; } } - t->totalSize = 6 * faceSize; /* total texmem needed */ + t->base.totalSize = 6 * faceSize; /* total texmem needed */ } @@ -743,7 +752,7 @@ do { \ * Texture unit state management */ -static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) +static GLboolean r200UpdateTextureEnv( GLcontext *ctx, int unit ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; @@ -804,7 +813,7 @@ static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; @@ -828,7 +837,7 @@ static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; @@ -849,7 +858,7 @@ static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; @@ -873,7 +882,7 @@ static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; @@ -897,7 +906,7 @@ static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) break; case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } break; @@ -931,7 +940,7 @@ static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) numColorArgs = 3; break; default: - return; + return GL_FALSE; } switch ( texUnit->CombineModeA ) { @@ -951,7 +960,7 @@ static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) numAlphaArgs = 3; break; default: - return; + return GL_FALSE; } /* Step 1: @@ -984,7 +993,7 @@ static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) color_arg[i] = r200_zero_color[op+1]; break; default: - return; + return GL_FALSE; } } @@ -1015,7 +1024,7 @@ static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) alpha_arg[i] = r200_zero_alpha[op+1]; break; default: - return; + return GL_FALSE; } } @@ -1119,7 +1128,7 @@ static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) R200_COLOR_ARG( 2, B ); break; default: - return; + return GL_FALSE; } switch ( texUnit->CombineModeA ) { @@ -1186,7 +1195,7 @@ static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) R200_ALPHA_ARG( 2, B ); break; default: - return; + return GL_FALSE; } if ( (texUnit->CombineModeRGB == GL_DOT3_RGB_EXT) @@ -1207,7 +1216,7 @@ static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) break; default: - return; + return GL_FALSE; } } @@ -1221,13 +1230,15 @@ static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2] = color_scale; rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2] = alpha_scale; } + + return GL_TRUE; } -#define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK | \ +#define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK | \ R200_MIN_FILTER_MASK | \ R200_MAG_FILTER_MASK | \ R200_MAX_ANISO_MASK | \ - R200_YUV_TO_RGB | \ + R200_YUV_TO_RGB | \ R200_YUV_TEMPERATURE_MASK | \ R200_CLAMP_S_MASK | \ R200_CLAMP_T_MASK) @@ -1235,14 +1246,14 @@ static void r200UpdateTextureEnv( GLcontext *ctx, int unit ) #define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK | \ R200_TXFORMAT_HEIGHT_MASK | \ R200_TXFORMAT_FORMAT_MASK | \ - R200_TXFORMAT_F5_WIDTH_MASK | \ - R200_TXFORMAT_F5_HEIGHT_MASK | \ - R200_TXFORMAT_ALPHA_IN_MAP | \ - R200_TXFORMAT_CUBIC_MAP_ENABLE | \ + R200_TXFORMAT_F5_WIDTH_MASK | \ + R200_TXFORMAT_F5_HEIGHT_MASK | \ + R200_TXFORMAT_ALPHA_IN_MAP | \ + R200_TXFORMAT_CUBIC_MAP_ENABLE | \ R200_TXFORMAT_NON_POWER2) -#define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \ - R200_TEXCOORD_MASK | \ +#define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \ + R200_TEXCOORD_MASK | \ R200_VOLUME_FILTER_MASK) @@ -1264,9 +1275,9 @@ static void import_tex_obj_state( r200ContextPtr rmesa, cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color; R200_DB_STATECHANGE( rmesa, &rmesa->hw.tex[unit] ); - if (texobj->tObj->Target == GL_TEXTURE_CUBE_MAP) { + if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) { GLuint *cube_cmd = R200_DB_STATE( cube[unit] ); - GLuint bytesPerFace = texobj->totalSize / 6; + GLuint bytesPerFace = texobj->base.totalSize / 6; ASSERT(texobj->totalSize % 6 == 0); cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces; cube_cmd[CUBE_PP_CUBIC_OFFSET_F1] = texobj->pp_txoffset + 1 * bytesPerFace; @@ -1447,10 +1458,6 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit ) rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; } - if (0) - fprintf(stderr, "%s unit %d neednormals %d\n", __FUNCTION__, unit, - rmesa->TexGenNeedNormals[unit]); - return GL_TRUE; } @@ -1461,7 +1468,15 @@ static void disable_tex( GLcontext *ctx, int unit ) if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<<unit)) { /* Texture unit disabled */ - rmesa->state.texture.unit[unit].texobj = 0; + if ( rmesa->state.texture.unit[unit].texobj != NULL ) { + /* The old texture is no longer bound to this texture unit. + * Mark it as such. + */ + + rmesa->state.texture.unit[unit].texobj->base.bound &= ~(1UL << unit); + rmesa->state.texture.unit[unit].texobj = NULL; + } + R200_STATECHANGE( rmesa, ctx ); rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~((R200_TEX_0_ENABLE | R200_TEX_BLEND_0_ENABLE) << unit); @@ -1477,6 +1492,7 @@ static void disable_tex( GLcontext *ctx, int unit ) /* Actually want to keep all units less than max active texture * enabled, right? Fix this for >2 texunits. */ + /* FIXME: What should happen here if r200UpdateTextureEnv fails? */ if (unit == 0) r200UpdateTextureEnv( ctx, unit ); @@ -1511,19 +1527,19 @@ static GLboolean enable_tex_2d( GLcontext *ctx, int unit ) */ if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) { t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2; - t->dirty_images[0] = ~0; + t->base.dirty_images[0] = ~0; } ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D); - if ( t->dirty_images[0] ) { + if ( t->base.dirty_images[0] ) { R200_FIREVERTICES( rmesa ); r200SetTexImages( rmesa, tObj ); r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 ); - if ( !t->memBlock ) + if ( !t->base.memBlock ) return GL_FALSE; } - + return GL_TRUE; } @@ -1539,16 +1555,16 @@ static GLboolean enable_tex_3d( GLcontext *ctx, int unit ) */ if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) { t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2; - t->dirty_images[0] = ~0; + t->base.dirty_images[0] = ~0; } ASSERT(tObj->Target == GL_TEXTURE_3D); - if ( t->dirty_images[0] ) { + if ( t->base.dirty_images[0] ) { R200_FIREVERTICES( rmesa ); r200SetTexImages( rmesa, tObj ); r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 ); - if ( !t->memBlock ) + if ( !t->base.memBlock ) return GL_FALSE; } @@ -1569,14 +1585,14 @@ static GLboolean enable_tex_cube( GLcontext *ctx, int unit ) if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) { t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2; for (face = 0; face < 6; face++) - t->dirty_images[face] = ~0; + t->base.dirty_images[face] = ~0; } ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP); - if ( t->dirty_images[0] || t->dirty_images[1] || - t->dirty_images[2] || t->dirty_images[3] || - t->dirty_images[4] || t->dirty_images[5] ) { + if ( t->base.dirty_images[0] || t->base.dirty_images[1] || + t->base.dirty_images[2] || t->base.dirty_images[3] || + t->base.dirty_images[4] || t->base.dirty_images[5] ) { /* flush */ R200_FIREVERTICES( rmesa ); /* layout memory space, once for all faces */ @@ -1585,12 +1601,12 @@ static GLboolean enable_tex_cube( GLcontext *ctx, int unit ) /* upload (per face) */ for (face = 0; face < 6; face++) { - if (t->dirty_images[face]) { + if (t->base.dirty_images[face]) { r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, face ); } } - if ( !t->memBlock ) { + if ( !t->base.memBlock ) { /* texmem alloc failed, use s/w fallback */ return GL_FALSE; } @@ -1607,16 +1623,16 @@ static GLboolean enable_tex_rect( GLcontext *ctx, int unit ) if (!(t->pp_txformat & R200_TXFORMAT_NON_POWER2)) { t->pp_txformat |= R200_TXFORMAT_NON_POWER2; - t->dirty_images[0] = ~0; + t->base.dirty_images[0] = ~0; } ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV); - if ( t->dirty_images[0] ) { + if ( t->base.dirty_images[0] ) { R200_FIREVERTICES( rmesa ); r200SetTexImages( rmesa, tObj ); r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 ); - if ( !t->memBlock && !rmesa->prefer_agp_client_texturing ) + if ( !t->base.memBlock && !rmesa->prefer_agp_client_texturing ) return GL_FALSE; } @@ -1634,19 +1650,25 @@ static GLboolean update_tex_common( GLcontext *ctx, int unit ) /* Fallback if there's a texture border */ if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) - return GL_FALSE; + return GL_FALSE; /* Update state if this is a different texture object to last * time. */ if ( rmesa->state.texture.unit[unit].texobj != t ) { + if ( rmesa->state.texture.unit[unit].texobj != NULL ) { + /* The old texture is no longer bound to this texture unit. + * Mark it as such. + */ + + rmesa->state.texture.unit[unit].texobj->base.bound &= + ~(1UL << unit); + } + rmesa->state.texture.unit[unit].texobj = t; + t->base.bound |= (1UL << unit); t->dirty_state |= 1<<unit; - - R200_FIREVERTICES( rmesa ); - LOCK_HARDWARE( rmesa ); - r200UpdateTexLRU( rmesa, t ); - UNLOCK_HARDWARE( rmesa ); + driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */ } @@ -1679,7 +1701,9 @@ static GLboolean update_tex_common( GLcontext *ctx, int unit ) rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) { rmesa->state.texture.unit[unit].format = format; rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode; - r200UpdateTextureEnv( ctx, unit ); + if ( ! r200UpdateTextureEnv( ctx, unit ) ) { + return GL_FALSE; + } } return GL_TRUE; diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c index 8e5329a92..5a4f59d97 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h index d52094bf9..fde3eca46 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h +++ b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_c.c b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_c.c index 281dc873e..b7f3fec43 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_c.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_c.c @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -542,12 +544,20 @@ static void r200_TexCoord2fv( const GLfloat *v ) /* MultiTexcoord + * + * Technically speaking, these functions should subtract GL_TEXTURE0 from + * \c target before masking and using it. The value of GL_TEXTURE0 is 0x84C0, + * which has the low-order 5 bits 0. For all possible valid values of + * \c target. Subtracting GL_TEXTURE0 has the net effect of masking \c target + * with 0x1F. Masking with 0x1F and then masking with 0x01 is redundant, so + * the subtraction has been omitted. */ + static void r200_MultiTexCoord1fARB( GLenum target, GLfloat s ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + GLfloat *dest = rmesa->vb.texcoordptr[target & 1]; dest[0] = s; dest[1] = 0; } @@ -556,7 +566,7 @@ static void r200_MultiTexCoord1fvARB( GLenum target, const GLfloat *v ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + GLfloat *dest = rmesa->vb.texcoordptr[target & 1]; dest[0] = v[0]; dest[1] = 0; } @@ -565,7 +575,7 @@ static void r200_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + GLfloat *dest = rmesa->vb.texcoordptr[target & 1]; dest[0] = s; dest[1] = t; } @@ -574,7 +584,7 @@ static void r200_MultiTexCoord2fvARB( GLenum target, const GLfloat *v ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + GLfloat *dest = rmesa->vb.texcoordptr[target & 1]; dest[0] = v[0]; dest[1] = v[1]; } diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_sse.c b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_sse.c index 0d4fc3598..83eb3e13b 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_sse.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_sse.c @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -38,48 +40,186 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_vtxfmt.h" #if defined(USE_SSE_ASM) +#include "X86/common_x86_asm.h" + +#define EXTERN( FUNC ) \ +extern const char *FUNC; \ +extern const char *FUNC##_end + +EXTERN( _sse_Attribute2fv ); +EXTERN( _sse_Attribute2f ); +EXTERN( _sse_Attribute3fv ); +EXTERN( _sse_Attribute3f ); +EXTERN( _sse_MultiTexCoord2fv ); +EXTERN( _sse_MultiTexCoord2f ); +EXTERN( _sse_MultiTexCoord2fv_2 ); +EXTERN( _sse_MultiTexCoord2f_2 ); /* Build specialized versions of the immediate calls on the fly for - * the current state. ???P4 SSE2 versions??? + * the current state. */ +static struct dynfn *r200_makeSSEAttribute2fv( struct dynfn * cache, const int * key, + const char * name, void * dest) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", name, key[0] ); + + DFN ( _sse_Attribute2fv, (*cache) ); + FIXUP(dfn->code, 10, 0x0, (int)dest); + return dfn; +} + +static struct dynfn *r200_makeSSEAttribute2f( struct dynfn * cache, const int * key, + const char * name, void * dest ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", name, key[0] ); + + DFN ( _sse_Attribute2f, (*cache) ); + FIXUP(dfn->code, 8, 0x0, (int)dest); + return dfn; +} + +static struct dynfn *r200_makeSSEAttribute3fv( struct dynfn * cache, const int * key, + const char * name, void * dest) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", name, key[0] ); + + DFN ( _sse_Attribute3fv, (*cache) ); + FIXUP(dfn->code, 13, 0x0, (int)dest); + FIXUP(dfn->code, 18, 0x8, 8+(int)dest); + return dfn; +} + +static struct dynfn *r200_makeSSEAttribute3f( struct dynfn * cache, const int * key, + const char * name, void * dest ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", name, key[0] ); + + DFN ( _sse_Attribute3f, (*cache) ); + FIXUP(dfn->code, 12, 0x0, (int)dest); + FIXUP(dfn->code, 17, 0x8, 8+(int)dest); + return dfn; +} + +static struct dynfn *r200_makeSSENormal3fv( GLcontext *ctx, const int *key ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + return r200_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, + __FUNCTION__, rmesa->vb.normalptr ); +} + +static struct dynfn *r200_makeSSENormal3f( GLcontext *ctx, const int * key ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + return r200_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Normal3f, key, + __FUNCTION__, rmesa->vb.normalptr ); +} + +static struct dynfn *r200_makeSSEColor3fv( GLcontext *ctx, const int * key ) +{ + if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) + return 0; + else + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + return r200_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, + __FUNCTION__, rmesa->vb.floatcolorptr ); + } +} + +static struct dynfn *r200_makeSSEColor3f( GLcontext *ctx, const int * key ) +{ + if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) + return 0; + else + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + return r200_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Color3f, key, + __FUNCTION__, rmesa->vb.floatcolorptr ); + } +} -static struct dynfn *makeSSENormal3fv( GLcontext *ctx, const int *key ) +static struct dynfn *r200_makeSSETexCoord2fv( GLcontext *ctx, const int * key ) { - /* Requires P4 (sse2?) - */ - static unsigned char temp[] = { - 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $0x12345678,%edx */ - 0xf3, 0x0f, 0x7e, 0x00, /* movq (%eax),%xmm0 */ - 0x66, 0x0f, 0x6e, 0x48, 0x08, /* movd 0x8(%eax),%xmm1 */ - 0x66, 0x0f, 0xd6, 0x42, 0x0c, /* movq %xmm0,0xc(%edx) */ - 0x66, 0x0f, 0x7e, 0x4a, 0x14, /* movd %xmm1,0x14(%edx) */ - 0xc3, /* ret */ - }; + r200ContextPtr rmesa = R200_CONTEXT(ctx); + return r200_makeSSEAttribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, + __FUNCTION__, rmesa->vb.texcoordptr[0] ); +} + +static struct dynfn *r200_makeSSETexCoord2f( GLcontext *ctx, const int * key ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + return r200_makeSSEAttribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, + __FUNCTION__, rmesa->vb.texcoordptr[0] ); +} + +static struct dynfn *r200_makeSSEMultiTexCoord2fv( GLcontext *ctx, const int * key ) +{ struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); - insert_at_head( &rmesa->vb.dfn_cache.Normal3fv, dfn ); - dfn->key[0] = key[0]; - dfn->key[1] = key[1]; - dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); - memcpy (dfn->code, temp, sizeof(temp)); - FIXUP(dfn->code, 5, 0x0, (int)rmesa->vb.normalptr); + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); + + if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { + DFN ( _sse_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + FIXUP(dfn->code, 18, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); + } else { + DFN ( _sse_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); + } return dfn; } -void r200InitSSECodegen( struct dfn_generators *gen ) +static struct dynfn *r200_makeSSEMultiTexCoord2f( GLcontext *ctx, const int * key ) { - /* Need to: - * - check kernel sse support - * - check p4/sse2 - */ - (void) makeSSENormal3fv; + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); + + if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { + DFN ( _sse_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + FIXUP(dfn->code, 16, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); + } else { + DFN ( _sse_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + FIXUP(dfn->code, 15, 0x0, (int)rmesa->vb.texcoordptr); + } + return dfn; } +void r200InitSSECodegen( struct dfn_generators *gen ) +{ + if ( cpu_has_xmm ) { + gen->Normal3fv = (void *) r200_makeSSENormal3fv; + gen->Normal3f = (void *) r200_makeSSENormal3f; + gen->Color3fv = (void *) r200_makeSSEColor3fv; + gen->Color3f = (void *) r200_makeSSEColor3f; + gen->TexCoord2fv = (void *) r200_makeSSETexCoord2fv; + gen->TexCoord2f = (void *) r200_makeSSETexCoord2f; + gen->MultiTexCoord2fvARB = (void *) r200_makeSSEMultiTexCoord2fv; + gen->MultiTexCoord2fARB = (void *) r200_makeSSEMultiTexCoord2f; + } +} #else @@ -89,7 +229,3 @@ void r200InitSSECodegen( struct dfn_generators *gen ) } #endif - - - - diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_x86.c b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_x86.c index b19745ed3..a806eca0b 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_x86.c +++ b/xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_x86.c @@ -1,5 +1,6 @@ /* $XFree86$ */ -/* +/************************************************************************** + Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. The Weather Channel (TM) funded Tungsten Graphics to develop the @@ -25,7 +26,8 @@ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS 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: @@ -43,8 +45,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. extern const char *FUNC; \ extern const char *FUNC##_end -EXTERN ( _x86_Normal3fv ); -EXTERN ( _x86_Normal3f ); +EXTERN ( _x86_Attribute2fv ); +EXTERN ( _x86_Attribute2f ); +EXTERN ( _x86_Attribute3fv ); +EXTERN ( _x86_Attribute3f ); EXTERN ( _x86_Vertex3fv_6 ); EXTERN ( _x86_Vertex3fv_8 ); EXTERN ( _x86_Vertex3fv ); @@ -54,14 +58,10 @@ EXTERN ( _x86_Vertex3f ); EXTERN ( _x86_Color4ubv_ub ); EXTERN ( _x86_Color4ubv_4f ); EXTERN ( _x86_Color4ub_ub ); -EXTERN ( _x86_Color3fv_3f ); -EXTERN ( _x86_Color3f_3f ); -EXTERN ( _x86_TexCoord2fv ); -EXTERN ( _x86_TexCoord2f ); -EXTERN ( _x86_MultiTexCoord2fvARB ); -EXTERN ( _x86_MultiTexCoord2fvARB_2 ); -EXTERN ( _x86_MultiTexCoord2fARB ); -EXTERN ( _x86_MultiTexCoord2fARB_2 ); +EXTERN ( _x86_MultiTexCoord2fv ); +EXTERN ( _x86_MultiTexCoord2fv_2 ); +EXTERN ( _x86_MultiTexCoord2f ); +EXTERN ( _x86_MultiTexCoord2f_2 ); /* Build specialized versions of the immediate calls on the fly for @@ -181,37 +181,88 @@ struct dynfn *r200_makeX86Vertex3fv( GLcontext *ctx, const int *key ) return dfn; } -struct dynfn *r200_makeX86Normal3fv( GLcontext *ctx, const int *key ) +static struct dynfn * +r200_makeX86Attribute2fv( struct dynfn * cache, const int *key, + const char * name, void * dest ) { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - int i = 0; if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); + fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - DFN ( _x86_Normal3fv, rmesa->vb.dfn_cache.Normal3fv ); + DFN ( _x86_Attribute2fv, (*cache) ); + FIXUP(dfn->code, 11, 0x0, (int)dest); + FIXUP(dfn->code, 16, 0x4, 4+(int)dest); - FIXUP2(dfn->code, i, 0x0, (int)rmesa->vb.normalptr); - FIXUP2(dfn->code, i, 0x4, 4+(int)rmesa->vb.normalptr); - FIXUP2(dfn->code, i, 0x8, 8+(int)rmesa->vb.normalptr); - /*fprintf(stderr, "%s done\n", __FUNCTION__);*/ return dfn; } -struct dynfn *r200_makeX86Normal3f( GLcontext *ctx, const int *key ) +static struct dynfn * +r200_makeX86Attribute2f( struct dynfn * cache, const int *key, + const char * name, void * dest ) { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); + fprintf(stderr, "%s 0x%08x\n", name, key[0] ); + + DFN ( _x86_Attribute2f, (*cache) ); + FIXUP(dfn->code, 1, 0x0, (int)dest); - DFN ( _x86_Normal3f, rmesa->vb.dfn_cache.Normal3f ); - FIXUP(dfn->code, 1, 0x12345678, (int)rmesa->vb.normalptr); return dfn; } + +static struct dynfn * +r200_makeX86Attribute3fv( struct dynfn * cache, const int *key, + const char * name, void * dest ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", name, key[0] ); + + DFN ( _x86_Attribute3fv, (*cache) ); + FIXUP(dfn->code, 14, 0x0, (int)dest); + FIXUP(dfn->code, 20, 0x4, 4+(int)dest); + FIXUP(dfn->code, 25, 0x8, 8+(int)dest); + + return dfn; +} + +static struct dynfn * +r200_makeX86Attribute3f( struct dynfn * cache, const int *key, + const char * name, void * dest ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (R200_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", name, key[0] ); + + DFN ( _x86_Attribute3f, (*cache) ); + FIXUP(dfn->code, 14, 0x0, (int)dest); + FIXUP(dfn->code, 20, 0x4, 4+(int)dest); + FIXUP(dfn->code, 25, 0x8, 8+(int)dest); + + return dfn; +} + +struct dynfn *r200_makeX86Normal3fv( GLcontext *ctx, const int *key ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + return r200_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, + __FUNCTION__, rmesa->vb.normalptr ); +} + +struct dynfn *r200_makeX86Normal3f( GLcontext *ctx, const int *key ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + + return r200_makeX86Attribute3f( & rmesa->vb.dfn_cache.Normal3f, key, + __FUNCTION__, rmesa->vb.normalptr ); +} + struct dynfn *r200_makeX86Color4ubv( GLcontext *ctx, const int *key ) { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); @@ -265,15 +316,10 @@ struct dynfn *r200_makeX86Color3fv( GLcontext *ctx, const int *key ) return 0; else { - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); - - DFN ( _x86_Color3fv_3f, rmesa->vb.dfn_cache.Color3fv ); - FIXUP(dfn->code, 5, 0x0, (int)rmesa->vb.floatcolorptr); - return dfn; + return r200_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, + __FUNCTION__, rmesa->vb.floatcolorptr ); } } @@ -283,15 +329,10 @@ struct dynfn *r200_makeX86Color3f( GLcontext *ctx, const int *key ) return 0; else { - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); - - DFN ( _x86_Color3f_3f, rmesa->vb.dfn_cache.Color3f ); - FIXUP(dfn->code, 1, 0x12345678, (int)rmesa->vb.floatcolorptr); - return dfn; + return r200_makeX86Attribute3f( & rmesa->vb.dfn_cache.Color3f, key, + __FUNCTION__, rmesa->vb.floatcolorptr ); } } @@ -299,61 +340,22 @@ struct dynfn *r200_makeX86Color3f( GLcontext *ctx, const int *key ) struct dynfn *r200_makeX86TexCoord2fv( GLcontext *ctx, const int *key ) { - - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); - - DFN ( _x86_TexCoord2fv, rmesa->vb.dfn_cache.TexCoord2fv ); - FIXUP(dfn->code, 5, 0x12345678, (int)rmesa->vb.texcoordptr[0]); - return dfn; + return r200_makeX86Attribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, + __FUNCTION__, rmesa->vb.texcoordptr[0] ); } struct dynfn *r200_makeX86TexCoord2f( GLcontext *ctx, const int *key ) { - - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); - - DFN ( _x86_TexCoord2f, rmesa->vb.dfn_cache.TexCoord2f ); - FIXUP(dfn->code, 1, 0x12345678, (int)rmesa->vb.texcoordptr[0]); - return dfn; + return r200_makeX86Attribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, + __FUNCTION__, rmesa->vb.texcoordptr[0] ); } struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *ctx, const int *key ) { -#if 0 - static char temp[] = { - 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */ - 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ - 0x83, 0xe0, 0x01, /* and $0x1,%eax */ - 0x8b, 0x11, /* mov (%ecx),%edx */ - 0xc1, 0xe0, 0x03, /* shl $0x3,%eax */ - 0x8b, 0x49, 0x04, /* mov 0x4(%ecx),%ecx */ - 0x89, 0x90, 0, 0, 0, 0,/* mov %edx,DEST(%eax) */ - 0x89, 0x88, 0, 0, 0, 0,/* mov %ecx,DEST+8(%eax) */ - 0xc3, /* ret */ - }; - static char temp2[] = { - 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */ - 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ - 0x83, 0xe0, 0x01, /* and $0x1,%eax */ - 0x8b, 0x14, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%edx */ - 0x8b, 0x01, /* mov (%ecx),%eax */ - 0x89, 0x02, /* mov %eax,(%edx) */ - 0x8b, 0x41, 0x04, /* mov 0x4(%ecx),%eax */ - 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */ - 0xc3, /* ret */ - }; -#endif - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); @@ -361,12 +363,12 @@ struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *ctx, const int *key ) fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { - DFN ( _x86_MultiTexCoord2fvARB, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 26, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 32, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); + DFN ( _x86_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + FIXUP(dfn->code, 21, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); + FIXUP(dfn->code, 27, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); } else { - DFN ( _x86_MultiTexCoord2fvARB_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 19, 0x0, (int)rmesa->vb.texcoordptr); + DFN ( _x86_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); } return dfn; } @@ -374,31 +376,6 @@ struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *ctx, const int *key ) struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *ctx, const int *key ) { -#if 0 - static char temp[] = { - 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */ - 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ - 0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */ - 0x83, 0xe0, 0x01, /* and $0x1,%eax */ - 0xc1, 0xe0, 0x03, /* shl $0x3,%eax */ - 0x89, 0x90, 0, 0, 0, 0, /* mov %edx,DEST(%eax) */ - 0x89, 0x88, 0, 0, 0, 0, /* mov %ecx,DEST+8(%eax) */ - 0xc3, /* ret */ - }; - - static char temp2[] = { - 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */ - 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ - 0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */ - 0x83, 0xe0, 0x01, /* and $0x1,%eax */ - 0x8b, 0x04, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%eax */ - 0x89, 0x10, /* mov %edx,(%eax) */ - 0x89, 0x48, 0x04, /* mov %ecx,0x4(%eax) */ - 0xc3, /* ret */ - }; -#endif struct dynfn *dfn = MALLOC_STRUCT( dynfn ); r200ContextPtr rmesa = R200_CONTEXT(ctx); @@ -406,16 +383,16 @@ struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *ctx, fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { - DFN ( _x86_MultiTexCoord2fARB, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 25, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 31, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); + DFN ( _x86_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + FIXUP(dfn->code, 20, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); + FIXUP(dfn->code, 26, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); } else { /* Note: this might get generated multiple times, even though the * actual emitted code is the same. */ - DFN ( _x86_MultiTexCoord2fARB_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 23, 0x0, (int)rmesa->vb.texcoordptr); + DFN ( _x86_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.texcoordptr); } return dfn; } diff --git a/xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S b/xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S index 4980ce1bb..f1494601f 100644 --- a/xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S +++ b/xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S @@ -32,16 +32,6 @@ x: .data .align 4 -GLOBL( _x86_Normal3fv) - movl 4(%esp), %eax /* load 'v' off stack */ - movl (%eax), %ecx /* load v[0] */ - movl 4(%eax), %edx /* load v[1] */ - movl 8(%eax), %eax /* load v[2] */ - movl %ecx, 0 /* store v[0] to current vertex */ - movl %edx, 4 /* store v[1] to current vertex */ - movl %eax, 8 /* store v[2] to current vertex */ - ret -GLOBL ( _x86_Normal3fv_end ) /* vertex 3f vertex size 4 @@ -218,19 +208,70 @@ GLOBL ( _x86_Vertex3fv ) .6: jmp *0 GLOBL ( _x86_Vertex3fv_end ) -/* - Normal 3f -*/ -GLOBL ( _x86_Normal3f ) - movl $0x12345678, %edx + +/** + * Generic handler for 2 float format data. This can be used for + * TexCoord2f and possibly other functions. + */ + +GLOBL ( _x86_Attribute2f ) + movl $0x0, %edx movl 4(%esp), %eax + movl 8(%esp), %ecx movl %eax, (%edx) - movl 8(%esp), %eax - movl %eax, 4(%edx) + movl %ecx, 4(%edx) + ret +GLOBL ( _x86_Attribute2f_end ) + + +/** + * Generic handler for 2 float vector format data. This can be used for + * TexCoord2fv and possibly other functions. + */ + +GLOBL( _x86_Attribute2fv) + movl 4(%esp), %eax /* load 'v' off stack */ + movl (%eax), %ecx /* load v[0] */ + movl 4(%eax), %eax /* load v[1] */ + movl %ecx, 0 /* store v[0] to current vertex */ + movl %eax, 4 /* store v[1] to current vertex */ + ret +GLOBL ( _x86_Attribute2fv_end ) + + +/** + * Generic handler for 3 float format data. This can be used for + * Normal3f, Color3f (when the color target is also float), or + * TexCoord3f. + */ + +GLOBL ( _x86_Attribute3f ) + movl 4(%esp), %ecx + movl 8(%esp), %edx movl 12(%esp), %eax - movl %eax, 8(%edx) + movl %ecx, 0 + movl %edx, 4 + movl %eax, 8 ret -GLOBL ( _x86_Normal3f_end ) +GLOBL ( _x86_Attribute3f_end ) + +/** + * Generic handler for 3 float vector format data. This can be used for + * Normal3f, Color3f (when the color target is also float), or + * TexCoord3f. + */ + +GLOBL( _x86_Attribute3fv) + movl 4(%esp), %eax /* load 'v' off stack */ + movl (%eax), %ecx /* load v[0] */ + movl 4(%eax), %edx /* load v[1] */ + movl 8(%eax), %eax /* load v[2] */ + movl %ecx, 0 /* store v[0] to current vertex */ + movl %edx, 4 /* store v[1] to current vertex */ + movl %eax, 8 /* store v[2] to current vertex */ + ret +GLOBL ( _x86_Attribute3fv_end ) + /* Color 4ubv_ub @@ -290,69 +331,13 @@ GLOBL( _x86_Color4ub_ub ) ret GLOBL( _x86_Color4ub_ub_end ) -/* - Color3fv_3f -*/ -GLOBL( _x86_Color3fv_3f ) - movl 4(%esp), %eax - movl $0, %edx - movl (%eax), %ecx - movl %ecx, (%edx) - movl 4(%eax), %ecx - movl %ecx, 4(%edx) - movl 8(%eax), %ecx - movl %ecx, 8(%edx) - ret -GLOBL( _x86_Color3fv_3f_end ) - -/* - Color3f_3f -*/ -GLOBL( _x86_Color3f_3f ) - movl $0x12345678, %edx - movl 4(%esp), %eax - movl %eax, (%edx) - movl 8(%esp,1), %eax - movl %eax, 4(%edx) - movl 12(%esp), %eax - movl %eax, 8(%edx) - ret -GLOBL( _x86_Color3f_3f_end ) /* - TexCoord2fv + MultiTexCoord2fv st0/st1 */ - -GLOBL( _x86_TexCoord2fv ) - movl 4(%esp), %eax - movl $0x12345678, %edx - movl (%eax), %ecx - movl 4(%eax), %eax - movl %ecx, (%edx) - movl %eax, 4(%edx) - ret - -GLOBL( _x86_TexCoord2fv_end ) -/* - TexCoord2f -*/ -GLOBL( _x86_TexCoord2f ) - movl $0x12345678, %edx +GLOBL( _x86_MultiTexCoord2fv ) movl 4(%esp), %eax movl 8(%esp), %ecx - movl %eax, (%edx) - movl %ecx, 4(%edx) - ret -GLOBL( _x86_TexCoord2f_end ) - -/* - MultiTexCoord2fvARB st0/st1 -*/ -GLOBL( _x86_MultiTexCoord2fvARB ) - - movl 4(%esp), %eax - movl 8(%esp), %ecx - sub $0x84c0, %eax and $1, %eax movl (%ecx), %edx shl $3, %eax @@ -360,15 +345,15 @@ GLOBL( _x86_MultiTexCoord2fvARB ) movl %edx, 0xdeadbeef(%eax) movl %ecx, 0xdeadbeef(%eax) ret -GLOBL( _x86_MultiTexCoord2fvARB_end ) +GLOBL( _x86_MultiTexCoord2fv_end ) + /* - MultiTexCoord2fvARB + MultiTexCoord2fv */ -GLOBL( _x86_MultiTexCoord2fvARB_2 ) +GLOBL( _x86_MultiTexCoord2fv_2 ) movl 4(%esp,1), %eax movl 8(%esp,1), %ecx - sub $0x84c0, %eax and $0x1, %eax movl 0(,%eax,4), %edx movl (%ecx), %eax @@ -376,35 +361,132 @@ GLOBL( _x86_MultiTexCoord2fvARB_2 ) movl 4(%ecx), %eax movl %eax, 4(%edx) ret - -GLOBL( _x86_MultiTexCoord2fvARB_2_end ) +GLOBL( _x86_MultiTexCoord2fv_2_end ) /* - MultiTexCoord2fARB st0/st1 + MultiTexCoord2f st0/st1 */ -GLOBL( _x86_MultiTexCoord2fARB ) +GLOBL( _x86_MultiTexCoord2f ) movl 4(%esp), %eax movl 8(%esp), %edx - sub $0x84c0, %eax movl 12(%esp), %ecx and $1, %eax shl $3, %eax movl %edx, 0xdeadbeef(%eax) movl %ecx, 0xdeadbeef(%eax) ret -GLOBL( _x86_MultiTexCoord2fARB_end ) +GLOBL( _x86_MultiTexCoord2f_end ) /* - MultiTexCoord2fARB + MultiTexCoord2f */ -GLOBL( _x86_MultiTexCoord2fARB_2 ) +GLOBL( _x86_MultiTexCoord2f_2 ) movl 4(%esp), %eax movl 8(%esp), %edx - sub $0x84c0, %eax movl 12(%esp,1), %ecx and $1,%eax movl 0(,%eax,4), %eax movl %edx, (%eax) movl %ecx, 4(%eax) ret -GLOBL( _x86_MultiTexCoord2fARB_2_end ) +GLOBL( _x86_MultiTexCoord2f_2_end ) + +/** + * This can be used as a template for either Color3fv (when the color + * target is also a 3f) or Normal3fv. + */ + +GLOBL( _sse_Attribute3fv ) + movl 4(%esp), %eax + movlps (%eax), %xmm0 + movl 8(%eax), %eax + movlps %xmm0, 0 + movl %eax, 8 + ret +GLOBL( _sse_Attribute3fv_end ) + +/** + * This can be used as a template for either Color3f (when the color + * target is also a 3f) or Normal3f. + */ + +GLOBL( _sse_Attribute3f ) + movlps 4(%esp), %xmm0 + movl 12(%esp), %eax + movlps %xmm0, 0 + movl %eax, 8 + ret +GLOBL( _sse_Attribute3f_end ) + + +/** + * Generic handler for 2 float vector format data. This can be used for + * TexCoord2fv and possibly other functions. + */ + +GLOBL( _sse_Attribute2fv ) + movl 4(%esp), %eax + movlps (%eax), %xmm0 + movlps %xmm0, 0 + ret +GLOBL( _sse_Attribute2fv_end ) + + +/** + * Generic handler for 2 float format data. This can be used for + * TexCoord2f and possibly other functions. + */ + +GLOBL( _sse_Attribute2f ) + movlps 4(%esp), %xmm0 + movlps %xmm0, 0 + ret +GLOBL( _sse_Attribute2f_end ) + +/* + MultiTexCoord2fv st0/st1 +*/ +GLOBL( _sse_MultiTexCoord2fv ) + movl 4(%esp), %eax + movl 8(%esp), %ecx + and $1, %eax + movlps (%ecx), %xmm0 + movlps %xmm0, 0xdeadbeef(,%eax,8) + ret +GLOBL( _sse_MultiTexCoord2fv_end ) + +/* + MultiTexCoord2fv +*/ +GLOBL( _sse_MultiTexCoord2fv_2 ) + movl 4(%esp), %eax + movl 8(%esp), %ecx + and $0x1, %eax + movl 0(,%eax,4), %edx + movlps (%ecx), %xmm0 + movlps %xmm0, (%edx) + ret +GLOBL( _sse_MultiTexCoord2fv_2_end ) + +/* + MultiTexCoord2f st0/st1 +*/ +GLOBL( _sse_MultiTexCoord2f ) + movl 4(%esp), %eax + and $1, %eax + movlps 8(%esp), %xmm0 + movlps %xmm0, 0xdeadbeef(,%eax,8) + ret +GLOBL( _sse_MultiTexCoord2f_end ) + +/* + MultiTexCoord2f +*/ +GLOBL( _sse_MultiTexCoord2f_2 ) + movl 4(%esp), %eax + movlps 8(%esp), %xmm0 + and $1,%eax + movl 0(,%eax,4), %eax + movlps %xmm0, (%eax) + ret +GLOBL( _sse_MultiTexCoord2f_2_end ) diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c index 6ed0c1478..6c0a7b8d0 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, VA LINUX SYSTEMS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ @@ -32,14 +33,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> * Keith Whitwell <keith@tungstengraphics.com> - * */ #include "glheader.h" -#include "imports.h" #include "api_arrayelt.h" #include "context.h" #include "simple_list.h" +#include "imports.h" #include "matrix.h" #include "extensions.h" @@ -64,8 +64,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "X86/common_x86_asm.h" #endif -#define RADEON_DATE "20021125" +#define DRIVER_DATE "20030328" +#include "vblank.h" +#include "utils.h" #ifndef RADEON_DEBUG int RADEON_DEBUG = (0); #endif @@ -92,64 +94,20 @@ static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); static char buffer[128]; + unsigned offset; switch ( name ) { case GL_VENDOR: return (GLubyte *)"Tungsten Graphics, Inc."; case GL_RENDERER: - sprintf( buffer, "Mesa DRI Radeon " RADEON_DATE); - - /* Append any chipset-specific information. None yet. - */ - - /* Append any AGP-specific information. - */ - switch ( rmesa->radeonScreen->AGPMode ) { - case 1: - strncat( buffer, " AGP 1x", 7 ); - break; - case 2: - strncat( buffer, " AGP 2x", 7 ); - break; - case 4: - strncat( buffer, " AGP 4x", 7 ); - break; - } - - /* Append any CPU-specific information. - */ -#ifdef USE_X86_ASM - if ( _mesa_x86_cpu_features ) { - strncat( buffer, " x86", 4 ); - } -#ifdef USE_MMX_ASM - if ( cpu_has_mmx ) { - strncat( buffer, "/MMX", 4 ); - } -#endif -#ifdef USE_3DNOW_ASM - if ( cpu_has_3dnow ) { - strncat( buffer, "/3DNow!", 7 ); - } -#endif -#ifdef USE_SSE_ASM - if ( cpu_has_xmm ) { - strncat( buffer, "/SSE", 4 ); - } -#endif -#endif + offset = driGetRendererString( buffer, "Radeon", DRIVER_DATE, + rmesa->radeonScreen->AGPMode ); - if ( rmesa->dri.drmMinor < 3 ) { - strncat( buffer, " DRM-COMPAT", 11 ); - } - - if ( !(rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) ) { - strncat( buffer, " TCL", 4 ); - } - else { - strncat( buffer, " NO-TCL", 7 ); - } + sprintf( & buffer[ offset ], "%s %sTCL", + ( rmesa->dri.drmMinor < 3 ) ? " DRM-COMPAT" : "", + !(rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE) + ? "" : "NO-" ); return (GLubyte *)buffer; @@ -161,7 +119,7 @@ static const GLubyte *radeonGetString( GLcontext *ctx, GLenum name ) /* Extension strings exported by the R100 driver. */ -static const char * const radeon_extensions[] = +static const char * const card_extensions[] = { "GL_ARB_multisample", "GL_ARB_multitexture", @@ -173,8 +131,8 @@ static const char * const radeon_extensions[] = "GL_ARB_texture_mirrored_repeat", "GL_EXT_blend_logic_op", "GL_EXT_blend_subtract", -/* "GL_EXT_fog_coord", */ "GL_EXT_secondary_color", + "GL_EXT_texture_edge_clamp", "GL_EXT_texture_env_add", "GL_EXT_texture_env_combine", "GL_EXT_texture_env_dot3", @@ -186,21 +144,10 @@ static const char * const radeon_extensions[] = "GL_NV_blend_square", "GL_SGIS_generate_mipmap", "GL_SGIS_texture_border_clamp", + "GL_SGIS_texture_edge_clamp", NULL }; -/* Initialize the extensions supported by this driver. - */ -static void radeonInitExtensions( GLcontext *ctx ) -{ - unsigned i; - _mesa_enable_imaging_extensions( ctx ); - - for ( i = 0 ; radeon_extensions[i] != NULL ; i++ ) { - _mesa_enable_extension( ctx, radeon_extensions[i] ); - } -} - extern const struct gl_pipeline_stage _radeon_render_stage; extern const struct gl_pipeline_stage _radeon_tcl_stage; @@ -251,24 +198,49 @@ static void radeonInitDriverFuncs( GLcontext *ctx ) ctx->Driver.Bitmap = NULL; } +static const struct dri_debug_control debug_control[] = +{ + { "fall", DEBUG_FALLBACKS }, + { "tex", DEBUG_TEXTURE }, + { "ioctl", DEBUG_IOCTL }, + { "prim", DEBUG_PRIMS }, + { "vert", DEBUG_VERTS }, + { "state", DEBUG_STATE }, + { "code", DEBUG_CODEGEN }, + { "vfmt", DEBUG_VFMT }, + { "vtxf", DEBUG_VFMT }, + { "verb", DEBUG_VERBOSE }, + { "dri", DEBUG_DRI }, + { "dma", DEBUG_DMA }, + { "san", DEBUG_SANITY }, + { NULL, 0 } +}; + + +static int +get_ust_nop( int64_t * ust ) +{ + *ust = 1; + return 0; +} /* Create the device specific context. */ -static GLboolean +GLboolean radeonCreateContext( const __GLcontextModes *glVisual, __DRIcontextPrivate *driContextPriv, void *sharedContextPrivate) { __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - radeonScreenPtr radeonScreen = (radeonScreenPtr)(sPriv->private); + radeonScreenPtr screen = (radeonScreenPtr)(sPriv->private); radeonContextPtr rmesa; GLcontext *ctx, *shareCtx; int i; assert(glVisual); assert(driContextPriv); - assert(radeonScreen); + assert(screen); /* Allocate the Radeon context */ rmesa = (radeonContextPtr) CALLOC( sizeof(*rmesa) ); @@ -302,44 +274,54 @@ radeonCreateContext( const __GLcontextModes *glVisual, else rmesa->dri.drmMinor = sPriv->drmMinor; - rmesa->radeonScreen = radeonScreen; + rmesa->radeonScreen = screen; rmesa->sarea = (RADEONSAREAPrivPtr)((GLubyte *)sPriv->pSAREA + - radeonScreen->sarea_priv_offset); + screen->sarea_priv_offset); rmesa->dma.buf0_address = rmesa->radeonScreen->buffers->list[0].address; - for ( i = 0 ; i < radeonScreen->numTexHeaps ; i++ ) { - make_empty_list( &rmesa->texture.objects[i] ); - rmesa->texture.heap[i] = mmInit( 0, radeonScreen->texSize[i] ); - rmesa->texture.age[i] = -1; + (void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) ); + make_empty_list( & rmesa->swapped ); + + rmesa->nr_heaps = screen->numTexHeaps; + for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { + rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa, + screen->texSize[i], + 12, + RADEON_NR_TEX_REGIONS, + rmesa->sarea->texList[i], + & rmesa->sarea->texAge[i], + & rmesa->swapped, + sizeof( radeonTexObj ), + (destroy_texture_object_t *) radeonDestroyTexObj ); + + driSetTextureSwapCounterLocation( rmesa->texture_heaps[i], + & rmesa->c_textureSwaps ); } - rmesa->texture.numHeaps = radeonScreen->numTexHeaps; - make_empty_list( &rmesa->texture.swapped ); rmesa->swtcl.RenderIndex = ~0; rmesa->lost_context = 1; - /* KW: Set the maximum texture size small enough that we can - * guarentee that both texture units can bind a maximal texture - * and have them both in on-card memory at once. - * Test for 2 textures * 4 bytes/texel * size * size. + /* Set the maximum texture size small enough that we can guarentee that + * all texture units can bind a maximal texture and have them both in + * texturable memory at once. */ - ctx = rmesa->glCtx; - if (radeonScreen->texSize[RADEON_CARD_HEAP] >= 2 * 4 * 2048 * 2048) { - ctx->Const.MaxTextureLevels = 12; /* 2048x2048 */ - } - else if (radeonScreen->texSize[RADEON_CARD_HEAP] >= 2 * 4 * 1024 * 1024) { - ctx->Const.MaxTextureLevels = 11; /* 1024x1024 */ - } - else if (radeonScreen->texSize[RADEON_CARD_HEAP] >= 2 * 4 * 512 * 512) { - ctx->Const.MaxTextureLevels = 10; /* 512x512 */ - } - else { - ctx->Const.MaxTextureLevels = 9; /* 256x256 */ - } + ctx = rmesa->glCtx; ctx->Const.MaxTextureUnits = 2; + + driCalculateMaxTextureLevels( rmesa->texture_heaps, + rmesa->nr_heaps, + & 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 ); + ctx->Const.MaxTextureMaxAnisotropy = 16.0; /* No wide points. @@ -364,11 +346,7 @@ radeonCreateContext( const __GLcontextModes *glVisual, MIN2( ctx->Const.MaxArrayLockSize, RADEON_BUFFER_SIZE / RADEON_MAX_TCL_VERTSIZE ); - if (getenv("LIBGL_PERFORMANCE_BOXES")) - rmesa->boxes = 1; - else - rmesa->boxes = 0; - + rmesa->boxes = (getenv("LIBGL_PERFORMANCE_BOXES") != NULL); /* Initialize the software rasterizer and helper modules. */ @@ -396,8 +374,6 @@ radeonCreateContext( const __GLcontextModes *glVisual, _tnl_isolate_materials( ctx, GL_TRUE ); -/* _mesa_allow_light_in_model( ctx, GL_FALSE ); */ - /* Configure swrast to match hardware characteristics: */ _swrast_allow_pixel_fog( ctx, GL_FALSE ); @@ -411,7 +387,7 @@ radeonCreateContext( const __GLcontextModes *glVisual, _math_matrix_set_identity( &rmesa->TexGenMatrix[1] ); _math_matrix_set_identity( &rmesa->tmpmat ); - radeonInitExtensions( ctx ); + driInitExtensions( ctx, card_extensions, GL_TRUE ); radeonInitDriverFuncs( ctx ); radeonInitIoctlFuncs( ctx ); radeonInitStateFuncs( ctx ); @@ -420,90 +396,23 @@ radeonCreateContext( const __GLcontextModes *glVisual, radeonInitState( rmesa ); radeonInitSwtcl( ctx ); - rmesa->do_irqs = (rmesa->radeonScreen->irq && !getenv("RADEON_NO_IRQS")); - rmesa->irqsEmitted = 0; rmesa->iw.irq_seq = -1; + rmesa->irqsEmitted = 0; + rmesa->do_irqs = (rmesa->radeonScreen->irq && !getenv("RADEON_NO_IRQS")); rmesa->do_usleeps = !getenv("RADEON_NO_USLEEPS"); - -#if DO_DEBUG - if (getenv("RADEON_DEBUG_FALLBACKS")) - RADEON_DEBUG |= DEBUG_FALLBACKS; - - if (getenv("RADEON_DEBUG_TEXTURE")) - RADEON_DEBUG |= DEBUG_TEXTURE; - - if (getenv("RADEON_DEBUG_IOCTL")) - RADEON_DEBUG |= DEBUG_IOCTL; - - if (getenv("RADEON_DEBUG_PRIMS")) - RADEON_DEBUG |= DEBUG_PRIMS; - - if (getenv("RADEON_DEBUG_VERTS")) - RADEON_DEBUG |= DEBUG_VERTS; - - if (getenv("RADEON_DEBUG_STATE")) - RADEON_DEBUG |= DEBUG_STATE; - - if (getenv("RADEON_DEBUG_CODEGEN")) - RADEON_DEBUG |= DEBUG_CODEGEN; - - if (getenv("RADEON_DEBUG_VTXFMT")) - RADEON_DEBUG |= DEBUG_VFMT; - - if (getenv("RADEON_DEBUG_VERBOSE")) - RADEON_DEBUG |= DEBUG_VERBOSE; - - if (getenv("RADEON_DEBUG_DRI")) - RADEON_DEBUG |= DEBUG_DRI; - - if (getenv("RADEON_DEBUG_DMA")) - RADEON_DEBUG |= DEBUG_DMA; - - if (getenv("RADEON_DEBUG_SANITY")) - RADEON_DEBUG |= DEBUG_SANITY; - - if (getenv("RADEON_DEBUG")) - { - const char *debug = getenv("RADEON_DEBUG"); - if (strstr(debug, "fall")) - RADEON_DEBUG |= DEBUG_FALLBACKS; - - if (strstr(debug, "tex")) - RADEON_DEBUG |= DEBUG_TEXTURE; - - if (strstr(debug, "ioctl")) - RADEON_DEBUG |= DEBUG_IOCTL; - - if (strstr(debug, "prim")) - RADEON_DEBUG |= DEBUG_PRIMS; - - if (strstr(debug, "vert")) - RADEON_DEBUG |= DEBUG_VERTS; - - if (strstr(debug, "state")) - RADEON_DEBUG |= DEBUG_STATE; - - if (strstr(debug, "code")) - RADEON_DEBUG |= DEBUG_CODEGEN; - - if (strstr(debug, "vfmt") || strstr(debug, "vtxf")) - RADEON_DEBUG |= DEBUG_VFMT; - if (strstr(debug, "verb")) - RADEON_DEBUG |= DEBUG_VERBOSE; + rmesa->vblank_flags = (rmesa->do_irqs) + ? driGetDefaultVBlankFlags() : VBLANK_FLAG_NO_IRQ; - if (strstr(debug, "dri")) - RADEON_DEBUG |= DEBUG_DRI; - - if (strstr(debug, "dma")) - RADEON_DEBUG |= DEBUG_DMA; - - if (strstr(debug, "san")) - RADEON_DEBUG |= DEBUG_SANITY; + rmesa->get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( "__glXGetUST" ); + if ( rmesa->get_ust == NULL ) { + rmesa->get_ust = get_ust_nop; } - +#if DO_DEBUG + RADEON_DEBUG = driParseDebugString( getenv( "RADEON_DEBUG" ), + debug_control ); #endif if (getenv("RADEON_NO_RAST")) { @@ -536,8 +445,7 @@ radeonCreateContext( const __GLcontextModes *glVisual, */ /* Destroy the Mesa and driver specific context data. */ -static void -radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) +void radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) { GET_CURRENT_CONTEXT(ctx); radeonContextPtr rmesa = (radeonContextPtr) driContextPriv->driverPrivate; @@ -552,33 +460,16 @@ radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) /* Free radeon context resources */ assert(rmesa); /* should never be null */ if ( rmesa ) { - if (rmesa->glCtx->Shared->RefCount == 1) { - /* This share group is about to go away, free our private - * texture object data. - */ - radeonTexObjPtr t, next_t; - int i; + GLboolean release_texture_heaps; - for ( i = 0 ; i < rmesa->texture.numHeaps ; i++ ) { - foreach_s ( t, next_t, &rmesa->texture.objects[i] ) { - radeonDestroyTexObj( rmesa, t ); - } - mmDestroy( rmesa->texture.heap[i] ); - rmesa->texture.heap[i] = NULL; - } - - foreach_s ( t, next_t, &rmesa->texture.swapped ) { - radeonDestroyTexObj( rmesa, t ); - } - } + release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( rmesa->glCtx ); _tnl_DestroyContext( rmesa->glCtx ); _ac_DestroyContext( rmesa->glCtx ); _swrast_DestroyContext( rmesa->glCtx ); radeonDestroySwtcl( rmesa->glCtx ); - radeonReleaseArrays( rmesa->glCtx, ~0 ); if (rmesa->dma.current.buf) { radeonReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ ); @@ -598,69 +489,28 @@ radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) rmesa->state.scissor.pClipRects = 0; } - FREE( rmesa ); - } - -#if 0 - /* Use this to force shared object profiling. */ - glx_fini_prof(); -#endif -} - - -/* Initialize the driver specific screen private data. - */ -static GLboolean -radeonInitDriver( __DRIscreenPrivate *sPriv ) -{ - sPriv->private = (void *) radeonCreateScreen( sPriv ); - if ( !sPriv->private ) { - radeonDestroyScreen( sPriv ); - return GL_FALSE; - } + if ( release_texture_heaps ) { + /* This share group is about to go away, free our private + * texture object data. + */ + int i; - return GL_TRUE; -} + assert( is_empty_list( & rmesa->swapped ) ); + for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { + driDestroyTextureHeap( rmesa->texture_heaps[ i ] ); + rmesa->texture_heaps[ i ] = NULL; + } + } -/* Create and initialize the Mesa and driver specific pixmap buffer - * data. - */ -static GLboolean -radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, - __DRIdrawablePrivate *driDrawPriv, - const __GLcontextModes *mesaVis, - GLboolean isPixmap ) -{ - if (isPixmap) { - return GL_FALSE; /* not implemented */ - } - else { - const GLboolean swDepth = GL_FALSE; - const GLboolean swAlpha = GL_FALSE; - const GLboolean swAccum = mesaVis->accumRedBits > 0; - const GLboolean swStencil = mesaVis->stencilBits > 0 && - mesaVis->depthBits != 24; - driDrawPriv->driverPrivate = (void *) - _mesa_create_framebuffer( mesaVis, - swDepth, - swStencil, - swAccum, - swAlpha ); - return (driDrawPriv->driverPrivate != NULL); + FREE( rmesa ); } } -static void -radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) -{ - _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); -} - -static void +void radeonSwapBuffers( __DRIdrawablePrivate *dPriv ) { @@ -682,7 +532,7 @@ radeonSwapBuffers( __DRIdrawablePrivate *dPriv ) } else { /* XXX this shouldn't be an error but we can't handle it for now */ - _mesa_problem(NULL, "radeonSwapBuffers: drawable has no context!\n"); + _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__); } } @@ -690,39 +540,39 @@ radeonSwapBuffers( __DRIdrawablePrivate *dPriv ) /* Force the context `c' to be the current context and associate with it * buffer `b'. */ -static GLboolean +GLboolean radeonMakeCurrent( __DRIcontextPrivate *driContextPriv, __DRIdrawablePrivate *driDrawPriv, __DRIdrawablePrivate *driReadPriv ) { if ( driContextPriv ) { - radeonContextPtr newRadeonCtx = + radeonContextPtr newCtx = (radeonContextPtr) driContextPriv->driverPrivate; if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s ctx %p\n", __FUNCTION__, newRadeonCtx->glCtx); + fprintf(stderr, "%s ctx %p\n", __FUNCTION__, newCtx->glCtx); - if ( newRadeonCtx->dri.drawable != driDrawPriv ) { - newRadeonCtx->dri.drawable = driDrawPriv; - radeonUpdateWindow( newRadeonCtx->glCtx ); - radeonUpdateViewportOffset( newRadeonCtx->glCtx ); + if ( newCtx->dri.drawable != driDrawPriv ) { + newCtx->dri.drawable = driDrawPriv; + radeonUpdateWindow( newCtx->glCtx ); + radeonUpdateViewportOffset( newCtx->glCtx ); } - _mesa_make_current2( newRadeonCtx->glCtx, + _mesa_make_current2( newCtx->glCtx, (GLframebuffer *) driDrawPriv->driverPrivate, (GLframebuffer *) driReadPriv->driverPrivate ); - if ( !newRadeonCtx->glCtx->Viewport.Width ) { - _mesa_set_viewport( newRadeonCtx->glCtx, 0, 0, + if ( !newCtx->glCtx->Viewport.Width ) { + _mesa_set_viewport( newCtx->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h ); } - if (newRadeonCtx->vb.enabled) - radeonVtxfmtMakeCurrent( newRadeonCtx->glCtx ); + if (newCtx->vb.enabled) + radeonVtxfmtMakeCurrent( newCtx->glCtx ); } else { if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s ctx %p\n", __FUNCTION__, NULL); + fprintf(stderr, "%s ctx is null\n", __FUNCTION__); _mesa_make_current( 0, 0 ); } @@ -733,7 +583,7 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv, /* Force the context `c' to be unbound from its buffer. */ -static GLboolean +GLboolean radeonUnbindContext( __DRIcontextPrivate *driContextPriv ) { radeonContextPtr rmesa = (radeonContextPtr) driContextPriv->driverPrivate; @@ -743,55 +593,3 @@ radeonUnbindContext( __DRIcontextPrivate *driContextPriv ) return GL_TRUE; } - -/* Fullscreen mode isn't used for much -- could be a way to shrink - * front/back buffers & get more texture memory if the client has - * changed the video resolution. - * - * Pageflipping is now done automatically whenever there is a single - * 3d client. - */ -static GLboolean -radeonOpenCloseFullScreen( __DRIcontextPrivate *driContextPriv ) -{ - return GL_TRUE; -} - - - -void -__driRegisterExtensions( void ) -{ - /* See r200 driver for info */ -} - - - -static struct __DriverAPIRec radeonAPI = { - radeonInitDriver, - radeonDestroyScreen, - radeonCreateContext, - radeonDestroyContext, - radeonCreateBuffer, - radeonDestroyBuffer, - radeonSwapBuffers, - radeonMakeCurrent, - radeonUnbindContext, - radeonOpenCloseFullScreen, - radeonOpenCloseFullScreen -}; - - - -/* - * This is the bootstrap function for the driver. - * The __driCreateScreen name is the symbol that libGL.so fetches. - * Return: pointer to a __DRIscreenPrivate. - */ -void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, - int numConfigs, __GLXvisualConfig *config) -{ - __DRIscreenPrivate *psp; - psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &radeonAPI); - return (void *) psp; -} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h index 9cb5af9da..3e8816df2 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, VA LINUX SYSTEMS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ @@ -39,16 +40,22 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef GLX_DIRECT_RENDERING +#include <stdint.h> +#include "dri_util.h" +#include "radeon_common.h" +#include "texmem.h" + +#include "macros.h" +#include "mtypes.h" +#include "colormac.h" + struct radeon_context; typedef struct radeon_context radeonContextRec; typedef struct radeon_context *radeonContextPtr; -#include "mtypes.h" -#include "macros.h" #include "radeon_lock.h" #include "radeon_screen.h" #include "mm.h" -#include "colormac.h" /* Flags for software fallback cases */ /* See correponding strings in radeon_swtcl.c */ @@ -60,6 +67,10 @@ typedef struct radeon_context *radeonContextPtr; #define RADEON_FALLBACK_BLEND_FUNC 0x0020 #define RADEON_FALLBACK_DISABLE 0x0040 +/* The blit width for texture uploads + */ +#define BLIT_WIDTH_BYTES 1024 + /* Use the templated vertex format: */ #define COLOR_IS_RGBA @@ -124,18 +135,11 @@ typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr; /* Texture object in locally shared texture space. */ struct radeon_tex_obj { - radeonTexObjPtr next, prev; - - struct gl_texture_object *tObj; /* Mesa texture object */ + driTextureObject base; - PMemBlock memBlock; /* Memory block containing texture */ GLuint bufAddr; /* Offset to start of locally shared texture block */ - GLuint dirty_images; /* Flags for whether or not - images need to be uploaded to - local or AGP texture space */ - GLuint dirty_state; /* Flags (1 per texunit) for whether or not this texobj has dirty hardware state @@ -143,17 +147,17 @@ struct radeon_tex_obj { brought into the texunit. */ - GLint heap; /* Texture heap currently stored in */ - - drmRadeonTexImage image[RADEON_MAX_TEXTURE_LEVELS]; - - GLint totalSize; /* Total size of the texture - including all mipmap levels */ + drmRadeonTexImage image[6][RADEON_MAX_TEXTURE_LEVELS]; + /* Six, for the cube faces */ GLuint pp_txfilter; /* hardware register values */ GLuint pp_txformat; - GLuint pp_txoffset; + GLuint pp_txoffset; /* Image location in texmem. + All cube faces follow. */ + GLuint pp_txsize; /* npot only */ + GLuint pp_txpitch; /* npot only */ GLuint pp_border_color; + GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */ /* texObj->Image[firstLevel] through texObj->Image[lastLevel] are the * images to upload. @@ -187,8 +191,8 @@ struct radeon_state_atom { /* Trying to keep these relatively short as the variables are becoming - * extravagently long. Drop the RADEON_ off the front of everything - - * I think we know we're in the radeon driver by now, and keep the + * extravagently long. Drop the driver name prefix off the front of + * everything - I think we know which driver we're in by now, and keep the * prefix to 3 letters unless absolutely impossible. */ @@ -429,15 +433,6 @@ struct radeon_state { struct radeon_texture_state texture; }; -struct radeon_texture { - radeonTexObj objects[RADEON_NR_TEX_HEAPS]; - radeonTexObj swapped; - - memHeap_t *heap[RADEON_NR_TEX_HEAPS]; - GLint age[RADEON_NR_TEX_HEAPS]; - - GLint numHeaps; -}; /* Need refcounting on dma buffers: */ @@ -658,7 +653,7 @@ struct radeon_vbinfo { GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */ GLuint primflags; - GLboolean enabled; /* RADEON_NO_VTXFMT//RADEON_NO_TCL env vars */ + GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */ GLboolean installed; GLboolean fell_back; GLboolean recheck; @@ -689,7 +684,9 @@ struct radeon_context { /* Texture object bookkeeping */ - struct radeon_texture texture; + unsigned nr_heaps; + driTexHeap * texture_heaps[ RADEON_NR_TEX_HEAPS ]; + driTextureObject swapped; /* Rasterization and vertex state: @@ -743,6 +740,15 @@ struct radeon_context { /* VBI */ GLuint vbl_seq; + GLuint vblank_flags; + + uint64_t swap_ust; + uint64_t swap_missed_ust; + + GLuint swap_count; + GLuint swap_missed_count; + + PFNGLXGETUSTPROC get_ust; /* radeon_tcl.c */ @@ -791,6 +797,17 @@ static __inline GLuint radeonPackColor( GLuint cpp, #define RADEON_OLD_PACKETS 1 + +extern void radeonDestroyContext( __DRIcontextPrivate *driContextPriv ); +extern GLboolean radeonCreateContext(const __GLcontextModes *glVisual, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate); +extern void radeonSwapBuffers( __DRIdrawablePrivate *dPriv ); +extern GLboolean radeonMakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ); +extern GLboolean radeonUnbindContext( __DRIcontextPrivate *driContextPriv ); + /* ================================================================ * Debugging: */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c index fd2991787..c1d35767b 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, VA LINUX SYSTEMS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ @@ -32,7 +33,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> * Keith Whitwell <keith@tungstengraphics.com> - * */ #include "glheader.h" @@ -48,19 +48,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_macros.h" /* for INREG() */ -#undef usleep -#include <unistd.h> /* for usleep() */ +#include "vblank.h" #define RADEON_TIMEOUT 512 #define RADEON_IDLE_RETRY 16 -static void do_usleep( int nr, const char *caller ) -{ - if (0) fprintf(stderr, "usleep %d in %s\n", nr, caller ); - if (1) usleep( nr ); -} - static void radeonWaitForIdle( radeonContextPtr rmesa ); /* ============================================================= @@ -426,8 +419,13 @@ static int radeonFlushCmdBufLocked( radeonContextPtr rmesa, ret = radeonSanityCmdBuffer( rmesa, rmesa->numClipRects, rmesa->pClipRects); + if (ret) { + fprintf(stderr, "drmSanityCommandWrite: %d\n", ret); + goto out; + } } + cmd.bufsz = rmesa->store.cmd_used; cmd.buf = rmesa->store.cmd_buf; @@ -443,6 +441,10 @@ static int radeonFlushCmdBufLocked( radeonContextPtr rmesa, DRM_RADEON_CMDBUF, &cmd, sizeof(cmd) ); + if (ret) + fprintf(stderr, "drmCommandWrite: %d\n", ret); + + out: rmesa->store.primnr = 0; rmesa->store.statenr = 0; rmesa->store.cmd_used = 0; @@ -469,7 +471,7 @@ void radeonFlushCmdBuf( radeonContextPtr rmesa, const char *caller ) UNLOCK_HARDWARE( rmesa ); if (ret) { - fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret); + fprintf(stderr, "drmRadeonCmdBuffer: %d (exiting)\n", ret); exit(ret); } } @@ -727,7 +729,7 @@ static void radeonWaitForFrameCompletion( radeonContextPtr rmesa ) while (radeonGetLastFrame (rmesa) < sarea->last_frame) { UNLOCK_HARDWARE( rmesa ); if (rmesa->do_usleeps) - do_usleep(1, __FUNCTION__); + DO_USLEEP( 1 ); LOCK_HARDWARE( rmesa ); } } @@ -739,6 +741,8 @@ void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv ) { radeonContextPtr rmesa; GLint nbox, i, ret; + GLboolean missed_target; + int64_t ust; assert(dPriv); assert(dPriv->driContextPriv); @@ -751,15 +755,15 @@ void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv ) } RADEON_FIREVERTICES( rmesa ); - LOCK_HARDWARE( rmesa ); - /* Throttle the frame rate -- only allow one pending swap buffers * request at a time. */ radeonWaitForFrameCompletion( rmesa ); - radeonWaitForVBlank( rmesa ); + UNLOCK_HARDWARE( rmesa ); + driWaitForVBlank( & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target ); + LOCK_HARDWARE( rmesa ); nbox = rmesa->dri.drawable->numClipRects; /* must be in locked region */ @@ -785,12 +789,21 @@ void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv ) } UNLOCK_HARDWARE( rmesa ); + rmesa->swap_count++; + (*rmesa->get_ust)( & ust ); + if ( missed_target ) { + rmesa->swap_missed_count++; + rmesa->swap_missed_ust = ust - rmesa->swap_ust; + } + + rmesa->swap_ust = ust; } void radeonPageFlip( const __DRIdrawablePrivate *dPriv ) { radeonContextPtr rmesa; GLint ret; + GLboolean missed_target; assert(dPriv); assert(dPriv->driContextPriv); @@ -799,12 +812,11 @@ void radeonPageFlip( const __DRIdrawablePrivate *dPriv ) rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; if ( RADEON_DEBUG & DEBUG_IOCTL ) { - fprintf(stderr, "%s %d\n", __FUNCTION__, - rmesa->sarea->pfCurrentPage ); + fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, + rmesa->sarea->pfCurrentPage); } RADEON_FIREVERTICES( rmesa ); - LOCK_HARDWARE( rmesa ); /* Need to do this for the perf box placement: @@ -817,12 +829,17 @@ void radeonPageFlip( const __DRIdrawablePrivate *dPriv ) rmesa->sarea->nbox = 1; } - - /* Throttle the frame rate -- only allow one pending swap buffers + /* Throttle the frame rate -- only allow a few pending swap buffers * request at a time. */ radeonWaitForFrameCompletion( rmesa ); - radeonWaitForVBlank( rmesa ); + UNLOCK_HARDWARE( rmesa ); + driWaitForVBlank( & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target ); + if ( missed_target ) { + rmesa->swap_missed_count++; + (void) (*rmesa->get_ust)( & rmesa->swap_missed_ust ); + } + LOCK_HARDWARE( rmesa ); ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP ); @@ -833,6 +850,9 @@ void radeonPageFlip( const __DRIdrawablePrivate *dPriv ) exit( 1 ); } + rmesa->swap_count++; + (void) (*rmesa->get_ust)( & rmesa->swap_ust ); + if ( rmesa->sarea->pfCurrentPage == 1 ) { rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset; rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch; @@ -950,7 +970,7 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean all, if ( rmesa->do_usleeps ) { UNLOCK_HARDWARE( rmesa ); - do_usleep(1, __FUNCTION__); + DO_USLEEP( 1 ); LOCK_HARDWARE( rmesa ); } } @@ -1037,14 +1057,6 @@ void radeonWaitForIdleLocked( radeonContextPtr rmesa ) do { ret = drmCommandNone( fd, DRM_RADEON_CP_IDLE); } while ( ret && errno == EBUSY && i++ < RADEON_IDLE_RETRY ); - if (ret && ret != -EBUSY) { - /* - * JO - I'm reluctant to print this message while holding the lock - * - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "%s: CP idle %d\n", __FUNCTION__, ret); - */ - } } while ( ( ret == -EBUSY ) && ( to++ < RADEON_TIMEOUT ) ); if ( ret < 0 ) { @@ -1057,47 +1069,12 @@ void radeonWaitForIdleLocked( radeonContextPtr rmesa ) static void radeonWaitForIdle( radeonContextPtr rmesa ) { - LOCK_HARDWARE(rmesa); - radeonWaitForIdleLocked( rmesa ); - UNLOCK_HARDWARE(rmesa); + LOCK_HARDWARE(rmesa); + radeonWaitForIdleLocked( rmesa ); + UNLOCK_HARDWARE(rmesa); } -void radeonWaitForVBlank( radeonContextPtr rmesa ) -{ - drmVBlank vbl; - int ret; - - if ( !rmesa->radeonScreen->irq ) - return; - - if ( getenv("LIBGL_SYNC_REFRESH") ) { - /* Wait for until the next vertical blank */ - vbl.request.type = DRM_VBLANK_RELATIVE; - vbl.request.sequence = 1; - } else if ( getenv("LIBGL_THROTTLE_REFRESH") ) { - /* Wait for at least one vertical blank since the last call */ - vbl.request.type = DRM_VBLANK_ABSOLUTE; - vbl.request.sequence = rmesa->vbl_seq + 1; - } else { - return; - } - - UNLOCK_HARDWARE( rmesa ); - - if ((ret = drmWaitVBlank( rmesa->dri.fd, &vbl ))) { - fprintf(stderr, "%s: drmWaitVBlank returned %d, IRQs don't seem to be" - " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH" - " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret); - exit(1); - } else if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s: drmWaitVBlank returned %d\n", __FUNCTION__, ret); - - rmesa->vbl_seq = vbl.reply.sequence; - - LOCK_HARDWARE( rmesa ); -} - void radeonFlush( GLcontext *ctx ) { radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h index 8777ae278..f53b3efe9 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, VA LINUX SYSTEMS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ @@ -31,7 +32,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Authors: * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> - * */ #ifndef __RADEON_IOCTL_H__ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c index 630c80a4f..96a4f9d11 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, VA LINUX SYSTEMS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ @@ -31,7 +32,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Authors: * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> - * */ #include "glheader.h" @@ -94,7 +94,6 @@ void radeonGetLock( radeonContextPtr rmesa, GLuint flags ) __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; __DRIscreenPrivate *sPriv = rmesa->dri.screen; RADEONSAREAPrivPtr sarea = rmesa->sarea; - int i; drmGetLock( rmesa->dri.fd, rmesa->dri.hwContext, flags ); @@ -119,12 +118,11 @@ void radeonGetLock( radeonContextPtr rmesa, GLuint flags ) } if ( sarea->ctxOwner != rmesa->dri.hwContext ) { + int i; sarea->ctxOwner = rmesa->dri.hwContext; - for ( i = 0 ; i < rmesa->texture.numHeaps ; i++ ) { - if ( rmesa->texture.heap[i] && sarea->texAge[i] != rmesa->texture.age[i] ) { - radeonAgeTextures( rmesa, i ); - } + for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { + DRI_AGE_TEXTURES( rmesa->texture_heaps[ i ] ); } } } diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h index 5402df83c..783db7e92 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, VA LINUX SYSTEMS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ @@ -31,7 +32,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Authors: * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> - * */ #ifndef __RADEON_LOCK_H__ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_maos.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos.h index 6f31969fd..7e2bd643d 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_maos.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos.h @@ -6,31 +6,31 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, TUNGSTEN GRAHPICS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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: * Keith Whitwell <keith@tungstengraphics.com> - * */ #ifndef __RADEON_MAOS_H__ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_arrays.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_arrays.c index c01425892..cec05a89d 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_arrays.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_arrays.c @@ -6,36 +6,37 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, TUNGSTEN GRAPHICS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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: * Keith Whitwell <keith@tungstengraphics.com> - * */ #include "glheader.h" #include "imports.h" #include "mtypes.h" +#include "mmath.h" #include "macros.h" #include "swrast_setup/swrast_setup.h" @@ -260,7 +261,8 @@ static void emit_vector( GLcontext *ctx, radeonContextPtr rmesa = RADEON_CONTEXT(ctx); if (RADEON_DEBUG & DEBUG_VERTS) - fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size); + fprintf(stderr, "%s count %d size %d stride %d\n", + __FUNCTION__, count, size, stride); assert (!rvb->buf); @@ -481,7 +483,6 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs ) emitsize = 3; } - if (!rmesa->tcl.rgba.buf) emit_vector( ctx, &(rmesa->tcl.rgba), diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_verts.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_verts.c index 671133a8b..39b1f5750 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_verts.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_maos_verts.c @@ -6,31 +6,31 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, TUNGSTEN GRAPHICS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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: * Keith Whitwell <keith@tungstengraphics.com> - * */ #include "glheader.h" diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_sanity.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_sanity.c index e5b97d2c9..39a18955e 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_sanity.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_sanity.c @@ -601,16 +601,16 @@ static int print_vertex_format( int vfmt ) static char *primname[0xf] = { "NONE", - "POINT", - "LINE", + "POINTS", + "LINES", "LINE_STRIP", - "TRI_LIST", - "TRI_FAN", - "TRI_STRIP", + "TRIANGLES", + "TRIANGLE_FAN", + "TRIANGLE_STRIP", "TRI_TYPE_2", "RECT_LIST", - "3VRT_POINT_LIST", - "3VRT_LINE_LIST", + "3VRT_POINTS", + "3VRT_LINES", }; static int print_prim_and_flags( int prim ) diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c index 74b058660..65ef74d35 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, VA LINUX SYSTEMS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ @@ -37,8 +38,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "glheader.h" #include "imports.h" +#include "radeon_context.h" #include "radeon_screen.h" +#include "radeon_macros.h" +#include "utils.h" +#include "context.h" +#include "vblank.h" + +#include "glxextensions.h" #if 1 /* Including xf86PciInfo.h introduces a bunch of errors... @@ -56,51 +64,25 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define PCI_CHIP_RADEON_LY 0x4C59 #define PCI_CHIP_RADEON_LZ 0x4C5A -#define PCI_CHIP_RV200_QW 0x5157 /* a confusing name for a radeon */ +#define PCI_CHIP_RV200_QW 0x5157 /* Radeon 7500 - not an R200 at all */ #endif +static int get_MSC( __DRIscreenPrivate * priv, int64_t * count ); /* Create the device specific screen private data struct. */ radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ) { - radeonScreenPtr radeonScreen; - RADEONDRIPtr radeonDRIPriv = (RADEONDRIPtr)sPriv->pDevPriv; - - /* Check the DRI extension version */ - if ( sPriv->driMajor != 4 || sPriv->driMinor < 0 ) { - __driUtilMessage( "Radeon DRI driver expected DRI version 4.0.x " - "but got version %d.%d.%d", - sPriv->driMajor, sPriv->driMinor, sPriv->driPatch ); - return NULL; - } + radeonScreenPtr screen; + RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv; - /* Check that the DDX driver version is compatible */ - if ( sPriv->ddxMajor != 4 || - sPriv->ddxMinor < 0 ) { - __driUtilMessage( "Radeon DRI driver expected DDX driver version 4.0.x " - "but got version %d.%d.%d", - sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); + if ( ! driCheckDriDdxDrmVersions( sPriv, "Radeon", 4, 0, 4, 0, 1, 3 ) ) return NULL; - } - - /* Check that the DRM driver version is compatible */ - /* KW: Check minor number here too -- compatibility mode is broken - * atm. - */ - if ( sPriv->drmMajor != 1 || - sPriv->drmMinor < 3) { - __driUtilMessage( "Radeon DRI driver expected DRM driver version 1.3.x " - "or newer but got version %d.%d.%d", - sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); - return NULL; - } - /* Allocate the private area */ - radeonScreen = (radeonScreenPtr) CALLOC( sizeof(*radeonScreen) ); - if ( !radeonScreen ) { - __driUtilMessage("%s: CALLOC radeonScreen struct failed", + screen = (radeonScreenPtr) CALLOC( sizeof(*screen) ); + if ( !screen ) { + __driUtilMessage("%s: Could not allocate memory for screen structure", __FUNCTION__); return NULL; } @@ -118,90 +100,88 @@ radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ) /* This is first since which regions we map depends on whether or * not we are using a PCI card. */ - radeonScreen->IsPCI = radeonDRIPriv->IsPCI; + screen->IsPCI = dri_priv->IsPCI; if (sPriv->drmMinor >= 3) { int ret; drmRadeonGetParam gp; gp.param = RADEON_PARAM_AGP_BUFFER_OFFSET; - gp.value = &radeonScreen->agp_buffer_offset; + gp.value = &screen->agp_buffer_offset; ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); if (ret) { - FREE( radeonScreen ); fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_AGP_BUFFER_OFFSET): %d\n", ret); return NULL; } if (sPriv->drmMinor >= 6) { gp.param = RADEON_PARAM_IRQ_NR; - gp.value = &radeonScreen->irq; + gp.value = &screen->irq; ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); if (ret) { - FREE( radeonScreen ); + FREE( screen ); fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n", ret); return NULL; } } - } - radeonScreen->mmio.handle = radeonDRIPriv->registerHandle; - radeonScreen->mmio.size = radeonDRIPriv->registerSize; + screen->mmio.handle = dri_priv->registerHandle; + screen->mmio.size = dri_priv->registerSize; if ( drmMap( sPriv->fd, - radeonScreen->mmio.handle, - radeonScreen->mmio.size, - &radeonScreen->mmio.map ) ) { - FREE( radeonScreen ); - __driUtilMessage("radeonCreateScreen(): drmMap failed\n"); + screen->mmio.handle, + screen->mmio.size, + &screen->mmio.map ) ) { + FREE( screen ); + __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ ); return NULL; } - radeonScreen->status.handle = radeonDRIPriv->statusHandle; - radeonScreen->status.size = radeonDRIPriv->statusSize; + screen->status.handle = dri_priv->statusHandle; + screen->status.size = dri_priv->statusSize; if ( drmMap( sPriv->fd, - radeonScreen->status.handle, - radeonScreen->status.size, - &radeonScreen->status.map ) ) { - drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size ); - FREE( radeonScreen ); - __driUtilMessage("radeonCreateScreen(): drmMap (2) failed\n"); + screen->status.handle, + screen->status.size, + &screen->status.map ) ) { + drmUnmap( screen->mmio.map, screen->mmio.size ); + FREE( screen ); + __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ ); return NULL; } - radeonScreen->scratch = (__volatile__ CARD32 *) - ((GLubyte *)radeonScreen->status.map + RADEON_SCRATCH_REG_OFFSET); - - radeonScreen->buffers = drmMapBufs( sPriv->fd ); - if ( !radeonScreen->buffers ) { - drmUnmap( radeonScreen->status.map, radeonScreen->status.size ); - drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size ); - FREE( radeonScreen ); - __driUtilMessage("radeonCreateScreen(): drmMapBufs failed\n"); + screen->scratch = (__volatile__ CARD32 *) + ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET); + + screen->buffers = drmMapBufs( sPriv->fd ); + if ( !screen->buffers ) { + drmUnmap( screen->status.map, screen->status.size ); + drmUnmap( screen->mmio.map, screen->mmio.size ); + FREE( screen ); + __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ ); return NULL; } - if ( !radeonScreen->IsPCI ) { - radeonScreen->agpTextures.handle = radeonDRIPriv->agpTexHandle; - radeonScreen->agpTextures.size = radeonDRIPriv->agpTexMapSize; + if ( !screen->IsPCI ) { + screen->agpTextures.handle = dri_priv->agpTexHandle; + screen->agpTextures.size = dri_priv->agpTexMapSize; if ( drmMap( sPriv->fd, - radeonScreen->agpTextures.handle, - radeonScreen->agpTextures.size, - (drmAddressPtr)&radeonScreen->agpTextures.map ) ) { - drmUnmapBufs( radeonScreen->buffers ); - drmUnmap( radeonScreen->status.map, radeonScreen->status.size ); - drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size ); - FREE( radeonScreen ); - __driUtilMessage("radeonCreateScreen(): IsPCI failed\n"); + screen->agpTextures.handle, + screen->agpTextures.size, + (drmAddressPtr)&screen->agpTextures.map ) ) { + drmUnmapBufs( screen->buffers ); + drmUnmap( screen->status.map, screen->status.size ); + drmUnmap( screen->mmio.map, screen->mmio.size ); + FREE( screen ); + __driUtilMessage("%s: IsPCI failed\n", __FUNCTION__); return NULL; } } - radeonScreen->chipset = 0; - switch ( radeonDRIPriv->deviceID ) { + screen->chipset = 0; + switch ( dri_priv->deviceID ) { default: fprintf(stderr, "unknown chip id, assuming full radeon support\n"); case PCI_CHIP_RADEON_QD: @@ -210,7 +190,7 @@ radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ) case PCI_CHIP_RADEON_QG: case PCI_CHIP_RV200_QW: case PCI_CHIP_RADEON_LW: - radeonScreen->chipset |= RADEON_CHIPSET_TCL; + screen->chipset |= RADEON_CHIPSET_TCL; case PCI_CHIP_RADEON_QY: case PCI_CHIP_RADEON_QZ: case PCI_CHIP_RADEON_LY: @@ -218,57 +198,230 @@ radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ) break; } - radeonScreen->cpp = radeonDRIPriv->bpp / 8; - radeonScreen->AGPMode = radeonDRIPriv->AGPMode; - - radeonScreen->frontOffset = radeonDRIPriv->frontOffset; - radeonScreen->frontPitch = radeonDRIPriv->frontPitch; - radeonScreen->backOffset = radeonDRIPriv->backOffset; - radeonScreen->backPitch = radeonDRIPriv->backPitch; - radeonScreen->depthOffset = radeonDRIPriv->depthOffset; - radeonScreen->depthPitch = radeonDRIPriv->depthPitch; - - radeonScreen->texOffset[RADEON_CARD_HEAP] = radeonDRIPriv->textureOffset; - radeonScreen->texSize[RADEON_CARD_HEAP] = radeonDRIPriv->textureSize; - radeonScreen->logTexGranularity[RADEON_CARD_HEAP] = - radeonDRIPriv->log2TexGran; - - if ( radeonScreen->IsPCI ) { - radeonScreen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1; - radeonScreen->texOffset[RADEON_AGP_HEAP] = 0; - radeonScreen->texSize[RADEON_AGP_HEAP] = 0; - radeonScreen->logTexGranularity[RADEON_AGP_HEAP] = 0; + screen->cpp = dri_priv->bpp / 8; + screen->AGPMode = dri_priv->AGPMode; + + screen->frontOffset = dri_priv->frontOffset; + screen->frontPitch = dri_priv->frontPitch; + screen->backOffset = dri_priv->backOffset; + screen->backPitch = dri_priv->backPitch; + screen->depthOffset = dri_priv->depthOffset; + screen->depthPitch = dri_priv->depthPitch; + + screen->texOffset[RADEON_CARD_HEAP] = dri_priv->textureOffset; + screen->texSize[RADEON_CARD_HEAP] = dri_priv->textureSize; + screen->logTexGranularity[RADEON_CARD_HEAP] = + dri_priv->log2TexGran; + + if ( screen->IsPCI + || getenv( "RADEON_AGPTEXTURING_FORCE_DISABLE" ) ) { + screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1; + screen->texOffset[RADEON_AGP_HEAP] = 0; + screen->texSize[RADEON_AGP_HEAP] = 0; + screen->logTexGranularity[RADEON_AGP_HEAP] = 0; } else { - radeonScreen->numTexHeaps = RADEON_NR_TEX_HEAPS; - radeonScreen->texOffset[RADEON_AGP_HEAP] = - radeonDRIPriv->agpTexOffset + RADEON_AGP_TEX_OFFSET; - radeonScreen->texSize[RADEON_AGP_HEAP] = radeonDRIPriv->agpTexMapSize; - radeonScreen->logTexGranularity[RADEON_AGP_HEAP] = - radeonDRIPriv->log2AGPTexGran; + screen->numTexHeaps = RADEON_NR_TEX_HEAPS; + screen->texOffset[RADEON_AGP_HEAP] = + dri_priv->agpTexOffset + RADEON_AGP_TEX_OFFSET; + screen->texSize[RADEON_AGP_HEAP] = dri_priv->agpTexMapSize; + screen->logTexGranularity[RADEON_AGP_HEAP] = + dri_priv->log2AGPTexGran; } - radeonScreen->driScreen = sPriv; - radeonScreen->sarea_priv_offset = radeonDRIPriv->sarea_priv_offset; - return radeonScreen; + screen->driScreen = sPriv; + screen->sarea_priv_offset = dri_priv->sarea_priv_offset; + return screen; } /* Destroy the device specific screen private data struct. */ void radeonDestroyScreen( __DRIscreenPrivate *sPriv ) { - radeonScreenPtr radeonScreen = (radeonScreenPtr)sPriv->private; + radeonScreenPtr screen = (radeonScreenPtr)sPriv->private; - if (!radeonScreen) + if (!screen) return; - if ( !radeonScreen->IsPCI ) { - drmUnmap( radeonScreen->agpTextures.map, - radeonScreen->agpTextures.size ); + if ( !screen->IsPCI ) { + drmUnmap( screen->agpTextures.map, + screen->agpTextures.size ); } - drmUnmapBufs( radeonScreen->buffers ); - drmUnmap( radeonScreen->status.map, radeonScreen->status.size ); - drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size ); + drmUnmapBufs( screen->buffers ); + drmUnmap( screen->status.map, screen->status.size ); + drmUnmap( screen->mmio.map, screen->mmio.size ); - FREE( radeonScreen ); + FREE( screen ); sPriv->private = NULL; } + + +/* Initialize the driver specific screen private data. + */ +static GLboolean +radeonInitDriver( __DRIscreenPrivate *sPriv ) +{ + sPriv->private = (void *) radeonCreateScreen( sPriv ); + if ( !sPriv->private ) { + radeonDestroyScreen( sPriv ); + return GL_FALSE; + } + + return GL_TRUE; +} + + + +/* Create and initialize the Mesa and driver specific pixmap buffer + * data. + */ +static GLboolean +radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + const __GLcontextModes *mesaVis, + GLboolean isPixmap ) +{ + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + const GLboolean swDepth = GL_FALSE; + const GLboolean swAlpha = GL_FALSE; + const GLboolean swAccum = mesaVis->accumRedBits > 0; + const GLboolean swStencil = mesaVis->stencilBits > 0 && + mesaVis->depthBits != 24; + driDrawPriv->driverPrivate = (void *) + _mesa_create_framebuffer( mesaVis, + swDepth, + swStencil, + swAccum, + swAlpha ); + return (driDrawPriv->driverPrivate != NULL); + } +} + + +static void +radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +{ + _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); +} + + + + +/* Fullscreen mode isn't used for much -- could be a way to shrink + * front/back buffers & get more texture memory if the client has + * changed the video resolution. + * + * Pageflipping is now done automatically whenever there is a single + * 3d client. + */ +static GLboolean +radeonOpenCloseFullScreen( __DRIcontextPrivate *driContextPriv ) +{ + return GL_TRUE; +} + +static struct __DriverAPIRec radeonAPI = { + radeonInitDriver, + radeonDestroyScreen, + radeonCreateContext, + radeonDestroyContext, + radeonCreateBuffer, + radeonDestroyBuffer, + radeonSwapBuffers, + radeonMakeCurrent, + radeonUnbindContext, + radeonOpenCloseFullScreen, + radeonOpenCloseFullScreen, + + .GetMSC = get_MSC, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL +}; + + + +/* + * This is the bootstrap function for the driver. + * The __driCreateScreen name is the symbol that libGL.so fetches. + * Return: pointer to a __DRIscreenPrivate. + */ +void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, + int numConfigs, __GLXvisualConfig *config) +{ + __DRIscreenPrivate *psp; + psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &radeonAPI); + return (void *) psp; +} + + +/* This function is called by libGL.so as soon as libGL.so is loaded. + * This is where we'd register new extension functions with the dispatcher. + */ +void +__driRegisterExtensions( void ) +{ + PFNGLXENABLEEXTENSIONPROC glx_enable_extension; + + + if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) { + glx_enable_extension = (PFNGLXENABLEEXTENSIONPROC) + glXGetProcAddress( "__glXEnableExtension" ); + + if ( glx_enable_extension != NULL ) { + glx_enable_extension( "GLX_SGI_swap_control", GL_FALSE ); + glx_enable_extension( "GLX_SGI_video_sync", GL_FALSE ); + glx_enable_extension( "GLX_MESA_swap_control", GL_FALSE ); + } + } +} + + + + +/** + * Get the current MSC. + * + * Stores the 64-bit count of vertical refreshes since some (arbitrary) + * point in time in \c count. Unless the value wraps around, which it + * may, it will never decrease. + * + * \param priv Pointer to the private screen structure. + * \param count Storage to hold the MSC. + * \return Zero is returned on success. A negative errno value + * is returned on failure. + */ +static int +get_MSC( __DRIscreenPrivate * priv, int64_t * count ) +{ + drmRadeonGetParam gp; + int frame; + int ret; + + if ( priv->drmMinor >= 4 ) { + gp.param = RADEON_PARAM_LAST_FRAME; + gp.value = &frame; + ret = drmCommandWriteRead( priv->fd, DRM_RADEON_GETPARAM, + &gp, sizeof(gp) ); + } + else { + ret = -EINVAL; + } + +#if 0 + if ( ret == -EINVAL ) { + unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map; + + frame = INREG( RADEON_LAST_FRAME_REG ); + ret = 0; + } +#endif + + if ( ret == 0 ) { + *count = frame; + } + + return ret; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h index 12cecd0dc..2c69d8657 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, VA LINUX SYSTEMS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ @@ -31,7 +32,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Authors: * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> - * */ #ifndef __RADEON_SCREEN_H__ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c index 1db2ac776..029d7cd8e 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, VA LINUX SYSTEMS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ @@ -151,22 +152,27 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define INIT_MONO_PIXEL(p, color) \ p = PACK_COLOR_8888( color[3], color[0], color[1], color[2] ) -#define WRITE_RGBA( _x, _y, r, g, b, a ) \ - *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \ - (g << 8) | \ - (r << 16) | \ - (a << 24) ) +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ +do { \ + *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \ + (g << 8) | \ + (r << 16) | \ + (a << 24) ); \ +} while (0) -#define WRITE_PIXEL( _x, _y, p ) \ - *(GLuint *)(buf + _x*4 + _y*pitch) = p +#define WRITE_PIXEL( _x, _y, p ) \ +do { \ + *(GLuint *)(buf + _x*4 + _y*pitch) = p; \ +} while (0) -#define READ_RGBA( rgba, _x, _y ) \ -do { \ - GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \ - rgba[0] = (p >> 16) & 0xff; \ - rgba[1] = (p >> 8) & 0xff; \ - rgba[2] = (p >> 0) & 0xff; \ - rgba[3] = (p >> 24) & 0xff; \ +#define READ_RGBA( rgba, _x, _y ) \ +do { \ + volatile GLuint *ptr = (volatile GLuint *)(read_buf + _x*4 + _y*pitch); \ + GLuint p = *ptr; \ + rgba[0] = (p >> 16) & 0xff; \ + rgba[1] = (p >> 8) & 0xff; \ + rgba[2] = (p >> 0) & 0xff; \ + rgba[3] = (p >> 24) & 0xff; \ } while (0) #define TAG(x) radeon##x##_ARGB8888 @@ -178,37 +184,17 @@ do { \ * Depth buffer */ -/* The Radeon has depth tiling on all the time, so we have to convert +/* The Radeon family has depth tiling on all the time, so we have to convert * the x,y coordinates into the memory bus address (mba) in the same * manner as the engine. In each case, the linear block address (ba) * is calculated, and then wired with x and y to produce the final * memory address. */ -static __inline GLuint radeon_mba_z16( radeonContextPtr rmesa, - GLint x, GLint y ) -{ - radeonScreenPtr radeonScreen = rmesa->radeonScreen; - GLuint pitch = radeonScreen->frontPitch; - GLuint ba, address = 0; /* a[0] = 0 */ - - ba = (y / 16) * (pitch / 32) + (x / 32); - - address |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */ - address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */ - address |= (x & 0x8) << 4; /* a[7] = x[3] */ - address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ - address |= (y & 0x8) << 7; /* a[10] = y[3] */ - address |= ((x & 0x10) ^ (y & 0x10)) << 7; /* a[11] = x[4] ^ y[4] */ - address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ - - return address; -} static GLuint radeon_mba_z32( radeonContextPtr rmesa, GLint x, GLint y ) { - radeonScreenPtr radeonScreen = rmesa->radeonScreen; - GLuint pitch = radeonScreen->frontPitch; + GLuint pitch = rmesa->radeonScreen->frontPitch; GLuint ba, address = 0; /* a[0..1] = 0 */ ba = (y / 16) * (pitch / 16) + (x / 16); @@ -227,6 +213,24 @@ static GLuint radeon_mba_z32( radeonContextPtr rmesa, return address; } +static __inline GLuint radeon_mba_z16( radeonContextPtr rmesa, GLint x, GLint y ) +{ + GLuint pitch = rmesa->radeonScreen->frontPitch; + GLuint ba, address = 0; /* a[0] = 0 */ + + ba = (y / 16) * (pitch / 32) + (x / 32); + + address |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */ + address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */ + address |= (x & 0x8) << 4; /* a[7] = x[3] */ + address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ + address |= (y & 0x8) << 7; /* a[10] = y[3] */ + address |= ((x & 0x10) ^ (y & 0x10)) << 7; /* a[11] = x[4] ^ y[4] */ + address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ + + return address; +} + /* 16-bit depth buffer functions */ @@ -337,6 +341,7 @@ static void radeonSetBuffer( GLcontext *ctx, static void radeonSpanRenderStart( GLcontext *ctx ) { radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + RADEON_FIREVERTICES( rmesa ); LOCK_HARDWARE( rmesa ); radeonWaitForIdleLocked( rmesa ); diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h index b4c9cf585..011e8eff5 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, VA LINUX SYSTEMS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ @@ -31,7 +32,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Authors: * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> - * */ #ifndef __RADEON_SPAN_H__ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c index 78401cd30..dd8774f5d 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c @@ -1,31 +1,36 @@ /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v 1.8 2002/12/16 16:18:58 dawes Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. + +**************************************************************************/ + /* - * Copyright 2000, 2001 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 - * 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 - * VA LINUX SYSTEMS AND/OR ITS 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> - * Keith Whitwell <keith@tungstengraphics.com> + * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> */ #include "glheader.h" @@ -33,8 +38,6 @@ #include "api_arrayelt.h" #include "enums.h" #include "colormac.h" -#include "light.h" -#include "api_arrayelt.h" #include "swrast/swrast.h" #include "array_cache/acache.h" @@ -42,7 +45,6 @@ #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" - #include "radeon_context.h" #include "radeon_ioctl.h" #include "radeon_state.h" @@ -51,15 +53,6 @@ #include "radeon_swtcl.h" #include "radeon_vtxfmt.h" - -#define MODEL_PROJ 0 -#define MODEL 1 -#define MODEL_IT 2 -#define TEXMAT_0 3 -#define TEXMAT_1 4 -#define TEXMAT_2 5 - - /* ============================================================= * Alpha blending */ @@ -187,6 +180,8 @@ static void radeonBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) case GL_ONE_MINUS_CONSTANT_ALPHA: fallback = GL_TRUE; break; + default: + break; } switch ( ctx->Color.BlendDstRGB ) { @@ -226,6 +221,8 @@ static void radeonBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) case GL_ONE_MINUS_CONSTANT_ALPHA: fallback = GL_TRUE; break; + default: + break; } FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, fallback ); @@ -687,61 +684,60 @@ static void radeonUpdateSpecular( GLcontext *ctx ) radeonContextPtr rmesa = RADEON_CONTEXT(ctx); CARD32 p = rmesa->hw.ctx.cmd[CTX_PP_CNTL]; - if ( ctx->_TriangleCaps & DD_SEPARATE_SPECULAR ) { - p |= RADEON_SPECULAR_ENABLE; - } else { - p &= ~RADEON_SPECULAR_ENABLE; - } + RADEON_STATECHANGE( rmesa, tcl ); - if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) { - RADEON_STATECHANGE( rmesa, ctx ); - rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p; - } + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_DIFFUSE; + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE; - /* Bizzare: have to leave lighting enabled to get fog. - */ - RADEON_STATECHANGE( rmesa, tcl ); - if ((ctx->Light.Enabled && - ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { + p &= ~RADEON_SPECULAR_ENABLE; + + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_DIFFUSE_SPECULAR_COMBINE; + + + if (ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) { rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; - } - else if (ctx->Fog.Enabled) { - if (ctx->Light.Enabled) { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; - } else { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; - } + p |= RADEON_SPECULAR_ENABLE; + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= + ~RADEON_DIFFUSE_SPECULAR_COMBINE; } else if (ctx->Light.Enabled) { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; } else if (ctx->Fog.ColorSumEnabled ) { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE; + p |= RADEON_SPECULAR_ENABLE; } else { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE; + } + + if (ctx->Fog.Enabled) { + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; + + /* Bizzare: have to leave lighting enabled to get fog. + */ + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; + } + + if ( ctx->_TriangleCaps & DD_SEPARATE_SPECULAR ) { + assert( (p & RADEON_SPECULAR_ENABLE) != 0 ); + } else { + assert( (p & RADEON_SPECULAR_ENABLE) == 0 ); + } + + if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) { + RADEON_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p; } /* Update vertex/render formats @@ -1001,7 +997,6 @@ static void update_light( GLcontext *ctx ) } -/* RADEON_STATECHANGE( rmesa, glt ); */ if (ctx->Light.Enabled) { GLint p; @@ -1079,6 +1074,7 @@ static void radeonLightfv( GLcontext *ctx, GLenum light, rmesa->hw.tcl.cmd[idx] |= flag; else rmesa->hw.tcl.cmd[idx] &= ~flag; + break; } @@ -1138,14 +1134,6 @@ static void radeonLightModelfv( GLcontext *ctx, GLenum pname, case GL_LIGHT_MODEL_COLOR_CONTROL: radeonUpdateSpecular(ctx); - - RADEON_STATECHANGE( rmesa, tcl ); - if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= - ~RADEON_DIFFUSE_SPECULAR_COMBINE; - else - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= - RADEON_DIFFUSE_SPECULAR_COMBINE; break; default: @@ -1735,14 +1723,6 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state ) case GL_LIGHTING: RADEON_STATECHANGE(rmesa, tcl); - if (state) { -/* rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; */ -/* rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; */ - } - else { -/* rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE; */ -/* rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; */ - } radeonUpdateSpecular(ctx); check_twoside_fallback( ctx ); break; @@ -1899,7 +1879,8 @@ static void radeonLightingSpaceChange( GLcontext *ctx ) RADEON_STATECHANGE( rmesa, tcl ); if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "%s %d\n", __FUNCTION__, ctx->_NeedEyeCoords); + fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords, + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]); if (ctx->_NeedEyeCoords) tmp = ctx->Transform.RescaleNormals; @@ -1911,6 +1892,10 @@ static void radeonLightingSpaceChange( GLcontext *ctx ) } else { rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS; } + + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords, + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]); } /* ============================================================= @@ -2095,8 +2080,6 @@ static void radeonWrapRunPipeline( GLcontext *ctx ) } - - /* Initialize the driver's state functions. */ void radeonInitStateFuncs( GLcontext *ctx ) diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h index 45a368d95..a181d427e 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, VA LINUX SYSTEMS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state_init.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_state_init.c index 6f3d15ce9..4f0841489 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_state_init.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state_init.c @@ -405,57 +405,37 @@ void radeonInitState( radeonContextPtr rmesa ) rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = 0x00000000; rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = 0x00000000; - rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] = RADEON_BORDER_MODE_OGL; - rmesa->hw.tex[0].cmd[TEX_PP_TXFORMAT] = - (RADEON_TXFORMAT_ENDIAN_NO_SWAP | - RADEON_TXFORMAT_PERSPECTIVE_ENABLE | - RADEON_TXFORMAT_ST_ROUTE_STQ0 | - (2 << RADEON_TXFORMAT_WIDTH_SHIFT) | - (2 << RADEON_TXFORMAT_HEIGHT_SHIFT)); - rmesa->hw.tex[0].cmd[TEX_PP_TXOFFSET] = 0x2000; - rmesa->hw.tex[0].cmd[TEX_PP_BORDER_COLOR] = 0; - rmesa->hw.tex[0].cmd[TEX_PP_TXCBLEND] = - (RADEON_COLOR_ARG_A_ZERO | - RADEON_COLOR_ARG_B_ZERO | - RADEON_COLOR_ARG_C_CURRENT_COLOR | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX); - rmesa->hw.tex[0].cmd[TEX_PP_TXABLEND] = - (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_CURRENT_ALPHA | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX); - rmesa->hw.tex[0].cmd[TEX_PP_TFACTOR] = 0; - - rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] = RADEON_BORDER_MODE_OGL; - rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] = - (RADEON_TXFORMAT_ENDIAN_NO_SWAP | - RADEON_TXFORMAT_PERSPECTIVE_ENABLE | - RADEON_TXFORMAT_ST_ROUTE_STQ1 | - (2 << RADEON_TXFORMAT_WIDTH_SHIFT) | - (2 << RADEON_TXFORMAT_HEIGHT_SHIFT)); - rmesa->hw.tex[1].cmd[TEX_PP_TXOFFSET] = 0x8000; - rmesa->hw.tex[1].cmd[TEX_PP_BORDER_COLOR] = 0; - rmesa->hw.tex[1].cmd[TEX_PP_TXCBLEND] = - (RADEON_COLOR_ARG_A_ZERO | - RADEON_COLOR_ARG_B_ZERO | - RADEON_COLOR_ARG_C_CURRENT_COLOR | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX); - rmesa->hw.tex[1].cmd[TEX_PP_TXABLEND] = - (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_CURRENT_ALPHA | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX); - rmesa->hw.tex[1].cmd[TEX_PP_TFACTOR] = 0; - - /* Can oly add ST1 at the time of doing some multitex but can keep + for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { + rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] = RADEON_BORDER_MODE_OGL; + rmesa->hw.tex[i].cmd[TEX_PP_TXFORMAT] = + (RADEON_TXFORMAT_ENDIAN_NO_SWAP | + RADEON_TXFORMAT_PERSPECTIVE_ENABLE | + (i << 24) | /* This is one of RADEON_TXFORMAT_ST_ROUTE_STQ[012] */ + (2 << RADEON_TXFORMAT_WIDTH_SHIFT) | + (2 << RADEON_TXFORMAT_HEIGHT_SHIFT)); + + /* FIXME: What is this magic value? */ + rmesa->hw.tex[i].cmd[TEX_PP_TXOFFSET] = 0x2000 << (2 * i); + + rmesa->hw.tex[i].cmd[TEX_PP_BORDER_COLOR] = 0; + rmesa->hw.tex[i].cmd[TEX_PP_TXCBLEND] = + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_CURRENT_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX); + rmesa->hw.tex[i].cmd[TEX_PP_TXABLEND] = + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX); + rmesa->hw.tex[i].cmd[TEX_PP_TFACTOR] = 0; + } + + /* Can only add ST1 at the time of doing some multitex but can keep * it after that. Errors if DIFFUSE is missing. */ rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] = @@ -532,15 +512,6 @@ void radeonInitState( radeonContextPtr rmesa ) ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color ); ctx->Driver.Fogfv( ctx, GL_FOG_COORDINATE_SOURCE_EXT, 0 ); - - /* Set up vector and scalar state commands: - */ -/* upload_matrix( rmesa, ctx->ModelView.m, MODEL ); */ -/* upload_matrix_t( rmesa, ctx->ModelView.inv, MODEL_IT ); */ -/* upload_matrix( rmesa, ctx->TextureMatrix[0].m, TEXMAT_0 ); */ -/* upload_matrix( rmesa, ctx->TextureMatrix[1].m, TEXMAT_1 ); */ -/* upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, TEXMAT_2 ); */ - rmesa->hw.grd.cmd[GRD_VERT_GUARD_CLIP_ADJ] = IEEE_ONE; rmesa->hw.grd.cmd[GRD_VERT_GUARD_DISCARD_ADJ] = IEEE_ONE; rmesa->hw.grd.cmd[GRD_HORZ_GUARD_CLIP_ADJ] = IEEE_ONE; diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.c index a10e9d099..583e88350 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.c @@ -6,31 +6,31 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, VA LINUX SYSTEMS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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: * Keith Whitwell <keith@tungstengraphics.com> - * */ #include "glheader.h" @@ -265,7 +265,7 @@ static void radeonRenderStart( GLcontext *ctx ) if (!setup_tab[rmesa->swtcl.SetupIndex].check_tex_sizes(ctx)) { GLuint ind = rmesa->swtcl.SetupIndex |= (RADEON_PTEX_BIT|RADEON_RGBA_BIT); - /* Radeon handles projective textures nicely; just have to change + /* Projective textures are handled nicely; just have to change * up to the new vertex format. */ if (setup_tab[ind].vertex_format != rmesa->swtcl.vertex_format) { @@ -282,8 +282,8 @@ static void radeonRenderStart( GLcontext *ctx ) } if (rmesa->dma.flush != 0 && - rmesa->dma.flush != flush_last_swtcl_prim && - rmesa->dma.flush != flush_last_swtcl_prim_compat) + rmesa->dma.flush != flush_last_swtcl_prim_compat && + rmesa->dma.flush != flush_last_swtcl_prim) rmesa->dma.flush( rmesa ); } @@ -690,7 +690,7 @@ static GLboolean radeon_run_render( GLcontext *ctx, */ return GL_TRUE; } - + tnl->Driver.Render.Start( ctx ); if (VB->Elts) { @@ -793,6 +793,7 @@ static void radeonResetLineStipple( GLcontext *ctx ); * Emit primitives as inline vertices * ***********************************************************************/ +#undef LOCAL_VARS #define CTX_ARG radeonContextPtr rmesa #define CTX_ARG2 rmesa #define GET_VERTEX_DWORDS() rmesa->swtcl.vertex_size @@ -880,6 +881,9 @@ static struct { #define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = LE32_TO_CPU(spec[idx]) #undef LOCAL_VARS +#undef TAG +#undef INIT + #define LOCAL_VARS(n) \ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ GLuint color[n], spec[n]; \ @@ -1141,7 +1145,7 @@ void radeonFlushVertices( GLcontext *ctx, GLuint flags ) { _tnl_flush_vertices( ctx, flags ); - if (flags & FLUSH_STORED_VERTICES) + if (flags & FLUSH_STORED_VERTICES) RADEON_NEWPRIM( RADEON_CONTEXT( ctx ) ); } diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.c index 7575b64ce..b361815b6 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.c @@ -6,31 +6,31 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, TUNGSTEN GRAPHICS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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: * Keith Whitwell <keith@tungstengraphics.com> - * */ #include "glheader.h" @@ -85,17 +85,18 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define HW_POLYGON RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN -static GLboolean discreet_prim[0x10] = { - 0, /* none */ - 1, /* points */ - 1, /* lines */ - 0, /* line_strip */ - 1, /* tri_list */ - 0, /* tri_fan */ - 0, /* tri_type_2 */ - 1, /* rect list (unused) */ - 1, /* 3 vert point */ - 1, /* 3 vert line */ +static GLboolean discrete_prim[0x10] = { + 0, /* 0 none */ + 1, /* 1 points */ + 1, /* 2 lines */ + 0, /* 3 line_strip */ + 1, /* 4 tri_list */ + 0, /* 5 tri_fan */ + 0, /* 6 tri_type2 */ + 1, /* 7 rect list (unused) */ + 1, /* 8 3vert point */ + 1, /* 9 3vert line */ + 0, 0, 0, 0, @@ -179,7 +180,7 @@ do { \ /* TODO: Try to extend existing primitive if both are identical, - * discreet and there are no intervening state changes. (Somewhat + * discrete and there are no intervening state changes. (Somewhat * duplicates changes to DrawArrays code) */ static void EMIT_PRIM( GLcontext *ctx, @@ -267,7 +268,7 @@ void radeonTclPrimitive( GLcontext *ctx, GLuint newprim = hw_prim | RADEON_CP_VC_CNTL_TCL_ENABLE; if (newprim != rmesa->tcl.hw_primitive || - !discreet_prim[hw_prim&0xf]) { + !discrete_prim[hw_prim&0xf]) { RADEON_NEWPRIM( rmesa ); rmesa->tcl.hw_primitive = newprim; } diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.h index 4edf33154..15c288e21 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.h @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, TUNGSTEN GRAHPICS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c index 5e757a96e..22841f0fb 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c @@ -1,29 +1,32 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c,v 1.9 2002/12/16 16:18:59 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c,v 1.6 2002/09/16 18:05:20 eich Exp $ */ +/* +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + 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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. +*/ + /* - * Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - * 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 - * 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, VA LINUX SYSTEMS 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> * Brian Paul <brianp@valinux.com> @@ -47,8 +50,12 @@ -/* ============================================================= - * Utility functions: +/** + * Set the texture wrap modes. + * + * \param t Texture object whose wrap modes are to be set + * \param swrap Wrap mode for the \a s texture coordinate + * \param twrap Wrap mode for the \a t texture coordinate */ static void radeonSetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap ) @@ -77,6 +84,8 @@ static void radeonSetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap ) case GL_MIRROR_CLAMP_TO_EDGE_ATI: t->pp_txfilter |= RADEON_CLAMP_S_MIRROR_CLAMP_LAST; break; + default: + _mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__); } switch ( twrap ) { @@ -101,6 +110,8 @@ static void radeonSetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap ) case GL_MIRROR_CLAMP_TO_EDGE_ATI: t->pp_txfilter |= RADEON_CLAMP_T_MIRROR_CLAMP_LAST; break; + default: + _mesa_problem(NULL, "bad T wrap mode in %s", __FUNCTION__); } } @@ -121,6 +132,14 @@ static void radeonSetTexMaxAnisotropy( radeonTexObjPtr t, GLfloat max ) } } +/** + * Set the texture magnification and minification modes. + * + * \param t Texture whose filter modes are to be set + * \param minf Texture minification mode + * \param magf Texture magnification mode + */ + static void radeonSetTexFilter( radeonTexObjPtr t, GLenum minf, GLenum magf ) { GLuint anisotropy = (t->pp_txfilter & RADEON_MAX_ANISO_MASK); @@ -183,27 +202,39 @@ static void radeonSetTexBorderColor( radeonTexObjPtr t, GLubyte c[4] ) } +/** + * Allocate space for and load the mesa images into the texture memory block. + * This will happen before drawing with a new texture, or drawing with a + * texture after it was swapped out or teximaged again. + */ + static radeonTexObjPtr radeonAllocTexObj( struct gl_texture_object *texObj ) { radeonTexObjPtr t; t = CALLOC_STRUCT( radeon_tex_obj ); - if (!t) - return NULL; + texObj->DriverData = t; + if ( t != NULL ) { + if ( RADEON_DEBUG & DEBUG_TEXTURE ) { + fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, texObj, t ); + } - if ( RADEON_DEBUG & DEBUG_TEXTURE ) { - fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, texObj, t ); - } + /* Initialize non-image-dependent parts of the state: + */ + t->base.tObj = texObj; - t->tObj = texObj; - make_empty_list( t ); + t->pp_txfilter = RADEON_BORDER_MODE_OGL; + t->pp_txformat = (RADEON_TXFORMAT_ENDIAN_NO_SWAP | + RADEON_TXFORMAT_PERSPECTIVE_ENABLE); + + make_empty_list( & t->base ); + + radeonSetTexWrap( t, texObj->WrapS, texObj->WrapT ); + radeonSetTexMaxAnisotropy( t, texObj->MaxAnisotropy ); + radeonSetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); + radeonSetTexBorderColor( t, texObj->_BorderChan ); + } - /* Initialize non-image-dependent parts of the state: - */ - radeonSetTexWrap( t, texObj->WrapS, texObj->WrapT ); - radeonSetTexMaxAnisotropy( t, texObj->MaxAnisotropy ); - radeonSetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); - radeonSetTexBorderColor( t, texObj->_BorderChan ); return t; } @@ -301,7 +332,7 @@ radeonChooseTextureFormat( GLcontext *ctx, GLint internalFormat, return &_mesa_texformat_i8; default: - _mesa_problem(ctx, "unexpected texture format in radeonChoosTexFormat"); + _mesa_problem(ctx, "unexpected texture format in %s", __FUNCTION__); return NULL; } @@ -317,27 +348,25 @@ static void radeonTexImage1D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; if ( t ) { - radeonSwapOutTexObj( rmesa, t ); + driSwapOutTextureObject( t ); } else { - t = radeonAllocTexObj( texObj ); + t = (driTextureObject *) radeonAllocTexObj( texObj ); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); return; } - texObj->DriverData = t; } - /* Note, this will call radeonChooseTextureFormat */ + /* Note, this will call ChooseTextureFormat */ _mesa_store_teximage1d(ctx, target, level, internalFormat, width, border, format, type, pixels, &ctx->Unpack, texObj, texImage); - t->dirty_images |= (1 << level); + t->dirty_images[0] |= (1 << level); } @@ -350,28 +379,25 @@ static void radeonTexSubImage1D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; assert( t ); /* this _should_ be true */ if ( t ) { - radeonSwapOutTexObj( rmesa, t ); - t->dirty_images |= (1 << level); + driSwapOutTextureObject( t ); } else { - t = radeonAllocTexObj(texObj); + t = (driTextureObject *) radeonAllocTexObj( texObj ); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); return; } - texObj->DriverData = t; } _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, format, type, pixels, packing, texObj, texImage); - t->dirty_images |= (1 << level); + t->dirty_images[0] |= (1 << level); } @@ -383,29 +409,41 @@ static void radeonTexImage2D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData; - -/* fprintf(stderr, "%s\n", __FUNCTION__); */ + driTextureObject * t = (driTextureObject *) texObj->DriverData; + GLuint face; + + /* which cube face or ordinary 2D image */ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; + ASSERT(face < 6); + break; + default: + face = 0; + } - if ( t ) { - radeonSwapOutTexObj( rmesa, t ); + if ( t != NULL ) { + driSwapOutTextureObject( t ); } else { - t = radeonAllocTexObj( texObj ); + t = (driTextureObject *) radeonAllocTexObj( texObj ); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; } - texObj->DriverData = t; } - /* Note, this will call radeonChooseTextureFormat */ + /* Note, this will call ChooseTextureFormat */ _mesa_store_teximage2d(ctx, target, level, internalFormat, width, height, border, format, type, pixels, &ctx->Unpack, texObj, texImage); - t->dirty_images |= (1 << level); + t->dirty_images[face] |= (1 << level); } @@ -418,29 +456,42 @@ static void radeonTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData; - -/* fprintf(stderr, "%s\n", __FUNCTION__); */ + driTextureObject * t = (driTextureObject *) texObj->DriverData; + GLuint face; + + + /* which cube face or ordinary 2D image */ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; + ASSERT(face < 6); + break; + default: + face = 0; + } assert( t ); /* this _should_ be true */ if ( t ) { - radeonSwapOutTexObj( rmesa, t ); + driSwapOutTextureObject( t ); } else { - t = radeonAllocTexObj(texObj); + t = (driTextureObject *) radeonAllocTexObj( texObj ); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); return; } - texObj->DriverData = t; } _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, height, format, type, pixels, packing, texObj, texImage); - t->dirty_images |= (1 << level); + t->dirty_images[face] |= (1 << level); } @@ -503,11 +554,16 @@ static void radeonTexEnv( GLcontext *ctx, GLenum target, } } + +/** + * Changes variables and flags for a state update, which will happen at the + * next UpdateTextureState + */ + static void radeonTexParameter( GLcontext *ctx, GLenum target, struct gl_texture_object *texObj, GLenum pname, const GLfloat *params ) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData; if ( RADEON_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { @@ -541,11 +597,11 @@ static void radeonTexParameter( GLcontext *ctx, GLenum target, case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: /* This isn't the most efficient solution but there doesn't appear to - * be a nice alternative for Radeon. Since there's no LOD clamping, + * be a nice alternative. Since there's no LOD clamping, * we just have to rely on loading the right subset of mipmap levels * to simulate a clamped LOD. */ - radeonSwapOutTexObj( rmesa, t ); + driSwapOutTextureObject( (driTextureObject *) t ); break; default: @@ -562,17 +618,14 @@ static void radeonTexParameter( GLcontext *ctx, GLenum target, static void radeonBindTexture( GLcontext *ctx, GLenum target, struct gl_texture_object *texObj ) { - radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData; - GLuint unit = ctx->Texture.CurrentUnit; - if ( RADEON_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { - fprintf( stderr, "%s( %p ) unit=%d\n", __FUNCTION__, texObj, unit ); + fprintf( stderr, "%s( %p ) unit=%d\n", __FUNCTION__, texObj, + ctx->Texture.CurrentUnit ); } if ( target == GL_TEXTURE_2D || target == GL_TEXTURE_1D ) { - if ( !t ) { - t = radeonAllocTexObj( texObj ); - texObj->DriverData = t; + if ( texObj->DriverData == NULL ) { + radeonAllocTexObj( texObj ); } } } @@ -581,61 +634,20 @@ static void radeonDeleteTexture( GLcontext *ctx, struct gl_texture_object *texObj ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData; + driTextureObject * t = (driTextureObject *) texObj->DriverData; if ( RADEON_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) { - fprintf( stderr, "%s( %p )\n", __FUNCTION__, texObj ); + fprintf( stderr, "%s( %p (target = %s) )\n", __FUNCTION__, texObj, + _mesa_lookup_enum_by_nr( texObj->Target ) ); } - if ( t ) { + if ( t != NULL ) { if ( rmesa ) { RADEON_FIREVERTICES( rmesa ); } - radeonDestroyTexObj( rmesa, t ); - texObj->DriverData = NULL; - } -} - -static GLboolean radeonIsTextureResident( GLcontext *ctx, - struct gl_texture_object *texObj ) -{ - radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData; - return ( t && t->memBlock ); -} - - -static void radeonInitTextureObjects( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct gl_texture_object *texObj; - GLuint tmp = ctx->Texture.CurrentUnit; - - ctx->Texture.CurrentUnit = 0; - - texObj = ctx->Texture.Unit[0].Current1D; - radeonBindTexture( ctx, GL_TEXTURE_1D, texObj ); - move_to_tail( &rmesa->texture.swapped, - (radeonTexObjPtr)texObj->DriverData ); - - texObj = ctx->Texture.Unit[0].Current2D; - radeonBindTexture( ctx, GL_TEXTURE_2D, texObj ); - move_to_tail( &rmesa->texture.swapped, - (radeonTexObjPtr)texObj->DriverData ); - - ctx->Texture.CurrentUnit = 1; - - texObj = ctx->Texture.Unit[1].Current1D; - radeonBindTexture( ctx, GL_TEXTURE_1D, texObj ); - move_to_tail( &rmesa->texture.swapped, - (radeonTexObjPtr)texObj->DriverData ); - - texObj = ctx->Texture.Unit[1].Current2D; - radeonBindTexture( ctx, GL_TEXTURE_2D, texObj ); - move_to_tail( &rmesa->texture.swapped, - (radeonTexObjPtr)texObj->DriverData ); - - ctx->Texture.CurrentUnit = tmp; + driDestroyTextureObject( t ); + } } /* Need: @@ -661,6 +673,9 @@ static void radeonTexGen( GLcontext *ctx, void radeonInitTextureFuncs( GLcontext *ctx ) { + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + ctx->Driver.ChooseTextureFormat = radeonChooseTextureFormat; ctx->Driver.TexImage1D = radeonTexImage1D; ctx->Driver.TexImage2D = radeonTexImage2D; @@ -678,7 +693,7 @@ void radeonInitTextureFuncs( GLcontext *ctx ) ctx->Driver.BindTexture = radeonBindTexture; ctx->Driver.CreateTexture = NULL; /* FIXME: Is this used??? */ ctx->Driver.DeleteTexture = radeonDeleteTexture; - ctx->Driver.IsTextureResident = radeonIsTextureResident; + ctx->Driver.IsTextureResident = driIsTextureResident; ctx->Driver.PrioritizeTexture = NULL; ctx->Driver.ActiveTexture = NULL; ctx->Driver.UpdateTexturePalette = NULL; @@ -687,5 +702,7 @@ void radeonInitTextureFuncs( GLcontext *ctx ) ctx->Driver.TexParameter = radeonTexParameter; ctx->Driver.TexGen = radeonTexGen; - radeonInitTextureObjects( ctx ); + driInitTextureObjects( ctx, & rmesa->swapped, + DRI_TEXMGR_DO_TEXTURE_1D + | DRI_TEXMGR_DO_TEXTURE_2D ); } diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h index 89a5af14c..ce079baec 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, VA LINUX SYSTEMS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ @@ -41,15 +42,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern void radeonUpdateTextureState( GLcontext *ctx ); -extern int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t ); +extern int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t, + GLuint face ); -extern void radeonAgeTextures( radeonContextPtr rmesa, int heap ); extern void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ); -extern void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ); - -extern void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap ); -extern void radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap ); -extern void radeonUpdateTexLRU( radeonContextPtr rmesa, radeonTexObjPtr t ); extern void radeonInitTextureFuncs( GLcontext *ctx ); diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c index dbc5b0c1c..27b793443 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texmem.c @@ -6,24 +6,26 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, VA LINUX SYSTEMS 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. +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, VA LINUX SYSTEMS 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. **************************************************************************/ @@ -44,302 +46,87 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tex.h" -/* Destroy hardware state associated with texture `t'. +/** + * Destroy any device-dependent state associated with the texture. This may + * include NULLing out hardware state that points to the texture. */ -void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) +void +radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) { - if ( !t ) - return; - if ( RADEON_DEBUG & DEBUG_TEXTURE ) { - fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj ); - } - - if ( t->memBlock ) { - mmFreeMem( t->memBlock ); - t->memBlock = NULL; - } - - if ( t->tObj ) - t->tObj->DriverData = NULL; - - if ( rmesa ) { - /* Bump the performace counter */ - rmesa->c_textureSwaps++; - - if ( t == rmesa->state.texture.unit[0].texobj ) { - rmesa->state.texture.unit[0].texobj = NULL; - remove_from_list( &rmesa->hw.tex[0] ); - make_empty_list( &rmesa->hw.tex[0] ); - } - - if ( t == rmesa->state.texture.unit[1].texobj ) { - rmesa->state.texture.unit[1].texobj = NULL; - remove_from_list( &rmesa->hw.tex[1] ); - make_empty_list( &rmesa->hw.tex[1] ); - } - } - - remove_from_list( t ); - FREE( t ); -} - - -/* Keep track of swapped out texture objects. - */ -void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) -{ - if ( RADEON_DEBUG & DEBUG_TEXTURE ) { - fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj ); - } - - /* Bump the performace counter */ - rmesa->c_textureSwaps++; - - if ( t->memBlock ) { - mmFreeMem( t->memBlock ); - t->memBlock = NULL; - } - - t->dirty_images = ~0; - move_to_tail( &rmesa->texture.swapped, t ); -} - -/* Print out debugging information about texture LRU. - */ -void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap ) -{ - radeonTexObjPtr t; - int sz = 1 << (rmesa->radeonScreen->logTexGranularity[heap]); - - fprintf( stderr, "\nLocal LRU, heap %d:\n", heap ); - - foreach ( t, &rmesa->texture.objects[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 at 0x%x sz 0x%x\n", - t->memBlock->ofs, - t->memBlock->size ); - } - } - - fprintf( stderr, "\n" ); -} - -void radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap ) -{ - radeon_tex_region_t *list = rmesa->sarea->texList[heap]; - int i, j; - - fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list ); - - for ( i = 0, j = RADEON_NR_TEX_REGIONS ; i < RADEON_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 == RADEON_NR_TEX_REGIONS ) break; - } - - if ( j != RADEON_NR_TEX_REGIONS ) { - fprintf( stderr, "Loop detected in global LRU\n" ); - for ( i = 0 ; i < RADEON_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 ); - } - } - - fprintf( stderr, "\n" ); -} - -/* Reset the global texture LRU. - */ -static void radeonResetGlobalLRU( radeonContextPtr rmesa, int heap ) -{ - radeon_tex_region_t *list = rmesa->sarea->texList[heap]; - int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap]; - int i; - - /* - * (Re)initialize the global circular LRU list. The last element in - * the array (RADEON_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 <= rmesa->radeonScreen->texSize[heap] ; i++ ) { - list[i].prev = i-1; - list[i].next = i+1; - list[i].age = 0; - } - - i--; - list[0].prev = RADEON_NR_TEX_REGIONS; - list[i].prev = i-1; - list[i].next = RADEON_NR_TEX_REGIONS; - list[RADEON_NR_TEX_REGIONS].prev = i; - list[RADEON_NR_TEX_REGIONS].next = 0; - rmesa->sarea->texAge[heap] = 0; -} - -/* Update the local and glock texture LRUs. - */ -void radeonUpdateTexLRU(radeonContextPtr rmesa, radeonTexObjPtr t ) -{ - int heap = t->heap; - radeon_tex_region_t *list = rmesa->sarea->texList[heap]; - int sz = rmesa->radeonScreen->logTexGranularity[heap]; - int start = t->memBlock->ofs >> sz; - int end = (t->memBlock->ofs + t->memBlock->size-1) >> sz; - int i; - - rmesa->texture.age[heap] = ++rmesa->sarea->texAge[heap]; - - if ( !t->memBlock ) { - fprintf( stderr, "no memblock\n\n" ); - return; - } - - /* Update our local LRU */ - move_to_head( &rmesa->texture.objects[heap], t ); - - /* Update the global LRU */ - for ( i = start ; i <= end ; i++ ) { - list[i].in_use = 1; - list[i].age = rmesa->texture.age[heap]; - - /* remove_from_list(i) */ - list[(CARD32)list[i].next].prev = list[i].prev; - list[(CARD32)list[i].prev].next = list[i].next; - - /* insert_at_head(list, i) */ - list[i].prev = RADEON_NR_TEX_REGIONS; - list[i].next = list[RADEON_NR_TEX_REGIONS].next; - list[(CARD32)list[RADEON_NR_TEX_REGIONS].next].prev = i; - list[RADEON_NR_TEX_REGIONS].next = i; - } - - if ( 0 ) { - radeonPrintGlobalLRU( rmesa, t->heap ); - radeonPrintLocalLRU( rmesa, 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). - */ -static void radeonTexturesGone( radeonContextPtr rmesa, int heap, - int offset, int size, int in_use ) -{ - radeonTexObjPtr t, tmp; - - foreach_s ( t, tmp, &rmesa->texture.objects[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. - */ - radeonSwapOutTexObj( rmesa, t ); + fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->base.tObj ); } - if ( in_use ) { - t = (radeonTexObjPtr) CALLOC( sizeof(*t) ); - if ( !t ) return; - - t->memBlock = mmAllocMem( rmesa->texture.heap[heap], size, 0, offset ); - if ( !t->memBlock ) { - fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n", - (int)size, (int)offset ); - mmDumpMemInfo( rmesa->texture.heap[heap] ); - return; - } - insert_at_head( &rmesa->texture.objects[heap], t ); - } -} + if ( rmesa != NULL ) { + unsigned i; -/* 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 radeonAgeTextures( radeonContextPtr rmesa, int heap ) -{ - RADEONSAREAPrivPtr sarea = rmesa->sarea; - - if ( sarea->texAge[heap] != rmesa->texture.age[heap] ) { - int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap]; - int nr = 0; - int idx; - - for ( idx = sarea->texList[heap][RADEON_NR_TEX_REGIONS].prev ; - idx != RADEON_NR_TEX_REGIONS && nr < RADEON_NR_TEX_REGIONS ; - idx = sarea->texList[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 > rmesa->radeonScreen->texSize[heap] ) { - nr = RADEON_NR_TEX_REGIONS; - break; - } - if ( sarea->texList[heap][idx].age > rmesa->texture.age[heap] ) { - radeonTexturesGone( rmesa, heap, idx * sz, sz, - sarea->texList[heap][idx].in_use ); + for ( i = 0 ; i < rmesa->glCtx->Const.MaxTextureUnits ; i++ ) { + if ( t == rmesa->state.texture.unit[i].texobj ) { + rmesa->state.texture.unit[i].texobj = NULL; + remove_from_list( &rmesa->hw.tex[i] ); + make_empty_list( &rmesa->hw.tex[i] ); } } - - if ( nr == RADEON_NR_TEX_REGIONS ) { - radeonTexturesGone( rmesa, heap, 0, - rmesa->radeonScreen->texSize[heap], 0 ); - radeonResetGlobalLRU( rmesa, heap ); - } - - rmesa->texture.age[heap] = sarea->texAge[heap]; } } -/* ============================================================= +/* ------------------------------------------------------------ * Texture image conversions */ -/* Upload the texture image associated with texture `t' at level `level' - * at the address relative to `start'. +/** + * Upload the texture image associated with texture \a t at the specified + * level at the address relative to \a start. */ -static void radeonUploadSubImage( radeonContextPtr rmesa, - radeonTexObjPtr t, GLint level, - GLint x, GLint y, GLint width, GLint height ) +static void uploadSubImage( radeonContextPtr rmesa, radeonTexObjPtr t, + GLint hwlevel, + GLint x, GLint y, GLint width, GLint height, + GLuint face ) { - struct gl_texture_image *texImage; - const struct gl_texture_format *texFormat; - GLint texelsPerDword = 0; - GLuint format, pitch, offset; + struct gl_texture_image *texImage = NULL; + GLuint offset; GLint imageWidth, imageHeight; GLint ret; drmRadeonTexture tex; drmRadeonTexImage tmp; + const int level = hwlevel + t->firstLevel; if ( RADEON_DEBUG & DEBUG_TEXTURE ) { - fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, t, t->tObj ); + fprintf( stderr, "%s( %p, %p ) level/width/height/face = %d/%d/%d/%u\n", + __FUNCTION__, t, t->base.tObj, level, width, height, face ); } + ASSERT(face < 6); + /* Ensure we have a valid texture to upload */ - level += t->firstLevel; - if ( ( level < 0 ) || ( level >= RADEON_MAX_TEXTURE_LEVELS ) ) { - _mesa_problem(NULL, "bad texture level in radeonUploadSubimage"); + if ( ( hwlevel < 0 ) || ( hwlevel >= RADEON_MAX_TEXTURE_LEVELS ) ) { + _mesa_problem(NULL, "bad texture level in %s", __FUNCTION__); return; } - texImage = t->tObj->Image[level]; + switch (face) { + case 0: + texImage = t->base.tObj->Image[level]; + break; + case 1: + texImage = t->base.tObj->NegX[level]; + break; + case 2: + texImage = t->base.tObj->PosY[level]; + break; + case 3: + texImage = t->base.tObj->NegY[level]; + break; + case 4: + texImage = t->base.tObj->PosZ[level]; + break; + case 5: + texImage = t->base.tObj->NegZ[level]; + break; + } + if ( !texImage ) { if ( RADEON_DEBUG & DEBUG_TEXTURE ) fprintf( stderr, "%s: texImage %d is NULL!\n", __FUNCTION__, level ); @@ -351,199 +138,135 @@ static void radeonUploadSubImage( radeonContextPtr rmesa, return; } - texFormat = texImage->TexFormat; - - switch ( texFormat->TexelBytes ) { - case 1: - texelsPerDword = 4; - break; - case 2: - texelsPerDword = 2; - break; - case 4: - texelsPerDword = 1; - break; - } - - format = t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK; - imageWidth = texImage->Width; imageHeight = texImage->Height; offset = t->bufAddr; - pitch = (t->image[0].width * texFormat->TexelBytes) / 64; - -#if 0 - /* Bump the performace counter */ - rmesa->c_textureBytes += (dwords << 2); -#endif if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) { GLint imageX = 0; GLint imageY = 0; - GLint blitX = t->image[level].x; - GLint blitY = t->image[level].y; - GLint blitWidth = t->image[level].width; - GLint blitHeight = t->image[level].height; + GLint blitX = t->image[face][hwlevel].x; + GLint blitY = t->image[face][hwlevel].y; + GLint blitWidth = t->image[face][hwlevel].width; + GLint blitHeight = t->image[face][hwlevel].height; fprintf( stderr, " upload image: %d,%d at %d,%d\n", imageWidth, imageHeight, imageX, imageY ); fprintf( stderr, " upload blit: %d,%d at %d,%d\n", blitWidth, blitHeight, blitX, blitY ); - fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x " - "level: %d format: %x\n", - (GLuint)offset, (GLuint)pitch, level, format ); + fprintf( stderr, " blit ofs: 0x%07x level: %d/%d\n", + (GLuint)offset, hwlevel, level ); } - t->image[level].data = texImage->Data; + t->image[face][hwlevel].data = texImage->Data; + /* Init the DRM_RADEON_TEXTURE command / drmRadeonTexture struct. + * NOTE: we're always use a 1KB-wide blit and I8 texture format. + * We used to use 1, 2 and 4-byte texels and used to use the texture + * width to dictate the blit width - but that won't work for compressed + * textures. (Brian) + */ tex.offset = offset; - tex.pitch = pitch; - tex.format = format; - tex.width = imageWidth; - tex.height = imageHeight; + tex.pitch = BLIT_WIDTH_BYTES / 64; + tex.format = RADEON_TXFORMAT_I8; /* any 1-byte texel format */ + if (texImage->TexFormat->TexelBytes) { + tex.width = imageWidth * texImage->TexFormat->TexelBytes; /* in bytes */ + tex.height = imageHeight; + } + else { + tex.width = imageWidth; /* compressed */ + tex.height = imageHeight; + if (tex.height < 4) + tex.height = 4; + } tex.image = &tmp; - memcpy( &tmp, &t->image[level], sizeof(drmRadeonTexImage) ); + /* copy (x,y,width,height,data) */ + memcpy( &tmp, &t->image[face][hwlevel], sizeof(drmRadeonTexImage) ); + LOCK_HARDWARE( rmesa ); do { ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_TEXTURE, &tex, sizeof(drmRadeonTexture) ); } while ( ret && errno == EAGAIN ); + UNLOCK_HARDWARE( rmesa ); + if ( ret ) { - UNLOCK_HARDWARE( rmesa ); fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret ); - fprintf( stderr, " offset=0x%08x pitch=0x%x format=%d\n", - offset, pitch, format ); + fprintf( stderr, " offset=0x%08x\n", + offset ); fprintf( stderr, " image width=%d height=%d\n", imageWidth, imageHeight ); fprintf( stderr, " blit width=%d height=%d data=%p\n", - t->image[level].width, t->image[level].height, - t->image[level].data ); + t->image[face][hwlevel].width, t->image[face][hwlevel].height, + t->image[face][hwlevel].data ); exit( 1 ); } } -/* 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. + +/** + * Upload the texture images associated with texture \a t. This might + * require the allocation of texture memory. + * + * \param rmesa Context pointer + * \param t Texture to be uploaded + * \param face Cube map face to be uploaded. Zero for non-cube maps. */ -int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t ) + +int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t, GLuint face ) { const int numLevels = t->lastLevel - t->firstLevel + 1; - int i; - int heap; - radeonTexObjPtr t0 = rmesa->state.texture.unit[0].texobj; - radeonTexObjPtr t1 = rmesa->state.texture.unit[1].texobj; if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) { fprintf( stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__, - rmesa->glCtx, t->tObj, t->totalSize, + rmesa->glCtx, t->base.tObj, t->base.totalSize, t->firstLevel, t->lastLevel ); } - if ( !t || t->totalSize == 0 ) + if ( !t || t->base.totalSize == 0 ) return 0; LOCK_HARDWARE( rmesa ); - /* Choose the heap appropriately */ - heap = t->heap = RADEON_CARD_HEAP; -#if 0 - if ( !rmesa->radeonScreen->IsPCI && - t->totalSize > rmesa->radeonScreen->texSize[heap] ) { - heap = t->heap = RADEON_AGP_HEAP; - } -#endif - - /* Do we need to eject LRU texture objects? */ - if ( !t->memBlock ) { - /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */ - t->memBlock = mmAllocMem( rmesa->texture.heap[heap], - t->totalSize, 12, 0 ); - -#if 0 - /* Try AGP before kicking anything out of local mem */ - if ( !t->memBlock && heap == RADEON_CARD_HEAP ) { - t->memBlock = mmAllocMem( rmesa->texture.heap[RADEON_AGP_HEAP], - t->totalSize, 12, 0 ); - - if ( t->memBlock ) - heap = t->heap = RADEON_AGP_HEAP; - } -#endif - - /* Kick out textures until the requested texture fits */ - while ( !t->memBlock ) { - if ( rmesa->texture.objects[heap].prev == t0 || - rmesa->texture.objects[heap].prev == t1 ) { - fprintf( stderr, - "radeonUploadTexImages: ran into bound texture\n" ); - UNLOCK_HARDWARE( rmesa ); - return -1; - } - if ( rmesa->texture.objects[heap].prev == - &rmesa->texture.objects[heap] ) { - if ( rmesa->radeonScreen->IsPCI ) { - fprintf( stderr, "radeonUploadTexImages: upload texture " - "failure on local texture heaps, sz=%d\n", - t->totalSize ); - UNLOCK_HARDWARE( rmesa ); - return -1; -#if 0 - } else if ( heap == RADEON_CARD_HEAP ) { - heap = t->heap = RADEON_AGP_HEAP; - continue; -#endif - } else { - fprintf( stderr, "radeonUploadTexImages: upload texture " - "failure on both local and AGP texture heaps, " - "sz=%d\n", - t->totalSize ); - UNLOCK_HARDWARE( rmesa ); - return -1; - } - } + if ( t->base.memBlock == NULL ) { + int heap; - radeonSwapOutTexObj( rmesa, rmesa->texture.objects[heap].prev ); - - t->memBlock = mmAllocMem( rmesa->texture.heap[heap], - t->totalSize, 12, 0 ); + heap = driAllocateTexture( rmesa->texture_heaps, rmesa->nr_heaps, + (driTextureObject *) t ); + if ( heap == -1 ) { + UNLOCK_HARDWARE( rmesa ); + return -1; } /* Set the base offset of the texture image */ - t->bufAddr = rmesa->radeonScreen->texOffset[heap] + t->memBlock->ofs; + t->bufAddr = rmesa->radeonScreen->texOffset[heap] + + t->base.memBlock->ofs; t->pp_txoffset = t->bufAddr; -#if 0 - /* Fix AGP texture offsets */ - if ( heap == RADEON_AGP_HEAP ) { - t->setup.pp_tx_offset += RADEON_AGP_TEX_OFFSET + - rmesa->radeonScreen->agpTexOffset; - } -#endif /* Mark this texobj as dirty on all units: */ t->dirty_state = TEX_ALL; } - /* Let the world know we've used this memory recently */ - radeonUpdateTexLRU( rmesa, t ); + /* Let the world know we've used this memory recently. + */ + driUpdateTextureLRU( (driTextureObject *) t ); + UNLOCK_HARDWARE( rmesa ); /* Upload any images that are new */ - if (t->dirty_images) { + if (t->base.dirty_images[face]) { + int i; for ( i = 0 ; i < numLevels ; i++ ) { - if ( t->dirty_images & (1 << i) ) { - radeonUploadSubImage( rmesa, t, i, 0, 0, - t->image[i].width, t->image[i].height ); + if ( (t->base.dirty_images[face] & (1 << (i+t->firstLevel))) != 0 ) { + uploadSubImage( rmesa, t, i, 0, 0, t->image[face][i].width, + t->image[face][i].height, face ); } } - t->dirty_images = 0; + t->base.dirty_images[face] = 0; } - - UNLOCK_HARDWARE( rmesa ); - return 0; } diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c index a52969d33..fe52f60da 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, VA LINUX SYSTEMS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ @@ -31,16 +32,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Authors: * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> - * */ #include "glheader.h" #include "imports.h" #include "colormac.h" #include "context.h" -#include "enums.h" #include "macros.h" #include "texformat.h" +#include "enums.h" #include "radeon_context.h" #include "radeon_state.h" @@ -50,103 +50,102 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tcl.h" +#define RADEON_TXFORMAT_AL88 RADEON_TXFORMAT_AI88 + +#define _COLOR(f) \ + [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, 0 } +#define _ALPHA(f) \ + [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 } +#define _INVALID(f) \ + [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 } +#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_YCBCR_REV) \ + && (tx_table[f].format != 0xffffffff) ) + +static const struct { + GLuint format, filter; +} +tx_table[] = +{ + _ALPHA(RGBA8888), + _ALPHA(ARGB8888), + _INVALID(RGB888), + _COLOR(RGB565), + _ALPHA(ARGB4444), + _ALPHA(ARGB1555), + _ALPHA(AL88), + _INVALID(A8), + _INVALID(L8), + _COLOR(I8), + _INVALID(CI8), + _INVALID(YCBCR), + _INVALID(YCBCR_REV), +}; + +#undef _COLOR +#undef _ALPHA +#undef _INVALID + +/** + * This function computes the number of bytes of storage needed for + * the given texture object (all mipmap levels, all cube faces). + * The \c image[face][level].x/y/width/height parameters for upload/blitting + * are computed here. \c pp_txfilter, \c pp_txformat, etc. will be set here + * too. + * + * \param rmesa Context pointer + * \param tObj GL texture object whose images are to be posted to + * hardware state. + */ static void radeonSetTexImages( radeonContextPtr rmesa, struct gl_texture_object *tObj ) { radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData; const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel]; - GLint totalSize; - GLint texelsPerDword = 0, blitWidth = 0, blitPitch = 0; - GLint x, y, width, height; + GLint curOffset; GLint i; - GLint firstLevel, lastLevel, numLevels; - GLint log2Width, log2Height; - GLuint txformat = 0; + GLint firstLevel=0, lastLevel=0, numLevels; + GLint log2Width, log2Height, log2Depth; /* Set the hardware texture format */ - switch (baseImage->TexFormat->MesaFormat) { - case MESA_FORMAT_I8: - txformat = RADEON_TXFORMAT_I8; - break; - case MESA_FORMAT_AL88: - txformat = RADEON_TXFORMAT_AI88; - break; - case MESA_FORMAT_RGBA8888: - txformat = RADEON_TXFORMAT_RGBA8888; - break; - case MESA_FORMAT_ARGB8888: - txformat = RADEON_TXFORMAT_ARGB8888; - break; - case MESA_FORMAT_RGB565: - txformat = RADEON_TXFORMAT_RGB565; - break; - case MESA_FORMAT_ARGB1555: - txformat = RADEON_TXFORMAT_ARGB1555; - break; - case MESA_FORMAT_ARGB4444: - txformat = RADEON_TXFORMAT_ARGB4444; - break; - default: - _mesa_problem(NULL, "unexpected texture format in radeonTexImage2D"); - return; - } t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK | RADEON_TXFORMAT_ALPHA_IN_MAP); - t->pp_txformat |= txformat; + t->pp_txfilter &= ~RADEON_YUV_TO_RGB; - if ( txformat == RADEON_TXFORMAT_RGBA8888 || - txformat == RADEON_TXFORMAT_ARGB4444 || - txformat == RADEON_TXFORMAT_ARGB1555 || - txformat == RADEON_TXFORMAT_AI88 ) { - t->pp_txformat |= RADEON_TXFORMAT_ALPHA_IN_MAP; + if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) { + t->pp_txformat |= tx_table[ baseImage->TexFormat->MesaFormat ].format; + t->pp_txfilter |= tx_table[ baseImage->TexFormat->MesaFormat ].filter; } - - /* The Radeon has a 64-byte minimum pitch for all blits. We - * calculate the equivalent number of texels to simplify the - * calculation of the texture image area. - */ - switch ( baseImage->TexFormat->TexelBytes ) { - case 1: - texelsPerDword = 4; - blitPitch = 64; - break; - case 2: - texelsPerDword = 2; - blitPitch = 32; - break; - case 4: - texelsPerDword = 1; - blitPitch = 16; - break; + else { + _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); + return; } - /* Select the larger of the two widths for our global texture image - * coordinate space. As the Radeon has very strict offset rules, we - * can't upload mipmaps directly and have to reference their location - * from the aligned start of the whole image. - */ - blitWidth = MAX2( baseImage->Width, blitPitch ); - /* Calculate mipmap offsets and dimensions. - */ - totalSize = 0; - x = 0; - y = 0; /* Compute which mipmap levels we really want to send to the hardware. * This depends on the base image size, GL_TEXTURE_MIN_LOD, * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. * Yes, this looks overly complicated, but it's all needed. */ - firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); - firstLevel = MAX2(firstLevel, tObj->BaseLevel); - lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); - lastLevel = MAX2(lastLevel, tObj->BaseLevel); - lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); - lastLevel = MIN2(lastLevel, tObj->MaxLevel); - lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + switch (tObj->Target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5); + firstLevel = MAX2(firstLevel, tObj->BaseLevel); + lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5); + lastLevel = MAX2(lastLevel, tObj->BaseLevel); + lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); + lastLevel = MIN2(lastLevel, tObj->MaxLevel); + lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + log2Width = tObj->Image[firstLevel]->WidthLog2; + log2Height = tObj->Image[firstLevel]->HeightLog2; + log2Depth = 0; + break; + default: + return; + } /* save these values */ t->firstLevel = firstLevel; @@ -154,10 +153,15 @@ static void radeonSetTexImages( radeonContextPtr rmesa, numLevels = lastLevel - firstLevel + 1; - log2Width = tObj->Image[firstLevel]->WidthLog2; - log2Height = tObj->Image[firstLevel]->HeightLog2; + assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS); - for ( i = 0 ; i < numLevels ; i++ ) { + /* Calculate mipmap offsets and dimensions for blitting (uploading) + * The idea is that we lay out the mipmap levels within a block of + * memory organized as a rectangle of width BLIT_WIDTH_BYTES. + */ + curOffset = 0; + + for (i = 0; i < numLevels; i++) { const struct gl_texture_image *texImage; GLuint size; @@ -165,58 +169,49 @@ static void radeonSetTexImages( radeonContextPtr rmesa, if ( !texImage ) break; - width = texImage->Width; - height = texImage->Height; - - /* Texture images have a minimum pitch of 32 bytes (half of the - * 64-byte minimum pitch for blits). For images that have a - * width smaller than this, we must pad each texture image - * scanline out to this amount. - */ - if ( width < blitPitch / 2 ) { - width = blitPitch / 2; + /* find image size in bytes */ + if (texImage->IsCompressed) { + size = texImage->CompressedSize; } + else { + int w = texImage->Width * texImage->TexFormat->TexelBytes; + if (w < 32) + w = 32; + size = w * texImage->Height * texImage->Depth; + } + assert(size > 0); - size = width * height * baseImage->TexFormat->TexelBytes; - totalSize += size; - ASSERT( (totalSize & 31) == 0 ); - - while ( width < blitWidth && height > 1 ) { - width *= 2; - height /= 2; + if (curOffset & 0x1f) { + /* align to 32-byte offset */ + curOffset = (curOffset + 0x1f) & ~0x1f; } - assert(i < RADEON_MAX_TEXTURE_LEVELS); - t->image[i].x = x; - t->image[i].y = y; + t->image[0][i].x = curOffset % BLIT_WIDTH_BYTES; + t->image[0][i].y = curOffset / BLIT_WIDTH_BYTES; + t->image[0][i].width = MIN2(size, BLIT_WIDTH_BYTES); + t->image[0][i].height = size / t->image[0][i].width; - t->image[i].width = width; - t->image[i].height = height; +#if 0 + /* for debugging only and only applicable to non-rectangle targets */ + assert(size % t->image[0][i].width == 0); + assert(t->image[0][i].x == 0 + || (size < BLIT_WIDTH_BYTES && t->image[0][i].height == 1)); +#endif - /* While blits must have a pitch of at least 64 bytes, mipmaps - * must be aligned on a 32-byte boundary (just like each texture - * image scanline). - */ - if ( width >= blitWidth ) { - y += height; - } else { - x += width; - if ( x >= blitWidth ) { - x = 0; - y++; - } - } + if (0) + fprintf(stderr, + "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n", + i, texImage->Width, texImage->Height, + t->image[0][i].x, t->image[0][i].y, + t->image[0][i].width, t->image[0][i].height, size, curOffset); + + curOffset += size; - if ( 0 ) - fprintf( stderr, "level=%d p=%d %dx%d -> %dx%d at (%d,%d)\n", - i, blitWidth, baseImage->Width, baseImage->Height, - t->image[i].width, t->image[i].height, - t->image[i].x, t->image[i].y ); } /* Align the total size of texture memory block. */ - t->totalSize = (totalSize + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; + t->base.totalSize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; /* Hardware state: */ @@ -224,13 +219,27 @@ static void radeonSetTexImages( radeonContextPtr rmesa, t->pp_txfilter |= (numLevels - 1) << RADEON_MAX_MIP_LEVEL_SHIFT; t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK | - RADEON_TXFORMAT_HEIGHT_MASK); + RADEON_TXFORMAT_HEIGHT_MASK | + RADEON_TXFORMAT_CUBIC_MAP_ENABLE); t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) | (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT)); + t->pp_txsize = (((tObj->Image[firstLevel]->Width - 1) << 0) | + ((tObj->Image[firstLevel]->Height - 1) << 16)); + + /* Only need to round to nearest 32 for textures, but the blitter + * requires 64-byte aligned pitches, and we may/may not need the + * blitter. NPOT only! + */ + if (baseImage->IsCompressed) + t->pp_txpitch = (tObj->Image[firstLevel]->Width + 63) & ~(63); + else + t->pp_txpitch = ((tObj->Image[firstLevel]->Width * baseImage->TexFormat->TexelBytes) + 63) & ~(63); + t->pp_txpitch -= 32; + t->dirty_state = TEX_ALL; - radeonUploadTexImages( rmesa, t ); + /* FYI: radeonUploadTexImages( rmesa, t ); used to be called here */ } @@ -608,7 +617,7 @@ static GLuint radeon_alpha_combine[][RADEON_MAX_COMBFUNC] = }; -/* GL_EXT_texture_env_combine support +/* GL_ARB_texture_env_combine support */ /* The color tables have combine functions for GL_SRC_COLOR, @@ -723,24 +732,24 @@ static GLuint radeon_zero_alpha[] = /* Extract the arg from slot A, shift it into the correct argument slot * and set the corresponding complement bit. */ -#define RADEON_COLOR_ARG( n, arg ) \ -do { \ - color_combine |= \ - ((color_arg[n] & RADEON_COLOR_ARG_MASK) \ - << RADEON_COLOR_ARG_##arg##_SHIFT); \ - color_combine |= \ - ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \ - << RADEON_COMP_ARG_##arg##_SHIFT); \ +#define RADEON_COLOR_ARG( n, arg ) \ +do { \ + color_combine |= \ + ((color_arg[n] & RADEON_COLOR_ARG_MASK) \ + << RADEON_COLOR_ARG_##arg##_SHIFT); \ + color_combine |= \ + ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \ + << RADEON_COMP_ARG_##arg##_SHIFT); \ } while (0) -#define RADEON_ALPHA_ARG( n, arg ) \ -do { \ - alpha_combine |= \ - ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \ - << RADEON_ALPHA_ARG_##arg##_SHIFT); \ - alpha_combine |= \ - ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \ - << RADEON_COMP_ARG_##arg##_SHIFT); \ +#define RADEON_ALPHA_ARG( n, arg ) \ +do { \ + alpha_combine |= \ + ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \ + << RADEON_ALPHA_ARG_##arg##_SHIFT); \ + alpha_combine |= \ + ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \ + << RADEON_COMP_ARG_##arg##_SHIFT); \ } while (0) @@ -752,443 +761,459 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - const struct gl_texture_object *tObj = texUnit->_Current; - const GLenum format = tObj->Image[tObj->BaseLevel]->Format; GLuint color_combine, alpha_combine; - GLuint color_arg[3], alpha_arg[3]; - GLuint i, numColorArgs = 0, numAlphaArgs = 0; + + /* texUnit->_Current can be NULL if and only if the texture unit is + * not actually enabled. + */ + assert( (texUnit->_ReallyEnabled == 0) + || (texUnit->_Current != NULL) ); if ( RADEON_DEBUG & DEBUG_TEXTURE ) { - fprintf( stderr, "%s( %p, %d ) format=%s\n", __FUNCTION__, - ctx, unit, _mesa_lookup_enum_by_nr( format ) ); + fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, ctx, unit ); } /* Set the texture environment state. Isn't this nice and clean? - * The Radeon will automagically set the texture alpha to 0xff when + * The chip will automagically set the texture alpha to 0xff when * the texture format does not include an alpha component. This * reduces the amount of special-casing we have to do, alpha-only * textures being a notable exception. */ - switch ( texUnit->EnvMode ) { - case GL_REPLACE: - switch ( format ) { - case GL_RGBA: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - color_combine = radeon_color_combine[unit][RADEON_REPLACE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE]; - break; - case GL_ALPHA: - color_combine = radeon_color_combine[unit][RADEON_DISABLE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE]; - break; - case GL_LUMINANCE: - case GL_RGB: - color_combine = radeon_color_combine[unit][RADEON_REPLACE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; - break; - case GL_COLOR_INDEX: - default: - return GL_FALSE; - } - break; - - case GL_MODULATE: - switch ( format ) { - case GL_RGBA: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - color_combine = radeon_color_combine[unit][RADEON_MODULATE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; - break; - case GL_ALPHA: - color_combine = radeon_color_combine[unit][RADEON_DISABLE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; - break; - case GL_RGB: - case GL_LUMINANCE: - color_combine = radeon_color_combine[unit][RADEON_MODULATE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; - break; - case GL_COLOR_INDEX: - default: - return GL_FALSE; - } - break; - - case GL_DECAL: - switch ( format ) { - case GL_RGBA: - case GL_RGB: - color_combine = radeon_color_combine[unit][RADEON_DECAL]; - alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; - break; - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - color_combine = radeon_color_combine[unit][RADEON_DISABLE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; - break; - case GL_COLOR_INDEX: - default: - return GL_FALSE; - } - break; - - case GL_BLEND: - switch ( format ) { - case GL_RGBA: - case GL_RGB: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - color_combine = radeon_color_combine[unit][RADEON_BLEND]; - alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; - break; - case GL_ALPHA: - color_combine = radeon_color_combine[unit][RADEON_DISABLE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; - break; - case GL_INTENSITY: - color_combine = radeon_color_combine[unit][RADEON_BLEND]; - alpha_combine = radeon_alpha_combine[unit][RADEON_BLEND]; - break; - case GL_COLOR_INDEX: - default: - return GL_FALSE; - } - break; - - case GL_ADD: - switch ( format ) { - case GL_RGBA: - case GL_RGB: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - color_combine = radeon_color_combine[unit][RADEON_ADD]; - alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; - break; - case GL_ALPHA: - color_combine = radeon_color_combine[unit][RADEON_DISABLE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; - break; - case GL_INTENSITY: - color_combine = radeon_color_combine[unit][RADEON_ADD]; - alpha_combine = radeon_alpha_combine[unit][RADEON_ADD]; - break; - case GL_COLOR_INDEX: - default: - return GL_FALSE; - } - break; - - case GL_COMBINE_EXT: + if ( !texUnit->_ReallyEnabled ) { /* Don't cache these results. */ rmesa->state.texture.unit[unit].format = 0; rmesa->state.texture.unit[unit].envMode = 0; - - /* Step 0: - * Calculate how many arguments we need to process. - */ - switch ( texUnit->CombineModeRGB ) { + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; + } + else { + const struct gl_texture_object *tObj = texUnit->_Current; + const GLenum format = tObj->Image[tObj->BaseLevel]->Format; + GLuint color_arg[3], alpha_arg[3]; + GLuint i, numColorArgs = 0, numAlphaArgs = 0; + GLuint RGBshift = texUnit->CombineScaleShiftRGB; + GLuint Ashift = texUnit->CombineScaleShiftA; + + switch ( texUnit->EnvMode ) { case GL_REPLACE: - numColorArgs = 1; + switch ( format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_REPLACE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE]; + break; + case GL_LUMINANCE: + case GL_RGB: + color_combine = radeon_color_combine[unit][RADEON_REPLACE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; + break; + case GL_COLOR_INDEX: + default: + return GL_FALSE; + } break; + case GL_MODULATE: - case GL_ADD: - case GL_ADD_SIGNED: - case GL_SUBTRACT: - case GL_DOT3_RGB: - case GL_DOT3_RGBA: - case GL_DOT3_RGB_EXT: - case GL_DOT3_RGBA_EXT: - numColorArgs = 2; + switch ( format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_MODULATE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_RGB: + case GL_LUMINANCE: + color_combine = radeon_color_combine[unit][RADEON_MODULATE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; + break; + case GL_COLOR_INDEX: + default: + return GL_FALSE; + } break; - case GL_INTERPOLATE: - case GL_MODULATE_ADD_ATI: - case GL_MODULATE_SIGNED_ADD_ATI: - case GL_MODULATE_SUBTRACT_ATI: - numColorArgs = 3; + + case GL_DECAL: + switch ( format ) { + case GL_RGBA: + case GL_RGB: + color_combine = radeon_color_combine[unit][RADEON_DECAL]; + alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; + break; + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; + break; + case GL_COLOR_INDEX: + default: + return GL_FALSE; + } break; - default: - return GL_FALSE; - } - switch ( texUnit->CombineModeA ) { - case GL_REPLACE: - numAlphaArgs = 1; + case GL_BLEND: + switch ( format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_BLEND]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_BLEND]; + alpha_combine = radeon_alpha_combine[unit][RADEON_BLEND]; + break; + case GL_COLOR_INDEX: + default: + return GL_FALSE; + } break; - case GL_MODULATE: + case GL_ADD: - case GL_ADD_SIGNED: - case GL_SUBTRACT: - numAlphaArgs = 2; - break; - case GL_INTERPOLATE: - case GL_MODULATE_ADD_ATI: - case GL_MODULATE_SIGNED_ADD_ATI: - case GL_MODULATE_SUBTRACT_ATI: - numAlphaArgs = 3; + switch ( format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_ADD]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_ADD]; + alpha_combine = radeon_alpha_combine[unit][RADEON_ADD]; + break; + case GL_COLOR_INDEX: + default: + return GL_FALSE; + } break; - default: - return GL_FALSE; - } - /* Step 1: - * Extract the color and alpha combine function arguments. - */ - for ( i = 0 ; i < numColorArgs ; i++ ) { - const GLuint op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR; - ASSERT(op >= 0); - ASSERT(op <= 3); - switch ( texUnit->CombineSourceRGB[i] ) { - case GL_TEXTURE: - color_arg[i] = radeon_texture_color[op][unit]; + case GL_COMBINE: + /* Don't cache these results. + */ + rmesa->state.texture.unit[unit].format = 0; + rmesa->state.texture.unit[unit].envMode = 0; + + /* Step 0: + * Calculate how many arguments we need to process. + */ + switch ( texUnit->CombineModeRGB ) { + case GL_REPLACE: + numColorArgs = 1; break; - case GL_CONSTANT: - color_arg[i] = radeon_tfactor_color[op]; + case GL_MODULATE: + case GL_ADD: + case GL_ADD_SIGNED: + case GL_SUBTRACT: + case GL_DOT3_RGB: + case GL_DOT3_RGBA: + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + numColorArgs = 2; break; - case GL_PRIMARY_COLOR: - color_arg[i] = radeon_primary_color[op]; + case GL_INTERPOLATE: + case GL_MODULATE_ADD_ATI: + case GL_MODULATE_SIGNED_ADD_ATI: + case GL_MODULATE_SUBTRACT_ATI: + numColorArgs = 3; break; - case GL_PREVIOUS: - color_arg[i] = radeon_previous_color[op]; + default: + return GL_FALSE; + } + + switch ( texUnit->CombineModeA ) { + case GL_REPLACE: + numAlphaArgs = 1; break; - case GL_ZERO: - color_arg[i] = radeon_zero_color[op]; + case GL_MODULATE: + case GL_ADD: + case GL_ADD_SIGNED: + case GL_SUBTRACT: + numAlphaArgs = 2; break; - case GL_ONE: - color_arg[i] = radeon_zero_color[op+1]; + case GL_INTERPOLATE: + case GL_MODULATE_ADD_ATI: + case GL_MODULATE_SIGNED_ADD_ATI: + case GL_MODULATE_SUBTRACT_ATI: + numAlphaArgs = 3; break; default: return GL_FALSE; } - } - for ( i = 0 ; i < numAlphaArgs ; i++ ) { - const GLuint op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA; - ASSERT(op >= 0); - ASSERT(op <= 1); - switch ( texUnit->CombineSourceA[i] ) { - case GL_TEXTURE: - alpha_arg[i] = radeon_texture_alpha[op][unit]; + /* Step 1: + * Extract the color and alpha combine function arguments. + */ + for ( i = 0 ; i < numColorArgs ; i++ ) { + const GLuint op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR; + assert(op >= 0); + assert(op <= 3); + switch ( texUnit->CombineSourceRGB[i] ) { + case GL_TEXTURE: + color_arg[i] = radeon_texture_color[op][unit]; + break; + case GL_CONSTANT: + color_arg[i] = radeon_tfactor_color[op]; + break; + case GL_PRIMARY_COLOR: + color_arg[i] = radeon_primary_color[op]; + break; + case GL_PREVIOUS: + color_arg[i] = radeon_previous_color[op]; + break; + case GL_ZERO: + color_arg[i] = radeon_zero_color[op]; + break; + case GL_ONE: + color_arg[i] = radeon_zero_color[op+1]; + break; + default: + return GL_FALSE; + } + } + + for ( i = 0 ; i < numAlphaArgs ; i++ ) { + const GLuint op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA; + assert(op >= 0); + assert(op <= 1); + switch ( texUnit->CombineSourceA[i] ) { + case GL_TEXTURE: + alpha_arg[i] = radeon_texture_alpha[op][unit]; + break; + case GL_CONSTANT: + alpha_arg[i] = radeon_tfactor_alpha[op]; + break; + case GL_PRIMARY_COLOR: + alpha_arg[i] = radeon_primary_alpha[op]; + break; + case GL_PREVIOUS: + alpha_arg[i] = radeon_previous_alpha[op]; + break; + case GL_ZERO: + alpha_arg[i] = radeon_zero_alpha[op]; + break; + case GL_ONE: + alpha_arg[i] = radeon_zero_alpha[op+1]; + break; + default: + return GL_FALSE; + } + } + + /* Step 2: + * Build up the color and alpha combine functions. + */ + switch ( texUnit->CombineModeRGB ) { + case GL_REPLACE: + color_combine = (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, C ); break; - case GL_CONSTANT: - alpha_arg[i] = radeon_tfactor_alpha[op]; + case GL_MODULATE: + color_combine = (RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, B ); break; - case GL_PRIMARY_COLOR: - alpha_arg[i] = radeon_primary_alpha[op]; + case GL_ADD: + color_combine = (RADEON_COLOR_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, C ); break; - case GL_PREVIOUS: - alpha_arg[i] = radeon_previous_alpha[op]; + case GL_ADD_SIGNED: + color_combine = (RADEON_COLOR_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADDSIGNED | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, C ); break; - case GL_ZERO: - alpha_arg[i] = radeon_zero_alpha[op]; + case GL_SUBTRACT: + color_combine = (RADEON_COLOR_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_SUBTRACT | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, C ); break; - case GL_ONE: - alpha_arg[i] = radeon_zero_alpha[op+1]; + case GL_INTERPOLATE: + color_combine = (RADEON_BLEND_CTL_BLEND | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, B ); + RADEON_COLOR_ARG( 1, A ); + RADEON_COLOR_ARG( 2, C ); + break; + + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + /* The EXT version of the DOT3 extension does not support the + * scale factor, but the ARB version (and the version in OpenGL + * 1.3) does. + */ + RGBshift = 0; + Ashift = 0; + /* FALLTHROUGH */ + + case GL_DOT3_RGB: + case GL_DOT3_RGBA: + /* The R100 / RV200 only support a 1X multiplier in hardware + * w/the ARB version. + */ + if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) { + return GL_FALSE; + } + + RGBshift += 2; + Ashift = RGBshift; + + color_combine = (RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_DOT3 | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, B ); + break; + + case GL_MODULATE_ADD_ATI: + color_combine = (RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, C ); + RADEON_COLOR_ARG( 2, B ); + break; + case GL_MODULATE_SIGNED_ADD_ATI: + color_combine = (RADEON_BLEND_CTL_ADDSIGNED | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, C ); + RADEON_COLOR_ARG( 2, B ); + break; + case GL_MODULATE_SUBTRACT_ATI: + color_combine = (RADEON_BLEND_CTL_SUBTRACT | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, C ); + RADEON_COLOR_ARG( 2, B ); break; default: return GL_FALSE; } - } - /* Step 2: - * Build up the color and alpha combine functions. - */ - switch ( texUnit->CombineModeRGB ) { - case GL_REPLACE: - color_combine = (RADEON_COLOR_ARG_A_ZERO | - RADEON_COLOR_ARG_B_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, C ); - break; - case GL_MODULATE: - color_combine = (RADEON_COLOR_ARG_C_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, A ); - RADEON_COLOR_ARG( 1, B ); - break; - case GL_ADD: - color_combine = (RADEON_COLOR_ARG_B_ZERO | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_ADD | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, A ); - RADEON_COLOR_ARG( 1, C ); - break; - case GL_ADD_SIGNED: - color_combine = (RADEON_COLOR_ARG_B_ZERO | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_ADDSIGNED | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, A ); - RADEON_COLOR_ARG( 1, C ); - break; - case GL_SUBTRACT: - color_combine = (RADEON_COLOR_ARG_B_ZERO | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_SUBTRACT | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, A ); - RADEON_COLOR_ARG( 1, C ); - break; - case GL_INTERPOLATE: - color_combine = (RADEON_BLEND_CTL_BLEND | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, B ); - RADEON_COLOR_ARG( 1, A ); - RADEON_COLOR_ARG( 2, C ); - break; + switch ( texUnit->CombineModeA ) { + case GL_REPLACE: + alpha_combine = (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, C ); + break; + case GL_MODULATE: + alpha_combine = (RADEON_ALPHA_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, B ); + break; + case GL_ADD: + alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, C ); + break; + case GL_ADD_SIGNED: + alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADDSIGNED | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, C ); + break; + case GL_SUBTRACT: + alpha_combine = (RADEON_COLOR_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_SUBTRACT | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, C ); + break; + case GL_INTERPOLATE: + alpha_combine = (RADEON_BLEND_CTL_BLEND | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, B ); + RADEON_ALPHA_ARG( 1, A ); + RADEON_ALPHA_ARG( 2, C ); + break; - case GL_DOT3_RGB: - case GL_DOT3_RGBA: - if ( texUnit->CombineScaleShiftRGB - != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) - { - return GL_FALSE; + case GL_MODULATE_ADD_ATI: + alpha_combine = (RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, C ); + RADEON_ALPHA_ARG( 2, B ); + break; + case GL_MODULATE_SIGNED_ADD_ATI: + alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, C ); + RADEON_ALPHA_ARG( 2, B ); + break; + case GL_MODULATE_SUBTRACT_ATI: + alpha_combine = (RADEON_BLEND_CTL_SUBTRACT | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, C ); + RADEON_ALPHA_ARG( 2, B ); + break; + default: + return GL_FALSE; } - /* FALLTHROUGH */ - - case GL_DOT3_RGB_EXT: - case GL_DOT3_RGBA_EXT: - color_combine = (RADEON_COLOR_ARG_C_ZERO | - RADEON_BLEND_CTL_DOT3 | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, A ); - RADEON_COLOR_ARG( 1, B ); - break; - case GL_MODULATE_ADD_ATI: - color_combine = (RADEON_BLEND_CTL_ADD | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, A ); - RADEON_COLOR_ARG( 1, C ); - RADEON_COLOR_ARG( 2, B ); - break; - case GL_MODULATE_SIGNED_ADD_ATI: - color_combine = (RADEON_BLEND_CTL_ADDSIGNED | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, A ); - RADEON_COLOR_ARG( 1, C ); - RADEON_COLOR_ARG( 2, B ); - break; - case GL_MODULATE_SUBTRACT_ATI: - color_combine = (RADEON_BLEND_CTL_SUBTRACT | - RADEON_CLAMP_TX); - RADEON_COLOR_ARG( 0, A ); - RADEON_COLOR_ARG( 1, C ); - RADEON_COLOR_ARG( 2, B ); - break; - default: - return GL_FALSE; - } + if ( (texUnit->CombineModeRGB == GL_DOT3_RGB_EXT) + || (texUnit->CombineModeRGB == GL_DOT3_RGB) ) { + alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE; + } - switch ( texUnit->CombineModeA ) { - case GL_REPLACE: - alpha_combine = (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_CLAMP_TX); - RADEON_ALPHA_ARG( 0, C ); - break; - case GL_MODULATE: - alpha_combine = (RADEON_ALPHA_ARG_C_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_CLAMP_TX); - RADEON_ALPHA_ARG( 0, A ); - RADEON_ALPHA_ARG( 1, B ); - break; - case GL_ADD: - alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_ADD | - RADEON_CLAMP_TX); - RADEON_ALPHA_ARG( 0, A ); - RADEON_ALPHA_ARG( 1, C ); - break; - case GL_ADD_SIGNED: - alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_ADDSIGNED | - RADEON_CLAMP_TX); - RADEON_ALPHA_ARG( 0, A ); - RADEON_ALPHA_ARG( 1, C ); - break; - case GL_SUBTRACT: - alpha_combine = (RADEON_COLOR_ARG_B_ZERO | - RADEON_COMP_ARG_B | - RADEON_BLEND_CTL_SUBTRACT | - RADEON_CLAMP_TX); - RADEON_ALPHA_ARG( 0, A ); - RADEON_ALPHA_ARG( 1, C ); - break; - case GL_INTERPOLATE: - alpha_combine = (RADEON_BLEND_CTL_BLEND | - RADEON_CLAMP_TX); - RADEON_ALPHA_ARG( 0, B ); - RADEON_ALPHA_ARG( 1, A ); - RADEON_ALPHA_ARG( 2, C ); - break; + /* Step 3: + * Apply the scale factor. + */ + color_combine |= (RGBshift << RADEON_SCALE_SHIFT); + alpha_combine |= (Ashift << RADEON_SCALE_SHIFT); - case GL_MODULATE_ADD_ATI: - alpha_combine = (RADEON_BLEND_CTL_ADD | - RADEON_CLAMP_TX); - RADEON_ALPHA_ARG( 0, A ); - RADEON_ALPHA_ARG( 1, C ); - RADEON_ALPHA_ARG( 2, B ); - break; - case GL_MODULATE_SIGNED_ADD_ATI: - alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED | - RADEON_CLAMP_TX); - RADEON_ALPHA_ARG( 0, A ); - RADEON_ALPHA_ARG( 1, C ); - RADEON_ALPHA_ARG( 2, B ); - break; - case GL_MODULATE_SUBTRACT_ATI: - alpha_combine = (RADEON_BLEND_CTL_SUBTRACT | - RADEON_CLAMP_TX); - RADEON_ALPHA_ARG( 0, A ); - RADEON_ALPHA_ARG( 1, C ); - RADEON_ALPHA_ARG( 2, B ); + /* All done! + */ break; + default: return GL_FALSE; } - - if ( (texUnit->CombineModeRGB == GL_DOT3_RGB_EXT) - || (texUnit->CombineModeRGB == GL_DOT3_RGB_ARB) ) { - alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE; - } - - /* Step 3: - * Apply the scale factor. The EXT version of the DOT3 extension does - * not support the scale factor, but the ARB version (and the version in - * OpenGL 1.3) does. The catch is that the Radeon only supports a 1X - * multiplier in hardware w/the ARB version. - */ - if ( texUnit->CombineModeRGB != GL_DOT3_RGB_EXT && - texUnit->CombineModeRGB != GL_DOT3_RGBA_EXT && - texUnit->CombineModeRGB != GL_DOT3_RGB && - texUnit->CombineModeRGB != GL_DOT3_RGBA ) { - color_combine |= (texUnit->CombineScaleShiftRGB << RADEON_SCALE_SHIFT); - alpha_combine |= (texUnit->CombineScaleShiftA << RADEON_SCALE_SHIFT); - } - else - { - color_combine |= RADEON_SCALE_4X; - alpha_combine |= RADEON_SCALE_4X; - } - - /* All done! - */ - break; - - default: - return GL_FALSE; } if ( rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] != color_combine || @@ -1197,7 +1222,7 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ) rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] = color_combine; rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] = alpha_combine; } - + return GL_TRUE; } @@ -1205,13 +1230,19 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ) RADEON_MIN_FILTER_MASK | \ RADEON_MAG_FILTER_MASK | \ RADEON_MAX_ANISO_MASK | \ + RADEON_YUV_TO_RGB | \ + RADEON_YUV_TEMPERATURE_MASK | \ RADEON_CLAMP_S_MASK | \ RADEON_CLAMP_T_MASK) #define TEXOBJ_TXFORMAT_MASK (RADEON_TXFORMAT_WIDTH_MASK | \ RADEON_TXFORMAT_HEIGHT_MASK | \ RADEON_TXFORMAT_FORMAT_MASK | \ - RADEON_TXFORMAT_ALPHA_IN_MAP) + RADEON_TXFORMAT_F5_WIDTH_MASK | \ + RADEON_TXFORMAT_F5_HEIGHT_MASK | \ + RADEON_TXFORMAT_ALPHA_IN_MAP | \ + RADEON_TXFORMAT_CUBIC_MAP_ENABLE | \ + RADEON_TXFORMAT_NON_POWER2) static void import_tex_obj_state( radeonContextPtr rmesa, @@ -1221,8 +1252,8 @@ static void import_tex_obj_state( radeonContextPtr rmesa, GLuint *cmd = RADEON_DB_STATE( tex[unit] ); cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK; - cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK; + cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK; cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset; cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color; @@ -1236,13 +1267,13 @@ static void import_tex_obj_state( radeonContextPtr rmesa, static void set_texgen_matrix( radeonContextPtr rmesa, GLuint unit, - GLfloat *s_plane, - GLfloat *t_plane ) + const GLfloat *s_plane, + const GLfloat *t_plane ) { static const GLfloat scale_identity[4] = { 1,1,1,1 }; if (!TEST_EQ_4V( s_plane, scale_identity) || - !(TEST_EQ_4V( t_plane, scale_identity))) { + !TEST_EQ_4V( t_plane, scale_identity)) { rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE<<unit; rmesa->TexGenMatrix[unit].m[0] = s_plane[0]; rmesa->TexGenMatrix[unit].m[4] = s_plane[1]; @@ -1273,10 +1304,6 @@ static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit ) rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift); rmesa->TexGenNeedNormals[unit] = 0; - if (0) - fprintf(stderr, "%s unit %d cleared texgenEnabled %x\n", __FUNCTION__, - unit, rmesa->TexGenEnabled); - if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) == 0) { /* Disabled, no fallback: */ @@ -1295,7 +1322,7 @@ static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit ) texUnit->GenModeS != texUnit->GenModeT) { /* Mixed modes, fallback: */ -/* fprintf(stderr, "fallback mixed texgen\n"); */ + /* fprintf(stderr, "fallback mixed texgen\n"); */ return GL_FALSE; } else @@ -1338,100 +1365,28 @@ static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit ) rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; } -/* fprintf(stderr, "%s unit %d texgenEnabled %x\n", __FUNCTION__, */ -/* unit, rmesa->TexGenEnabled); */ return GL_TRUE; } - - -static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit ) +static void disable_tex( GLcontext *ctx, int unit ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - -/* fprintf(stderr, "%s\n", __FUNCTION__); */ - - if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) { - struct gl_texture_object *tObj = texUnit->_Current; - radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData; - GLenum format; - - /* Fallback if there's a texture border */ - if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) - return GL_FALSE; - /* Upload teximages (not pipelined) - */ - if ( t->dirty_images ) { - RADEON_FIREVERTICES( rmesa ); - radeonSetTexImages( rmesa, tObj ); - /* Fallback if we can't upload: + if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit)) { + /* Texture unit disabled */ + if ( rmesa->state.texture.unit[unit].texobj != NULL ) { + /* The old texture is no longer bound to this texture unit. + * Mark it as such. */ - if ( !t->memBlock ) - return GL_FALSE; - } - /* Update state if this is a different texture object to last - * time. - */ - if ( rmesa->state.texture.unit[unit].texobj != t ) { - rmesa->state.texture.unit[unit].texobj = t; - t->dirty_state |= 1<<unit; - radeonUpdateTexLRU( rmesa, t ); /* XXX: should be locked! */ + rmesa->state.texture.unit[unit].texobj->base.bound &= ~(1UL << unit); + rmesa->state.texture.unit[unit].texobj = NULL; } - - /* Newly enabled? - */ - if ( !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit))) { - RADEON_STATECHANGE( rmesa, ctx ); - rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= - (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit; - - RADEON_STATECHANGE( rmesa, tcl ); - - if (unit == 0) - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST0; - else - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST1; - - rmesa->recheck_texgen[unit] = GL_TRUE; - } - - if (t->dirty_state & (1<<unit)) { - import_tex_obj_state( rmesa, unit, t ); - } - - if (rmesa->recheck_texgen[unit]) { - GLboolean fallback = !radeon_validate_texgen( ctx, unit ); - TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), fallback); - rmesa->recheck_texgen[unit] = 0; - rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; - } - - format = tObj->Image[tObj->BaseLevel]->Format; - if ( rmesa->state.texture.unit[unit].format != format || - rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) { - rmesa->state.texture.unit[unit].format = format; - rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode; - if ( ! radeonUpdateTextureEnv( ctx, unit ) ) { - return GL_FALSE; - } - } - } - else if ( texUnit->_ReallyEnabled ) { - /* 3d textures, etc: - */ - return GL_FALSE; - } - else if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit)) { - /* Texture unit disabled */ - rmesa->state.texture.unit[unit].texobj = 0; RADEON_STATECHANGE( rmesa, ctx ); rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= - ~((RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit); + ~((RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit); RADEON_STATECHANGE( rmesa, tcl ); switch (unit) { @@ -1464,7 +1419,7 @@ static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit ) rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift); rmesa->TexGenNeedNormals[unit] = 0; rmesa->TexGenEnabled |= - (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift; + (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift; if (tmp != rmesa->TexGenEnabled) { rmesa->recheck_texgen[unit] = GL_TRUE; @@ -1472,10 +1427,128 @@ static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit ) } } } +} + +static GLboolean enable_tex_2d( GLcontext *ctx, int unit ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + struct gl_texture_object *tObj = texUnit->_Current; + radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData; + + /* Need to load the 2d images associated with this unit. + */ + if (t->pp_txformat & RADEON_TXFORMAT_NON_POWER2) { + t->pp_txformat &= ~RADEON_TXFORMAT_NON_POWER2; + t->base.dirty_images[0] = ~0; + } + + ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D); + + if ( t->base.dirty_images[0] ) { + RADEON_FIREVERTICES( rmesa ); + radeonSetTexImages( rmesa, tObj ); + radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 ); + if ( !t->base.memBlock ) + return GL_FALSE; + } + + return GL_TRUE; +} + + +static GLboolean update_tex_common( GLcontext *ctx, int unit ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + struct gl_texture_object *tObj = texUnit->_Current; + radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData; + GLenum format; + + /* Fallback if there's a texture border */ + if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) + return GL_FALSE; + + /* Update state if this is a different texture object to last + * time. + */ + if ( rmesa->state.texture.unit[unit].texobj != t ) { + if ( rmesa->state.texture.unit[unit].texobj != NULL ) { + /* The old texture is no longer bound to this texture unit. + * Mark it as such. + */ + + rmesa->state.texture.unit[unit].texobj->base.bound &= + ~(1UL << unit); + } + + rmesa->state.texture.unit[unit].texobj = t; + t->base.bound |= (1UL << unit); + t->dirty_state |= 1<<unit; + driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */ + } + + + /* Newly enabled? + */ + if ( !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit))) { + RADEON_STATECHANGE( rmesa, ctx ); + rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= + (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit; + + RADEON_STATECHANGE( rmesa, tcl ); + + if (unit == 0) + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST0; + else + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST1; + + rmesa->recheck_texgen[unit] = GL_TRUE; + } + + if (t->dirty_state & (1<<unit)) { + import_tex_obj_state( rmesa, unit, t ); + } + + if (rmesa->recheck_texgen[unit]) { + GLboolean fallback = !radeon_validate_texgen( ctx, unit ); + TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), fallback); + rmesa->recheck_texgen[unit] = 0; + rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; + } + + format = tObj->Image[tObj->BaseLevel]->Format; + if ( rmesa->state.texture.unit[unit].format != format || + rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) { + rmesa->state.texture.unit[unit].format = format; + rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode; + if ( ! radeonUpdateTextureEnv( ctx, unit ) ) { + return GL_FALSE; + } + } return GL_TRUE; } + + +static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit ) +{ + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + + if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) { + return (enable_tex_2d( ctx, unit ) && + update_tex_common( ctx, unit )); + } + else if ( texUnit->_ReallyEnabled ) { + return GL_FALSE; + } + else { + disable_tex( ctx, unit ); + return GL_TRUE; + } +} + void radeonUpdateTextureState( GLcontext *ctx ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c index 6b14f5069..b613e9eb4 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c @@ -6,31 +6,31 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, TUNGSTEN GRAPHICS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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: * Keith Whitwell <keith@tungstengraphics.com> - * */ #include "glheader.h" #include "imports.h" @@ -779,9 +779,10 @@ static void radeon_Begin( GLenum mode ) { GET_CURRENT_CONTEXT(ctx); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - + if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); + fprintf(stderr, "%s( %s )\n", __FUNCTION__, + _mesa_lookup_enum_by_nr( mode )); if (mode > GL_POLYGON) { _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" ); diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h index 3c9b2fafe..9792fcbb7 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h @@ -6,31 +6,31 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, TUNGSTEN GRAPHICS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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: * Keith Whitwell <keith@tungstengraphics.com> - * */ #ifndef __RADEON_VTXFMT_H__ @@ -73,13 +73,13 @@ do { \ /* Useful for figuring out the offsets: */ -#define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL ) \ -do { \ - while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++; \ - /* fprintf(stderr, "%s/%d CVAL %x OFFSET %d VAL %x\n", __FUNCTION__, */ \ -/* __LINE__, CHECKVAL, OFFSET, (int)(NEWVAL)); */ \ - *(int *)(CODE+OFFSET) = (int)(NEWVAL); \ - OFFSET += 4; \ +#define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL ) \ +do { \ + while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++; \ + fprintf(stderr, "%s/%d CVAL %x OFFSET %d VAL %x\n", __FUNCTION__, \ + __LINE__, CHECKVAL, OFFSET, (int)(NEWVAL)); \ + *(int *)(CODE+OFFSET) = (int)(NEWVAL); \ + OFFSET += 4; \ } while (0) /* diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_c.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_c.c index 536e6b547..188e34a42 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_c.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_c.c @@ -6,24 +6,25 @@ Copyright 2002 ATI Technologies Inc., Ontario, Canada, and 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, TUNGSTEN GRAPHICS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ @@ -539,12 +540,20 @@ static void radeon_TexCoord2fv( const GLfloat *v ) /* MultiTexcoord + * + * Technically speaking, these functions should subtract GL_TEXTURE0 from + * \c target before masking and using it. The value of GL_TEXTURE0 is 0x84C0, + * which has the low-order 5 bits 0. For all possible valid values of + * \c target. Subtracting GL_TEXTURE0 has the net effect of masking \c target + * with 0x1F. Masking with 0x1F and then masking with 0x01 is redundant, so + * the subtraction has been omitted. */ + static void radeon_MultiTexCoord1fARB( GLenum target, GLfloat s ) { GET_CURRENT_CONTEXT(ctx); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + GLfloat *dest = rmesa->vb.texcoordptr[target & 1]; dest[0] = s; dest[1] = 0; } @@ -553,7 +562,7 @@ static void radeon_MultiTexCoord1fvARB( GLenum target, const GLfloat *v ) { GET_CURRENT_CONTEXT(ctx); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + GLfloat *dest = rmesa->vb.texcoordptr[target & 1]; dest[0] = v[0]; dest[1] = 0; } @@ -562,7 +571,7 @@ static void radeon_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t ) { GET_CURRENT_CONTEXT(ctx); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + GLfloat *dest = rmesa->vb.texcoordptr[target & 1]; dest[0] = s; dest[1] = t; } @@ -571,7 +580,7 @@ static void radeon_MultiTexCoord2fvARB( GLenum target, const GLfloat *v ) { GET_CURRENT_CONTEXT(ctx); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[(target - GL_TEXTURE0_ARB)&1]; + GLfloat *dest = rmesa->vb.texcoordptr[target & 1]; dest[0] = v[0]; dest[1] = v[1]; } @@ -597,8 +606,9 @@ static void choose_##FN ARGS1 \ GET_CURRENT_CONTEXT(ctx); \ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \ - struct dynfn *dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ + struct dynfn *dfn; \ \ + dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ if (dfn == 0) \ dfn = rmesa->vb.codegen.FN( ctx, key ); \ else if (RADEON_DEBUG & DEBUG_CODEGEN) \ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_sse.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_sse.c index 04bb48566..0f2c82bd8 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_sse.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_sse.c @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, TUNGSTEN GRAPHICS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ @@ -40,41 +41,185 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #if defined(USE_SSE_ASM) #include "X86/common_x86_asm.h" +#define EXTERN( FUNC ) \ +extern const char *FUNC; \ +extern const char *FUNC##_end + +EXTERN( _sse_Attribute2fv ); +EXTERN( _sse_Attribute2f ); +EXTERN( _sse_Attribute3fv ); +EXTERN( _sse_Attribute3f ); +EXTERN( _sse_MultiTexCoord2fv ); +EXTERN( _sse_MultiTexCoord2f ); +EXTERN( _sse_MultiTexCoord2fv_2 ); +EXTERN( _sse_MultiTexCoord2f_2 ); + /* Build specialized versions of the immediate calls on the fly for - * the current state. ???P4 SSE2 versions??? + * the current state. */ +static struct dynfn *radeon_makeSSEAttribute2fv( struct dynfn * cache, int key, + const char * name, void * dest) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", name, key ); + + DFN ( _sse_Attribute2fv, (*cache) ); + FIXUP(dfn->code, 10, 0x0, (int)dest); + return dfn; +} + +static struct dynfn *radeon_makeSSEAttribute2f( struct dynfn * cache, int key, + const char * name, void * dest ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", name, key ); + + DFN ( _sse_Attribute2f, (*cache) ); + FIXUP(dfn->code, 8, 0x0, (int)dest); + return dfn; +} + +static struct dynfn *radeon_makeSSEAttribute3fv( struct dynfn * cache, int key, + const char * name, void * dest) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", name, key ); + + DFN ( _sse_Attribute3fv, (*cache) ); + FIXUP(dfn->code, 13, 0x0, (int)dest); + FIXUP(dfn->code, 18, 0x8, 8+(int)dest); + return dfn; +} + +static struct dynfn *radeon_makeSSEAttribute3f( struct dynfn * cache, int key, + const char * name, void * dest ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", name, key ); + + DFN ( _sse_Attribute3f, (*cache) ); + FIXUP(dfn->code, 12, 0x0, (int)dest); + FIXUP(dfn->code, 17, 0x8, 8+(int)dest); + return dfn; +} + +static struct dynfn * radeon_makeSSENormal3fv( GLcontext *ctx, int key ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + return radeon_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, + __FUNCTION__, rmesa->vb.normalptr ); +} + +static struct dynfn *radeon_makeSSENormal3f( GLcontext *ctx, int key ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + return radeon_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Normal3f, key, + __FUNCTION__, rmesa->vb.normalptr ); +} + +static struct dynfn *radeon_makeSSEColor3fv( GLcontext *ctx, int key ) +{ + if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) + return 0; + else + { + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + return radeon_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, + __FUNCTION__, rmesa->vb.floatcolorptr ); + } +} + +static struct dynfn *radeon_makeSSEColor3f( GLcontext *ctx, int key ) +{ + if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) + return 0; + else + { + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + return radeon_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Color3f, key, + __FUNCTION__, rmesa->vb.floatcolorptr ); + } +} -static struct dynfn *makeSSENormal3fv( GLcontext *ctx, int key ) +static struct dynfn *radeon_makeSSETexCoord2fv( GLcontext *ctx, int key ) { - /* Requires P4 (sse2?) - */ - static unsigned char temp[] = { - 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $0x12345678,%edx */ - 0xf3, 0x0f, 0x7e, 0x00, /* movq (%eax),%xmm0 */ - 0x66, 0x0f, 0x6e, 0x48, 0x08, /* movd 0x8(%eax),%xmm1 */ - 0x66, 0x0f, 0xd6, 0x42, 0x0c, /* movq %xmm0,0xc(%edx) */ - 0x66, 0x0f, 0x7e, 0x4a, 0x14, /* movd %xmm1,0x14(%edx) */ - 0xc3, /* ret */ - }; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + return radeon_makeSSEAttribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, + __FUNCTION__, rmesa->vb.texcoordptr[0] ); +} + +static struct dynfn *radeon_makeSSETexCoord2f( GLcontext *ctx, int key ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + return radeon_makeSSEAttribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, + __FUNCTION__, rmesa->vb.texcoordptr[0] ); +} +static struct dynfn *radeon_makeSSEMultiTexCoord2fv( GLcontext *ctx, int key ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + + if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == + (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { + DFN ( _sse_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + FIXUP(dfn->code, 18, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); + } else { + DFN ( _sse_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); + } + return dfn; +} + +static struct dynfn *radeon_makeSSEMultiTexCoord2f( GLcontext *ctx, int key ) +{ struct dynfn *dfn = MALLOC_STRUCT( dynfn ); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - insert_at_head( &rmesa->vb.dfn_cache.Normal3fv, dfn ); - dfn->key = key; - dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); - memcpy (dfn->code, temp, sizeof(temp)); - FIXUP(dfn->code, 5, 0x0, (int)rmesa->vb.normalptr); + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + + if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == + (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { + DFN ( _sse_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + FIXUP(dfn->code, 16, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); + } else { + DFN ( _sse_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + FIXUP(dfn->code, 15, 0x0, (int)rmesa->vb.texcoordptr); + } return dfn; } void radeonInitSSECodegen( struct dfn_generators *gen ) { - if ( cpu_has_xmm && cpu_has_xmm2 ) - /*gen->Normal3fv = */ (void)makeSSENormal3fv; + if ( cpu_has_xmm ) { + gen->Normal3fv = (void *) radeon_makeSSENormal3fv; + gen->Normal3f = (void *) radeon_makeSSENormal3f; + gen->Color3fv = (void *) radeon_makeSSEColor3fv; + gen->Color3f = (void *) radeon_makeSSEColor3f; + gen->TexCoord2fv = (void *) radeon_makeSSETexCoord2fv; + gen->TexCoord2f = (void *) radeon_makeSSETexCoord2f; + gen->MultiTexCoord2fvARB = (void *) radeon_makeSSEMultiTexCoord2fv; + gen->MultiTexCoord2fARB = (void *) radeon_makeSSEMultiTexCoord2f; + } } #else diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_x86.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_x86.c index db5b35775..92941ca5f 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_x86.c +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_x86.c @@ -6,24 +6,25 @@ Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 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, TUNGSTEN GRAPHICS 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. +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 THE COPYRIGHT OWNER(S) AND/OR ITS 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. **************************************************************************/ @@ -43,8 +44,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern const char *FUNC; \ extern const char *FUNC##_end -EXTERN ( _x86_Normal3fv ); -EXTERN ( _x86_Normal3f ); +EXTERN ( _x86_Attribute2fv ); +EXTERN ( _x86_Attribute2f ); +EXTERN ( _x86_Attribute3fv ); +EXTERN ( _x86_Attribute3f ); EXTERN ( _x86_Vertex3fv_6 ); EXTERN ( _x86_Vertex3fv_8 ); EXTERN ( _x86_Vertex3fv ); @@ -54,14 +57,10 @@ EXTERN ( _x86_Vertex3f ); EXTERN ( _x86_Color4ubv_ub ); EXTERN ( _x86_Color4ubv_4f ); EXTERN ( _x86_Color4ub_ub ); -EXTERN ( _x86_Color3fv_3f ); -EXTERN ( _x86_Color3f_3f ); -EXTERN ( _x86_TexCoord2fv ); -EXTERN ( _x86_TexCoord2f ); -EXTERN ( _x86_MultiTexCoord2fvARB ); -EXTERN ( _x86_MultiTexCoord2fvARB_2 ); -EXTERN ( _x86_MultiTexCoord2fARB ); -EXTERN ( _x86_MultiTexCoord2fARB_2 ); +EXTERN ( _x86_MultiTexCoord2fv ); +EXTERN ( _x86_MultiTexCoord2fv_2 ); +EXTERN ( _x86_MultiTexCoord2f ); +EXTERN ( _x86_MultiTexCoord2f_2 ); /* Build specialized versions of the immediate calls on the fly for @@ -179,37 +178,88 @@ struct dynfn *radeon_makeX86Vertex3fv( GLcontext *ctx, int key ) return dfn; } -struct dynfn *radeon_makeX86Normal3fv( GLcontext *ctx, int key ) +static struct dynfn * +radeon_makeX86Attribute2fv( struct dynfn * cache, int key, + const char * name, void * dest ) { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i = 0; if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + fprintf(stderr, "%s 0x%08x\n", name, key ); - DFN ( _x86_Normal3fv, rmesa->vb.dfn_cache.Normal3fv ); + DFN ( _x86_Attribute2fv, (*cache) ); + FIXUP(dfn->code, 11, 0x0, (int)dest); + FIXUP(dfn->code, 16, 0x4, 4+(int)dest); - FIXUP2(dfn->code, i, 0x0, (int)rmesa->vb.normalptr); - FIXUP2(dfn->code, i, 0x4, 4+(int)rmesa->vb.normalptr); - FIXUP2(dfn->code, i, 0x8, 8+(int)rmesa->vb.normalptr); - /* fprintf(stderr, "%s done\n", __FUNCTION__); */ return dfn; } -struct dynfn *radeon_makeX86Normal3f( GLcontext *ctx, int key ) +static struct dynfn * +radeon_makeX86Attribute2f( struct dynfn * cache, int key, + const char * name, void * dest ) { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); + fprintf(stderr, "%s 0x%08x\n", name, key ); + + DFN ( _x86_Attribute2f, (*cache) ); + FIXUP(dfn->code, 1, 0x0, (int)dest); + + return dfn; +} + + +static struct dynfn * +radeon_makeX86Attribute3fv( struct dynfn * cache, int key, + const char * name, void * dest ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", name, key ); + + DFN ( _x86_Attribute3fv, (*cache) ); + FIXUP(dfn->code, 14, 0x0, (int)dest); + FIXUP(dfn->code, 20, 0x4, 4+(int)dest); + FIXUP(dfn->code, 25, 0x8, 8+(int)dest); - DFN ( _x86_Normal3f, rmesa->vb.dfn_cache.Normal3f ); - FIXUP(dfn->code, 1, 0x12345678, (int)rmesa->vb.normalptr); return dfn; } +static struct dynfn * +radeon_makeX86Attribute3f( struct dynfn * cache, int key, + const char * name, void * dest ) +{ + struct dynfn *dfn = MALLOC_STRUCT( dynfn ); + + if (RADEON_DEBUG & DEBUG_CODEGEN) + fprintf(stderr, "%s 0x%08x\n", name, key ); + + DFN ( _x86_Attribute3f, (*cache) ); + FIXUP(dfn->code, 14, 0x0, (int)dest); + FIXUP(dfn->code, 20, 0x4, 4+(int)dest); + FIXUP(dfn->code, 25, 0x8, 8+(int)dest); + + return dfn; +} + +struct dynfn *radeon_makeX86Normal3fv( GLcontext *ctx, int key ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + return radeon_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, + __FUNCTION__, rmesa->vb.normalptr ); +} + +struct dynfn *radeon_makeX86Normal3f( GLcontext *ctx, int key ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + return radeon_makeX86Attribute3f( & rmesa->vb.dfn_cache.Normal3f, key, + __FUNCTION__, rmesa->vb.normalptr ); +} + struct dynfn *radeon_makeX86Color4ubv( GLcontext *ctx, int key ) { struct dynfn *dfn = MALLOC_STRUCT( dynfn ); @@ -263,15 +313,10 @@ struct dynfn *radeon_makeX86Color3fv( GLcontext *ctx, int key ) return 0; else { - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - DFN ( _x86_Color3fv_3f, rmesa->vb.dfn_cache.Color3fv ); - FIXUP(dfn->code, 5, 0x0, (int)rmesa->vb.floatcolorptr); - return dfn; + return radeon_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, + __FUNCTION__, rmesa->vb.floatcolorptr ); } } @@ -281,15 +326,10 @@ struct dynfn *radeon_makeX86Color3f( GLcontext *ctx, int key ) return 0; else { - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - DFN ( _x86_Color3f_3f, rmesa->vb.dfn_cache.Color3f ); - FIXUP(dfn->code, 1, 0x12345678, (int)rmesa->vb.floatcolorptr); - return dfn; + return radeon_makeX86Attribute3f( & rmesa->vb.dfn_cache.Color3f, key, + __FUNCTION__, rmesa->vb.floatcolorptr ); } } @@ -297,61 +337,22 @@ struct dynfn *radeon_makeX86Color3f( GLcontext *ctx, int key ) struct dynfn *radeon_makeX86TexCoord2fv( GLcontext *ctx, int key ) { - - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - DFN ( _x86_TexCoord2fv, rmesa->vb.dfn_cache.TexCoord2fv ); - FIXUP(dfn->code, 5, 0x12345678, (int)rmesa->vb.texcoordptr[0]); - return dfn; + return radeon_makeX86Attribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, + __FUNCTION__, rmesa->vb.texcoordptr[0] ); } struct dynfn *radeon_makeX86TexCoord2f( GLcontext *ctx, int key ) { - - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - DFN ( _x86_TexCoord2f, rmesa->vb.dfn_cache.TexCoord2f ); - FIXUP(dfn->code, 1, 0x12345678, (int)rmesa->vb.texcoordptr[0]); - return dfn; + return radeon_makeX86Attribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, + __FUNCTION__, rmesa->vb.texcoordptr[0] ); } struct dynfn *radeon_makeX86MultiTexCoord2fvARB( GLcontext *ctx, int key ) { -#if 0 - static char temp[] = { - 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */ - 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ - 0x83, 0xe0, 0x01, /* and $0x1,%eax */ - 0x8b, 0x11, /* mov (%ecx),%edx */ - 0xc1, 0xe0, 0x03, /* shl $0x3,%eax */ - 0x8b, 0x49, 0x04, /* mov 0x4(%ecx),%ecx */ - 0x89, 0x90, 0, 0, 0, 0,/* mov %edx,DEST(%eax) */ - 0x89, 0x88, 0, 0, 0, 0,/* mov %ecx,DEST+8(%eax) */ - 0xc3, /* ret */ - }; - static char temp2[] = { - 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */ - 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ - 0x83, 0xe0, 0x01, /* and $0x1,%eax */ - 0x8b, 0x14, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%edx */ - 0x8b, 0x01, /* mov (%ecx),%eax */ - 0x89, 0x02, /* mov %eax,(%edx) */ - 0x8b, 0x41, 0x04, /* mov 0x4(%ecx),%eax */ - 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */ - 0xc3, /* ret */ - }; -#endif - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); @@ -360,12 +361,12 @@ struct dynfn *radeon_makeX86MultiTexCoord2fvARB( GLcontext *ctx, int key ) if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { - DFN ( _x86_MultiTexCoord2fvARB, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 26, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 32, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); + DFN ( _x86_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + FIXUP(dfn->code, 21, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); + FIXUP(dfn->code, 27, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); } else { - DFN ( _x86_MultiTexCoord2fvARB_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 19, 0x0, (int)rmesa->vb.texcoordptr); + DFN ( _x86_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); + FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); } return dfn; } @@ -373,31 +374,6 @@ struct dynfn *radeon_makeX86MultiTexCoord2fvARB( GLcontext *ctx, int key ) struct dynfn *radeon_makeX86MultiTexCoord2fARB( GLcontext *ctx, int key ) { -#if 0 - static char temp[] = { - 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */ - 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ - 0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */ - 0x83, 0xe0, 0x01, /* and $0x1,%eax */ - 0xc1, 0xe0, 0x03, /* shl $0x3,%eax */ - 0x89, 0x90, 0, 0, 0, 0, /* mov %edx,DEST(%eax) */ - 0x89, 0x88, 0, 0, 0, 0, /* mov %ecx,DEST+8(%eax) */ - 0xc3, /* ret */ - }; - - static char temp2[] = { - 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */ - 0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */ - 0x2d, 0xc0, 0x84, 0x00, 0x00, /* sub $0x84c0,%eax */ - 0x8b, 0x4c, 0x24, 0x0c, /* mov 0xc(%esp,1),%ecx */ - 0x83, 0xe0, 0x01, /* and $0x1,%eax */ - 0x8b, 0x04, 0x85, 0, 0, 0, 0, /* mov DEST(,%eax,4),%eax */ - 0x89, 0x10, /* mov %edx,(%eax) */ - 0x89, 0x48, 0x04, /* mov %ecx,0x4(%eax) */ - 0xc3, /* ret */ - }; -#endif struct dynfn *dfn = MALLOC_STRUCT( dynfn ); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); @@ -406,16 +382,16 @@ struct dynfn *radeon_makeX86MultiTexCoord2fARB( GLcontext *ctx, if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { - DFN ( _x86_MultiTexCoord2fARB, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 25, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 31, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); + DFN ( _x86_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + FIXUP(dfn->code, 20, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); + FIXUP(dfn->code, 26, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); } else { /* Note: this might get generated multiple times, even though the * actual emitted code is the same. */ - DFN ( _x86_MultiTexCoord2fARB_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 23, 0x0, (int)rmesa->vb.texcoordptr); + DFN ( _x86_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); + FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.texcoordptr); } return dfn; } diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S index f41c37fc3..c77b41059 100644 --- a/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S @@ -32,16 +32,6 @@ x: .data .align 4 -GLOBL( _x86_Normal3fv) - movl 4(%esp), %eax /* load 'v' off stack */ - movl (%eax), %ecx /* load v[0] */ - movl 4(%eax), %edx /* load v[1] */ - movl 8(%eax), %eax /* load v[2] */ - movl %ecx, 0 /* store v[0] to current vertex */ - movl %edx, 4 /* store v[1] to current vertex */ - movl %eax, 8 /* store v[2] to current vertex */ - ret -GLOBL ( _x86_Normal3fv_end ) /* vertex 3f vertex size 4 @@ -218,19 +208,70 @@ GLOBL ( _x86_Vertex3fv ) .6: jmp *0 GLOBL ( _x86_Vertex3fv_end ) -/* - Normal 3f -*/ -GLOBL ( _x86_Normal3f ) - movl $0x12345678, %edx + +/** + * Generic handler for 2 float format data. This can be used for + * TexCoord2f and possibly other functions. + */ + +GLOBL ( _x86_Attribute2f ) + movl $0x0, %edx movl 4(%esp), %eax + movl 8(%esp), %ecx movl %eax, (%edx) - movl 8(%esp), %eax - movl %eax, 4(%edx) + movl %ecx, 4(%edx) + ret +GLOBL ( _x86_Attribute2f_end ) + + +/** + * Generic handler for 2 float vector format data. This can be used for + * TexCoord2fv and possibly other functions. + */ + +GLOBL( _x86_Attribute2fv) + movl 4(%esp), %eax /* load 'v' off stack */ + movl (%eax), %ecx /* load v[0] */ + movl 4(%eax), %eax /* load v[1] */ + movl %ecx, 0 /* store v[0] to current vertex */ + movl %eax, 4 /* store v[1] to current vertex */ + ret +GLOBL ( _x86_Attribute2fv_end ) + + +/** + * Generic handler for 3 float format data. This can be used for + * Normal3f, Color3f (when the color target is also float), or + * TexCoord3f. + */ + +GLOBL ( _x86_Attribute3f ) + movl 4(%esp), %ecx + movl 8(%esp), %edx movl 12(%esp), %eax - movl %eax, 8(%edx) + movl %ecx, 0 + movl %edx, 4 + movl %eax, 8 ret -GLOBL ( _x86_Normal3f_end ) +GLOBL ( _x86_Attribute3f_end ) + +/** + * Generic handler for 3 float vector format data. This can be used for + * Normal3f, Color3f (when the color target is also float), or + * TexCoord3f. + */ + +GLOBL( _x86_Attribute3fv) + movl 4(%esp), %eax /* load 'v' off stack */ + movl (%eax), %ecx /* load v[0] */ + movl 4(%eax), %edx /* load v[1] */ + movl 8(%eax), %eax /* load v[2] */ + movl %ecx, 0 /* store v[0] to current vertex */ + movl %edx, 4 /* store v[1] to current vertex */ + movl %eax, 8 /* store v[2] to current vertex */ + ret +GLOBL ( _x86_Attribute3fv_end ) + /* Color 4ubv_ub @@ -290,69 +331,13 @@ GLOBL( _x86_Color4ub_ub ) ret GLOBL( _x86_Color4ub_ub_end ) -/* - Color3fv_3f -*/ -GLOBL( _x86_Color3fv_3f ) - movl 4(%esp), %eax - movl $0, %edx - movl (%eax), %ecx - movl %ecx, (%edx) - movl 4(%eax), %ecx - movl %ecx, 4(%edx) - movl 8(%eax), %ecx - movl %ecx, 8(%edx) - ret -GLOBL( _x86_Color3fv_3f_end ) - -/* - Color3f_3f -*/ -GLOBL( _x86_Color3f_3f ) - movl $0x12345678, %edx - movl 4(%esp), %eax - movl %eax, (%edx) - movl 8(%esp,1), %eax - movl %eax, 4(%edx) - movl 12(%esp), %eax - movl %eax, 8(%edx) - ret -GLOBL( _x86_Color3f_3f_end ) /* - TexCoord2fv + MultiTexCoord2fv st0/st1 */ - -GLOBL( _x86_TexCoord2fv ) - movl 4(%esp), %eax - movl $0x12345678, %edx - movl (%eax), %ecx - movl 4(%eax), %eax - movl %ecx, (%edx) - movl %eax, 4(%edx) - ret - -GLOBL( _x86_TexCoord2fv_end ) -/* - TexCoord2f -*/ -GLOBL( _x86_TexCoord2f ) - movl $0x12345678, %edx +GLOBL( _x86_MultiTexCoord2fv ) movl 4(%esp), %eax movl 8(%esp), %ecx - movl %eax, (%edx) - movl %ecx, 4(%edx) - ret -GLOBL( _x86_TexCoord2f_end ) - -/* - MultiTexCoord2fvARB st0/st1 -*/ -GLOBL( _x86_MultiTexCoord2fvARB ) - - movl 4(%esp), %eax - movl 8(%esp), %ecx - sub $0x84c0, %eax and $1, %eax movl (%ecx), %edx shl $3, %eax @@ -360,15 +345,15 @@ GLOBL( _x86_MultiTexCoord2fvARB ) movl %edx, 0xdeadbeef(%eax) movl %ecx, 0xdeadbeef(%eax) ret -GLOBL( _x86_MultiTexCoord2fvARB_end ) +GLOBL( _x86_MultiTexCoord2fv_end ) + /* - MultiTexCoord2fvARB + MultiTexCoord2fv */ -GLOBL( _x86_MultiTexCoord2fvARB_2 ) +GLOBL( _x86_MultiTexCoord2fv_2 ) movl 4(%esp,1), %eax movl 8(%esp,1), %ecx - sub $0x84c0, %eax and $0x1, %eax movl 0(,%eax,4), %edx movl (%ecx), %eax @@ -376,35 +361,132 @@ GLOBL( _x86_MultiTexCoord2fvARB_2 ) movl 4(%ecx), %eax movl %eax, 4(%edx) ret - -GLOBL( _x86_MultiTexCoord2fvARB_2_end ) +GLOBL( _x86_MultiTexCoord2fv_2_end ) /* - MultiTexCoord2fARB st0/st1 + MultiTexCoord2f st0/st1 */ -GLOBL( _x86_MultiTexCoord2fARB ) +GLOBL( _x86_MultiTexCoord2f ) movl 4(%esp), %eax movl 8(%esp), %edx - sub $0x84c0, %eax movl 12(%esp), %ecx and $1, %eax shl $3, %eax movl %edx, 0xdeadbeef(%eax) movl %ecx, 0xdeadbeef(%eax) ret -GLOBL( _x86_MultiTexCoord2fARB_end ) +GLOBL( _x86_MultiTexCoord2f_end ) /* - MultiTexCoord2fARB + MultiTexCoord2f */ -GLOBL( _x86_MultiTexCoord2fARB_2 ) +GLOBL( _x86_MultiTexCoord2f_2 ) movl 4(%esp), %eax movl 8(%esp), %edx - sub $0x84c0, %eax movl 12(%esp,1), %ecx and $1,%eax movl 0(,%eax,4), %eax movl %edx, (%eax) movl %ecx, 4(%eax) ret -GLOBL( _x86_MultiTexCoord2fARB_2_end ) +GLOBL( _x86_MultiTexCoord2f_2_end ) + +/** + * This can be used as a template for either Color3fv (when the color + * target is also a 3f) or Normal3fv. + */ + +GLOBL( _sse_Attribute3fv ) + movl 4(%esp), %eax + movlps (%eax), %xmm0 + movl 8(%eax), %eax + movlps %xmm0, 0 + movl %eax, 8 + ret +GLOBL( _sse_Attribute3fv_end ) + +/** + * This can be used as a template for either Color3f (when the color + * target is also a 3f) or Normal3f. + */ + +GLOBL( _sse_Attribute3f ) + movlps 4(%esp), %xmm0 + movl 12(%esp), %eax + movlps %xmm0, 0 + movl %eax, 8 + ret +GLOBL( _sse_Attribute3f_end ) + + +/** + * Generic handler for 2 float vector format data. This can be used for + * TexCoord2fv and possibly other functions. + */ + +GLOBL( _sse_Attribute2fv ) + movl 4(%esp), %eax + movlps (%eax), %xmm0 + movlps %xmm0, 0 + ret +GLOBL( _sse_Attribute2fv_end ) + + +/** + * Generic handler for 2 float format data. This can be used for + * TexCoord2f and possibly other functions. + */ + +GLOBL( _sse_Attribute2f ) + movlps 4(%esp), %xmm0 + movlps %xmm0, 0 + ret +GLOBL( _sse_Attribute2f_end ) + +/* + MultiTexCoord2fv st0/st1 +*/ +GLOBL( _sse_MultiTexCoord2fv ) + movl 4(%esp), %eax + movl 8(%esp), %ecx + and $1, %eax + movlps (%ecx), %xmm0 + movlps %xmm0, 0xdeadbeef(,%eax,8) + ret +GLOBL( _sse_MultiTexCoord2fv_end ) + +/* + MultiTexCoord2fv +*/ +GLOBL( _sse_MultiTexCoord2fv_2 ) + movl 4(%esp), %eax + movl 8(%esp), %ecx + and $0x1, %eax + movl 0(,%eax,4), %edx + movlps (%ecx), %xmm0 + movlps %xmm0, (%edx) + ret +GLOBL( _sse_MultiTexCoord2fv_2_end ) + +/* + MultiTexCoord2f st0/st1 +*/ +GLOBL( _sse_MultiTexCoord2f ) + movl 4(%esp), %eax + and $1, %eax + movlps 8(%esp), %xmm0 + movlps %xmm0, 0xdeadbeef(,%eax,8) + ret +GLOBL( _sse_MultiTexCoord2f_end ) + +/* + MultiTexCoord2f +*/ +GLOBL( _sse_MultiTexCoord2f_2 ) + movl 4(%esp), %eax + movlps 8(%esp), %xmm0 + and $1,%eax + movl 0(,%eax,4), %eax + movlps %xmm0, (%eax) + ret +GLOBL( _sse_MultiTexCoord2f_2_end ) diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c index 390538a93..b34779c21 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texman.c @@ -504,7 +504,7 @@ FindStartAddr(tdfxContextPtr fxMesa, FxU32 tmu, FxU32 size) #if 0 discardedCount++; if (discardedCount > MAX_DISCARDS + 1) { - _mesa_problem(NULL, "tdfx driver: extreme texmem fragmentation"); + _mesa_problem(NULL, "%s: extreme texmem fragmentation", __FUNCTION__); _glthread_UNLOCK_MUTEX(mesaShared->Mutex); return BAD_ADDRESS; } @@ -521,7 +521,7 @@ FindStartAddr(tdfxContextPtr fxMesa, FxU32 tmu, FxU32 size) fxMesa->stats.texSwaps++; } else { - _mesa_problem(NULL, "tdfx driver: extreme texmem fragmentation"); + _mesa_problem(NULL, "%s: extreme texmem fragmentation", __FUNCTION__); _glthread_UNLOCK_MUTEX(mesaShared->Mutex); return BAD_ADDRESS; } @@ -621,10 +621,8 @@ AllocTexMem(tdfxContextPtr fxMesa, FxU32 tmu, FxU32 texmemsize) FxU32 startAddr; startAddr = FindStartAddr(fxMesa, tmu, texmemsize); if (startAddr == BAD_ADDRESS) { - char err[100]; - sprintf(err, "AllocTexMem returned NULL! tmu=%d texmemsize=%d\n", - (int) tmu, (int) texmemsize); - _mesa_problem(fxMesa->glCtx, err); + _mesa_problem(fxMesa->glCtx, "%s returned NULL! tmu=%d texmemsize=%d", + __FUNCTION__, (int) tmu, (int) texmemsize); return NULL; } else { @@ -721,7 +719,7 @@ tdfxTMDownloadTexture(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) } break; default: - _mesa_problem(NULL, "error in tdfxTMDownloadTexture: bad tmu"); + _mesa_problem(NULL, "%s: bad tmu (%d)", __FUNCTION__, (int)targetTMU); return; } } @@ -794,7 +792,7 @@ tdfxTMReloadMipMapLevel(GLcontext *ctx, struct gl_texture_object *tObj, break; default: - _mesa_problem(ctx, "error in tdfxTMReloadMipMapLevel(): wrong tmu"); + _mesa_problem(ctx, "%s: bad tmu (%d)", __FUNCTION__, (int)tmu); break; } UNLOCK_HARDWARE(fxMesa); @@ -859,7 +857,7 @@ tdfxTMMoveInTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj, ti->tm[TDFX_TMU1] = AllocTexMem(fxMesa, TDFX_TMU1, texmemsize); break; default: - _mesa_problem(NULL, "error in tdfxTMMoveInTM() -> bad tmu (%d)"); + _mesa_problem(NULL, "%s: bad tmu (%d)", __FUNCTION__, (int)targetTMU); return; } @@ -882,7 +880,7 @@ tdfxTMMoveOutTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj ) tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); if (MESA_VERBOSE & VERBOSE_DRIVER) { - fprintf(stderr, "fxmesa: fxTMMoveOutTM(%p (%d))\n", tObj, tObj->Name); + fprintf(stderr, "fxmesa: %s(%p (%d))\n", __FUNCTION__, tObj, tObj->Name); } /* @@ -905,7 +903,7 @@ tdfxTMMoveOutTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj ) RemoveRange_NoLock(fxMesa, TDFX_TMU1, ti->tm[TDFX_TMU1]); break; default: - _mesa_problem(NULL, "tdfx driver: bad tmu in tdfxTMMOveOutTM()"); + _mesa_problem(NULL, "%s: bad tmu (%d)", __FUNCTION__, (int)ti->whichTMU); return; } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c index a20215cb8..e20938bf2 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c @@ -799,7 +799,7 @@ SetupTexEnvNapalm(GLcontext *ctx, GLboolean useIteratedRGBA, break; default: - _mesa_problem(ctx, "Bad envMode in SetupTexEnvNapalm"); + _mesa_problem(ctx, "%s: Bad envMode", __FUNCTION__); } fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_ENV; @@ -1009,7 +1009,7 @@ SetupSingleTexEnvVoodoo3(GLcontext *ctx, int unit, break; default: - _mesa_problem(NULL, "bad texture env mode in SetupSingleTexEnvVoodoo3"); + _mesa_problem(ctx, "bad texture env mode in %s", __FUNCTION__); } if (colorComb.Function != fxMesa->ColorCombine.Function || @@ -1251,7 +1251,7 @@ SetupDoubleTexEnvVoodoo3(GLcontext *ctx, int tmu0, fxMesa->AlphaCombine.Invert = FXFALSE; } else { - /*_mesa_problem(ctx, "Unexpected dual texture mode encountered\n");*/ + /*_mesa_problem(ctx, "%s: Unexpected dual texture mode encountered", __FUNCTION__);*/ return GL_FALSE; } |