revision 856:02ac5f37bfc9
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 856:02ac5f37bfc9 |
parent | 855:b937948d79d9 |
child | 857:3d8944884eaa |
author | nkeynes |
date | Thu Sep 11 22:51:24 2008 +0000 (15 years ago) |
Completely untested render-to-texture work in progress
1.1 --- a/src/pvr2/glrender.c Wed Sep 10 02:03:20 2008 +00001.2 +++ b/src/pvr2/glrender.c Thu Sep 11 22:51:24 2008 +00001.3 @@ -41,10 +41,6 @@1.4 GL_DECAL,1.5 GL_MODULATE1.6 };1.7 -int pvr2_render_colour_format[8] = {1.8 - COLFMT_BGRA1555, COLFMT_RGB565, COLFMT_BGRA4444, COLFMT_BGRA1555,1.9 - COLFMT_BGR888, COLFMT_BGRA8888, COLFMT_BGRA8888, COLFMT_BGRA4444 };1.10 -1.12 /**1.13 * Clip the tile bounds to the clipping plane.
2.1 --- a/src/pvr2/pvr2.c Wed Sep 10 02:03:20 2008 +00002.2 +++ b/src/pvr2/pvr2.c Thu Sep 11 22:51:24 2008 +00002.3 @@ -53,6 +53,10 @@2.4 void pvr2_display_frame( void );2.6 static int output_colour_formats[] = { COLFMT_BGRA1555, COLFMT_RGB565, COLFMT_BGR888, COLFMT_BGRA8888 };2.7 +static int render_colour_formats[8] = {2.8 + COLFMT_BGRA1555, COLFMT_RGB565, COLFMT_BGRA4444, COLFMT_BGRA1555,2.9 + COLFMT_BGR888, COLFMT_BGRA8888, COLFMT_BGRA8888, COLFMT_BGRA4444 };2.10 +2.12 struct dreamcast_module pvr2_module = { "PVR2", pvr2_init, pvr2_reset, NULL,2.13 pvr2_run_slice, NULL,2.14 @@ -478,6 +482,7 @@2.15 render_buffer_t buffer = pvr2_next_render_buffer();2.16 if( buffer != NULL ) {2.17 pvr2_scene_render( buffer );2.18 + pvr2_finish_render_buffer( buffer );2.19 }2.20 asic_event( EVENT_PVR_RENDER_DONE );2.21 break;2.22 @@ -849,6 +854,28 @@2.23 pvr2_ta_write( (unsigned char *)&val, sizeof(uint32_t) );2.24 }2.26 +render_buffer_t pvr2_create_render_buffer( sh4addr_t addr, int width, int height, GLuint tex_id )2.27 +{2.28 + if( display_driver != NULL && display_driver->create_render_buffer != NULL ) {2.29 + render_buffer_t buffer = display_driver->create_render_buffer(width,height,tex_id);2.30 + buffer->address = addr;2.31 + return buffer;2.32 + }2.33 + return NULL;2.34 +}2.35 +2.36 +void pvr2_destroy_render_buffer( render_buffer_t buffer )2.37 +{2.38 + if( !buffer->flushed )2.39 + pvr2_render_buffer_copy_to_sh4( buffer );2.40 + display_driver->destroy_render_buffer( buffer );2.41 +}2.42 +2.43 +void pvr2_finish_render_buffer( render_buffer_t buffer )2.44 +{2.45 + display_driver->finish_render( buffer );2.46 +}2.47 +2.48 /**2.49 * Find the render buffer corresponding to the requested output frame2.50 * (does not consider texture renders).2.51 @@ -964,17 +991,18 @@2.52 uint32_t render_scale = MMIO_READ( PVR2, RENDER_SCALER );2.53 uint32_t render_stride = MMIO_READ( PVR2, RENDER_SIZE ) << 3;2.55 + int width = pvr2_scene_buffer_width();2.56 + int height = pvr2_scene_buffer_height();2.57 + int colour_format = render_colour_formats[render_mode&0x07];2.58 +2.59 if( render_addr & 0x01000000 ) { /* vram64 */2.60 render_addr = (render_addr & 0x00FFFFFF) + PVR2_RAM_BASE_INT;2.61 + result = texcache_get_render_buffer( render_addr, colour_format, width, height );2.62 } else { /* vram32 */2.63 render_addr = (render_addr & 0x00FFFFFF) + PVR2_RAM_BASE;2.64 + result = pvr2_alloc_render_buffer( render_addr, width, height );2.65 }2.67 - int width = pvr2_scene_buffer_width();2.68 - int height = pvr2_scene_buffer_height();2.69 - int colour_format = pvr2_render_colour_format[render_mode&0x07];2.70 -2.71 - result = pvr2_alloc_render_buffer( render_addr, width, height );2.72 /* Setup the buffer */2.73 if( result != NULL ) {2.74 result->rowstride = render_stride;2.75 @@ -1018,7 +1046,6 @@2.76 (bufaddr + render_buffers[i]->size) > address ) {2.77 if( !render_buffers[i]->flushed ) {2.78 pvr2_render_buffer_copy_to_sh4( render_buffers[i] );2.79 - render_buffers[i]->flushed = TRUE;2.80 }2.81 if( isWrite ) {2.82 render_buffers[i]->address = -1; /* Invalid */
3.1 --- a/src/pvr2/pvr2.h Wed Sep 10 02:03:20 2008 +00003.2 +++ b/src/pvr2/pvr2.h Thu Sep 11 22:51:24 2008 +00003.3 @@ -273,6 +273,11 @@3.5 void gl_render_tilelist( pvraddr_t tile_entry );3.7 +render_buffer_t pvr2_create_render_buffer( sh4addr_t addr, int width, int height, GLuint tex_id );3.8 +3.9 +void pvr2_destroy_render_buffer( render_buffer_t buffer );3.10 +3.11 +3.12 /**3.13 * Structure to hold a complete unpacked vertex (excluding modifier3.14 * volume parameters - generate separate vertexes in that case).3.15 @@ -330,6 +335,8 @@3.16 */3.17 GLuint texcache_get_texture( uint32_t texture_word, int width, int height );3.19 +render_buffer_t texcache_get_render_buffer( uint32_t texture_addr, int mode, int width, int height );3.20 +3.21 void pvr2_check_palette_changed(void);3.23 int pvr2_render_save_scene( const gchar *filename );
4.1 --- a/src/pvr2/pvr2mem.c Wed Sep 10 02:03:20 2008 +00004.2 +++ b/src/pvr2/pvr2mem.c Thu Sep 11 22:51:24 2008 +00004.3 @@ -525,8 +525,6 @@4.4 *4.5 * @param buffer A render buffer indicating the address to store to, and the4.6 * format the data needs to be in.4.7 - * @param backBuffer TRUE to flush the back buffer, FALSE for4.8 - * the front buffer.4.9 */4.10 void pvr2_render_buffer_copy_to_sh4( render_buffer_t buffer )4.11 {4.12 @@ -546,5 +544,6 @@4.13 pvr2_vram_write_invert( buffer->address, target, buffer->size, line_size, line_size );4.14 }4.15 }4.16 + buffer->flushed = TRUE;4.17 }
5.1 --- a/src/pvr2/texcache.c Wed Sep 10 02:03:20 2008 +00005.2 +++ b/src/pvr2/texcache.c Thu Sep 11 22:51:24 2008 +00005.3 @@ -49,6 +49,7 @@5.4 uint32_t texture_addr;5.5 int width, height, mode;5.6 GLuint texture_id;5.7 + render_buffer_t buffer;5.8 texcache_entry_index next;5.9 uint32_t lru_count;5.10 } *texcache_entry_t;5.11 @@ -69,6 +70,7 @@5.12 for( i=0; i<MAX_TEXTURES; i++ ) {5.13 texcache_free_list[i] = i;5.14 texcache_active_list[i].texture_addr = -1;5.15 + texcache_active_list[i].buffer = NULL;5.16 texcache_active_list[i].next = EMPTY_ENTRY;5.17 }5.18 texcache_free_ptr = 0;5.19 @@ -90,6 +92,13 @@5.20 }5.21 }5.23 +void texcache_release_render_buffer( render_buffer_t buffer )5.24 +{5.25 + if( !buffer->flushed )5.26 + pvr2_render_buffer_copy_to_sh4(buffer);5.27 + pvr2_destroy_render_buffer(buffer);5.28 +}5.29 +5.30 /**5.31 * Flush all textures from the cache, returning them to the free list.5.32 */5.33 @@ -103,6 +112,10 @@5.34 for( i=0; i<MAX_TEXTURES; i++ ) {5.35 texcache_free_list[i] = i;5.36 texcache_active_list[i].next = EMPTY_ENTRY;5.37 + if( texcache_active_list[i].buffer != NULL ) {5.38 + texcache_release_render_buffer(texcache_active_list[i].buffer);5.39 + texcache_active_list[i].buffer = NULL;5.40 + }5.41 }5.42 texcache_free_ptr = 0;5.43 texcache_ref_counter = 0;5.44 @@ -133,6 +146,10 @@5.45 texcache_entry_index replace_next = texcache_active_list[slot].next;5.46 texcache_active_list[slot].texture_addr = -1;5.47 texcache_active_list[slot].next = EMPTY_ENTRY; /* Just for safety */5.48 + if( texcache_active_list[slot].buffer != NULL ) {5.49 + texcache_release_render_buffer(texcache_active_list[slot].buffer);5.50 + texcache_active_list[slot].buffer = NULL;5.51 + }5.52 if( texcache_page_lookup[evict_page] == slot ) {5.53 texcache_page_lookup[evict_page] = replace_next;5.54 } else {5.55 @@ -184,6 +201,10 @@5.56 do {5.57 texcache_entry_t entry = &texcache_active_list[idx];5.58 entry->texture_addr = -1;5.59 + if( entry->buffer != NULL ) {5.60 + texcache_release_render_buffer(entry->buffer);5.61 + entry->buffer = NULL;5.62 + }5.63 /* release entry */5.64 texcache_free_ptr--;5.65 texcache_free_list[texcache_free_ptr] = idx;5.66 @@ -322,6 +343,16 @@5.67 }5.68 }5.70 +static gboolean is_npot_texture( int width )5.71 +{5.72 + while( width != 0 ) {5.73 + if( width & 1 )5.74 + return width != 1;5.75 + width >>= 1;5.76 + }5.77 + return TRUE;5.78 +}5.79 +5.80 /**5.81 * Load texture data from the given address and parameters into the currently5.82 * bound OpenGL texture.5.83 @@ -519,17 +550,7 @@5.84 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);5.85 }5.87 -/**5.88 - * Return a texture ID for the texture specified at the supplied address5.89 - * and given parameters (the same sequence of bytes could in theory have5.90 - * multiple interpretations). We use the texture address as the primary5.91 - * index, but allow for multiple instances at each address. The texture5.92 - * will be bound to the GL_TEXTURE_2D target before being returned.5.93 - *5.94 - * If the texture has already been bound, return the ID to which it was5.95 - * bound. Otherwise obtain an unused texture ID and set it up appropriately.5.96 - */5.97 -GLuint texcache_get_texture( uint32_t texture_word, int width, int height )5.98 +static int texcache_find_texture_slot( uint32_t texture_word, int width, int height )5.99 {5.100 uint32_t texture_addr = (texture_word & 0x000FFFFF)<<3;5.101 uint32_t texture_page = texture_addr >> 12;5.102 @@ -542,13 +563,17 @@5.103 entry->width == width &&5.104 entry->height == height ) {5.105 entry->lru_count = texcache_ref_counter++;5.106 - return entry->texture_id;5.107 + return idx;5.108 }5.109 idx = entry->next;5.110 }5.111 + return -1;5.112 +}5.114 -5.115 - /* Not found - check the free list */5.116 +static int texcache_alloc_texture_slot( uint32_t texture_word, int width, int height )5.117 +{5.118 + uint32_t texture_addr = (texture_word & 0x000FFFFF)<<3;5.119 + uint32_t texture_page = texture_addr >> 12;5.120 texcache_entry_index slot = 0;5.122 if( texcache_free_ptr < MAX_TEXTURES ) {5.123 @@ -565,7 +590,7 @@5.124 texcache_active_list[slot].lru_count = texcache_ref_counter++;5.126 /* Add entry to the lookup table */5.127 - next = texcache_page_lookup[texture_page];5.128 + int next = texcache_page_lookup[texture_page];5.129 if( next == slot ) {5.130 int i;5.131 fprintf( stderr, "Active list: " );5.132 @@ -579,14 +604,72 @@5.133 assert( next != slot );5.134 texcache_active_list[slot].next = next;5.135 texcache_page_lookup[texture_page] = slot;5.136 + return slot;5.137 +}5.139 - /* Construct the GL texture */5.140 - glBindTexture( GL_TEXTURE_2D, texcache_active_list[slot].texture_id );5.141 - texcache_load_texture( texture_addr, width, height, texture_word );5.142 +/**5.143 + * Return a texture ID for the texture specified at the supplied address5.144 + * and given parameters (the same sequence of bytes could in theory have5.145 + * multiple interpretations). We use the texture address as the primary5.146 + * index, but allow for multiple instances at each address. The texture5.147 + * will be bound to the GL_TEXTURE_2D target before being returned.5.148 + *5.149 + * If the texture has already been bound, return the ID to which it was5.150 + * bound. Otherwise obtain an unused texture ID and set it up appropriately.5.151 + */5.152 +GLuint texcache_get_texture( uint32_t texture_word, int width, int height )5.153 +{5.154 + int slot = texcache_find_texture_slot( texture_word, width, height );5.155 +5.156 + if( slot == -1 ) {5.157 + /* Not found - check the free list */5.158 + slot = texcache_alloc_texture_slot( texture_word, width, height );5.159 +5.160 + /* Construct the GL texture */5.161 + uint32_t texture_addr = (texture_word & 0x000FFFFF)<<3;5.162 + glBindTexture( GL_TEXTURE_2D, texcache_active_list[slot].texture_id );5.163 + texcache_load_texture( texture_addr, width, height, texture_word );5.164 + }5.166 return texcache_active_list[slot].texture_id;5.167 }5.169 +render_buffer_t texcache_get_render_buffer( uint32_t texture_addr, int mode, int width, int height )5.170 +{5.171 + INFO( "Rendering to texture!" );5.172 + uint32_t texture_word = ((texture_addr >> 3) & 0x000FFFFF) | PVR2_TEX_UNTWIDDLED;5.173 + switch( mode ) {5.174 + case COLFMT_BGRA1555: texture_word |= PVR2_TEX_FORMAT_ARGB1555; break;5.175 + case COLFMT_RGB565: texture_word |= PVR2_TEX_FORMAT_RGB565; break;5.176 + case COLFMT_BGRA4444: texture_word |= PVR2_TEX_FORMAT_ARGB4444; break;5.177 + default:5.178 + WARN( "Rendering to non-texture colour format" );5.179 + }5.180 + if( is_npot_texture(width) )5.181 + texture_word |= PVR2_TEX_STRIDE;5.182 +5.183 +5.184 + int slot = texcache_find_texture_slot( texture_word, width, height );5.185 + if( slot == -1 ) {5.186 + slot = texcache_alloc_texture_slot( texture_word, width, height );5.187 + }5.188 +5.189 + texcache_entry_t entry = &texcache_active_list[slot];5.190 + if( entry->width != width || entry->height != height ) {5.191 + glBindTexture(GL_TEXTURE_2D, entry->texture_id );5.192 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);5.193 + if( entry->buffer != NULL ) {5.194 + texcache_release_render_buffer(entry->buffer);5.195 + }5.196 + entry->buffer = pvr2_create_render_buffer( texture_addr, width, height, entry->texture_id );5.197 + } else {5.198 + if( entry->buffer == NULL )5.199 + entry->buffer = pvr2_create_render_buffer( texture_addr, width, height, entry->texture_id );5.200 + }5.201 +5.202 + return entry->buffer;5.203 +}5.204 +5.205 /**5.206 * Check the integrity of the texcache. Verifies that every cache slot5.207 * appears exactly once on either the free list or one page list. For
.