filename | src/pvr2/tacore.c |
changeset | 193:31151fcc3cb7 |
prev | 189:615b70cfd729 |
next | 194:7fcecbcd5f01 |
author | nkeynes |
date | Fri Aug 04 01:38:30 2006 +0000 (16 years ago) |
permissions | -rw-r--r-- |
last change | Add more tile list limit tests Implement tile list limits in the ta core. Rename TA_TILEEND to TA_LISTEND |
file | annotate | diff | log | raw |
1.1 --- a/src/pvr2/tacore.c Wed Aug 02 04:06:45 2006 +00001.2 +++ b/src/pvr2/tacore.c Fri Aug 04 01:38:30 2006 +00001.3 @@ -1,5 +1,5 @@1.4 /**1.5 - * $Id: tacore.c,v 1.1 2006-08-02 04:06:45 nkeynes Exp $1.6 + * $Id: tacore.c,v 1.2 2006-08-04 01:38:27 nkeynes Exp $1.7 *1.8 * PVR2 Tile Accelerator implementation1.9 *1.10 @@ -120,7 +120,9 @@1.11 int width, height; /* Tile resolution, ie 20x15 */1.12 int tilelist_dir; /* Growth direction of the tilelist, 0 = up, 1 = down */1.13 uint32_t tilelist_size; /* Size of the tilelist segments */1.14 + uint32_t tilelist_start; /* Initial address of the tilelist */1.15 int current_vertex_type;1.16 + gboolean accept_vertexes;1.17 int vertex_count; /* index of last start-vertex seen, or -1 if no vertexes1.18 * are present1.19 */1.20 @@ -160,6 +162,18 @@1.21 ta_status.debug_output = 0;1.22 }1.24 +void pvr2_ta_save_state( FILE *f )1.25 +{1.26 + fwrite( &ta_status, sizeof(ta_status), 1, f );1.27 +}1.28 +1.29 +int pvr2_ta_load_state( FILE *f )1.30 +{1.31 + if( fread( &ta_status, sizeof(ta_status), 1, f ) != 1 )1.32 + return 1;1.33 + return 0;1.34 +}1.35 +1.36 void pvr2_ta_init() {1.37 ta_status.state = STATE_IDLE;1.38 ta_status.current_list_type = -1;1.39 @@ -168,6 +182,7 @@1.40 ta_status.vertex_count = 0;1.41 ta_status.max_vertex = 3;1.42 ta_status.last_triangle_bounds.x1 = -1;1.43 + ta_status.accept_vertexes = TRUE;1.45 uint32_t size = MMIO_READ( PVR2, TA_TILESIZE );1.46 ta_status.width = (size & 0xFFFF) + 1;1.47 @@ -181,6 +196,7 @@1.48 plistpos -= ta_status.tilelist_size;1.49 }1.50 MMIO_WRITE( PVR2, TA_LISTPOS, plistpos );1.51 + ta_status.tilelist_start = plistpos;1.52 }1.54 static uint32_t parse_float_colour( float a, float r, float g, float b ) {1.55 @@ -208,26 +224,42 @@1.56 static void ta_init_list( unsigned int listtype ) {1.57 int config = MMIO_READ( PVR2, TA_TILECFG );1.58 int tile_matrix = MMIO_READ( PVR2, TA_TILEBASE );1.59 - if( listtype <= TA_LIST_PUNCH_OUT ) {1.60 + int list_end = MMIO_READ( PVR2, TA_LISTEND );1.61 +1.62 + ta_status.current_tile_matrix = tile_matrix;1.63 +1.64 + /* If the list grows down, the end must be < tile matrix start.1.65 + * If it grows up, the end must be > tile matrix start.1.66 + * Don't ask me why, it just does...1.67 + */1.68 + if( ((ta_status.tilelist_dir == TA_GROW_DOWN && list_end <= tile_matrix) ||1.69 + (ta_status.tilelist_dir == TA_GROW_UP && list_end >= tile_matrix )) &&1.70 + listtype <= TA_LIST_PUNCH_OUT ) {1.71 int i;1.72 uint32_t *p;1.73 for( i=0; i < listtype; i++ ) {1.74 int size = tilematrix_sizes[(config & 0x03)] << 2;1.75 - tile_matrix += ta_status.width * ta_status.height * size;1.76 + ta_status.current_tile_matrix += ta_status.width * ta_status.height * size;1.77 config >>= 4;1.78 }1.79 - ta_status.current_tile_matrix = tile_matrix;1.80 ta_status.current_tile_size = tilematrix_sizes[(config & 0x03)];1.82 /* Initialize each tile to 0xF0000000 */1.83 if( ta_status.current_tile_size != 0 ) {1.84 - p = (uint32_t *)(video_base + tile_matrix);1.85 + p = (uint32_t *)(video_base + ta_status.current_tile_matrix);1.86 for( i=0; i< ta_status.width * ta_status.height; i++ ) {1.87 *p = 0xF0000000;1.88 p += ta_status.current_tile_size;1.89 }1.90 }1.91 + } else {1.92 + ta_status.current_tile_size = 0;1.93 }1.94 +1.95 + if( tile_matrix == list_end ) {1.96 + ta_status.current_tile_size = 0;1.97 + }1.98 +1.99 ta_status.state = STATE_IN_LIST;1.100 ta_status.current_list_type = listtype;1.101 ta_status.last_triangle_bounds.x1 = -1;1.102 @@ -274,19 +306,56 @@1.103 return rv;1.104 }1.106 +#define TA_NO_ALLOC 0xFFFFFFFF1.107 +1.108 /**1.109 - * Allocate a new tile list from the grow space1.110 + * Allocate a new tile list block from the grow space and update the1.111 + * word at reference to be a link to the new block.1.112 */1.113 -static uint32_t ta_alloc_tilelist() {1.114 +static uint32_t ta_alloc_tilelist( uint32_t reference ) {1.115 uint32_t posn = MMIO_READ( PVR2, TA_LISTPOS );1.116 + uint32_t limit = MMIO_READ( PVR2, TA_LISTEND ) >> 2;1.117 uint32_t newposn;1.118 + uint32_t result;1.119 if( ta_status.tilelist_dir == TA_GROW_DOWN ) {1.120 newposn = posn - ta_status.tilelist_size;1.121 + if( posn == limit ) {1.122 + PVRRAM(posn<<2) = 0xF0000000;1.123 + PVRRAM(reference) = 0xE0000000 | (posn<<2);1.124 + return TA_NO_ALLOC;1.125 + } else if( posn < limit ) {1.126 + PVRRAM(reference) = 0xE0000000 | (posn<<2);1.127 + return TA_NO_ALLOC;1.128 + } else if( newposn <= limit ) {1.129 + } else if( newposn <= (limit + ta_status.tilelist_size) ) {1.130 + asic_event( EVENT_TA_ERROR );1.131 + asic_event( EVENT_PVR_MATRIX_ALLOC_FAIL );1.132 + MMIO_WRITE( PVR2, TA_LISTPOS, newposn );1.133 + } else {1.134 + MMIO_WRITE( PVR2, TA_LISTPOS, newposn );1.135 + }1.136 + PVRRAM(reference) = 0xE0000000 | (posn<<2);1.137 + return posn << 2;1.138 } else {1.139 newposn = posn + ta_status.tilelist_size;1.140 + if( posn == limit ) {1.141 + PVRRAM(posn<<2) = 0xF0000000;1.142 + PVRRAM(reference) = 0xE0000000 | (posn<<2);1.143 + return TA_NO_ALLOC;1.144 + } else if ( posn > limit ) {1.145 + PVRRAM(reference) = 0xE0000000 | (posn<<2);1.146 + return TA_NO_ALLOC;1.147 + } else if( newposn >= limit ) {1.148 + } else if( newposn >= (limit - ta_status.tilelist_size) ) {1.149 + asic_event( EVENT_TA_ERROR );1.150 + asic_event( EVENT_PVR_MATRIX_ALLOC_FAIL );1.151 + MMIO_WRITE( PVR2, TA_LISTPOS, newposn );1.152 + } else {1.153 + MMIO_WRITE( PVR2, TA_LISTPOS, newposn );1.154 + }1.155 + PVRRAM(reference) = 0xE0000000 | (posn<<2);1.156 + return posn << 2;1.157 }1.158 - MMIO_WRITE( PVR2, TA_LISTPOS, newposn );1.159 - return posn << 2;1.160 }1.162 /**1.163 @@ -294,6 +363,7 @@1.164 */1.165 static int ta_write_tile_entry( int x, int y, uint32_t tile_entry ) {1.166 uint32_t tile = TILESLOT(x,y);1.167 + uint32_t tilestart = tile;1.168 uint32_t value;1.169 uint32_t lasttri = 0;1.170 int i,l;1.171 @@ -338,14 +408,17 @@1.172 }1.174 if( value == 0xF0000000 ) {1.175 - value = ta_alloc_tilelist();1.176 - PVRRAM(tile) = value | 0xE0000000;1.177 - tile = value;1.178 - PVRRAM(tile) = tile_entry;1.179 - PVRRAM(tile+4) = 0xF0000000;1.180 + tile = ta_alloc_tilelist(tile);1.181 + if( tile != TA_NO_ALLOC ) {1.182 + PVRRAM(tile) = tile_entry;1.183 + PVRRAM(tile+4) = 0xF0000000;1.184 + }1.185 return;1.186 } else if( (value & 0xFF000000) == 0xE0000000 ) {1.187 - tile = (value & 0x00FFFFFF);1.188 + value &= 0x00FFFFFF;1.189 + if( value == tilestart )1.190 + return 0; /* Loop */1.191 + tilestart = tile = value;1.192 } else {1.193 /* This should never happen */1.194 return 0;1.195 @@ -443,6 +516,11 @@1.196 }1.197 }1.199 + if( ta_status.current_tile_size == 0 ) {1.200 + /* No memory for tile entry, so don't write anything */1.201 + return;1.202 + }1.203 +1.204 /* And now the tile entries. Triangles are different from everything else */1.205 if( ta_status.vertex_count == 3 ) {1.206 tile_entry |= 0x80000000;1.207 @@ -642,7 +720,6 @@1.208 memcpy( &ta_status.poly_vertex[i], &ta_status.poly_vertex[ta_status.vertex_count-1],1.209 sizeof( struct pvr2_ta_vertex ) );1.210 }1.211 - ta_status.vertex_count = ta_status.max_vertex;1.212 }1.214 static void ta_parse_vertex( union ta_data *data ) {1.215 @@ -908,14 +985,17 @@1.216 }1.218 if( ta_status.vertex_count != 0 ) {1.219 + /* Error, and not a very well handled one either */1.220 + asic_event( EVENT_PVR_BAD_INPUT );1.221 + asic_event( EVENT_TA_ERROR );1.222 + ta_status.accept_vertexes = FALSE;1.223 ta_fill_vertexes();1.224 - ta_commit_polygon();1.225 - }1.226 -1.227 - if( TA_IS_MODIFIER_LIST( ta_status.current_list_type ) ) {1.228 - ta_parse_modifier_context(data);1.229 } else {1.230 - ta_parse_polygon_context(data);1.231 + if( TA_IS_MODIFIER_LIST( ta_status.current_list_type ) ) {1.232 + ta_parse_modifier_context(data);1.233 + } else {1.234 + ta_parse_polygon_context(data);1.235 + }1.236 }1.237 break;1.238 case TA_CMD_SPRITE_CONTEXT:
.