filename | src/pvr2/pvr2mem.c |
changeset | 284:808617ee7135 |
next | 285:4fefedafebc6 |
author | nkeynes |
date | Mon Jan 15 08:32:09 2007 +0000 (15 years ago) |
permissions | -rw-r--r-- |
last change | Break vram routines out into pvr2mem.c Initial (untested) implementation of stride textures Hookup YUV converter code in pvr2.c |
file | annotate | diff | log | raw |
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00001.2 +++ b/src/pvr2/pvr2mem.c Mon Jan 15 08:32:09 2007 +00001.3 @@ -0,0 +1,225 @@1.4 +/**1.5 + * $Id: pvr2mem.c,v 1.1 2007-01-15 08:32:09 nkeynes Exp $1.6 + *1.7 + * PVR2 (Video) VRAM handling routines (mainly for the 64-bit region)1.8 + *1.9 + * Copyright (c) 2005 Nathan Keynes.1.10 + *1.11 + * This program is free software; you can redistribute it and/or modify1.12 + * it under the terms of the GNU General Public License as published by1.13 + * the Free Software Foundation; either version 2 of the License, or1.14 + * (at your option) any later version.1.15 + *1.16 + * This program is distributed in the hope that it will be useful,1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1.19 + * GNU General Public License for more details.1.20 + */1.21 +#include "pvr2.h"1.22 +1.23 +extern char *video_base;1.24 +1.25 +void pvr2_vram64_write( sh4addr_t destaddr, char *src, uint32_t length )1.26 +{1.27 + int bank_flag = (destaddr & 0x04) >> 2;1.28 + uint32_t *banks[2];1.29 + uint32_t *dwsrc;1.30 + int i;1.31 +1.32 + destaddr = destaddr & 0x7FFFFF;1.33 + if( destaddr + length > 0x800000 ) {1.34 + length = 0x800000 - destaddr;1.35 + }1.36 +1.37 + for( i=destaddr & 0xFFFFF000; i < destaddr + length; i+= PAGE_SIZE ) {1.38 + texcache_invalidate_page( i );1.39 + }1.40 +1.41 + banks[0] = ((uint32_t *)(video_base + ((destaddr & 0x007FFFF8) >>1)));1.42 + banks[1] = banks[0] + 0x100000;1.43 + if( bank_flag )1.44 + banks[0]++;1.45 +1.46 + /* Handle non-aligned start of source */1.47 + if( destaddr & 0x03 ) {1.48 + char *dest = ((char *)banks[bank_flag]) + (destaddr & 0x03);1.49 + for( i= destaddr & 0x03; i < 4 && length > 0; i++, length-- ) {1.50 + *dest++ = *src++;1.51 + }1.52 + bank_flag = !bank_flag;1.53 + }1.54 +1.55 + dwsrc = (uint32_t *)src;1.56 + while( length >= 4 ) {1.57 + *banks[bank_flag]++ = *dwsrc++;1.58 + bank_flag = !bank_flag;1.59 + length -= 4;1.60 + }1.61 +1.62 + /* Handle non-aligned end of source */1.63 + if( length ) {1.64 + src = (char *)dwsrc;1.65 + char *dest = (char *)banks[bank_flag];1.66 + while( length-- > 0 ) {1.67 + *dest++ = *src++;1.68 + }1.69 + }1.70 +}1.71 +1.72 +/**1.73 + * Write an image to 64-bit vram, with a line-stride different from the line-size.1.74 + * The destaddr must be 32-bit aligned, and both line_bytes and line_stride_bytes1.75 + * must be multiples of 4.1.76 + */1.77 +void pvr2_vram64_write_stride( sh4addr_t destaddr, char *src, uint32_t line_bytes,1.78 + uint32_t line_stride_bytes, uint32_t line_count )1.79 +{1.80 + int bank_flag = (destaddr & 0x04) >> 2;1.81 + uint32_t *banks[2];1.82 + uint32_t *dwsrc;1.83 + uint32_t line_gap;1.84 + int line_gap_flag;1.85 + int i,j;1.86 +1.87 + destaddr = destaddr & 0x7FFFF8;1.88 + i = line_stride_bytes - line_bytes;1.89 + line_gap_flag = i & 0x04;1.90 + line_gap = i >> 3;1.91 + line_bytes >>= 2;1.92 +1.93 + for( i=destaddr & 0xFFFFF000; i < destaddr + line_stride_bytes*line_count; i+= PAGE_SIZE ) {1.94 + texcache_invalidate_page( i );1.95 + }1.96 +1.97 + banks[0] = (uint32_t *)(video_base + (destaddr >>1));1.98 + banks[1] = banks[0] + 0x100000;1.99 + if( bank_flag )1.100 + banks[0]++;1.101 +1.102 + dwsrc = (uint32_t *)src;1.103 + for( i=0; i<line_count; i++ ) {1.104 + for( j=0; j<line_bytes; j++ ) {1.105 + *banks[bank_flag]++ = *dwsrc++;1.106 + bank_flag = !bank_flag;1.107 + }1.108 + *banks[0] += line_gap;1.109 + *banks[1] += line_gap;1.110 + if( line_gap_flag ) {1.111 + *banks[bank_flag]++;1.112 + bank_flag = !bank_flag;1.113 + }1.114 + }1.115 +}1.116 +1.117 +/**1.118 + * Read an image from 64-bit vram, with a destination line-stride different from the line-size.1.119 + * The srcaddr must be 32-bit aligned, and both line_bytes and line_stride_bytes1.120 + * must be multiples of 4. line_stride_bytes must be >= line_bytes.1.121 + * This method is used to extract a "stride" texture from vram.1.122 + */1.123 +void pvr2_vram64_read_stride( char *dest, uint32_t dest_line_bytes, sh4addr_t srcaddr,1.124 + uint32_t src_line_bytes, uint32_t line_count )1.125 +{1.126 + int bank_flag = (srcaddr & 0x04) >> 2;1.127 + uint32_t *banks[2];1.128 + uint32_t *dwdest;1.129 + uint32_t dest_line_gap;1.130 + uint32_t src_line_gap;1.131 + uint32_t line_bytes;1.132 + int src_line_gap_flag;1.133 + int i,j;1.134 +1.135 + srcaddr = srcaddr & 0x7FFFF8;1.136 + if( src_line_bytes <= dest_line_bytes ) {1.137 + dest_line_gap = (dest_line_bytes - src_line_bytes) >> 2;1.138 + src_line_gap = 0;1.139 + src_line_gap_flag = 0;1.140 + line_bytes = src_line_bytes >> 2;1.141 + } else {1.142 + i = (src_line_bytes - dest_line_bytes);1.143 + src_line_gap_flag = i & 0x04;1.144 + src_line_gap = i >> 3;1.145 + line_bytes = dest_line_bytes >> 2;1.146 + }1.147 +1.148 + banks[0] = (uint32_t *)(video_base + (srcaddr>>1));1.149 + banks[1] = banks[0] + 0x100000;1.150 + if( bank_flag )1.151 + banks[0]++;1.152 +1.153 + dwdest = (uint32_t *)dest;1.154 + for( i=0; i<line_count; i++ ) {1.155 + for( j=0; j<line_bytes; j++ ) {1.156 + *dwdest++ = *banks[bank_flag]++;1.157 + bank_flag = !bank_flag;1.158 + }1.159 + dwdest += dest_line_gap;1.160 + banks[0] += src_line_gap;1.161 + banks[1] += src_line_gap;1.162 + if( src_line_gap_flag ) {1.163 + banks[bank_flag]++;1.164 + bank_flag = !bank_flag;1.165 + }1.166 + }1.167 +1.168 +}1.169 +1.170 +void pvr2_vram_write_invert( sh4addr_t destaddr, char *src, uint32_t length, uint32_t line_length )1.171 +{1.172 + char *dest = video_base + (destaddr & 0x007FFFFF);1.173 + char *p = src + length - line_length;1.174 + while( p >= src ) {1.175 + memcpy( dest, p, line_length );1.176 + p -= line_length;1.177 + dest += line_length;1.178 + }1.179 +}1.180 +1.181 +void pvr2_vram64_read( char *dest, sh4addr_t srcaddr, uint32_t length )1.182 +{1.183 + int bank_flag = (srcaddr & 0x04) >> 2;1.184 + uint32_t *banks[2];1.185 + uint32_t *dwdest;1.186 + int i;1.187 +1.188 + srcaddr = srcaddr & 0x7FFFFF;1.189 + if( srcaddr + length > 0x800000 )1.190 + length = 0x800000 - srcaddr;1.191 +1.192 + banks[0] = ((uint32_t *)(video_base + ((srcaddr&0x007FFFF8)>>1)));1.193 + banks[1] = banks[0] + 0x100000;1.194 + if( bank_flag )1.195 + banks[0]++;1.196 +1.197 + /* Handle non-aligned start of source */1.198 + if( srcaddr & 0x03 ) {1.199 + char *src = ((char *)banks[bank_flag]) + (srcaddr & 0x03);1.200 + for( i= srcaddr & 0x03; i < 4 && length > 0; i++, length-- ) {1.201 + *dest++ = *src++;1.202 + }1.203 + bank_flag = !bank_flag;1.204 + }1.205 +1.206 + dwdest = (uint32_t *)dest;1.207 + while( length >= 4 ) {1.208 + *dwdest++ = *banks[bank_flag]++;1.209 + bank_flag = !bank_flag;1.210 + length -= 4;1.211 + }1.212 +1.213 + /* Handle non-aligned end of source */1.214 + if( length ) {1.215 + dest = (char *)dwdest;1.216 + char *src = (char *)banks[bank_flag];1.217 + while( length-- > 0 ) {1.218 + *dest++ = *src++;1.219 + }1.220 + }1.221 +}1.222 +1.223 +void pvr2_vram64_dump( sh4addr_t addr, uint32_t length, FILE *f )1.224 +{1.225 + char tmp[length];1.226 + pvr2_vram64_read( tmp, addr, length );1.227 + fwrite_dump( tmp, length, f );1.228 +}
.