# HG changeset patch # User nkeynes # Date 1287885017 -36000 # Node ID 68daed8f38afabca94f35f4dbb3efab3aa9f8e3c # Parent f502f3d32f906dca1286d2dd1780acb61e553683 Set gl texture parameters at texture load time rather than render time. (This does mean that if the texture is used with variant parameters it will be loaded multiple times). 3-4% faster this way --- a/src/pvr2/glrender.c Fri Oct 22 20:55:32 2010 +1000 +++ b/src/pvr2/glrender.c Sun Oct 24 11:50:17 2010 +1000 @@ -61,20 +61,16 @@ { int i; - texcache_set_config( MMIO_READ( PVR2, RENDER_PALETTE ) & 0x03, + texcache_begin_scene( MMIO_READ( PVR2, RENDER_PALETTE ) & 0x03, (MMIO_READ( PVR2, RENDER_TEXSIZE ) & 0x003F) << 5 ); for( i=0; i < pvr2_scene.poly_count; i++ ) { struct polygon_struct *poly = &pvr2_scene.poly_array[i]; if( POLY1_TEXTURED(poly->context[0]) ) { - poly->tex_id = texcache_get_texture( poly->context[2], - POLY2_TEX_WIDTH(poly->context[1]), - POLY2_TEX_HEIGHT(poly->context[1]) ); + poly->tex_id = texcache_get_texture( poly->context[1], poly->context[2] ); if( poly->mod_vertex_index != -1 ) { if( pvr2_scene.shadow_mode == SHADOW_FULL ) { - poly->mod_tex_id = texcache_get_texture( poly->context[4], - POLY2_TEX_WIDTH(poly->context[3]), - POLY2_TEX_HEIGHT(poly->context[3]) ); + poly->mod_tex_id = texcache_get_texture( poly->context[3], poly->context[4] ); } else { poly->mod_tex_id = poly->tex_id; } @@ -155,21 +151,6 @@ if( POLY1_TEXTURED(poly1) ) { glEnable(GL_TEXTURE_2D); glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, pvr2_poly_texblend[POLY2_TEX_BLEND(poly2)] ); - - if( POLY2_TEX_CLAMP_U(poly2) ) { - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); - } else if( POLY2_TEX_MIRROR_U(poly2) ) { - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT_ARB ); - } else { - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); - } - if( POLY2_TEX_CLAMP_V(poly2) ) { - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); - } else if( POLY2_TEX_MIRROR_V(poly2) ) { - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT_ARB ); - } else { - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); - } } else { glDisable( GL_TEXTURE_2D ); } --- a/src/pvr2/pvr2.h Fri Oct 22 20:55:32 2010 +1000 +++ b/src/pvr2/pvr2.h Sun Oct 24 11:50:17 2010 +1000 @@ -344,7 +344,7 @@ * Set the global texture parameters for the scene (possibly invalidating * some existing textures) */ -void texcache_set_config( uint32_t palette_mode, uint32_t stride_width ); +void texcache_begin_scene( uint32_t palette_mode, uint32_t stride_width ); /** * Return a texture ID for the texture specified at the supplied address @@ -356,7 +356,7 @@ * If the texture has already been bound, return the ID to which it was * bound. Otherwise obtain an unused texture ID and set it up appropriately. */ -GLuint texcache_get_texture( uint32_t texture_word, int width, int height ); +GLuint texcache_get_texture( uint32_t poly2_word, uint32_t texture_word ); render_buffer_t texcache_get_render_buffer( uint32_t texture_addr, int mode, int width, int height ); --- a/src/pvr2/texcache.c Fri Oct 22 20:55:32 2010 +1000 +++ b/src/pvr2/texcache.c Sun Oct 24 11:50:17 2010 +1000 @@ -47,7 +47,7 @@ typedef struct texcache_entry { uint32_t texture_addr; - int width, height, mode; + uint32_t poly2_mode, tex_mode; GLuint texture_id; render_buffer_t buffer; texcache_entry_index next; @@ -230,7 +230,7 @@ int i; for( i=0; i> 12; @@ -587,10 +587,8 @@ texcache_entry_index idx = texcache_page_lookup[texture_page]; while( idx != EMPTY_ENTRY ) { texcache_entry_t entry = &texcache_active_list[idx]; - if( entry->texture_addr == texture_addr && - entry->mode == texture_word && - entry->width == width && - entry->height == height ) { + if( entry->tex_mode == texture_word && + entry->poly2_mode == poly2_masked_word ) { entry->lru_count = texcache_ref_counter++; return idx; } @@ -599,7 +597,7 @@ return -1; } -static int texcache_alloc_texture_slot( uint32_t texture_word, int width, int height ) +static int texcache_alloc_texture_slot( uint32_t poly2_word, uint32_t texture_word ) { uint32_t texture_addr = (texture_word & 0x000FFFFF)<<3; uint32_t texture_page = texture_addr >> 12; @@ -614,9 +612,8 @@ /* Construct new entry */ assert( texcache_active_list[slot].texture_addr == -1 ); texcache_active_list[slot].texture_addr = texture_addr; - texcache_active_list[slot].width = width; - texcache_active_list[slot].height = height; - texcache_active_list[slot].mode = texture_word; + texcache_active_list[slot].tex_mode = texture_word; + texcache_active_list[slot].poly2_mode = poly2_word; texcache_active_list[slot].lru_count = texcache_ref_counter++; /* Add entry to the lookup table */ @@ -640,29 +637,50 @@ * Return a texture ID for the texture specified at the supplied address * and given parameters (the same sequence of bytes could in theory have * multiple interpretations). We use the texture address as the primary - * index, but allow for multiple instances at each address. The texture - * will be bound to the GL_TEXTURE_2D target before being returned. + * index, but allow for multiple instances at each address. * * If the texture has already been bound, return the ID to which it was * bound. Otherwise obtain an unused texture ID and set it up appropriately. + * The current GL_TEXTURE_2D binding will be changed in this case. */ -GLuint texcache_get_texture( uint32_t texture_word, int width, int height ) +GLuint texcache_get_texture( uint32_t poly2_word, uint32_t texture_word ) { - int slot = texcache_find_texture_slot( texture_word, width, height ); + poly2_word &= 0x000F803F; /* Get just the texture-relevant bits */ + int slot = texcache_find_texture_slot( poly2_word, texture_word ); if( slot == -1 ) { /* Not found - check the free list */ - slot = texcache_alloc_texture_slot( texture_word, width, height ); + slot = texcache_alloc_texture_slot( poly2_word, texture_word ); /* Construct the GL texture */ uint32_t texture_addr = (texture_word & 0x000FFFFF)<<3; + unsigned width = POLY2_TEX_WIDTH(poly2_word); + unsigned height = POLY2_TEX_HEIGHT(poly2_word); + glBindTexture( GL_TEXTURE_2D, texcache_active_list[slot].texture_id ); texcache_load_texture( texture_addr, width, height, texture_word ); + + /* Set texture parameters from the poly2 word */ + if( POLY2_TEX_CLAMP_U(poly2_word) ) { + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); + } else if( POLY2_TEX_MIRROR_U(poly2_word) ) { + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT_ARB ); + } else { + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + } + if( POLY2_TEX_CLAMP_V(poly2_word) ) { + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); + } else if( POLY2_TEX_MIRROR_V(poly2_word) ) { + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT_ARB ); + } else { + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + } } return texcache_active_list[slot].texture_id; } +#if 0 render_buffer_t texcache_get_render_buffer( uint32_t texture_addr, int mode, int width, int height ) { uint32_t texture_word = ((texture_addr >> 3) & 0x000FFFFF) | PVR2_TEX_UNTWIDDLED; @@ -693,6 +711,7 @@ return entry->buffer; } +#endif /** * Check the integrity of the texcache. Verifies that every cache slot