Search
lxdream.org :: lxdream :: r869:b6f38c7ee7a3
lxdream 0.9.1
released Jun 29
Download Now
changeset869:b6f38c7ee7a3
parent868:c5b4ed31d819
child870:8d4deb2bc1ea
authornkeynes
dateFri Oct 10 00:09:37 2008 +0000 (11 years ago)
Implement render-buffer writeback to vram64 regions
src/pvr2/pvr2mem.c
1.1 --- a/src/pvr2/pvr2mem.c Fri Oct 10 00:07:54 2008 +0000
1.2 +++ b/src/pvr2/pvr2mem.c Fri Oct 10 00:09:37 2008 +0000
1.3 @@ -116,46 +116,34 @@
1.4
1.5 /**
1.6 * Write an image to 64-bit vram, with a line-stride different from the line-size.
1.7 - * The destaddr must be 32-bit aligned, and both line_bytes and line_stride_bytes
1.8 - * must be multiples of 4.
1.9 + * The destaddr must be 64-bit aligned, and both line_bytes and line_stride_bytes
1.10 + * must be multiples of 8.
1.11 */
1.12 void pvr2_vram64_write_stride( sh4addr_t destaddr, unsigned char *src, uint32_t line_bytes,
1.13 uint32_t line_stride_bytes, uint32_t line_count )
1.14 {
1.15 - int bank_flag = (destaddr & 0x04) >> 2;
1.16 + int i,j;
1.17 uint32_t *banks[2];
1.18 - uint32_t *dwsrc;
1.19 - uint32_t line_gap;
1.20 - int line_gap_flag;
1.21 - int i,j;
1.22 + uint32_t *dwsrc = (uint32_t *)src;
1.23 + uint32_t line_gap = (line_stride_bytes - line_bytes) >> 3;
1.24
1.25 destaddr = destaddr & 0x7FFFF8;
1.26 - i = line_stride_bytes - line_bytes;
1.27 - line_gap_flag = i & 0x04;
1.28 - line_gap = i >> 3;
1.29 - line_bytes >>= 2;
1.30 + line_bytes >>= 3;
1.31
1.32 - for( i=destaddr & 0xFFFFF000; i < destaddr + line_stride_bytes*line_count; i+= LXDREAM_PAGE_SIZE ) {
1.33 + for( i=destaddr; i < destaddr + line_stride_bytes*line_count; i+= LXDREAM_PAGE_SIZE ) {
1.34 texcache_invalidate_page( i );
1.35 }
1.36
1.37 banks[0] = (uint32_t *)(video_base + (destaddr >>1));
1.38 banks[1] = banks[0] + 0x100000;
1.39 - if( bank_flag )
1.40 - banks[0]++;
1.41
1.42 - dwsrc = (uint32_t *)src;
1.43 for( i=0; i<line_count; i++ ) {
1.44 for( j=0; j<line_bytes; j++ ) {
1.45 - *banks[bank_flag]++ = *dwsrc++;
1.46 - bank_flag = !bank_flag;
1.47 + *banks[0]++ = *dwsrc++;
1.48 + *banks[1]++ = *dwsrc++;
1.49 }
1.50 banks[0] += line_gap;
1.51 banks[1] += line_gap;
1.52 - if( line_gap_flag ) {
1.53 - banks[bank_flag]++;
1.54 - bank_flag = !bank_flag;
1.55 - }
1.56 }
1.57 }
1.58
1.59 @@ -443,6 +431,36 @@
1.60 }
1.61 }
1.62
1.63 +static void pvr2_vram64_write_invert( sh4addr_t destaddr, unsigned char *src,
1.64 + uint32_t src_size, uint32_t line_size,
1.65 + uint32_t dest_stride, uint32_t src_stride )
1.66 +{
1.67 + int i,j;
1.68 + uint32_t *banks[2];
1.69 + uint32_t *dwsrc = (uint32_t *)(src + src_size - src_stride);
1.70 + int32_t src_line_gap = ((int32_t)src_stride + line_size) >> 2;
1.71 + int32_t dest_line_gap = ((int32_t)dest_stride - (int32_t)line_size) >> 3;
1.72 +
1.73 + destaddr = destaddr & 0x7FFFF8;
1.74 +
1.75 + for( i=destaddr; i < destaddr + dest_stride*(src_size/src_stride); i+= LXDREAM_PAGE_SIZE ) {
1.76 + texcache_invalidate_page( i );
1.77 + }
1.78 +
1.79 + banks[0] = (uint32_t *)(video_base + (destaddr >>1));
1.80 + banks[1] = banks[0] + 0x100000;
1.81 +
1.82 + while( dwsrc >= (uint32_t *)src ) {
1.83 + for( j=0; j<line_size; j+=8 ) {
1.84 + *banks[0]++ = *dwsrc++;
1.85 + *banks[1]++ = *dwsrc++;
1.86 + }
1.87 + banks[0] += dest_line_gap;
1.88 + banks[1] += dest_line_gap;
1.89 + dwsrc -= src_line_gap;
1.90 + }
1.91 +}
1.92 +
1.93 /**
1.94 * Copy a pixel buffer to vram, flipping and scaling at the same time. This
1.95 * is not massively efficient, but it's used pretty rarely.
1.96 @@ -546,33 +564,31 @@
1.97 * Flush the indicated render buffer back to PVR. Caller is responsible for
1.98 * tracking whether there is actually anything in the buffer.
1.99 *
1.100 - * FIXME: Handle horizontal scaler
1.101 + * FIXME: Handle horizontal scaler
1.102 *
1.103 * @param buffer A render buffer indicating the address to store to, and the
1.104 * format the data needs to be in.
1.105 */
1.106 void pvr2_render_buffer_copy_to_sh4( render_buffer_t buffer )
1.107 {
1.108 + int line_size = buffer->width * colour_formats[buffer->colour_format].bpp;
1.109 + int src_stride = line_size;
1.110 + unsigned char target[buffer->size];
1.111 +
1.112 + display_driver->read_render_buffer( target, buffer, line_size, buffer->colour_format );
1.113 +
1.114 + if( (buffer->scale & 0xFFFF) == 0x0800 )
1.115 + src_stride <<= 1;
1.116 +
1.117 if( (buffer->address & 0xFF000000) == 0x04000000 ) {
1.118 - /* Interlaced buffer. Go the double copy... :( */
1.119 - unsigned char target[buffer->size];
1.120 - display_driver->read_render_buffer( target, buffer, buffer->rowstride, buffer->colour_format );
1.121 - pvr2_vram64_write( buffer->address, target, buffer->size );
1.122 + pvr2_vram64_write_invert( buffer->address, target, buffer->size, line_size,
1.123 + buffer->rowstride, src_stride );
1.124 } else {
1.125 /* Regular buffer */
1.126 - int line_size = buffer->width * colour_formats[buffer->colour_format].bpp;
1.127 - int src_stride = line_size;
1.128 - if( (buffer->scale & 0xFFFF) == 0x0800 )
1.129 - src_stride <<= 1;
1.130 -
1.131 if( buffer->scale & SCALER_HSCALE ) {
1.132 - unsigned char target[buffer->size];
1.133 - display_driver->read_render_buffer( target, buffer, line_size, buffer->colour_format );
1.134 pvr2_vram_write_invert_hscale( buffer->address, target, buffer->size, line_size, buffer->rowstride,
1.135 src_stride, colour_formats[buffer->colour_format].bpp );
1.136 } else {
1.137 - unsigned char target[buffer->size];
1.138 - display_driver->read_render_buffer( target, buffer, line_size, buffer->colour_format );
1.139 pvr2_vram_write_invert( buffer->address, target, buffer->size, line_size, buffer->rowstride,
1.140 src_stride );
1.141 }
.