Search
lxdream.org :: lxdream :: r856:02ac5f37bfc9
lxdream 0.9.1
released Jun 29
Download Now
changeset856:02ac5f37bfc9
parent855:b937948d79d9
child857:3d8944884eaa
authornkeynes
dateThu Sep 11 22:51:24 2008 +0000 (15 years ago)
Completely untested render-to-texture work in progress
src/pvr2/glrender.c
src/pvr2/pvr2.c
src/pvr2/pvr2.h
src/pvr2/pvr2mem.c
src/pvr2/texcache.c
1.1 --- a/src/pvr2/glrender.c Wed Sep 10 02:03:20 2008 +0000
1.2 +++ b/src/pvr2/glrender.c Thu Sep 11 22:51:24 2008 +0000
1.3 @@ -41,10 +41,6 @@
1.4 GL_DECAL,
1.5 GL_MODULATE
1.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.11
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 +0000
2.2 +++ b/src/pvr2/pvr2.c Thu Sep 11 22:51:24 2008 +0000
2.3 @@ -53,6 +53,10 @@
2.4 void pvr2_display_frame( void );
2.5
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.11
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.25
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 frame
2.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.54
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.66
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 +0000
3.2 +++ b/src/pvr2/pvr2.h Thu Sep 11 22:51:24 2008 +0000
3.3 @@ -273,6 +273,11 @@
3.4
3.5 void gl_render_tilelist( pvraddr_t tile_entry );
3.6
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 modifier
3.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.18
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.22
3.23 int pvr2_render_save_scene( const gchar *filename );
4.1 --- a/src/pvr2/pvr2mem.c Wed Sep 10 02:03:20 2008 +0000
4.2 +++ b/src/pvr2/pvr2mem.c Thu Sep 11 22:51:24 2008 +0000
4.3 @@ -525,8 +525,6 @@
4.4 *
4.5 * @param buffer A render buffer indicating the address to store to, and the
4.6 * format the data needs to be in.
4.7 - * @param backBuffer TRUE to flush the back buffer, FALSE for
4.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 }
4.18
5.1 --- a/src/pvr2/texcache.c Wed Sep 10 02:03:20 2008 +0000
5.2 +++ b/src/pvr2/texcache.c Thu Sep 11 22:51:24 2008 +0000
5.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.22
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.69
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 currently
5.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.86
5.87 -/**
5.88 - * Return a texture ID for the texture specified at the supplied address
5.89 - * and given parameters (the same sequence of bytes could in theory have
5.90 - * multiple interpretations). We use the texture address as the primary
5.91 - * index, but allow for multiple instances at each address. The texture
5.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 was
5.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.113
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.121
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.125
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.138
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 address
5.144 + * and given parameters (the same sequence of bytes could in theory have
5.145 + * multiple interpretations). We use the texture address as the primary
5.146 + * index, but allow for multiple instances at each address. The texture
5.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 was
5.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.165
5.166 return texcache_active_list[slot].texture_id;
5.167 }
5.168
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 slot
5.207 * appears exactly once on either the free list or one page list. For
.