# HG changeset patch # User nkeynes # Date 1169984160 0 # Node ID cdd757aa8e8cfc9199e08a670d6672014ba63f1d # Parent c3455be86ee20b9b3ebc4d6c9474b4c1660ac2c3 Invalidate palette textures when the palette changes (fixes a few texture bugs) Fix odd/even selection in pvr2_display_frame --- a/src/pvr2/pvr2.c Sat Jan 27 12:04:22 2007 +0000 +++ b/src/pvr2/pvr2.c Sun Jan 28 11:36:00 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: pvr2.c,v 1.42 2007-01-27 12:03:53 nkeynes Exp $ + * $Id: pvr2.c,v 1.43 2007-01-28 11:36:00 nkeynes Exp $ * * PVR2 (Video) Core module implementation and MMIO registers. * @@ -75,6 +75,7 @@ uint32_t irq_vpos1; uint32_t irq_vpos2; uint32_t odd_even_field; /* 1 = odd, 0 = even */ + gboolean palette_changed; /* TRUE if palette has changed since last render */ gchar *save_next_render_filename; /* timing */ uint32_t dot_clock; @@ -149,6 +150,7 @@ pvr2_state.timing = ntsc_timing; pvr2_state.dot_clock = PVR2_DOT_CLOCK; pvr2_state.back_porch_ns = 4000; + pvr2_state.palette_changed = FALSE; mmio_region_PVR2_write( DISP_TOTAL, 0x0270035F ); mmio_region_PVR2_write( DISP_SYNCTIME, 0x07D6A53F ); mmio_region_PVR2_write( YUV_ADDR, 0 ); @@ -204,6 +206,7 @@ if( pvr2_state.line_count >= pvr2_state.retrace_end_line && (old_line_count < pvr2_state.retrace_end_line || old_line_count > pvr2_state.line_count) ) { + pvr2_state.frame_count++; pvr2_display_frame(); } } @@ -259,8 +262,16 @@ buffer->vres <<= 1; buffer->rowstride = vid_ppl << 2; display_addr = MMIO_READ( PVR2, DISP_ADDR1 ); - } else { /* Just display the field as is, folks */ - if( pvr2_state.odd_even_field ) { + } else { + /* Just display the field as is, folks. This is slightly tricky - + * we pick the field based on which frame is about to come through, + * which may not be the same as the odd_even_field. + */ + gboolean oddfield = pvr2_state.odd_even_field; + if( pvr2_state.line_count >= pvr2_state.retrace_start_line ) { + oddfield = !oddfield; + } + if( oddfield ) { display_addr = MMIO_READ( PVR2, DISP_ADDR1 ); } else { display_addr = MMIO_READ( PVR2, DISP_ADDR2 ); @@ -308,7 +319,6 @@ display_driver->display_frame( buffer ); } } - pvr2_state.frame_count++; } /** @@ -362,14 +372,23 @@ case DISP_ADDR1: val &= 0x00FFFFFC; MMIO_WRITE( PVR2, reg, val ); + /* pvr2_update_raster_posn(sh4r.slice_cycle); - if( pvr2_state.line_count >= pvr2_state.retrace_start_line || - pvr2_state.line_count < pvr2_state.retrace_end_line ) { + fprintf( stderr, "Set Field 1 addr: %08X\n", val ); + if( (pvr2_state.line_count >= pvr2_state.retrace_start_line && !pvr2_state.odd_even_field) || + (pvr2_state.line_count < pvr2_state.retrace_end_line && pvr2_state.odd_even_field) ) { pvr2_display_frame(); } + */ break; case DISP_ADDR2: MMIO_WRITE( PVR2, reg, val&0x00FFFFFC ); + pvr2_update_raster_posn(sh4r.slice_cycle); + /* + if( (pvr2_state.line_count >= pvr2_state.retrace_start_line && pvr2_state.odd_even_field) || + (pvr2_state.line_count < pvr2_state.retrace_end_line && !pvr2_state.odd_even_field) ) { + pvr2_display_frame(); + }*/ break; case DISP_SIZE: MMIO_WRITE( PVR2, reg, val&0x3FFFFFFF ); @@ -669,7 +688,21 @@ } } -MMIO_REGION_DEFFNS( PVR2PAL ) +MMIO_REGION_WRITE_FN( PVR2PAL, reg, val ) +{ + MMIO_WRITE( PVR2PAL, reg, val ); + pvr2_state.palette_changed = TRUE; +} + +void pvr2_check_palette_changed() +{ + if( pvr2_state.palette_changed ) { + texcache_invalidate_palette(); + pvr2_state.palette_changed = FALSE; + } +} + +MMIO_REGION_READ_DEFFN( PVR2PAL ); void pvr2_set_base_address( uint32_t base ) { --- a/src/pvr2/pvr2.h Sat Jan 27 12:04:22 2007 +0000 +++ b/src/pvr2/pvr2.h Sun Jan 28 11:36:00 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: pvr2.h,v 1.31 2007-01-27 12:03:53 nkeynes Exp $ + * $Id: pvr2.h,v 1.32 2007-01-28 11:36:00 nkeynes Exp $ * * PVR2 (video chip) functions and macros. * @@ -84,6 +84,12 @@ #define PVR2_POLY_MODE_CLAMP_S 0x00010000 #define PVR2_POLY_MODE_CLAMP_T 0x00008000 +#define PVR2_POLY_FOG_LOOKUP 0x00000000 +#define PVR2_POLY_FOG_VERTEX 0x00400000 +#define PVR2_POLY_FOG_DISABLED 0x00800000 +#define PVR2_POLY_FOG_LOOKUP2 0x00C00000 + + #define PVR2_TEX_FORMAT_ARGB1555 0x00000000 #define PVR2_TEX_FORMAT_RGB565 0x08000000 #define PVR2_TEX_FORMAT_ARGB4444 0x10000000 @@ -97,6 +103,8 @@ #define PVR2_TEX_FORMAT_MASK 0x38000000 #define PVR2_TEX_UNTWIDDLED 0x04000000 #define PVR2_TEX_STRIDE 0x02000000 +#define PVR2_TEX_IS_PALETTE(mode) ( (mode & PVR2_TEX_FORMAT_MASK) == PVR2_TEX_FORMAT_IDX4 || (mode&PVR2_TEX_FORMAT_MASK) == PVR2_TEX_FORMAT_IDX8 ) + #define PVR2_TEX_ADDR(x) ( ((x)&0x01FFFFF)<<3 ); #define PVR2_TEX_IS_MIPMAPPED(x) ( (x) & PVR2_TEX_MIPMAP ) @@ -337,6 +345,7 @@ #define POLY2_DEST_BLEND(poly2) ( pvr2_poly_dstblend[((poly2)>>26)&0x07] ) #define POLY2_SRC_BLEND_TARGET(poly2) ((poly2)&0x02000000) #define POLY2_DEST_BLEND_TARGET(poly2) ((poly2)&0x01000000) +#define POLY2_FOG_MODE(poly2) ((poly2)&0x00C00000) #define POLY2_COLOUR_CLAMP_ENABLE(poly2) ((poly2)&0x00200000) #define POLY2_ALPHA_ENABLE(poly2) ((poly2)&0x00100000) #define POLY2_TEX_ALPHA_ENABLE(poly2) (((poly2)&0x00080000) == 0 ) --- a/src/pvr2/render.c Sat Jan 27 12:04:22 2007 +0000 +++ b/src/pvr2/render.c Sun Jan 28 11:36:00 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: render.c,v 1.21 2007-01-27 06:21:35 nkeynes Exp $ + * $Id: render.c,v 1.22 2007-01-28 11:36:00 nkeynes Exp $ * * PVR2 Renderer support. This part is primarily * @@ -180,6 +180,8 @@ back_buffer.scale = MMIO_READ( PVR2, RENDER_SCALER ); back_buffer.size = width * height * colour_format_bytes[colour_format]; + pvr2_check_palette_changed(); + /* Setup the display model */ glDrawBuffer(GL_BACK); glShadeModel(GL_SMOOTH); @@ -260,5 +262,5 @@ glPrintf( 4, 16, "Frame %d", pvr2_get_frame_count() ); /* Generate end of render event */ asic_event( EVENT_PVR_RENDER_DONE ); - DEBUG( "Rendered frame %d", pvr2_get_frame_count() ); + DEBUG( "Rendered frame %d to %08X", pvr2_get_frame_count(), render_addr ); } --- a/src/pvr2/texcache.c Sat Jan 27 12:04:22 2007 +0000 +++ b/src/pvr2/texcache.c Sun Jan 28 11:36:00 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: texcache.c,v 1.23 2007-01-25 13:03:23 nkeynes Exp $ + * $Id: texcache.c,v 1.24 2007-01-28 11:36:00 nkeynes Exp $ * * Texture cache. Responsible for maintaining a working set of OpenGL * textures. @@ -66,6 +66,7 @@ } for( i=0; i> 12; - texcache_entry_index idx = texcache_page_lookup[texture_page]; - if( idx == EMPTY_ENTRY ) - return; - assert( texcache_free_ptr >= 0 ); - do { - texcache_entry_t entry = &texcache_active_list[idx]; - /* release entry */ - texcache_free_ptr--; - texcache_free_list[texcache_free_ptr] = idx; - idx = entry->next; - entry->next = EMPTY_ENTRY; - } while( idx != EMPTY_ENTRY ); - texcache_page_lookup[texture_page] = EMPTY_ENTRY; -} - -/** - * Evict a single texture from the cache. - * @return the slot of the evicted texture. - */ -static texcache_entry_index texcache_evict( void ) +static void texcache_evict( int slot ) { - /* Full table scan - take over the entry with the lowest lru value */ - texcache_entry_index slot = 0; - int lru_value = texcache_active_list[0].lru_count; - int i; - for( i=1; i> 12; texcache_entry_index replace_next = texcache_active_list[slot].next; + texcache_active_list[slot].texture_addr = -1; texcache_active_list[slot].next = EMPTY_ENTRY; /* Just for safety */ if( texcache_page_lookup[evict_page] == slot ) { texcache_page_lookup[evict_page] = replace_next; @@ -176,9 +142,68 @@ idx = next; } while( next != EMPTY_ENTRY ); } +} + +/** + * Evict a single texture from the cache. + * @return the slot of the evicted texture. + */ +static texcache_entry_index texcache_evict_lru( void ) +{ + /* Full table scan - take over the entry with the lowest lru value */ + texcache_entry_index slot = 0; + int lru_value = texcache_active_list[0].lru_count; + int i; + for( i=1; i> 12; + texcache_entry_index idx = texcache_page_lookup[texture_page]; + if( idx == EMPTY_ENTRY ) + return; + assert( texcache_free_ptr >= 0 ); + do { + texcache_entry_t entry = &texcache_active_list[idx]; + entry->texture_addr = -1; + /* release entry */ + texcache_free_ptr--; + texcache_free_list[texcache_free_ptr] = idx; + idx = entry->next; + entry->next = EMPTY_ENTRY; + } while( idx != EMPTY_ENTRY ); + texcache_page_lookup[texture_page] = EMPTY_ENTRY; +} + +/** + * Mark all textures that use the palette table as needing a re-read (ie + * for when the palette is changed. We could track exactly which ones are + * affected, but it's not clear that the extra maintanence overhead is + * worthwhile. + */ +void texcache_invalidate_palette( ) +{ + int i; + for( i=0; i