Search
lxdream.org :: lxdream :: r315:2d8ba198d62c
lxdream 0.9.1
released Jun 29
Download Now
changeset315:2d8ba198d62c
parent314:2a1f3b3d8708
child316:5ae06185a3cd
authornkeynes
dateTue Jan 23 11:19:32 2007 +0000 (12 years ago)
Refactor render buffer read/write to pvr2mem.c
Implement 4-bit indexed textures (tentatively)
Fix RGB24 support
src/pvr2/pvr2.h
src/pvr2/pvr2mem.c
src/pvr2/render.c
src/pvr2/texcache.c
1.1 --- a/src/pvr2/pvr2.h Tue Jan 23 09:30:59 2007 +0000
1.2 +++ b/src/pvr2/pvr2.h Tue Jan 23 11:19:32 2007 +0000
1.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 address
1.12 * space), writing the image to the destination buffer in detwiddled format.
1.13 * Width and height must be powers of 2
1.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 address
1.21 + * space), writing the image to the destination buffer in detwiddled format.
1.22 + * Width and height must be powers of 2
1.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 address
1.34 * space.
1.35 */
1.36 void pvr2_vram64_dump( sh4addr_t addr, uint32_t length, FILE *f );
1.37
1.38 +
1.39 +/**
1.40 + * Describes a rendering buffer that's actually held in GL, for when we need
1.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 for
1.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 the
1.55 + * format the data needs to be in.
1.56 + * @param backBuffer TRUE to flush the back buffer, FALSE for
1.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 the
1.66 + * format the data is in.
1.67 + * @param backBuffer TRUE to write the back buffer, FALSE for
1.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 address
1.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.86
1.87 /**
1.88 - * Invalidate any caching on the supplied SH4 address
1.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 +0000
2.2 +++ b/src/pvr2/pvr2mem.c Tue Jan 23 11:19:32 2007 +0000
2.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.13
2.14 +
2.15 /**
2.16 * @param dest Destination image buffer
2.17 * @param banks Source data expressed as two bank pointers
2.18 @@ -172,26 +173,60 @@
2.19 * to read is (0..3)
2.20 * @param x1,y1 Destination coordinates
2.21 * @param width Width of current destination block
2.22 - * @param image_width Total width of image (ie stride)
2.23 + * @param stride Total width of image (ie stride) in bytes
2.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 buffer
2.52 + * @param banks Source data expressed as two bank pointers
2.53 + * @param offset Offset into banks[0] specifying where the next byte
2.54 + * to read is (0..3)
2.55 + * @param x1,y1 Destination coordinates
2.56 + * @param width Width of current destination block
2.57 + * @param stride Total width of image (ie stride)
2.58 */
2.59
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.88
2.89 @@ -202,27 +237,70 @@
2.90 * to read is (0 or 1)
2.91 * @param x1,y1 Destination coordinates
2.92 * @param width Width of current destination block
2.93 - * @param image_width Total width of image (ie stride)
2.94 + * @param stride Total width of image (ie stride)
2.95 */
2.96
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.122
2.123 /**
2.124 + * Read an image from 64-bit vram stored as twiddled 4-bit pixels. The
2.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 length
2.127 + * @param srcaddr source address in vram
2.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 banks
2.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. The
2.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 length
2.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 for
2.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 the
2.182 + * format the data needs to be in.
2.183 + * @param backBuffer TRUE to flush the back buffer, FALSE for
2.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 the
2.245 + * format the data is in.
2.246 + * @param backBuffer TRUE to write the back buffer, FALSE for
2.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 +0000
3.2 +++ b/src/pvr2/render.c Tue Jan 23 11:19:32 2007 +0000
3.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 primarily
3.9 *
3.10 @@ -19,16 +19,6 @@
3.11 #include "pvr2/pvr2.h"
3.12 #include "asic.h"
3.13
3.14 -/**
3.15 - * Describes a rendering buffer that's actually held in GL, for when we need
3.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.24
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.30
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.38
3.39 @@ -113,19 +98,19 @@
3.40 * PVR2 ram (note that front buffer flush may be corrupt under some
3.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 buffer
3.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.69
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 for
3.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 the
3.82 - * format the data needs to be in.
3.83 - * @param backBuffer TRUE to flush the back buffer, FALSE for
3.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 the
3.145 - * format the data is in.
3.146 - * @param backBuffer TRUE to write the back buffer, FALSE for
3.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 +0000
4.2 +++ b/src/pvr2/texcache.c Tue Jan 23 11:19:32 2007 +0000
4.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 OpenGL
4.9 * textures.
4.10 @@ -195,6 +195,27 @@
4.11 }
4.12 }
4.13
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.36
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 control
4.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];
.