Search
lxdream.org :: lxdream/src/pvr2/texcache.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/texcache.c
changeset 337:cdd757aa8e8c
prev329:4b453d68e9ae
next349:05c9b25c361d
author nkeynes
date Sun Jan 28 11:36:00 2007 +0000 (13 years ago)
permissions -rw-r--r--
last change Invalidate palette textures when the palette changes (fixes a few texture
bugs)
Fix odd/even selection in pvr2_display_frame
file annotate diff log raw
1.1 --- a/src/pvr2/texcache.c Thu Jan 25 13:03:23 2007 +0000
1.2 +++ b/src/pvr2/texcache.c Sun Jan 28 11:36:00 2007 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: texcache.c,v 1.23 2007-01-25 13:03:23 nkeynes Exp $
1.6 + * $Id: texcache.c,v 1.24 2007-01-28 11:36:00 nkeynes Exp $
1.7 *
1.8 * Texture cache. Responsible for maintaining a working set of OpenGL
1.9 * textures.
1.10 @@ -66,6 +66,7 @@
1.11 }
1.12 for( i=0; i<MAX_TEXTURES; i++ ) {
1.13 texcache_free_list[i] = i;
1.14 + texcache_active_list[i].texture_addr = -1;
1.15 }
1.16 texcache_free_ptr = 0;
1.17 texcache_ref_counter = 0;
1.18 @@ -120,47 +121,12 @@
1.19 glDeleteTextures( MAX_TEXTURES, texids );
1.20 }
1.21
1.22 -/**
1.23 - * Evict all textures contained in the page identified by a texture address.
1.24 - */
1.25 -void texcache_invalidate_page( uint32_t texture_addr ) {
1.26 - uint32_t texture_page = texture_addr >> 12;
1.27 - texcache_entry_index idx = texcache_page_lookup[texture_page];
1.28 - if( idx == EMPTY_ENTRY )
1.29 - return;
1.30 - assert( texcache_free_ptr >= 0 );
1.31 - do {
1.32 - texcache_entry_t entry = &texcache_active_list[idx];
1.33 - /* release entry */
1.34 - texcache_free_ptr--;
1.35 - texcache_free_list[texcache_free_ptr] = idx;
1.36 - idx = entry->next;
1.37 - entry->next = EMPTY_ENTRY;
1.38 - } while( idx != EMPTY_ENTRY );
1.39 - texcache_page_lookup[texture_page] = EMPTY_ENTRY;
1.40 -}
1.41 -
1.42 -/**
1.43 - * Evict a single texture from the cache.
1.44 - * @return the slot of the evicted texture.
1.45 - */
1.46 -static texcache_entry_index texcache_evict( void )
1.47 +static void texcache_evict( int slot )
1.48 {
1.49 - /* Full table scan - take over the entry with the lowest lru value */
1.50 - texcache_entry_index slot = 0;
1.51 - int lru_value = texcache_active_list[0].lru_count;
1.52 - int i;
1.53 - for( i=1; i<MAX_TEXTURES; i++ ) {
1.54 - /* FIXME: account for rollover */
1.55 - if( texcache_active_list[i].lru_count < lru_value ) {
1.56 - slot = i;
1.57 - lru_value = texcache_active_list[i].lru_count;
1.58 - }
1.59 - }
1.60 -
1.61 /* Remove the selected slot from the lookup table */
1.62 uint32_t evict_page = texcache_active_list[slot].texture_addr >> 12;
1.63 texcache_entry_index replace_next = texcache_active_list[slot].next;
1.64 + texcache_active_list[slot].texture_addr = -1;
1.65 texcache_active_list[slot].next = EMPTY_ENTRY; /* Just for safety */
1.66 if( texcache_page_lookup[evict_page] == slot ) {
1.67 texcache_page_lookup[evict_page] = replace_next;
1.68 @@ -176,9 +142,68 @@
1.69 idx = next;
1.70 } while( next != EMPTY_ENTRY );
1.71 }
1.72 +}
1.73 +
1.74 +/**
1.75 + * Evict a single texture from the cache.
1.76 + * @return the slot of the evicted texture.
1.77 + */
1.78 +static texcache_entry_index texcache_evict_lru( void )
1.79 +{
1.80 + /* Full table scan - take over the entry with the lowest lru value */
1.81 + texcache_entry_index slot = 0;
1.82 + int lru_value = texcache_active_list[0].lru_count;
1.83 + int i;
1.84 + for( i=1; i<MAX_TEXTURES; i++ ) {
1.85 + /* FIXME: account for rollover */
1.86 + if( texcache_active_list[i].lru_count < lru_value ) {
1.87 + slot = i;
1.88 + lru_value = texcache_active_list[i].lru_count;
1.89 + }
1.90 + }
1.91 + texcache_evict(slot);
1.92 +
1.93 return slot;
1.94 }
1.95
1.96 +/**
1.97 + * Evict all textures contained in the page identified by a texture address.
1.98 + */
1.99 +void texcache_invalidate_page( uint32_t texture_addr ) {
1.100 + uint32_t texture_page = texture_addr >> 12;
1.101 + texcache_entry_index idx = texcache_page_lookup[texture_page];
1.102 + if( idx == EMPTY_ENTRY )
1.103 + return;
1.104 + assert( texcache_free_ptr >= 0 );
1.105 + do {
1.106 + texcache_entry_t entry = &texcache_active_list[idx];
1.107 + entry->texture_addr = -1;
1.108 + /* release entry */
1.109 + texcache_free_ptr--;
1.110 + texcache_free_list[texcache_free_ptr] = idx;
1.111 + idx = entry->next;
1.112 + entry->next = EMPTY_ENTRY;
1.113 + } while( idx != EMPTY_ENTRY );
1.114 + texcache_page_lookup[texture_page] = EMPTY_ENTRY;
1.115 +}
1.116 +
1.117 +/**
1.118 + * Mark all textures that use the palette table as needing a re-read (ie
1.119 + * for when the palette is changed. We could track exactly which ones are
1.120 + * affected, but it's not clear that the extra maintanence overhead is
1.121 + * worthwhile.
1.122 + */
1.123 +void texcache_invalidate_palette( )
1.124 +{
1.125 + int i;
1.126 + for( i=0; i<MAX_TEXTURES; i++ ) {
1.127 + if( texcache_active_list[i].texture_addr != -1 &&
1.128 + PVR2_TEX_IS_PALETTE(texcache_active_list[i].mode) ) {
1.129 + texcache_evict( i );
1.130 + }
1.131 + }
1.132 +}
1.133 +
1.134 static void decode_pal8_to_32( uint32_t *out, uint8_t *in, int inbytes, uint32_t *pal )
1.135 {
1.136 int i;
1.137 @@ -500,7 +525,7 @@
1.138 if( texcache_free_ptr < MAX_TEXTURES ) {
1.139 slot = texcache_free_list[texcache_free_ptr++];
1.140 } else {
1.141 - slot = texcache_evict();
1.142 + slot = texcache_evict_lru();
1.143 }
1.144
1.145 /* Construct new entry */
.