revision 315:2d8ba198d62c
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 315:2d8ba198d62c |
parent | 314:2a1f3b3d8708 |
child | 316:5ae06185a3cd |
author | nkeynes |
date | Tue Jan 23 11:19:32 2007 +0000 (17 years ago) |
Refactor render buffer read/write to pvr2mem.c
Implement 4-bit indexed textures (tentatively)
Fix RGB24 support
Implement 4-bit indexed textures (tentatively)
Fix RGB24 support
src/pvr2/pvr2.h | view | annotate | diff | log | ||
src/pvr2/pvr2mem.c | view | annotate | diff | log | ||
src/pvr2/render.c | view | annotate | diff | log | ||
src/pvr2/texcache.c | view | annotate | diff | log |
1.1 --- a/src/pvr2/pvr2.h Tue Jan 23 09:30:59 2007 +00001.2 +++ b/src/pvr2/pvr2.h Tue Jan 23 11:19:32 2007 +00001.3 @@ -1,5 +1,5 @@1.4 /**1.5 - * $Id: pvr2.h,v 1.24 2007-01-22 11:45:37 nkeynes Exp $1.6 + * $Id: pvr2.h,v 1.25 2007-01-23 11:19:32 nkeynes Exp $1.7 *1.8 * PVR2 (video chip) functions and macros.1.9 *1.10 @@ -132,6 +132,15 @@1.11 * Read a twiddled image from interleaved memory address space (aka 64-bit address1.12 * space), writing the image to the destination buffer in detwiddled format.1.13 * Width and height must be powers of 21.14 + * This version reads 4-bit pixels.1.15 + */1.16 +void pvr2_vram64_read_twiddled_4( char *dest, sh4addr_t src, uint32_t width, uint32_t height );1.17 +1.18 +1.19 +/**1.20 + * Read a twiddled image from interleaved memory address space (aka 64-bit address1.21 + * space), writing the image to the destination buffer in detwiddled format.1.22 + * Width and height must be powers of 21.23 * This version reads 8-bit pixels.1.24 */1.25 void pvr2_vram64_read_twiddled_8( char *dest, sh4addr_t src, uint32_t width, uint32_t height );1.26 @@ -151,14 +160,55 @@1.27 */1.28 void pvr2_vram64_read_stride( char *dest, uint32_t dest_line_bytes, sh4addr_t srcaddr,1.29 uint32_t src_line_bytes, uint32_t line_count );1.30 -1.31 -1.32 /**1.33 * Dump a portion of vram to a stream from the interleaved memory address1.34 * space.1.35 */1.36 void pvr2_vram64_dump( sh4addr_t addr, uint32_t length, FILE *f );1.38 +1.39 +/**1.40 + * Describes a rendering buffer that's actually held in GL, for when we need1.41 + * to fetch the bits back to vram.1.42 + */1.43 +typedef struct pvr2_render_buffer {1.44 + sh4addr_t render_addr; /* The actual address rendered to in pvr ram */1.45 + uint32_t size; /* Length of rendering region in bytes */1.46 + int width, height;1.47 + int colour_format;1.48 +} *pvr2_render_buffer_t;1.49 +1.50 +/**1.51 + * Flush the indicated render buffer back to PVR. Caller is responsible for1.52 + * tracking whether there is actually anything in the buffer.1.53 + *1.54 + * @param buffer A render buffer indicating the address to store to, and the1.55 + * format the data needs to be in.1.56 + * @param backBuffer TRUE to flush the back buffer, FALSE for1.57 + * the front buffer.1.58 + */1.59 +void pvr2_render_buffer_copy_to_sh4( pvr2_render_buffer_t buffer,1.60 + gboolean backBuffer );1.61 +1.62 +/**1.63 + * Copy data from PVR ram into the GL render buffer.1.64 + *1.65 + * @param buffer A render buffer indicating the address to read from, and the1.66 + * format the data is in.1.67 + * @param backBuffer TRUE to write the back buffer, FALSE for1.68 + * the front buffer.1.69 + */1.70 +void pvr2_render_buffer_copy_from_sh4( pvr2_render_buffer_t buffer,1.71 + gboolean backBuffer );1.72 +1.73 +1.74 +/**1.75 + * Invalidate any caching on the supplied SH4 address1.76 + */1.77 +gboolean pvr2_render_buffer_invalidate( sh4addr_t addr );1.78 +1.79 +1.80 +1.81 /**************************** Tile Accelerator ***************************/1.82 /**1.83 * Process the data in the supplied buffer as an array of TA command lists.1.84 @@ -197,11 +247,6 @@1.85 gboolean pvr2_render_init( void );1.87 /**1.88 - * Invalidate any caching on the supplied SH4 address1.89 - */1.90 -gboolean pvr2_render_invalidate( sh4addr_t addr );1.91 -1.92 -/**1.93 * Render the current scene stored in PVR ram to the GL back buffer.1.94 */1.95 void pvr2_render_scene( void );
2.1 --- a/src/pvr2/pvr2mem.c Tue Jan 23 09:30:59 2007 +00002.2 +++ b/src/pvr2/pvr2mem.c Tue Jan 23 11:19:32 2007 +00002.3 @@ -1,5 +1,5 @@2.4 /**2.5 - * $Id: pvr2mem.c,v 1.4 2007-01-22 11:45:37 nkeynes Exp $2.6 + * $Id: pvr2mem.c,v 1.5 2007-01-23 11:19:32 nkeynes Exp $2.7 *2.8 * PVR2 (Video) VRAM handling routines (mainly for the 64-bit region)2.9 *2.10 @@ -165,6 +165,7 @@2.11 }2.12 }2.14 +2.15 /**2.16 * @param dest Destination image buffer2.17 * @param banks Source data expressed as two bank pointers2.18 @@ -172,26 +173,60 @@2.19 * to read is (0..3)2.20 * @param x1,y1 Destination coordinates2.21 * @param width Width of current destination block2.22 - * @param image_width Total width of image (ie stride)2.23 + * @param stride Total width of image (ie stride) in bytes2.24 + */2.25 +2.26 +static void pvr2_vram64_detwiddle_4( uint8_t *dest, uint8_t *banks[2], int offset,2.27 + int x1, int y1, int width, int stride )2.28 +{2.29 + if( width == 2 ) {2.30 + x1 = x1 >> 1;2.31 + uint8_t t1 = *banks[offset<4?0:1]++;2.32 + uint8_t t2 = *banks[offset<3?0:1]++;2.33 + dest[y1*stride + x1] = (t1 & 0x0F) | (t2<<4);2.34 + dest[(y1+1)*stride + x1] = (t1>>4) | (t2&0xF0);2.35 + } else if( width == 4 ) {2.36 + pvr2_vram64_detwiddle_4( dest, banks, offset, x1, y1, 2, stride );2.37 + pvr2_vram64_detwiddle_4( dest, banks, offset+2, x1, y1+2, 2, stride );2.38 + pvr2_vram64_detwiddle_4( dest, banks, offset+4, x1+2, y1, 2, stride );2.39 + pvr2_vram64_detwiddle_4( dest, banks, offset+6, x1+2, y1+2, 2, stride );2.40 +2.41 + } else {2.42 + int subdivide = width >> 1;2.43 + pvr2_vram64_detwiddle_4( dest, banks, offset, x1, y1, subdivide, stride );2.44 + pvr2_vram64_detwiddle_4( dest, banks, offset, x1, y1+subdivide, subdivide, stride );2.45 + pvr2_vram64_detwiddle_4( dest, banks, offset, x1+subdivide, y1, subdivide, stride );2.46 + pvr2_vram64_detwiddle_4( dest, banks, offset, x1+subdivide, y1+subdivide, subdivide, stride );2.47 + }2.48 +}2.49 +2.50 +/**2.51 + * @param dest Destination image buffer2.52 + * @param banks Source data expressed as two bank pointers2.53 + * @param offset Offset into banks[0] specifying where the next byte2.54 + * to read is (0..3)2.55 + * @param x1,y1 Destination coordinates2.56 + * @param width Width of current destination block2.57 + * @param stride Total width of image (ie stride)2.58 */2.60 static void pvr2_vram64_detwiddle_8( uint8_t *dest, uint8_t *banks[2], int offset,2.61 - int x1, int y1, int width, int image_width )2.62 + int x1, int y1, int width, int stride )2.63 {2.64 if( width == 2 ) {2.65 - dest[y1*image_width + x1] = *banks[0]++;2.66 - dest[(y1+1)*image_width + x1] = *banks[offset<3?0:1]++;2.67 - dest[y1*image_width + x1 + 1] = *banks[offset<2?0:1]++;2.68 - dest[(y1+1)*image_width + x1 + 1] = *banks[offset==0?0:1]++;2.69 + dest[y1*stride + x1] = *banks[0]++;2.70 + dest[(y1+1)*stride + x1] = *banks[offset<3?0:1]++;2.71 + dest[y1*stride + x1 + 1] = *banks[offset<2?0:1]++;2.72 + dest[(y1+1)*stride + x1 + 1] = *banks[offset==0?0:1]++;2.73 uint8_t *tmp = banks[0]; /* swap banks */2.74 banks[0] = banks[1];2.75 banks[1] = tmp;2.76 } else {2.77 int subdivide = width >> 1;2.78 - pvr2_vram64_detwiddle_8( dest, banks, offset, x1, y1, subdivide, image_width );2.79 - pvr2_vram64_detwiddle_8( dest, banks, offset, x1, y1+subdivide, subdivide, image_width );2.80 - pvr2_vram64_detwiddle_8( dest, banks, offset, x1+subdivide, y1, subdivide, image_width );2.81 - pvr2_vram64_detwiddle_8( dest, banks, offset, x1+subdivide, y1+subdivide, subdivide, image_width );2.82 + pvr2_vram64_detwiddle_8( dest, banks, offset, x1, y1, subdivide, stride );2.83 + pvr2_vram64_detwiddle_8( dest, banks, offset, x1, y1+subdivide, subdivide, stride );2.84 + pvr2_vram64_detwiddle_8( dest, banks, offset, x1+subdivide, y1, subdivide, stride );2.85 + pvr2_vram64_detwiddle_8( dest, banks, offset, x1+subdivide, y1+subdivide, subdivide, stride );2.86 }2.87 }2.89 @@ -202,27 +237,70 @@2.90 * to read is (0 or 1)2.91 * @param x1,y1 Destination coordinates2.92 * @param width Width of current destination block2.93 - * @param image_width Total width of image (ie stride)2.94 + * @param stride Total width of image (ie stride)2.95 */2.97 static void pvr2_vram64_detwiddle_16( uint16_t *dest, uint16_t *banks[2], int offset,2.98 - int x1, int y1, int width, int image_width )2.99 + int x1, int y1, int width, int stride )2.100 {2.101 if( width == 2 ) {2.102 - dest[y1*image_width + x1] = *banks[0]++;2.103 - dest[(y1+1)*image_width + x1] = *banks[offset]++;2.104 - dest[y1*image_width + x1 + 1] = *banks[1]++;2.105 - dest[(y1+1)*image_width + x1 + 1] = *banks[offset^1]++;2.106 + dest[y1*stride + x1] = *banks[0]++;2.107 + dest[(y1+1)*stride + x1] = *banks[offset]++;2.108 + dest[y1*stride + x1 + 1] = *banks[1]++;2.109 + dest[(y1+1)*stride + x1 + 1] = *banks[offset^1]++;2.110 } else {2.111 int subdivide = width >> 1;2.112 - pvr2_vram64_detwiddle_16( dest, banks, offset, x1, y1, subdivide, image_width );2.113 - pvr2_vram64_detwiddle_16( dest, banks, offset, x1, y1+subdivide, subdivide, image_width );2.114 - pvr2_vram64_detwiddle_16( dest, banks, offset, x1+subdivide, y1, subdivide, image_width );2.115 - pvr2_vram64_detwiddle_16( dest, banks, offset, x1+subdivide, y1+subdivide, subdivide, image_width );2.116 + pvr2_vram64_detwiddle_16( dest, banks, offset, x1, y1, subdivide, stride );2.117 + pvr2_vram64_detwiddle_16( dest, banks, offset, x1, y1+subdivide, subdivide, stride );2.118 + pvr2_vram64_detwiddle_16( dest, banks, offset, x1+subdivide, y1, subdivide, stride );2.119 + pvr2_vram64_detwiddle_16( dest, banks, offset, x1+subdivide, y1+subdivide, subdivide, stride );2.120 }2.121 }2.123 /**2.124 + * Read an image from 64-bit vram stored as twiddled 4-bit pixels. The2.125 + * image is written out to the destination in detwiddled form.2.126 + * @param dest destination buffer, which must be at least width*height/2 in length2.127 + * @param srcaddr source address in vram2.128 + * @param width image width (must be a power of 2)2.129 + * @param height image height (must be a power of 2)2.130 + */2.131 +void pvr2_vram64_read_twiddled_4( char *dest, sh4addr_t srcaddr, uint32_t width, uint32_t height )2.132 +{2.133 + int offset_flag = (srcaddr & 0x07);2.134 + uint8_t *banks[2];2.135 + uint8_t *wdest = (uint8_t*)dest;2.136 + uint32_t stride = width >> 1;2.137 + int i,j;2.138 +2.139 + srcaddr = srcaddr & 0x7FFFF8;2.140 +2.141 + banks[0] = (uint8_t *)(video_base + (srcaddr>>1));2.142 + banks[1] = banks[0] + 0x400000;2.143 + if( offset_flag & 0x04 ) { // If source is not 64-bit aligned, swap the banks2.144 + uint8_t *tmp = banks[0];2.145 + banks[0] = banks[1];2.146 + banks[1] = tmp + 4;2.147 + offset_flag &= 0x03;2.148 + }2.149 + banks[0] += offset_flag;2.150 +2.151 + if( width > height ) {2.152 + for( i=0; i<width; i+=height ) {2.153 + pvr2_vram64_detwiddle_4( wdest, banks, offset_flag, i, 0, height, stride );2.154 + }2.155 + } else if( height > width ) {2.156 + for( i=0; i<height; i+=width ) {2.157 + pvr2_vram64_detwiddle_4( wdest, banks, offset_flag, 0, i, width, stride );2.158 + }2.159 + } else if( width == 1 ) {2.160 + *wdest = *banks[0];2.161 + } else {2.162 + pvr2_vram64_detwiddle_4( wdest, banks, offset_flag, 0, 0, width, stride );2.163 + }2.164 +}2.165 +2.166 +/**2.167 * Read an image from 64-bit vram stored as twiddled 8-bit pixels. The2.168 * image is written out to the destination in detwiddled form.2.169 * @param dest destination buffer, which must be at least width*height in length2.170 @@ -389,3 +467,131 @@2.171 pvr2_vram64_read( tmp, addr, length );2.172 fwrite_dump( tmp, length, f );2.173 }2.174 +2.175 +2.176 +2.177 +/**2.178 + * Flush the indicated render buffer back to PVR. Caller is responsible for2.179 + * tracking whether there is actually anything in the buffer.2.180 + *2.181 + * @param buffer A render buffer indicating the address to store to, and the2.182 + * format the data needs to be in.2.183 + * @param backBuffer TRUE to flush the back buffer, FALSE for2.184 + * the front buffer.2.185 + */2.186 +void pvr2_render_buffer_copy_to_sh4( pvr2_render_buffer_t buffer,2.187 + gboolean backBuffer )2.188 +{2.189 + if( buffer->render_addr == -1 )2.190 + return;2.191 + GLenum type, format = GL_BGRA;2.192 + int line_size = buffer->width, size;2.193 +2.194 + switch( buffer->colour_format ) {2.195 + case COLFMT_RGB565:2.196 + type = GL_UNSIGNED_SHORT_5_6_5;2.197 + format = GL_BGR;2.198 + line_size <<= 1;2.199 + break;2.200 + case COLFMT_RGB888:2.201 + type = GL_UNSIGNED_BYTE;2.202 + format = GL_BGR;2.203 + line_size = (line_size<<1)+line_size;2.204 + break;2.205 + case COLFMT_ARGB1555:2.206 + type = GL_UNSIGNED_SHORT_5_5_5_1;2.207 + line_size <<= 1;2.208 + break;2.209 + case COLFMT_ARGB4444:2.210 + type = GL_UNSIGNED_SHORT_4_4_4_4;2.211 + line_size <<= 1;2.212 + break;2.213 + case COLFMT_ARGB8888:2.214 + type = GL_UNSIGNED_INT_8_8_8_8;2.215 + line_size <<= 2;2.216 + break;2.217 + }2.218 + size = line_size * buffer->height;2.219 +2.220 + if( backBuffer ) {2.221 + glFinish();2.222 + glReadBuffer( GL_BACK );2.223 + } else {2.224 + glReadBuffer( GL_FRONT );2.225 + }2.226 +2.227 + if( buffer->render_addr & 0xFF000000 == 0x04000000 ) {2.228 + /* Interlaced buffer. Go the double copy... :( */2.229 + char target[size];2.230 + glReadPixels( 0, 0, buffer->width, buffer->height, format, type, target );2.231 + pvr2_vram64_write( buffer->render_addr, target, size );2.232 + } else {2.233 + /* Regular buffer */2.234 + char target[size];2.235 + glReadPixels( 0, 0, buffer->width, buffer->height, format, type, target );2.236 + pvr2_vram_write_invert( buffer->render_addr, target, size, line_size );2.237 + }2.238 +}2.239 +2.240 +2.241 +/**2.242 + * Copy data from PVR ram into the GL render buffer.2.243 + *2.244 + * @param buffer A render buffer indicating the address to read from, and the2.245 + * format the data is in.2.246 + * @param backBuffer TRUE to write the back buffer, FALSE for2.247 + * the front buffer.2.248 + */2.249 +void pvr2_render_buffer_copy_from_sh4( pvr2_render_buffer_t buffer,2.250 + gboolean backBuffer )2.251 +{2.252 + if( buffer->render_addr == -1 )2.253 + return;2.254 + GLenum type, format = GL_RGBA;2.255 + int size = buffer->width * buffer->height;2.256 +2.257 + switch( buffer->colour_format ) {2.258 + case COLFMT_RGB565:2.259 + type = GL_UNSIGNED_SHORT_5_6_5;2.260 + format = GL_RGB;2.261 + size <<= 1;2.262 + break;2.263 + case COLFMT_RGB888:2.264 + type = GL_UNSIGNED_BYTE;2.265 + format = GL_BGR;2.266 + size = (size<<1)+size;2.267 + break;2.268 + case COLFMT_ARGB1555:2.269 + type = GL_UNSIGNED_SHORT_5_5_5_1;2.270 + size <<= 1;2.271 + break;2.272 + case COLFMT_ARGB4444:2.273 + type = GL_UNSIGNED_SHORT_4_4_4_4;2.274 + size <<= 1;2.275 + break;2.276 + case COLFMT_ARGB8888:2.277 + type = GL_UNSIGNED_INT_8_8_8_8;2.278 + size <<= 2;2.279 + break;2.280 + }2.281 +2.282 + if( backBuffer ) {2.283 + glDrawBuffer( GL_BACK );2.284 + } else {2.285 + glDrawBuffer( GL_FRONT );2.286 + }2.287 +2.288 + glRasterPos2i( 0, 0 );2.289 + if( buffer->render_addr & 0xFF000000 == 0x04000000 ) {2.290 + /* Interlaced buffer. Go the double copy... :( */2.291 + char target[size];2.292 + pvr2_vram64_read( target, buffer->render_addr, size );2.293 + glDrawPixels( buffer->width, buffer->height,2.294 + format, type, target );2.295 + } else {2.296 + /* Regular buffer - go direct */2.297 + char *target = mem_get_region( buffer->render_addr );2.298 + glDrawPixels( buffer->width, buffer->height,2.299 + format, type, target );2.300 + }2.301 +}
3.1 --- a/src/pvr2/render.c Tue Jan 23 09:30:59 2007 +00003.2 +++ b/src/pvr2/render.c Tue Jan 23 11:19:32 2007 +00003.3 @@ -1,5 +1,5 @@3.4 /**3.5 - * $Id: render.c,v 1.17 2007-01-21 11:28:43 nkeynes Exp $3.6 + * $Id: render.c,v 1.18 2007-01-23 11:19:32 nkeynes Exp $3.7 *3.8 * PVR2 Renderer support. This part is primarily3.9 *3.10 @@ -19,16 +19,6 @@3.11 #include "pvr2/pvr2.h"3.12 #include "asic.h"3.14 -/**3.15 - * Describes a rendering buffer that's actually held in GL, for when we need3.16 - * to fetch the bits back to vram.3.17 - */3.18 -typedef struct pvr2_render_buffer {3.19 - sh4addr_t render_addr; /* The actual address rendered to in pvr ram */3.20 - uint32_t size; /* Length of rendering region in bytes */3.21 - int width, height;3.22 - int colour_format;3.23 -} *pvr2_render_buffer_t;3.25 struct pvr2_render_buffer front_buffer;3.26 struct pvr2_render_buffer back_buffer;3.27 @@ -44,11 +34,6 @@3.28 uint32_t colour3;3.29 } *pvr2_bgplane_packed_t;3.31 -3.32 -3.33 -void pvr2_render_copy_to_sh4( pvr2_render_buffer_t buffer,3.34 - gboolean backBuffer );3.35 -3.36 int pvr2_render_font_list = -1;3.37 int pvr2_render_trace = 0;3.39 @@ -113,19 +98,19 @@3.40 * PVR2 ram (note that front buffer flush may be corrupt under some3.41 * circumstances).3.42 */3.43 -gboolean pvr2_render_invalidate( sh4addr_t address )3.44 +gboolean pvr2_render_buffer_invalidate( sh4addr_t address )3.45 {3.46 address = address & 0x1FFFFFFF;3.47 if( front_buffer.render_addr != -1 &&3.48 front_buffer.render_addr <= address &&3.49 (front_buffer.render_addr + front_buffer.size) > address ) {3.50 - pvr2_render_copy_to_sh4( &front_buffer, FALSE );3.51 + pvr2_render_buffer_copy_to_sh4( &front_buffer, FALSE );3.52 front_buffer.render_addr = -1;3.53 return TRUE;3.54 } else if( back_buffer.render_addr != -1 &&3.55 back_buffer.render_addr <= address &&3.56 (back_buffer.render_addr + back_buffer.size) > address ) {3.57 - pvr2_render_copy_to_sh4( &back_buffer, TRUE );3.58 + pvr2_render_buffer_copy_to_sh4( &back_buffer, TRUE );3.59 back_buffer.render_addr = -1;3.60 return TRUE;3.61 }3.62 @@ -178,7 +163,7 @@3.63 /* There's a current back buffer, and we're rendering somewhere else -3.64 * flush the back buffer back to vram and start a new back buffer3.65 */3.66 - pvr2_render_copy_to_sh4( &back_buffer, TRUE );3.67 + pvr2_render_buffer_copy_to_sh4( &back_buffer, TRUE );3.68 }3.70 if( front_buffer.render_addr == render_addr ) {3.71 @@ -275,130 +260,3 @@3.72 asic_event( EVENT_PVR_RENDER_DONE );3.73 DEBUG( "Rendered frame %d", pvr2_get_frame_count() );3.74 }3.75 -3.76 -3.77 -/**3.78 - * Flush the indicated render buffer back to PVR. Caller is responsible for3.79 - * tracking whether there is actually anything in the buffer.3.80 - *3.81 - * @param buffer A render buffer indicating the address to store to, and the3.82 - * format the data needs to be in.3.83 - * @param backBuffer TRUE to flush the back buffer, FALSE for3.84 - * the front buffer.3.85 - */3.86 -void pvr2_render_copy_to_sh4( pvr2_render_buffer_t buffer,3.87 - gboolean backBuffer )3.88 -{3.89 - if( buffer->render_addr == -1 )3.90 - return;3.91 - GLenum type, format = GL_RGBA;3.92 - int line_size = buffer->width, size;3.93 -3.94 - switch( buffer->colour_format ) {3.95 - case COLFMT_RGB565:3.96 - type = GL_UNSIGNED_SHORT_5_6_5;3.97 - format = GL_RGB;3.98 - line_size <<= 1;3.99 - break;3.100 - case COLFMT_RGB888:3.101 - type = GL_UNSIGNED_INT;3.102 - format = GL_RGB;3.103 - line_size = (line_size<<1)+line_size;3.104 - break;3.105 - case COLFMT_ARGB1555:3.106 - type = GL_UNSIGNED_SHORT_5_5_5_1;3.107 - line_size <<= 1;3.108 - break;3.109 - case COLFMT_ARGB4444:3.110 - type = GL_UNSIGNED_SHORT_4_4_4_4;3.111 - line_size <<= 1;3.112 - break;3.113 - case COLFMT_ARGB8888:3.114 - type = GL_UNSIGNED_INT_8_8_8_8;3.115 - line_size <<= 2;3.116 - break;3.117 - }3.118 - size = line_size * buffer->height;3.119 -3.120 - if( backBuffer ) {3.121 - glFinish();3.122 - glReadBuffer( GL_BACK );3.123 - } else {3.124 - glReadBuffer( GL_FRONT );3.125 - }3.126 -3.127 - if( buffer->render_addr & 0xFF000000 == 0x04000000 ) {3.128 - /* Interlaced buffer. Go the double copy... :( */3.129 - char target[size];3.130 - glReadPixels( 0, 0, buffer->width, buffer->height, format, type, target );3.131 - pvr2_vram64_write( buffer->render_addr, target, size );3.132 - } else {3.133 - /* Regular buffer */3.134 - char target[size];3.135 - glReadPixels( 0, 0, buffer->width, buffer->height, format, type, target );3.136 - pvr2_vram_write_invert( buffer->render_addr, target, size, line_size );3.137 - }3.138 -}3.139 -3.140 -3.141 -/**3.142 - * Copy data from PVR ram into the GL render buffer.3.143 - *3.144 - * @param buffer A render buffer indicating the address to read from, and the3.145 - * format the data is in.3.146 - * @param backBuffer TRUE to write the back buffer, FALSE for3.147 - * the front buffer.3.148 - */3.149 -void pvr2_render_copy_from_sh4( pvr2_render_buffer_t buffer,3.150 - gboolean backBuffer )3.151 -{3.152 - if( buffer->render_addr == -1 )3.153 - return;3.154 - GLenum type, format = GL_RGBA;3.155 - int size = buffer->width * buffer->height;3.156 -3.157 - switch( buffer->colour_format ) {3.158 - case COLFMT_RGB565:3.159 - type = GL_UNSIGNED_SHORT_5_6_5;3.160 - format = GL_RGB;3.161 - size <<= 1;3.162 - break;3.163 - case COLFMT_RGB888:3.164 - type = GL_UNSIGNED_INT;3.165 - format = GL_RGB;3.166 - size = (size<<1)+size;3.167 - break;3.168 - case COLFMT_ARGB1555:3.169 - type = GL_UNSIGNED_SHORT_5_5_5_1;3.170 - size <<= 1;3.171 - break;3.172 - case COLFMT_ARGB4444:3.173 - type = GL_UNSIGNED_SHORT_4_4_4_4;3.174 - size <<= 1;3.175 - break;3.176 - case COLFMT_ARGB8888:3.177 - type = GL_UNSIGNED_INT_8_8_8_8;3.178 - size <<= 2;3.179 - break;3.180 - }3.181 -3.182 - if( backBuffer ) {3.183 - glDrawBuffer( GL_BACK );3.184 - } else {3.185 - glDrawBuffer( GL_FRONT );3.186 - }3.187 -3.188 - glRasterPos2i( 0, 0 );3.189 - if( buffer->render_addr & 0xFF000000 == 0x04000000 ) {3.190 - /* Interlaced buffer. Go the double copy... :( */3.191 - char target[size];3.192 - pvr2_vram64_read( target, buffer->render_addr, size );3.193 - glDrawPixels( buffer->width, buffer->height,3.194 - format, type, target );3.195 - } else {3.196 - /* Regular buffer - go direct */3.197 - char *target = mem_get_region( buffer->render_addr );3.198 - glDrawPixels( buffer->width, buffer->height,3.199 - format, type, target );3.200 - }3.201 -}
4.1 --- a/src/pvr2/texcache.c Tue Jan 23 09:30:59 2007 +00004.2 +++ b/src/pvr2/texcache.c Tue Jan 23 11:19:32 2007 +00004.3 @@ -1,5 +1,5 @@4.4 /**4.5 - * $Id: texcache.c,v 1.18 2007-01-23 09:30:59 nkeynes Exp $4.6 + * $Id: texcache.c,v 1.19 2007-01-23 11:19:32 nkeynes Exp $4.7 *4.8 * Texture cache. Responsible for maintaining a working set of OpenGL4.9 * textures.4.10 @@ -195,6 +195,27 @@4.11 }4.12 }4.14 +static void decode_pal4_to_32( uint32_t *out, uint8_t *in, int inbytes, uint32_t *pal )4.15 +{4.16 + int i;4.17 + for( i=0; i<inbytes; i++ ) {4.18 + *out++ = pal[*in & 0x0F];4.19 + *out++ = pal[(*in >> 4)];4.20 + in++;4.21 + }4.22 +}4.23 +4.24 +4.25 +static void decode_pal4_to_16( uint16_t *out, uint8_t *in, int inbytes, uint16_t *pal )4.26 +{4.27 + int i;4.28 + for( i=0; i<inbytes; i++ ) {4.29 + *out++ = pal[*in & 0x0F];4.30 + *out++ = pal[(*in >> 4)];4.31 + in++;4.32 + }4.33 +}4.34 +4.35 #define VQ_CODEBOOK_SIZE 2048 /* 256 entries * 4 pixels per quad * 2 byte pixels */4.37 struct vq_codebook {4.38 @@ -283,7 +304,6 @@4.39 /* Decode the format parameters */4.40 switch( tex_format ) {4.41 case PVR2_TEX_FORMAT_IDX4:4.42 - ERROR( "4-bit indexed textures not supported" );4.43 case PVR2_TEX_FORMAT_IDX8:4.44 /* For indexed-colour modes, we need to lookup the palette control4.45 * word to determine the de-indexed texture format.4.46 @@ -385,13 +405,23 @@4.47 int bank = (mode >> 25) &0x03;4.48 char *palette = mmio_region_PVR2PAL.mem + (bank * (256 << bpp_shift));4.49 char tmp[inputlength];4.50 - char *p = tmp;4.51 pvr2_vram64_read_twiddled_8( tmp, texture_addr, mip_width, mip_height );4.52 if( bpp_shift == 2 ) {4.53 decode_pal8_to_32( (uint32_t *)data, tmp, inputlength, (uint32_t*)palette );4.54 } else {4.55 decode_pal8_to_16( (uint16_t *)data, tmp, inputlength, (uint16_t*)palette );4.56 }4.57 + } else if( tex_format == PVR2_TEX_FORMAT_IDX4 ) {4.58 + int inputlength = (mip_width * mip_height) >> 1;4.59 + int bank = (mode >>21 ) & 0x3F;4.60 + char *palette = mmio_region_PVR2PAL.mem + (bank * (16 << bpp_shift));4.61 + char tmp[inputlength];4.62 + pvr2_vram64_read_twiddled_4( tmp, texture_addr, mip_width, mip_height );4.63 + if( bpp_shift == 2 ) {4.64 + decode_pal4_to_32( (uint32_t *)data, tmp, inputlength, (uint32_t*)palette );4.65 + } else {4.66 + decode_pal4_to_16( (uint16_t *)data, tmp, inputlength, (uint16_t*)palette );4.67 + }4.68 } else if( tex_format == PVR2_TEX_FORMAT_YUV422 ) {4.69 int inputlength = ((mip_width*mip_height)<<1);4.70 char tmp[inputlength];
.