1.1 --- a/src/pvr2/texcache.c Sun Mar 04 21:10:12 2012 +1000
1.2 +++ b/src/pvr2/texcache.c Tue Mar 20 17:54:58 2012 +1000
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.12 texcache_stride_width = 0;
1.16 - * Setup the initial texture ids (must be called after the GL context is
1.19 -void texcache_gl_init( )
1.22 - GLuint texids[MAX_TEXTURES];
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.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.38 - texcache_have_palette_shader = FALSE;
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.47 void texcache_release_render_buffer( render_buffer_t buffer )
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.54 @@ -148,21 +118,59 @@
1.58 + * Setup the initial texture ids (must be called after the GL context is
1.61 +void texcache_gl_init( )
1.64 + GLuint texids[MAX_TEXTURES];
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.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.80 + texcache_have_palette_shader = FALSE;
1.82 + texcache_have_bgra = isGLBGRATextureSupported();
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.88 + INFO( "Texcache initialized (%s, %s)", (texcache_have_palette_shader ? "Palette shader" : "No palette support"),
1.89 + (texcache_have_bgra ? "BGRA" : "RGBA") );
1.93 * Flush all textures and delete. The cache will be non-functional until
1.94 - * the next call to texcache_init(). This would typically be done if
1.95 + * the next call to texcache_gl_init(). This would typically be done if
1.96 * switching GL targets.
1.98 -void texcache_shutdown( )
1.99 +void texcache_gl_shutdown( )
1.101 GLuint texids[MAX_TEXTURES];
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.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.115 glDeleteTextures( MAX_TEXTURES, texids );
1.117 @@ -244,6 +252,73 @@
1.121 + * Convert BGRA data in buffer to RGBA format (for systems that don't natively
1.123 + * @return converted format type
1.124 + * @param data BGRA pixel data
1.125 + * @param nPixels total number of pixels (width*height)
1.126 + * @param glFormatType GL format of source data. One of
1.127 + * GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_UNSIGNED_SHORT_4_4_4_4_REV, or GL_UNSIGNED_BYTE
1.129 +static int bgra_to_rgba( unsigned char *data, unsigned nPixels, int glFormatType )
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.138 + *p = (v >> 15) | (v<<1);
1.141 + return GL_UNSIGNED_SHORT_5_5_5_1;
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.148 + *p = (v >> 12) | (v<<4);
1.151 + return GL_UNSIGNED_SHORT_4_4_4_4;
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.158 + *p = (v&0xFF000000) | ((v<<16) & 0x00FF0000) | (v & 0x0000FF00) | ((v>>16) & 0x000000FF);
1.161 + return GL_UNSIGNED_BYTE;
1.164 + assert( 0 && "Unsupported BGRA format" );
1.165 + return glFormatType;
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 with
1.174 +static void texcache_load_image_2D( int level, GLint intFormat, int width, int height, GLint format, GLint type, unsigned char *data )
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.181 + glTexImage2D( GL_TEXTURE_2D, level, intFormat, width, height, 0, format, type,
1.188 * Load the palette into 4 textures of 256 entries each. This mirrors the
1.189 * banking done by the PVR2 for 8-bit textures, and also ensures that we
1.190 * can use 8-bit paletted textures ourselves.
1.191 @@ -254,7 +329,7 @@
1.194 uint32_t *palette = (uint32_t *)mmio_region_PVR2PAL.mem;
1.195 - uint16_t packed_palette[1024];
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.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.211 - data = (char *)packed_palette;
1.213 + if( !texcache_have_bgra && format == GL_BGRA ) {
1.214 + type = bgra_to_rgba(data, 1024, type);
1.215 + format = GL_RGBA;
1.217 + } else if( !texcache_have_bgra && format == GL_BGRA ) { /* bpp == 4 */
1.219 + memcpy( buf, palette, 4096 );
1.220 + type = bgra_to_rgba(buf, 1024, type);
1.221 + format = GL_RGBA;
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.234 @@ -555,10 +638,10 @@
1.236 case PVR2_TEX_FORMAT_YUV422:
1.237 /* YUV422 isn't directly supported by most implementations, so decode
1.238 - * it to a (reasonably) standard ARGB32.
1.239 + * it to a (reasonably) standard RGBA8.
1.242 - format = GL_BGRA;
1.243 + format = GL_RGBA;
1.244 type = GL_UNSIGNED_BYTE;
1.246 case PVR2_TEX_FORMAT_BUMPMAP:
1.247 @@ -577,7 +660,7 @@
1.249 pvr2_vram64_read_stride( data, width<<bpp_shift, texture_addr, texcache_stride_width<<bpp_shift, height );
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.256 @@ -678,11 +761,10 @@
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.264 - glTexImage2D( GL_TEXTURE_2D, level, intFormat, mip_width, mip_height, 0, format, type,
1.266 + texcache_load_image_2D( level, intFormat, mip_width, mip_height, format, type, data );
1.267 if( mip_width > 2 ) {
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.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.279 /* Set texture parameters from the poly2 word */
1.280 if( POLY2_TEX_CLAMP_U(poly2_word) ) {