From 11024512877d8d777d10edb44989736db7773d73 Mon Sep 17 00:00:00 2001 From: james7132 Date: Sat, 23 Mar 2024 21:04:30 -0700 Subject: [PATCH] Specialize ReadFrom --- src/core/rw.rs | 33 +++++++++++++++++++++++++++++++++ src/types/array.rs | 25 ++++++++++++++++++++++--- src/types/matrix.rs | 33 +++++++++++++++++++++++++++------ src/types/vector.rs | 28 ++++++++++++++++++++++++---- 4 files changed, 106 insertions(+), 13 deletions(-) diff --git a/src/core/rw.rs b/src/core/rw.rs index b4971d2..173169e 100644 --- a/src/core/rw.rs +++ b/src/core/rw.rs @@ -98,6 +98,11 @@ impl Reader { self.cursor.read() } + #[inline] + pub fn read_slice(&mut self, val: &mut [u8]) { + self.cursor.read_slice(val) + } + #[inline] pub fn remaining(&self) -> usize { self.cursor.remaining() @@ -135,6 +140,12 @@ impl Cursor { self.pos += N; res } + + #[inline] + fn read_slice(&mut self, val: &mut [u8]) { + self.buffer.read_slice(self.pos, val); + self.pos += val.len(); + } } impl Cursor { @@ -176,6 +187,8 @@ pub trait BufferRef { fn len(&self) -> usize; fn read(&self, offset: usize) -> &[u8; N]; + + fn read_slice(&self, offset: usize, val: &mut [u8]); } pub trait BufferMut { @@ -205,6 +218,11 @@ impl BufferRef for [u8] { use crate::utils::SliceExt; self.array(offset) } + + #[inline] + fn read_slice(&self, offset: usize, val: &mut [u8]) { + val.copy_from_slice(&self[offset..offset + val.len()]) + } } impl BufferRef for [u8; LEN] { @@ -217,6 +235,11 @@ impl BufferRef for [u8; LEN] { fn read(&self, offset: usize) -> &[u8; N] { <[u8] as BufferRef>::read(self, offset) } + + #[inline] + fn read_slice(&self, offset: usize, val: &mut [u8]) { + <[u8] as BufferRef>::read_slice(self, offset, val) + } } impl BufferRef for Vec { @@ -229,6 +252,11 @@ impl BufferRef for Vec { fn read(&self, offset: usize) -> &[u8; N] { <[u8] as BufferRef>::read(self, offset) } + + #[inline] + fn read_slice(&self, offset: usize, val: &mut [u8]) { + <[u8] as BufferRef>::read_slice(self, offset, val) + } } impl BufferMut for [u8] { @@ -301,6 +329,11 @@ macro_rules! impl_buffer_ref_for_wrappers { fn read(&self, offset: usize) -> &[u8; N] { T::read(self, offset) } + + #[inline] + fn read_slice(&self, offset: usize, val: &mut [u8]) { + T::read_slice(self, offset, val) + } } )*}; } diff --git a/src/types/array.rs b/src/types/array.rs index afd4c5c..19d7da4 100644 --- a/src/types/array.rs +++ b/src/types/array.rs @@ -97,9 +97,28 @@ where { #[inline] fn read_from(&mut self, reader: &mut Reader) { - for elem in self { - ReadFrom::read_from(elem, reader); - reader.advance(Self::METADATA.el_padding() as usize); + #[cfg(target_endian = "little")] + { + // Const branch, should be eliminated at compile time. + if Self::METADATA.has_internal_padding() { + for item in self { + ReadFrom::read_from(item, reader); + reader.advance(Self::METADATA.el_padding() as usize); + } + } else { + let ptr = self.as_mut_ptr() as *mut ::core::primitive::u8; + let byte_slice: &mut [::core::primitive::u8] = unsafe { + ::core::slice::from_raw_parts_mut(ptr, ::core::mem::size_of::()) + }; + reader.read_slice(byte_slice); + } + } + #[cfg(not(target_endian = "little"))] + { + for elem in self { + ReadFrom::read_from(elem, reader); + reader.advance(Self::METADATA.el_padding() as usize); + } } } } diff --git a/src/types/matrix.rs b/src/types/matrix.rs index 7148b96..59a7d17 100644 --- a/src/types/matrix.rs +++ b/src/types/matrix.rs @@ -184,8 +184,8 @@ macro_rules! impl_matrix_inner { } #[cfg(not(target_endian = "little"))] { - for item in self { - WriteInto::write_into(item, writer); + for col in columns { + WriteInto::write_into(col, writer); writer.advance(Self::METADATA.el_padding() as usize); } } @@ -198,13 +198,34 @@ macro_rules! impl_matrix_inner { $el_ty: $crate::private::MatrixScalar + $crate::private::ReadFrom, { #[inline] + #[allow(trivial_casts)] fn read_from(&mut self, reader: &mut $crate::private::Reader) { let columns = $crate::private::AsMutMatrixParts::<$el_ty, $c, $r>::as_mut_parts(self); - for col in columns { - for el in col { - $crate::private::ReadFrom::read_from(el, reader); + #[cfg(target_endian = "little")] + { + // Const branch, should be eliminated at compile time. + if ::METADATA.has_internal_padding() { + for col in columns { + for el in col { + $crate::private::ReadFrom::read_from(el, reader); + } + reader.advance(::METADATA.col_padding() as ::core::primitive::usize); + } + } else { + let ptr = (self as *mut Self) as *mut ::core::primitive::u8; + let byte_slice: &mut [::core::primitive::u8] = + unsafe { ::core::slice::from_raw_parts_mut(ptr, ::core::mem::size_of::()) }; + reader.read_slice(byte_slice); + } + } + #[cfg(not(target_endian = "little"))] + { + for col in columns { + for el in col { + $crate::private::ReadFrom::read_from(el, reader); + } + reader.advance(Self::METADATA.el_padding() as usize); } - reader.advance(::METADATA.col_padding() as ::core::primitive::usize); } } } diff --git a/src/types/vector.rs b/src/types/vector.rs index beb035b..319140c 100644 --- a/src/types/vector.rs +++ b/src/types/vector.rs @@ -171,13 +171,33 @@ macro_rules! impl_vector_inner { impl<$($generics)*> $crate::private::ReadFrom for $type where Self: $crate::private::AsMutVectorParts<$el_ty, $n>, - $el_ty: $crate::private::VectorScalar + $crate::private::ReadFrom, + $el_ty: $crate::private::ShaderSize + $crate::private::VectorScalar + $crate::private::ReadFrom, { #[inline] fn read_from(&mut self, reader: &mut $crate::private::Reader) { - let elements = $crate::private::AsMutVectorParts::<$el_ty, $n>::as_mut_parts(self); - for el in elements { - $crate::private::ReadFrom::read_from(el, reader); + #[cfg(target_endian = "little")] + { + // Const branch, should be eliminated at compile time. + if ::METADATA.has_internal_padding() { + let elements = $crate::private::AsMutVectorParts::<$el_ty, $n>::as_mut_parts(self); + for el in elements { + $crate::private::ReadFrom::read_from(el, reader); + } + } else { + let ptr: *mut Self = self; + let ptr = ptr.cast::<::core::primitive::u8>(); + let byte_slice: &mut [::core::primitive::u8] = unsafe { + ::core::slice::from_raw_parts_mut(ptr, ::core::mem::size_of::()) + }; + reader.read_slice(byte_slice); + } + } + #[cfg(not(target_endian = "little"))] + { + let elements = $crate::private::AsRefVectorParts::<$el_ty, $n>::as_ref_parts(self); + for el in elements { + $crate::private::ReadFrom::read_from(el, reader); + } } } }