Search
lxdream.org :: lxdream/src/pvr2/tacore.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/tacore.c
changeset 203:c86a40546fc0
prev200:c3bdcd373b6d
next206:f5de539c0fcb
author nkeynes
date Sun Aug 06 06:13:51 2006 +0000 (13 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 +0000
1.2 +++ b/src/pvr2/tacore.c Sun Aug 06 06:13:51 2006 +0000
1.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 implementation
1.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 0
1.15 +#define TA_POLYCMD_CLIP_INSIDE 2
1.16 +#define TA_POLYCMD_CLIP_OUTSIDE 3
1.17 #define TA_POLYCMD_COLOURFMT(i) (i & 0x00000030)
1.18 #define TA_POLYCMD_COLOURFMT_ARGB32 0x00000000
1.19 #define TA_POLYCMD_COLOURFMT_FLOAT 0x00000010
1.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 object
1.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.35
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.41
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.55
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.97
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 ) {
.