@@ -130,37 +130,48 @@ enum PrimitiveType {
130
130
}
131
131
132
132
mod bounded {
133
- use crate :: utils:: { bounded_int_lit, bounded_int_savestate} ;
133
+ use crate :: utils:: { bounded_int_lit, bounded_int_savestate, bounded_int_unsafe_from_into } ;
134
134
bounded_int_lit ! ( pub struct PrimVertIndex ( u8 ) , max 3 ) ;
135
135
bounded_int_savestate ! ( PrimVertIndex ( u8 ) ) ;
136
136
bounded_int_lit ! ( pub struct PrimMaxVerts ( u8 ) , max 4 ) ;
137
137
bounded_int_savestate ! ( PrimMaxVerts ( u8 ) ) ;
138
138
bounded_int_lit ! ( pub struct PolyVertIndex ( u8 ) , max 9 ) ;
139
- bounded_int_savestate ! ( PolyVertIndex ( u8 ) ) ;
140
139
bounded_int_lit ! ( pub struct PolyVertsLen ( u8 ) , max 10 ) ;
141
- bounded_int_savestate ! ( PolyVertsLen ( u8 ) ) ;
140
+ bounded_int_unsafe_from_into ! ( PolyVertsLen ( u8 ) ) ;
142
141
bounded_int_lit ! ( pub struct PolyAddr ( u16 ) , max 2047 ) ;
143
- bounded_int_savestate ! ( PolyAddr ( u16 ) ) ;
144
142
bounded_int_lit ! ( pub struct VertexAddr ( u16 ) , max 6143 ) ;
145
143
bounded_int_savestate ! ( VertexAddr ( u16 ) ) ;
146
144
}
147
145
pub use bounded:: { PolyAddr , PolyVertIndex , PolyVertsLen , VertexAddr } ;
148
146
use bounded:: { PrimMaxVerts , PrimVertIndex } ;
149
147
148
+ proc_bitfield:: bitfield! {
149
+ #[ derive( Clone , Copy , PartialEq , Eq , Savestate ) ]
150
+ pub struct RenderingPolygonAttrs ( u32 ) : Debug {
151
+ pub raw: u32 [ read_only] @ ..,
152
+ pub verts_len: u8 [ unsafe PolyVertsLen ] @ 0 ..=3 ,
153
+ pub mode: u8 @ 4 ..=5 ,
154
+ pub update_depth_for_translucent: bool @ 11 ,
155
+ pub depth_test_equal: bool @ 14 ,
156
+ pub fog_enabled: bool @ 15 ,
157
+ pub alpha: u8 @ 16 ..=20 ,
158
+ pub id: u8 @ 24 ..=29 ,
159
+ pub is_front_facing: bool @ 30 ,
160
+ pub is_translucent: bool @ 30 ,
161
+ }
162
+ }
163
+
150
164
#[ derive( Clone , Copy , Debug , PartialEq , Eq , Savestate ) ]
151
165
#[ repr( C ) ]
152
166
pub struct Polygon {
153
- pub vertices : [ VertexAddr ; 10 ] ,
167
+ pub verts : [ VertexAddr ; 10 ] ,
154
168
pub depth_values : [ u32 ; 10 ] ,
155
169
pub w_values : [ u16 ; 10 ] ,
156
170
pub top_y : u8 ,
157
171
pub bot_y : u8 ,
158
- pub vertices_len : PolyVertsLen ,
159
- pub attrs : PolygonAttrs ,
160
- pub is_front_facing : bool ,
161
- pub is_translucent : bool ,
162
- pub tex_params : TextureParams ,
163
172
pub tex_palette_base : u16 ,
173
+ pub tex_params : TextureParams ,
174
+ pub attrs : RenderingPolygonAttrs ,
164
175
}
165
176
166
177
proc_bitfield:: bitfield! {
@@ -936,7 +947,7 @@ impl Engine3d {
936
947
} ;
937
948
}
938
949
939
- macro_rules! run_pass {
950
+ macro_rules! run_clip_pass {
940
951
( $axis_i: expr, $clip_far: expr, $input: expr$( , $assume_init: ident) ? => $output: expr) => {
941
952
let input_len = replace( & mut clipped_verts_len, shared_verts) ;
942
953
for ( i, vert) in $input[ ..input_len] . iter( ) . enumerate( ) . skip( shared_verts) {
@@ -1004,6 +1015,7 @@ impl Engine3d {
1004
1015
}
1005
1016
}
1006
1017
if clipped_verts_len == 0 {
1018
+ self . connect_to_last_strip_prim = false ;
1007
1019
return ;
1008
1020
}
1009
1021
} ;
@@ -1022,43 +1034,48 @@ impl Engine3d {
1022
1034
buffer_0[ i] = MaybeUninit :: new ( self . cur_prim_verts [ i] ) ;
1023
1035
buffer_1[ i] = MaybeUninit :: new ( self . cur_prim_verts [ i] ) ;
1024
1036
}
1025
- run_pass ! ( 2 , self . cur_poly_attrs. clip_far_plane( ) , self . cur_prim_verts => buffer_0) ;
1037
+ run_clip_pass ! ( 2 , self . cur_poly_attrs. clip_far_plane( ) , self . cur_prim_verts => buffer_0) ;
1026
1038
unsafe {
1027
- run_pass ! ( 1 , true , buffer_0, assume_init_ref => buffer_1) ;
1028
- run_pass ! ( 0 , true , buffer_1, assume_init_ref => buffer_0) ;
1039
+ run_clip_pass ! ( 1 , true , buffer_0, assume_init_ref => buffer_1) ;
1040
+ run_clip_pass ! ( 0 , true , buffer_1, assume_init_ref => buffer_0) ;
1029
1041
}
1042
+ let clipped_verts =
1043
+ unsafe { MaybeUninit :: slice_assume_init_mut ( & mut buffer_0[ ..clipped_verts_len] ) } ;
1030
1044
1031
1045
if self . vert_ram_level as usize > self . vert_ram . len ( ) - ( clipped_verts_len - shared_verts) {
1032
1046
self . rendering_state
1033
1047
. control
1034
1048
. set_poly_vert_ram_overflow ( true ) ;
1049
+ self . connect_to_last_strip_prim = false ;
1035
1050
return ;
1036
1051
}
1037
1052
1053
+ let is_translucent = matches ! ( self . cur_poly_attrs. alpha( ) , 1 ..=30 )
1054
+ || ( matches ! ( self . cur_poly_attrs. mode( ) , 0 | 2 )
1055
+ && matches ! ( self . tex_params. format( ) , 1 | 6 ) ) ;
1056
+
1038
1057
let poly = & mut self . poly_ram [ self . poly_ram_level as usize ] ;
1039
1058
self . poly_ram_level += 1 ;
1040
- poly. vertices_len = PolyVertsLen :: new ( clipped_verts_len as u8 ) ;
1041
1059
poly. tex_palette_base = self . tex_palette_base ;
1042
1060
poly. tex_params = self . tex_params ;
1043
- poly. attrs = self . cur_poly_attrs ;
1044
- poly . is_front_facing = is_front_facing ;
1045
- poly . is_translucent = matches ! ( poly . attrs . alpha ( ) , 1 ..= 30 )
1046
- || ( matches ! ( poly . attrs . mode ( ) , 0 | 2 ) && matches ! ( poly . tex_params . format ( ) , 1 | 6 ) ) ;
1061
+ poly. attrs = RenderingPolygonAttrs ( self . cur_poly_attrs . 0 )
1062
+ . with_verts_len ( PolyVertsLen :: new ( clipped_verts_len as u8 ) )
1063
+ . with_is_front_facing ( is_front_facing )
1064
+ . with_is_translucent ( is_translucent ) ;
1047
1065
1048
1066
if connect_to_last_strip_prim {
1049
- poly. vertices [ ..2 ] . copy_from_slice ( & self . last_strip_prim_vert_indices ) ;
1067
+ poly. verts [ ..2 ] . copy_from_slice ( & self . last_strip_prim_vert_indices ) ;
1050
1068
}
1051
1069
1052
1070
let mut top_y = 0xFF ;
1053
1071
let mut bot_y = 0 ;
1054
1072
1055
1073
let viewport_origin = self . viewport_origin ;
1056
1074
let viewport_size = self . viewport_size ;
1057
- for ( vert, vert_addr) in buffer_0 [ shared_verts..clipped_verts_len ]
1075
+ for ( vert, vert_addr) in clipped_verts [ shared_verts..]
1058
1076
. iter_mut ( )
1059
- . zip ( & mut poly. vertices [ shared_verts..clipped_verts_len] )
1077
+ . zip ( & mut poly. verts [ shared_verts..clipped_verts_len] )
1060
1078
{
1061
- let vert = unsafe { vert. assume_init_mut ( ) } ;
1062
1079
vert. coords [ 3 ] &= 0x00FF_FFFF ;
1063
1080
let w = vert. coords [ 3 ] as u32 ;
1064
1081
let coords = if w == 0 {
@@ -1114,7 +1131,7 @@ impl Engine3d {
1114
1131
self . vert_ram_level += 1 ;
1115
1132
}
1116
1133
1117
- for & vert_addr in & poly. vertices [ ..shared_verts] {
1134
+ for & vert_addr in & poly. verts [ ..shared_verts] {
1118
1135
let y = self . vert_ram [ vert_addr. get ( ) as usize ] . coords [ 1 ] as u8 ;
1119
1136
top_y = top_y. min ( y) ;
1120
1137
bot_y = bot_y. max ( y) ;
@@ -1124,26 +1141,24 @@ impl Engine3d {
1124
1141
poly. bot_y = bot_y;
1125
1142
1126
1143
let mut w_leading_zeros = 32 ;
1127
- for vert in & buffer_0[ ..clipped_verts_len] {
1128
- w_leading_zeros =
1129
- w_leading_zeros. min ( unsafe { vert. assume_init_ref ( ) } . coords [ 3 ] . leading_zeros ( ) ) ;
1144
+ for vert in clipped_verts. iter ( ) {
1145
+ w_leading_zeros = w_leading_zeros. min ( vert. coords [ 3 ] . leading_zeros ( ) ) ;
1130
1146
}
1131
1147
w_leading_zeros &= !3 ;
1132
1148
1133
1149
if w_leading_zeros >= 16 {
1134
1150
let shift = w_leading_zeros - 16 ;
1135
- for ( i, vert) in buffer_0 [ ..clipped_verts_len ] . iter ( ) . enumerate ( ) {
1136
- poly. w_values [ i] = ( unsafe { vert. assume_init_ref ( ) } . coords [ 3 ] << shift) as u16 ;
1151
+ for ( i, vert) in clipped_verts . iter ( ) . enumerate ( ) {
1152
+ poly. w_values [ i] = ( vert. coords [ 3 ] << shift) as u16 ;
1137
1153
}
1138
1154
} else {
1139
1155
let shift = 16 - w_leading_zeros;
1140
- for ( i, vert) in buffer_0 [ ..clipped_verts_len ] . iter ( ) . enumerate ( ) {
1141
- poly. w_values [ i] = ( unsafe { vert. assume_init_ref ( ) } . coords [ 3 ] >> shift) as u16 ;
1156
+ for ( i, vert) in clipped_verts . iter ( ) . enumerate ( ) {
1157
+ poly. w_values [ i] = ( vert. coords [ 3 ] >> shift) as u16 ;
1142
1158
}
1143
1159
}
1144
1160
1145
- for ( i, vert) in buffer_0[ ..clipped_verts_len] . iter ( ) . enumerate ( ) {
1146
- let vert = unsafe { vert. assume_init_ref ( ) } ;
1161
+ for ( i, vert) in clipped_verts. iter ( ) . enumerate ( ) {
1147
1162
let w = vert. coords [ 3 ] as u32 ;
1148
1163
poly. depth_values [ i] = if self . rendering_state . w_buffering {
1149
1164
w & !( ( ( ( 1_u64 << ( 32 - w_leading_zeros) ) - 1 ) as u32 ) >> 16 )
@@ -1160,14 +1175,14 @@ impl Engine3d {
1160
1175
match self . cur_prim_type {
1161
1176
PrimitiveType :: TriangleStrip => {
1162
1177
self . last_strip_prim_vert_indices = if self . cur_strip_prim_is_odd {
1163
- [ poly. vertices [ 0 ] , poly. vertices [ 2 ] ]
1178
+ [ poly. verts [ 0 ] , poly. verts [ 2 ] ]
1164
1179
} else {
1165
- [ poly. vertices [ 2 ] , poly. vertices [ 1 ] ]
1180
+ [ poly. verts [ 2 ] , poly. verts [ 1 ] ]
1166
1181
} ;
1167
1182
}
1168
1183
1169
1184
PrimitiveType :: QuadStrip => {
1170
- self . last_strip_prim_vert_indices = [ poly. vertices [ 3 ] , poly. vertices [ 2 ] ] ;
1185
+ self . last_strip_prim_vert_indices = [ poly. verts [ 3 ] , poly. verts [ 2 ] ] ;
1171
1186
}
1172
1187
1173
1188
_ => { }
@@ -1201,7 +1216,7 @@ impl Engine3d {
1201
1216
{
1202
1217
emu. gpu . engine_3d . poly_ram [ ..emu. gpu . engine_3d . poly_ram_level as usize ]
1203
1218
. sort_by_key ( |poly| {
1204
- if poly. is_translucent {
1219
+ if poly. attrs . is_translucent ( ) {
1205
1220
0x1_0000
1206
1221
} else {
1207
1222
( poly. bot_y as u32 ) << 8 | poly. top_y as u32
@@ -1210,7 +1225,7 @@ impl Engine3d {
1210
1225
} else {
1211
1226
emu. gpu . engine_3d . poly_ram [ ..emu. gpu . engine_3d . poly_ram_level as usize ]
1212
1227
. sort_by_key ( |poly| {
1213
- ( poly. is_translucent as u32 ) << 16
1228
+ ( poly. attrs . is_translucent ( ) as u32 ) << 16
1214
1229
| ( poly. bot_y as u32 ) << 8
1215
1230
| poly. top_y as u32
1216
1231
} ) ;
0 commit comments