@@ -7,6 +7,7 @@ use crate::fixed_fifo::FixedFifo;
77use crate :: math:: { Matrix , Vectorf32 , Vectori16 , Vectori32 , Vectoru16 } ;
88use crate :: utils:: { rgb5_to_rgb6, HeapMem } ;
99use bilge:: prelude:: * ;
10+ use std:: arch:: arm:: { vcvtq_f32_s32, vld1q_s32, vmulq_n_f32, vst1q_f32} ;
1011use std:: hint:: unreachable_unchecked;
1112use std:: intrinsics:: unlikely;
1213use std:: mem;
@@ -241,24 +242,39 @@ fn intersect(v1: &Vectorf32<4>, v2: &Vectorf32<4>, val1: f32, val2: f32) -> Vect
241242 return * v1;
242243 }
243244
244- let mut vertex = Vectorf32 :: default ( ) ;
245- let dist_inverse = -d1 / ( d2 - d1) ;
246- vertex[ 0 ] = v1[ 0 ] + ( ( v2[ 0 ] - v1[ 0 ] ) * dist_inverse) ;
247- vertex[ 1 ] = v1[ 1 ] + ( ( v2[ 1 ] - v1[ 1 ] ) * dist_inverse) ;
248- vertex[ 2 ] = v1[ 2 ] + ( ( v2[ 2 ] - v1[ 2 ] ) * dist_inverse) ;
249- vertex[ 3 ] = v1[ 3 ] + ( ( v2[ 3 ] - v1[ 3 ] ) * dist_inverse) ;
245+ let mut vertex: Vectorf32 < 4 > = unsafe { MaybeUninit :: uninit ( ) . assume_init ( ) } ;
246+ let dist_inverse = -d1 as f64 / ( d2 - d1) as f64 ;
247+ vertex[ 0 ] = v1[ 0 ] + ( ( ( v2[ 0 ] - v1[ 0 ] ) as f64 * dist_inverse) as f32 ) ;
248+ vertex[ 1 ] = v1[ 1 ] + ( ( ( v2[ 1 ] - v1[ 1 ] ) as f64 * dist_inverse) as f32 ) ;
249+ vertex[ 2 ] = v1[ 2 ] + ( ( ( v2[ 2 ] - v1[ 2 ] ) as f64 * dist_inverse) as f32 ) ;
250+ vertex[ 3 ] = v1[ 3 ] + ( ( ( v2[ 3 ] - v1[ 3 ] ) as f64 * dist_inverse) as f32 ) ;
250251 vertex
251252}
252253
253254fn clip_polygon ( unclipped : & [ Vectori32 < 4 > ; 4 ] , clipped : & mut [ Vectorf32 < 4 > ; 10 ] , size : & mut usize ) -> bool {
254255 let mut clip = false ;
255256
256257 let mut vertices = [ Vectorf32 :: < 4 > :: default ( ) ; 10 ] ;
257- for i in 0 ..4 {
258- for j in 0 ..4 {
259- const NORMALIZE : f32 = 1f32 / 4096f32 ;
260- vertices[ i] [ j] = unclipped[ i] [ j] as f32 * NORMALIZE ;
261- }
258+ unsafe {
259+ let vertices0 = vld1q_s32 ( unclipped[ 0 ] . as_ref ( ) . as_ptr ( ) ) ;
260+ let vertices1 = vld1q_s32 ( unclipped[ 1 ] . as_ref ( ) . as_ptr ( ) ) ;
261+ let vertices2 = vld1q_s32 ( unclipped[ 2 ] . as_ref ( ) . as_ptr ( ) ) ;
262+ let vertices3 = vld1q_s32 ( unclipped[ 3 ] . as_ref ( ) . as_ptr ( ) ) ;
263+
264+ let vertices0 = vcvtq_f32_s32 ( vertices0) ;
265+ let vertices1 = vcvtq_f32_s32 ( vertices1) ;
266+ let vertices2 = vcvtq_f32_s32 ( vertices2) ;
267+ let vertices3 = vcvtq_f32_s32 ( vertices3) ;
268+
269+ let vertices0 = vmulq_n_f32 ( vertices0, 1f32 / 4096f32 ) ;
270+ let vertices1 = vmulq_n_f32 ( vertices1, 1f32 / 4096f32 ) ;
271+ let vertices2 = vmulq_n_f32 ( vertices2, 1f32 / 4096f32 ) ;
272+ let vertices3 = vmulq_n_f32 ( vertices3, 1f32 / 4096f32 ) ;
273+
274+ vst1q_f32 ( vertices[ 0 ] . as_mut ( ) . as_mut_ptr ( ) , vertices0) ;
275+ vst1q_f32 ( vertices[ 1 ] . as_mut ( ) . as_mut_ptr ( ) , vertices1) ;
276+ vst1q_f32 ( vertices[ 2 ] . as_mut ( ) . as_mut_ptr ( ) , vertices2) ;
277+ vst1q_f32 ( vertices[ 3 ] . as_mut ( ) . as_mut_ptr ( ) , vertices3) ;
262278 }
263279
264280 for i in 0 ..6 {
@@ -269,15 +285,11 @@ fn clip_polygon(unclipped: &[Vectori32<4>; 4], clipped: &mut [Vectorf32<4>; 10],
269285 let current = unsafe { vertices. get_unchecked ( j) } ;
270286 let previous = unsafe { vertices. get_unchecked ( if unlikely ( j == 0 ) { old_size - 1 } else { j - 1 } ) } ;
271287
272- let ( current_val, previous_val) = match i {
273- 0 => ( current[ 0 ] , previous[ 0 ] ) ,
274- 1 => ( -current[ 0 ] , -previous[ 0 ] ) ,
275- 2 => ( current[ 1 ] , previous[ 1 ] ) ,
276- 3 => ( -current[ 1 ] , -previous[ 1 ] ) ,
277- 4 => ( current[ 2 ] , previous[ 2 ] ) ,
278- 5 => ( -current[ 2 ] , -previous[ 2 ] ) ,
279- _ => unsafe { unreachable_unchecked ( ) } ,
280- } ;
288+ let ( mut current_val, mut previous_val) = ( current[ i >> 1 ] , previous[ i >> 1 ] ) ;
289+ if i & 1 == 1 {
290+ current_val = -current_val;
291+ previous_val = -previous_val;
292+ }
281293
282294 if current_val >= -current[ 3 ] {
283295 if previous_val < -previous[ 3 ] {
@@ -1218,12 +1230,14 @@ impl Gpu3DRegisters {
12181230
12191231 let mut unclipped = [ Vectori32 :: < 4 > :: default ( ) ; 4 ] ;
12201232 for i in 0 ..size {
1221- unclipped[ i ] = self . vertices . ins [ self . saved_polygon . vertices_index + i] . coords ;
1233+ unsafe { * unclipped. get_unchecked_mut ( i ) = self . vertices . ins . get_unchecked ( self . saved_polygon . vertices_index + i) . coords } ;
12221234 }
12231235
12241236 if self . polygon_type == PolygonType :: QuadliteralStrips {
1225- unclipped. swap ( 2 , 3 ) ;
1226- self . vertices . ins . swap ( self . saved_polygon . vertices_index + 2 , self . saved_polygon . vertices_index + 3 ) ;
1237+ unsafe {
1238+ unclipped. swap_unchecked ( 2 , 3 ) ;
1239+ self . vertices . ins . swap_unchecked ( self . saved_polygon . vertices_index + 2 , self . saved_polygon . vertices_index + 3 ) ;
1240+ }
12271241 }
12281242
12291243 let x1 = ( unclipped[ 1 ] [ 0 ] - unclipped[ 0 ] [ 0 ] ) as i64 ;
@@ -1265,23 +1279,31 @@ impl Gpu3DRegisters {
12651279 self . vertices . count_in -= size;
12661280 }
12671281 PolygonType :: TriangleStrips => {
1282+ let Vertices { ins, count_in, .. } = & mut self . vertices ;
12681283 if self . vertex_count == 3 {
1269- self . vertices . ins [ self . vertices . count_in - 3 ] = self . vertices . ins [ self . vertices . count_in - 2 ] ;
1270- self . vertices . ins [ self . vertices . count_in - 2 ] = self . vertices . ins [ self . vertices . count_in - 1 ] ;
1271- self . vertices . count_in -= 1 ;
1284+ unsafe {
1285+ * ins. get_unchecked_mut ( * count_in - 3 ) = * ins. get_unchecked ( * count_in - 2 ) ;
1286+ * ins. get_unchecked_mut ( * count_in - 2 ) = * ins. get_unchecked ( * count_in - 1 ) ;
1287+ }
1288+ * count_in -= 1 ;
12721289 self . vertex_count -= 1 ;
1273- } else if self . vertices . count_in < 6144 {
1274- self . vertices . ins [ self . vertices . count_in ] = self . vertices . ins [ self . vertices . count_in - 1 ] ;
1275- self . vertices . ins [ self . vertices . count_in - 1 ] = self . vertices . ins [ self . vertices . count_in - 2 ] ;
1276- self . vertices . count_in += 1 ;
1290+ } else if * count_in < 6144 {
1291+ unsafe {
1292+ * ins. get_unchecked_mut ( * count_in) = * ins. get_unchecked ( * count_in - 1 ) ;
1293+ * ins. get_unchecked_mut ( * count_in - 1 ) = * ins. get_unchecked ( * count_in - 2 ) ;
1294+ }
1295+ * count_in += 1 ;
12771296 self . vertex_count = 2 ;
12781297 }
12791298 }
12801299 PolygonType :: QuadliteralStrips => {
12811300 if self . vertex_count == 4 {
1282- self . vertices . ins [ self . vertices . count_in - 4 ] = self . vertices . ins [ self . vertices . count_in - 2 ] ;
1283- self . vertices . ins [ self . vertices . count_in - 3 ] = self . vertices . ins [ self . vertices . count_in - 1 ] ;
1284- self . vertices . count_in -= 2 ;
1301+ let Vertices { ins, count_in, .. } = & mut self . vertices ;
1302+ unsafe {
1303+ * ins. get_unchecked_mut ( * count_in - 4 ) = * ins. get_unchecked ( * count_in - 2 ) ;
1304+ * ins. get_unchecked_mut ( * count_in - 3 ) = * ins. get_unchecked ( * count_in - 1 ) ;
1305+ }
1306+ * count_in -= 2 ;
12851307 self . vertex_count -= 2 ;
12861308 } else {
12871309 self . vertex_count = 2 ;
0 commit comments