filename | src/pvr2/texcache.c |
changeset | 1275:83b15705cdde |
prev | 1256:a9d29fe74bf3 |
next | 1282:9f445c5e252b |
author | nkeynes |
date | Tue Mar 20 08:29:38 2012 +1000 (10 years ago) |
permissions | -rw-r--r-- |
last change | More android WIP - Implement onPause/onResume (although resume is not actually working yet) - Implement BGRA => RGBA texture conversion (BGRA doesn't seem to work on the TFP) Boot swirl is now displayed, albeit depth buffering seems to be broken. |
file | annotate | diff | log | raw |
1.1 --- a/src/pvr2/texcache.c Sun Mar 04 21:10:12 2012 +10001.2 +++ b/src/pvr2/texcache.c Tue Mar 20 08:29:38 2012 +10001.3 @@ -61,6 +61,7 @@1.4 static uint32_t texcache_palette_mode;1.5 static uint32_t texcache_stride_width;1.6 static gboolean texcache_have_palette_shader;1.7 +static gboolean texcache_have_bgra;1.8 static gboolean texcache_palette_valid;1.9 static GLuint texcache_palette_texid;1.11 @@ -85,41 +86,10 @@1.12 texcache_stride_width = 0;1.13 }1.15 -/**1.16 - * Setup the initial texture ids (must be called after the GL context is1.17 - * prepared)1.18 - */1.19 -void texcache_gl_init( )1.20 -{1.21 - int i;1.22 - GLuint texids[MAX_TEXTURES];1.23 -1.24 - if( display_driver->capabilities.has_sl ) {1.25 - texcache_have_palette_shader = TRUE;1.26 - texcache_palette_valid = FALSE;1.27 - glGenTextures(1, &texcache_palette_texid );1.28 -1.29 - /* Bind the texture and set the params */1.30 - glActiveTexture(GL_TEXTURE1);1.31 - glBindTexture(GL_TEXTURE_2D, texcache_palette_texid);1.32 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);1.33 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);1.34 - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );1.35 - glActiveTexture(GL_TEXTURE0);1.36 -1.37 - } else {1.38 - texcache_have_palette_shader = FALSE;1.39 - }1.40 -1.41 - glGenTextures( MAX_TEXTURES, texids );1.42 - for( i=0; i<MAX_TEXTURES; i++ ) {1.43 - texcache_active_list[i].texture_id = texids[i];1.44 - }1.45 -}1.47 void texcache_release_render_buffer( render_buffer_t buffer )1.48 {1.49 - if( !buffer->flushed )1.50 + if( !buffer->flushed )1.51 pvr2_render_buffer_copy_to_sh4(buffer);1.52 pvr2_destroy_render_buffer(buffer);1.53 }1.54 @@ -148,21 +118,59 @@1.55 }1.57 /**1.58 + * Setup the initial texture ids (must be called after the GL context is1.59 + * prepared)1.60 + */1.61 +void texcache_gl_init( )1.62 +{1.63 + int i;1.64 + GLuint texids[MAX_TEXTURES];1.65 +1.66 + if( display_driver->capabilities.has_sl ) {1.67 + texcache_have_palette_shader = TRUE;1.68 + texcache_palette_valid = FALSE;1.69 + glGenTextures(1, &texcache_palette_texid );1.70 +1.71 + /* Bind the texture and set the params */1.72 + glActiveTexture(GL_TEXTURE1);1.73 + glBindTexture(GL_TEXTURE_2D, texcache_palette_texid);1.74 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);1.75 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);1.76 + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );1.77 + glActiveTexture(GL_TEXTURE0);1.78 +1.79 + } else {1.80 + texcache_have_palette_shader = FALSE;1.81 + }1.82 + texcache_have_bgra = isGLBGRATextureSupported();1.83 +1.84 + glGenTextures( MAX_TEXTURES, texids );1.85 + for( i=0; i<MAX_TEXTURES; i++ ) {1.86 + texcache_active_list[i].texture_id = texids[i];1.87 + }1.88 + INFO( "Texcache initialized (%s, %s)", (texcache_have_palette_shader ? "Palette shader" : "No palette support"),1.89 + (texcache_have_bgra ? "BGRA" : "RGBA") );1.90 +}1.91 +1.92 +/**1.93 * Flush all textures and delete. The cache will be non-functional until1.94 - * the next call to texcache_init(). This would typically be done if1.95 + * the next call to texcache_gl_init(). This would typically be done if1.96 * switching GL targets.1.97 */1.98 -void texcache_shutdown( )1.99 +void texcache_gl_shutdown( )1.100 {1.101 GLuint texids[MAX_TEXTURES];1.102 int i;1.103 texcache_flush();1.105 - if( texcache_have_palette_shader )1.106 + if( texcache_have_palette_shader ) {1.107 glDeleteTextures( 1, &texcache_palette_texid );1.108 + texcache_palette_texid = -1;1.109 + }1.111 for( i=0; i<MAX_TEXTURES; i++ ) {1.112 texids[i] = texcache_active_list[i].texture_id;1.113 + texcache_active_list[i].texture_id = -1;1.114 }1.115 glDeleteTextures( MAX_TEXTURES, texids );1.116 }1.117 @@ -244,6 +252,73 @@1.118 }1.120 /**1.121 + * Convert BGRA data in buffer to RGBA format (for systems that don't natively1.122 + * support BGRA).1.123 + * @return converted format type1.124 + * @param data BGRA pixel data1.125 + * @param nPixels total number of pixels (width*height)1.126 + * @param glFormatType GL format of source data. One of1.127 + * GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_UNSIGNED_SHORT_4_4_4_4_REV, or GL_UNSIGNED_BYTE1.128 + */1.129 +static int bgra_to_rgba( unsigned char *data, unsigned nPixels, int glFormatType )1.130 +{1.131 + unsigned i;1.132 + switch( glFormatType ) {1.133 + case GL_UNSIGNED_SHORT_1_5_5_5_REV: {1.134 + uint16_t *p = (uint16_t *)data;1.135 + uint16_t *end = p + nPixels;1.136 + while( p != end ) {1.137 + uint16_t v = *p;1.138 + *p = (v >> 15) | (v<<1);1.139 + p++;1.140 + }1.141 + return GL_UNSIGNED_SHORT_5_5_5_1;1.142 + }1.143 + case GL_UNSIGNED_SHORT_4_4_4_4_REV: { /* ARGB => RGBA */1.144 + uint16_t *p = (uint16_t *)data;1.145 + uint16_t *end = p + nPixels;1.146 + while( p != end ) {1.147 + uint16_t v = *p;1.148 + *p = (v >> 12) | (v<<4);1.149 + p++;1.150 + }1.151 + return GL_UNSIGNED_SHORT_4_4_4_4;1.152 + }1.153 + case GL_UNSIGNED_BYTE: { /* ARGB => ABGR */1.154 + uint32_t *p = (uint32_t *)data;1.155 + uint32_t *end = p + nPixels;1.156 + while( p != end ) {1.157 + uint32_t v = *p;1.158 + *p = (v&0xFF000000) | ((v<<16) & 0x00FF0000) | (v & 0x0000FF00) | ((v>>16) & 0x000000FF);1.159 + p++;1.160 + }1.161 + return GL_UNSIGNED_BYTE;1.162 + }1.163 + default:1.164 + assert( 0 && "Unsupported BGRA format" );1.165 + return glFormatType;1.166 + }1.167 +}1.168 +1.169 +/**1.170 + * Install the image data in the currently bound 2D texture.1.171 + * May modify the buffered data if needed to make the texture compatible with1.172 + * the GL.1.173 + */1.174 +static void texcache_load_image_2D( int level, GLint intFormat, int width, int height, GLint format, GLint type, unsigned char *data )1.175 +{1.176 + if( format == GL_BGRA && !texcache_have_bgra ) {1.177 + GLint rgbaType = bgra_to_rgba( data, width*height, type );1.178 + glTexImage2D( GL_TEXTURE_2D, level, intFormat, width, height, 0, GL_RGBA, rgbaType,1.179 + data );1.180 + } else {1.181 + glTexImage2D( GL_TEXTURE_2D, level, intFormat, width, height, 0, format, type,1.182 + data );1.183 + }1.184 +1.185 +}1.186 +1.187 +/**1.188 * Load the palette into 4 textures of 256 entries each. This mirrors the1.189 * banking done by the PVR2 for 8-bit textures, and also ensures that we1.190 * can use 8-bit paletted textures ourselves.1.191 @@ -254,7 +329,7 @@1.192 unsigned i;1.193 int bpp = 2;1.194 uint32_t *palette = (uint32_t *)mmio_region_PVR2PAL.mem;1.195 - uint16_t packed_palette[1024];1.196 + char buf[4096];1.197 char *data = (char *)palette;1.199 switch( texcache_palette_mode ) {1.200 @@ -280,13 +355,21 @@1.201 break; /* Can't happen */1.202 }1.204 -1.205 if( bpp == 2 ) {1.206 + data = buf;1.207 + uint16_t *packed_palette = (uint16_t *)buf;1.208 for( i=0; i<1024; i++ ) {1.209 packed_palette[i] = (uint16_t)palette[i];1.210 }1.211 - data = (char *)packed_palette;1.212 -1.213 + if( !texcache_have_bgra && format == GL_BGRA ) {1.214 + type = bgra_to_rgba(data, 1024, type);1.215 + format = GL_RGBA;1.216 + }1.217 + } else if( !texcache_have_bgra && format == GL_BGRA ) { /* bpp == 4 */1.218 + data = buf;1.219 + memcpy( buf, palette, 4096 );1.220 + type = bgra_to_rgba(buf, 1024, type);1.221 + format = GL_RGBA;1.222 }1.224 glActiveTexture(GL_TEXTURE1);1.225 @@ -448,7 +531,7 @@1.226 if( r > 255 ) { r = 255; } else if( r < 0 ) { r = 0; }1.227 if( g > 255 ) { g = 255; } else if( g < 0 ) { g = 0; }1.228 if( b > 255 ) { b = 255; } else if( b < 0 ) { b = 0; }1.229 - return 0xFF000000 | (r<<16) | (g<<8) | (b);1.230 + return 0xFF000000 | (b<<16) | (g<<8) | (r);1.231 }1.234 @@ -555,10 +638,10 @@1.235 break;1.236 case PVR2_TEX_FORMAT_YUV422:1.237 /* YUV422 isn't directly supported by most implementations, so decode1.238 - * it to a (reasonably) standard ARGB32.1.239 + * it to a (reasonably) standard RGBA8.1.240 */1.241 bpp_shift = 2;1.242 - format = GL_BGRA;1.243 + format = GL_RGBA;1.244 type = GL_UNSIGNED_BYTE;1.245 break;1.246 case PVR2_TEX_FORMAT_BUMPMAP:1.247 @@ -577,7 +660,7 @@1.248 } else {1.249 pvr2_vram64_read_stride( data, width<<bpp_shift, texture_addr, texcache_stride_width<<bpp_shift, height );1.250 }1.251 - glTexImage2D( GL_TEXTURE_2D, 0, intFormat, width, height, 0, format, type, data );1.252 + texcache_load_image_2D( 0, intFormat, width, height, format, type, data );1.253 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);1.254 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, max_filter);1.255 return;1.256 @@ -678,11 +761,10 @@1.258 /* Pass to GL */1.259 if( level == last_level && level != 0 ) { /* 1x1 stored within a 2x2 */1.260 - glTexImage2D( GL_TEXTURE_2D, level, intFormat, 1, 1, 0, format, type,1.261 + texcache_load_image_2D( level, intFormat, 1, 1, format, type,1.262 data + (3 << bpp_shift) );1.263 } else {1.264 - glTexImage2D( GL_TEXTURE_2D, level, intFormat, mip_width, mip_height, 0, format, type,1.265 - data );1.266 + texcache_load_image_2D( level, intFormat, mip_width, mip_height, format, type, data );1.267 if( mip_width > 2 ) {1.268 mip_width >>= 1;1.269 mip_height >>= 1;1.270 @@ -780,7 +862,10 @@1.271 unsigned height = POLY2_TEX_HEIGHT(poly2_word);1.273 glBindTexture( GL_TEXTURE_2D, texcache_active_list[slot].texture_id );1.274 + glGetError();1.275 texcache_load_texture( texture_addr, width, height, texture_word );1.276 + INFO( "Loaded texture %d: %x %dx%d %x (%x)", texcache_active_list[slot].texture_id, texture_addr, width, height, texture_word,1.277 + glGetError() );1.279 /* Set texture parameters from the poly2 word */1.280 if( POLY2_TEX_CLAMP_U(poly2_word) ) {
.