filename | src/pvr2/tacore.c |
changeset | 203:c86a40546fc0 |
prev | 200:c3bdcd373b6d |
next | 206:f5de539c0fcb |
author | nkeynes |
date | Sun Aug 06 06:13:51 2006 +0000 (15 years ago) |
permissions | -rw-r--r-- |
last change | First pass at implementing the tile clip. Reasonably accurate wrt basic understanding of how its supposed to work, not so accurate wrt actual hardware behaviour |
file | annotate | diff | log | raw |
1.1 --- a/src/pvr2/tacore.c Sun Aug 06 04:01:37 2006 +00001.2 +++ b/src/pvr2/tacore.c Sun Aug 06 06:13:51 2006 +00001.3 @@ -1,5 +1,5 @@1.4 /**1.5 - * $Id: tacore.c,v 1.6 2006-08-06 04:01:37 nkeynes Exp $1.6 + * $Id: tacore.c,v 1.7 2006-08-06 06:13:51 nkeynes Exp $1.7 *1.8 * PVR2 Tile Accelerator implementation1.9 *1.10 @@ -81,6 +81,9 @@1.11 #define TA_POLYCMD_USELENGTH(i) ( i & 0x00800000 )1.12 #define TA_POLYCMD_LENGTH(i) strip_lengths[((i >> 18) & 0x03)]1.13 #define TA_POLYCMD_CLIP(i) ((i>>16)&0x03)1.14 +#define TA_POLYCMD_CLIP_NONE 01.15 +#define TA_POLYCMD_CLIP_INSIDE 21.16 +#define TA_POLYCMD_CLIP_OUTSIDE 31.17 #define TA_POLYCMD_COLOURFMT(i) (i & 0x00000030)1.18 #define TA_POLYCMD_COLOURFMT_ARGB32 0x000000001.19 #define TA_POLYCMD_COLOURFMT_FLOAT 0x000000101.20 @@ -139,7 +142,8 @@1.21 uint32_t current_tile_matrix; /* Memory location of the first tile for the current list. */1.22 uint32_t current_tile_size; /* Size of the tile matrix space in 32-bit words (0/8/16/32)*/1.23 uint32_t intensity1, intensity2;1.24 - struct tile_bounds clip;1.25 + struct tile_bounds clip;1.26 + int clip_mode;1.27 /**1.28 * Current working object1.29 */1.30 @@ -194,6 +198,7 @@1.31 ta_status.accept_vertexes = TRUE;1.32 ta_status.clip.x1 = 0;1.33 ta_status.clip.y1 = 0;1.34 + ta_status.clip_mode = TA_POLYCMD_CLIP_NONE;1.36 uint32_t size = MMIO_READ( PVR2, TA_TILESIZE );1.37 ta_status.width = (size & 0xFFFF) + 1;1.38 @@ -407,6 +412,13 @@1.39 uint32_t lasttri = 0;1.40 int i,l;1.42 + if( ta_status.clip_mode == TA_POLYCMD_CLIP_OUTSIDE &&1.43 + x >= ta_status.clip.x1 && x <= ta_status.clip.x2 &&1.44 + y >= ta_status.clip.y1 && y <= ta_status.clip.y2 ) {1.45 + /* Tile clipped out */1.46 + return 0;1.47 + }1.48 +1.49 if( (tile_entry & 0x80000000) &&1.50 ta_status.last_triangle_bounds.x1 != -1 &&1.51 ta_status.last_triangle_bounds.x1 <= x &&1.52 @@ -524,12 +536,6 @@1.53 }1.54 }1.56 - /* If the polygon is actually entirely out of the frustum, clip it entirely */1.57 - if( polygon_bound.x2 < 0 || polygon_bound.x1 > ta_status.width ||1.58 - polygon_bound.y2 < 0 || polygon_bound.y1 > ta_status.height ) {1.59 - return;1.60 - }1.61 -1.62 /* Clamp the polygon bounds to the frustum */1.63 if( polygon_bound.x1 < 0 ) polygon_bound.x1 = 0;1.64 if( polygon_bound.x2 >= ta_status.width ) polygon_bound.x2 = ta_status.width-1;1.65 @@ -541,6 +547,34 @@1.66 polygon_bound.y1 == polygon_bound.y2 ) {1.67 poly_context[0] |= 0x00200000;1.68 }1.69 +1.70 + /* If the polygon is entirely clipped, don't even write the polygon data */1.71 + switch( ta_status.clip_mode ) {1.72 + case TA_POLYCMD_CLIP_NONE:1.73 + if( polygon_bound.x2 < 0 || polygon_bound.x1 >= ta_status.width ||1.74 + polygon_bound.y2 < 0 || polygon_bound.y1 >= ta_status.height ) {1.75 + return;1.76 + }1.77 + break;1.78 + case TA_POLYCMD_CLIP_INSIDE:1.79 + if( polygon_bound.x2 < ta_status.clip.x1 || polygon_bound.x1 > ta_status.clip.x2 ||1.80 + polygon_bound.y2 < ta_status.clip.y1 || polygon_bound.y1 > ta_status.clip.y1 ) {1.81 + return;1.82 + } else {1.83 + /* Clamp to clip bounds */1.84 + if( polygon_bound.x1 < ta_status.clip.x1 ) polygon_bound.x1 = ta_status.clip.x1;1.85 + if( polygon_bound.x2 > ta_status.clip.x2 ) polygon_bound.x2 = ta_status.clip.x2;1.86 + if( polygon_bound.y1 < ta_status.clip.y1 ) polygon_bound.y1 = ta_status.clip.y1;1.87 + if( polygon_bound.y2 > ta_status.clip.y2 ) polygon_bound.y2 = ta_status.clip.y2;1.88 + }1.89 + break;1.90 + case TA_POLYCMD_CLIP_OUTSIDE:1.91 + if( polygon_bound.x1 >= ta_status.clip.x1 && polygon_bound.x2 <= ta_status.clip.x2 &&1.92 + polygon_bound.y1 >= ta_status.clip.y1 && polygon_bound.y2 <= ta_status.clip.y2 ) {1.93 + return;1.94 + }1.95 + break;1.96 + }1.98 /* Ok, we're good to go - write out the polygon first */1.99 uint32_t tile_entry = MMIO_READ( PVR2, TA_POLYPOS ) >> 2 | ta_status.poly_pointer;1.100 @@ -646,6 +680,10 @@1.101 if( TA_POLYCMD_USELENGTH(data[0].i) ) {1.102 ta_status.max_vertex = TA_POLYCMD_LENGTH(data[0].i);1.103 }1.104 + ta_status.clip_mode = TA_POLYCMD_CLIP(data[0].i);1.105 + if( ta_status.clip_mode == 1 ) { /* Reserved - treat as CLIP_INSIDE */1.106 + ta_status.clip_mode = TA_POLYCMD_CLIP_INSIDE;1.107 + }1.108 ta_status.vertex_count = 0;1.109 ta_status.poly_context[0] =1.110 (data[1].i & 0xFC1FFFFF) | ((data[0].i & 0x0B) << 22);1.111 @@ -1030,6 +1068,10 @@1.112 ta_status.clip.y1 = data[5].i & 0x0F;1.113 ta_status.clip.x2 = data[6].i & 0x3F;1.114 ta_status.clip.y2 = data[7].i & 0x0F;1.115 + if( ta_status.clip.x2 >= ta_status.width )1.116 + ta_status.clip.x2 = ta_status.width - 1;1.117 + if( ta_status.clip.y2 >= ta_status.height )1.118 + ta_status.clip.y2 = ta_status.height - 1;1.119 break;1.120 case TA_CMD_POLYGON_CONTEXT:1.121 if( ta_status.state == STATE_IDLE ) {
.