Search
lxdream.org :: lxdream/src/pvr2/texcache.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/texcache.c
changeset 1275:83b15705cdde
prev1256:a9d29fe74bf3
next1282:9f445c5e252b
author nkeynes
date Tue Mar 20 17:54:58 2012 +1000 (12 years ago)
permissions -rw-r--r--
last change Fix missing return statement
file annotate diff log raw
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.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.10
1.11 @@ -85,41 +86,10 @@
1.12 texcache_stride_width = 0;
1.13 }
1.14
1.15 -/**
1.16 - * Setup the initial texture ids (must be called after the GL context is
1.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.46
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.56
1.57 /**
1.58 + * Setup the initial texture ids (must be called after the GL context is
1.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 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.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.104
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.110
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.119
1.120 /**
1.121 + * Convert BGRA data in buffer to RGBA format (for systems that don't natively
1.122 + * support BGRA).
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.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 with
1.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 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.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.198
1.199 switch( texcache_palette_mode ) {
1.200 @@ -280,13 +355,21 @@
1.201 break; /* Can't happen */
1.202 }
1.203
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.223
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.232
1.233
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 decode
1.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.257
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.272
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.278
1.279 /* Set texture parameters from the poly2 word */
1.280 if( POLY2_TEX_CLAMP_U(poly2_word) ) {
.