Search
lxdream.org :: lxdream :: r337:cdd757aa8e8c
lxdream 0.9.1
released Jun 29
Download Now
changeset337:cdd757aa8e8c
parent336:c3455be86ee2
child338:8c68d9097846
authornkeynes
dateSun Jan 28 11:36:00 2007 +0000 (17 years ago)
Invalidate palette textures when the palette changes (fixes a few texture
bugs)
Fix odd/even selection in pvr2_display_frame
src/pvr2/pvr2.c
src/pvr2/pvr2.h
src/pvr2/render.c
src/pvr2/texcache.c
1.1 --- a/src/pvr2/pvr2.c Sat Jan 27 12:04:22 2007 +0000
1.2 +++ b/src/pvr2/pvr2.c Sun Jan 28 11:36:00 2007 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: pvr2.c,v 1.42 2007-01-27 12:03:53 nkeynes Exp $
1.6 + * $Id: pvr2.c,v 1.43 2007-01-28 11:36:00 nkeynes Exp $
1.7 *
1.8 * PVR2 (Video) Core module implementation and MMIO registers.
1.9 *
1.10 @@ -75,6 +75,7 @@
1.11 uint32_t irq_vpos1;
1.12 uint32_t irq_vpos2;
1.13 uint32_t odd_even_field; /* 1 = odd, 0 = even */
1.14 + gboolean palette_changed; /* TRUE if palette has changed since last render */
1.15 gchar *save_next_render_filename;
1.16 /* timing */
1.17 uint32_t dot_clock;
1.18 @@ -149,6 +150,7 @@
1.19 pvr2_state.timing = ntsc_timing;
1.20 pvr2_state.dot_clock = PVR2_DOT_CLOCK;
1.21 pvr2_state.back_porch_ns = 4000;
1.22 + pvr2_state.palette_changed = FALSE;
1.23 mmio_region_PVR2_write( DISP_TOTAL, 0x0270035F );
1.24 mmio_region_PVR2_write( DISP_SYNCTIME, 0x07D6A53F );
1.25 mmio_region_PVR2_write( YUV_ADDR, 0 );
1.26 @@ -204,6 +206,7 @@
1.27 if( pvr2_state.line_count >= pvr2_state.retrace_end_line &&
1.28 (old_line_count < pvr2_state.retrace_end_line ||
1.29 old_line_count > pvr2_state.line_count) ) {
1.30 + pvr2_state.frame_count++;
1.31 pvr2_display_frame();
1.32 }
1.33 }
1.34 @@ -259,8 +262,16 @@
1.35 buffer->vres <<= 1;
1.36 buffer->rowstride = vid_ppl << 2;
1.37 display_addr = MMIO_READ( PVR2, DISP_ADDR1 );
1.38 - } else { /* Just display the field as is, folks */
1.39 - if( pvr2_state.odd_even_field ) {
1.40 + } else {
1.41 + /* Just display the field as is, folks. This is slightly tricky -
1.42 + * we pick the field based on which frame is about to come through,
1.43 + * which may not be the same as the odd_even_field.
1.44 + */
1.45 + gboolean oddfield = pvr2_state.odd_even_field;
1.46 + if( pvr2_state.line_count >= pvr2_state.retrace_start_line ) {
1.47 + oddfield = !oddfield;
1.48 + }
1.49 + if( oddfield ) {
1.50 display_addr = MMIO_READ( PVR2, DISP_ADDR1 );
1.51 } else {
1.52 display_addr = MMIO_READ( PVR2, DISP_ADDR2 );
1.53 @@ -308,7 +319,6 @@
1.54 display_driver->display_frame( buffer );
1.55 }
1.56 }
1.57 - pvr2_state.frame_count++;
1.58 }
1.59
1.60 /**
1.61 @@ -362,14 +372,23 @@
1.62 case DISP_ADDR1:
1.63 val &= 0x00FFFFFC;
1.64 MMIO_WRITE( PVR2, reg, val );
1.65 + /*
1.66 pvr2_update_raster_posn(sh4r.slice_cycle);
1.67 - if( pvr2_state.line_count >= pvr2_state.retrace_start_line ||
1.68 - pvr2_state.line_count < pvr2_state.retrace_end_line ) {
1.69 + fprintf( stderr, "Set Field 1 addr: %08X\n", val );
1.70 + if( (pvr2_state.line_count >= pvr2_state.retrace_start_line && !pvr2_state.odd_even_field) ||
1.71 + (pvr2_state.line_count < pvr2_state.retrace_end_line && pvr2_state.odd_even_field) ) {
1.72 pvr2_display_frame();
1.73 }
1.74 + */
1.75 break;
1.76 case DISP_ADDR2:
1.77 MMIO_WRITE( PVR2, reg, val&0x00FFFFFC );
1.78 + pvr2_update_raster_posn(sh4r.slice_cycle);
1.79 + /*
1.80 + if( (pvr2_state.line_count >= pvr2_state.retrace_start_line && pvr2_state.odd_even_field) ||
1.81 + (pvr2_state.line_count < pvr2_state.retrace_end_line && !pvr2_state.odd_even_field) ) {
1.82 + pvr2_display_frame();
1.83 + }*/
1.84 break;
1.85 case DISP_SIZE:
1.86 MMIO_WRITE( PVR2, reg, val&0x3FFFFFFF );
1.87 @@ -669,7 +688,21 @@
1.88 }
1.89 }
1.90
1.91 -MMIO_REGION_DEFFNS( PVR2PAL )
1.92 +MMIO_REGION_WRITE_FN( PVR2PAL, reg, val )
1.93 +{
1.94 + MMIO_WRITE( PVR2PAL, reg, val );
1.95 + pvr2_state.palette_changed = TRUE;
1.96 +}
1.97 +
1.98 +void pvr2_check_palette_changed()
1.99 +{
1.100 + if( pvr2_state.palette_changed ) {
1.101 + texcache_invalidate_palette();
1.102 + pvr2_state.palette_changed = FALSE;
1.103 + }
1.104 +}
1.105 +
1.106 +MMIO_REGION_READ_DEFFN( PVR2PAL );
1.107
1.108 void pvr2_set_base_address( uint32_t base )
1.109 {
2.1 --- a/src/pvr2/pvr2.h Sat Jan 27 12:04:22 2007 +0000
2.2 +++ b/src/pvr2/pvr2.h Sun Jan 28 11:36:00 2007 +0000
2.3 @@ -1,5 +1,5 @@
2.4 /**
2.5 - * $Id: pvr2.h,v 1.31 2007-01-27 12:03:53 nkeynes Exp $
2.6 + * $Id: pvr2.h,v 1.32 2007-01-28 11:36:00 nkeynes Exp $
2.7 *
2.8 * PVR2 (video chip) functions and macros.
2.9 *
2.10 @@ -84,6 +84,12 @@
2.11 #define PVR2_POLY_MODE_CLAMP_S 0x00010000
2.12 #define PVR2_POLY_MODE_CLAMP_T 0x00008000
2.13
2.14 +#define PVR2_POLY_FOG_LOOKUP 0x00000000
2.15 +#define PVR2_POLY_FOG_VERTEX 0x00400000
2.16 +#define PVR2_POLY_FOG_DISABLED 0x00800000
2.17 +#define PVR2_POLY_FOG_LOOKUP2 0x00C00000
2.18 +
2.19 +
2.20 #define PVR2_TEX_FORMAT_ARGB1555 0x00000000
2.21 #define PVR2_TEX_FORMAT_RGB565 0x08000000
2.22 #define PVR2_TEX_FORMAT_ARGB4444 0x10000000
2.23 @@ -97,6 +103,8 @@
2.24 #define PVR2_TEX_FORMAT_MASK 0x38000000
2.25 #define PVR2_TEX_UNTWIDDLED 0x04000000
2.26 #define PVR2_TEX_STRIDE 0x02000000
2.27 +#define PVR2_TEX_IS_PALETTE(mode) ( (mode & PVR2_TEX_FORMAT_MASK) == PVR2_TEX_FORMAT_IDX4 || (mode&PVR2_TEX_FORMAT_MASK) == PVR2_TEX_FORMAT_IDX8 )
2.28 +
2.29
2.30 #define PVR2_TEX_ADDR(x) ( ((x)&0x01FFFFF)<<3 );
2.31 #define PVR2_TEX_IS_MIPMAPPED(x) ( (x) & PVR2_TEX_MIPMAP )
2.32 @@ -337,6 +345,7 @@
2.33 #define POLY2_DEST_BLEND(poly2) ( pvr2_poly_dstblend[((poly2)>>26)&0x07] )
2.34 #define POLY2_SRC_BLEND_TARGET(poly2) ((poly2)&0x02000000)
2.35 #define POLY2_DEST_BLEND_TARGET(poly2) ((poly2)&0x01000000)
2.36 +#define POLY2_FOG_MODE(poly2) ((poly2)&0x00C00000)
2.37 #define POLY2_COLOUR_CLAMP_ENABLE(poly2) ((poly2)&0x00200000)
2.38 #define POLY2_ALPHA_ENABLE(poly2) ((poly2)&0x00100000)
2.39 #define POLY2_TEX_ALPHA_ENABLE(poly2) (((poly2)&0x00080000) == 0 )
3.1 --- a/src/pvr2/render.c Sat Jan 27 12:04:22 2007 +0000
3.2 +++ b/src/pvr2/render.c Sun Jan 28 11:36:00 2007 +0000
3.3 @@ -1,5 +1,5 @@
3.4 /**
3.5 - * $Id: render.c,v 1.21 2007-01-27 06:21:35 nkeynes Exp $
3.6 + * $Id: render.c,v 1.22 2007-01-28 11:36:00 nkeynes Exp $
3.7 *
3.8 * PVR2 Renderer support. This part is primarily
3.9 *
3.10 @@ -180,6 +180,8 @@
3.11 back_buffer.scale = MMIO_READ( PVR2, RENDER_SCALER );
3.12 back_buffer.size = width * height * colour_format_bytes[colour_format];
3.13
3.14 + pvr2_check_palette_changed();
3.15 +
3.16 /* Setup the display model */
3.17 glDrawBuffer(GL_BACK);
3.18 glShadeModel(GL_SMOOTH);
3.19 @@ -260,5 +262,5 @@
3.20 glPrintf( 4, 16, "Frame %d", pvr2_get_frame_count() );
3.21 /* Generate end of render event */
3.22 asic_event( EVENT_PVR_RENDER_DONE );
3.23 - DEBUG( "Rendered frame %d", pvr2_get_frame_count() );
3.24 + DEBUG( "Rendered frame %d to %08X", pvr2_get_frame_count(), render_addr );
3.25 }
4.1 --- a/src/pvr2/texcache.c Sat Jan 27 12:04:22 2007 +0000
4.2 +++ b/src/pvr2/texcache.c Sun Jan 28 11:36:00 2007 +0000
4.3 @@ -1,5 +1,5 @@
4.4 /**
4.5 - * $Id: texcache.c,v 1.23 2007-01-25 13:03:23 nkeynes Exp $
4.6 + * $Id: texcache.c,v 1.24 2007-01-28 11:36:00 nkeynes Exp $
4.7 *
4.8 * Texture cache. Responsible for maintaining a working set of OpenGL
4.9 * textures.
4.10 @@ -66,6 +66,7 @@
4.11 }
4.12 for( i=0; i<MAX_TEXTURES; i++ ) {
4.13 texcache_free_list[i] = i;
4.14 + texcache_active_list[i].texture_addr = -1;
4.15 }
4.16 texcache_free_ptr = 0;
4.17 texcache_ref_counter = 0;
4.18 @@ -120,47 +121,12 @@
4.19 glDeleteTextures( MAX_TEXTURES, texids );
4.20 }
4.21
4.22 -/**
4.23 - * Evict all textures contained in the page identified by a texture address.
4.24 - */
4.25 -void texcache_invalidate_page( uint32_t texture_addr ) {
4.26 - uint32_t texture_page = texture_addr >> 12;
4.27 - texcache_entry_index idx = texcache_page_lookup[texture_page];
4.28 - if( idx == EMPTY_ENTRY )
4.29 - return;
4.30 - assert( texcache_free_ptr >= 0 );
4.31 - do {
4.32 - texcache_entry_t entry = &texcache_active_list[idx];
4.33 - /* release entry */
4.34 - texcache_free_ptr--;
4.35 - texcache_free_list[texcache_free_ptr] = idx;
4.36 - idx = entry->next;
4.37 - entry->next = EMPTY_ENTRY;
4.38 - } while( idx != EMPTY_ENTRY );
4.39 - texcache_page_lookup[texture_page] = EMPTY_ENTRY;
4.40 -}
4.41 -
4.42 -/**
4.43 - * Evict a single texture from the cache.
4.44 - * @return the slot of the evicted texture.
4.45 - */
4.46 -static texcache_entry_index texcache_evict( void )
4.47 +static void texcache_evict( int slot )
4.48 {
4.49 - /* Full table scan - take over the entry with the lowest lru value */
4.50 - texcache_entry_index slot = 0;
4.51 - int lru_value = texcache_active_list[0].lru_count;
4.52 - int i;
4.53 - for( i=1; i<MAX_TEXTURES; i++ ) {
4.54 - /* FIXME: account for rollover */
4.55 - if( texcache_active_list[i].lru_count < lru_value ) {
4.56 - slot = i;
4.57 - lru_value = texcache_active_list[i].lru_count;
4.58 - }
4.59 - }
4.60 -
4.61 /* Remove the selected slot from the lookup table */
4.62 uint32_t evict_page = texcache_active_list[slot].texture_addr >> 12;
4.63 texcache_entry_index replace_next = texcache_active_list[slot].next;
4.64 + texcache_active_list[slot].texture_addr = -1;
4.65 texcache_active_list[slot].next = EMPTY_ENTRY; /* Just for safety */
4.66 if( texcache_page_lookup[evict_page] == slot ) {
4.67 texcache_page_lookup[evict_page] = replace_next;
4.68 @@ -176,9 +142,68 @@
4.69 idx = next;
4.70 } while( next != EMPTY_ENTRY );
4.71 }
4.72 +}
4.73 +
4.74 +/**
4.75 + * Evict a single texture from the cache.
4.76 + * @return the slot of the evicted texture.
4.77 + */
4.78 +static texcache_entry_index texcache_evict_lru( void )
4.79 +{
4.80 + /* Full table scan - take over the entry with the lowest lru value */
4.81 + texcache_entry_index slot = 0;
4.82 + int lru_value = texcache_active_list[0].lru_count;
4.83 + int i;
4.84 + for( i=1; i<MAX_TEXTURES; i++ ) {
4.85 + /* FIXME: account for rollover */
4.86 + if( texcache_active_list[i].lru_count < lru_value ) {
4.87 + slot = i;
4.88 + lru_value = texcache_active_list[i].lru_count;
4.89 + }
4.90 + }
4.91 + texcache_evict(slot);
4.92 +
4.93 return slot;
4.94 }
4.95
4.96 +/**
4.97 + * Evict all textures contained in the page identified by a texture address.
4.98 + */
4.99 +void texcache_invalidate_page( uint32_t texture_addr ) {
4.100 + uint32_t texture_page = texture_addr >> 12;
4.101 + texcache_entry_index idx = texcache_page_lookup[texture_page];
4.102 + if( idx == EMPTY_ENTRY )
4.103 + return;
4.104 + assert( texcache_free_ptr >= 0 );
4.105 + do {
4.106 + texcache_entry_t entry = &texcache_active_list[idx];
4.107 + entry->texture_addr = -1;
4.108 + /* release entry */
4.109 + texcache_free_ptr--;
4.110 + texcache_free_list[texcache_free_ptr] = idx;
4.111 + idx = entry->next;
4.112 + entry->next = EMPTY_ENTRY;
4.113 + } while( idx != EMPTY_ENTRY );
4.114 + texcache_page_lookup[texture_page] = EMPTY_ENTRY;
4.115 +}
4.116 +
4.117 +/**
4.118 + * Mark all textures that use the palette table as needing a re-read (ie
4.119 + * for when the palette is changed. We could track exactly which ones are
4.120 + * affected, but it's not clear that the extra maintanence overhead is
4.121 + * worthwhile.
4.122 + */
4.123 +void texcache_invalidate_palette( )
4.124 +{
4.125 + int i;
4.126 + for( i=0; i<MAX_TEXTURES; i++ ) {
4.127 + if( texcache_active_list[i].texture_addr != -1 &&
4.128 + PVR2_TEX_IS_PALETTE(texcache_active_list[i].mode) ) {
4.129 + texcache_evict( i );
4.130 + }
4.131 + }
4.132 +}
4.133 +
4.134 static void decode_pal8_to_32( uint32_t *out, uint8_t *in, int inbytes, uint32_t *pal )
4.135 {
4.136 int i;
4.137 @@ -500,7 +525,7 @@
4.138 if( texcache_free_ptr < MAX_TEXTURES ) {
4.139 slot = texcache_free_list[texcache_free_ptr++];
4.140 } else {
4.141 - slot = texcache_evict();
4.142 + slot = texcache_evict_lru();
4.143 }
4.144
4.145 /* Construct new entry */
.