Skip to content

Commit

Permalink
Specialize ReadFrom
Browse files Browse the repository at this point in the history
  • Loading branch information
james7132 committed Mar 24, 2024
1 parent fe8028f commit 1102451
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 13 deletions.
33 changes: 33 additions & 0 deletions src/core/rw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ impl<B: BufferRef> Reader<B> {
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()
Expand Down Expand Up @@ -135,6 +140,12 @@ impl<B: BufferRef> Cursor<B> {
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<B: BufferMut> Cursor<B> {
Expand Down Expand Up @@ -176,6 +187,8 @@ pub trait BufferRef {
fn len(&self) -> usize;

fn read<const N: usize>(&self, offset: usize) -> &[u8; N];

fn read_slice(&self, offset: usize, val: &mut [u8]);
}

pub trait BufferMut {
Expand Down Expand Up @@ -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<const LEN: usize> BufferRef for [u8; LEN] {
Expand All @@ -217,6 +235,11 @@ impl<const LEN: usize> BufferRef for [u8; LEN] {
fn read<const N: usize>(&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<u8> {
Expand All @@ -229,6 +252,11 @@ impl BufferRef for Vec<u8> {
fn read<const N: usize>(&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] {
Expand Down Expand Up @@ -301,6 +329,11 @@ macro_rules! impl_buffer_ref_for_wrappers {
fn read<const N: usize>(&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)
}
}
)*};
}
Expand Down
25 changes: 22 additions & 3 deletions src/types/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,28 @@ where
{
#[inline]
fn read_from<B: BufferRef>(&mut self, reader: &mut Reader<B>) {
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::<Self>())
};
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);
}
}
}
}
Expand Down
33 changes: 27 additions & 6 deletions src/types/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand All @@ -198,13 +198,34 @@ macro_rules! impl_matrix_inner {
$el_ty: $crate::private::MatrixScalar + $crate::private::ReadFrom,
{
#[inline]
#[allow(trivial_casts)]
fn read_from<B: $crate::private::BufferRef>(&mut self, reader: &mut $crate::private::Reader<B>) {
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 <Self as $crate::private::ShaderType>::METADATA.has_internal_padding() {
for col in columns {
for el in col {
$crate::private::ReadFrom::read_from(el, reader);
}
reader.advance(<Self as $crate::private::ShaderType>::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::<Self>()) };
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(<Self as $crate::private::ShaderType>::METADATA.col_padding() as ::core::primitive::usize);
}
}
}
Expand Down
28 changes: 24 additions & 4 deletions src/types/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<B: $crate::private::BufferRef>(&mut self, reader: &mut $crate::private::Reader<B>) {
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 <Self as $crate::private::ShaderType>::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::<Self>())
};
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);
}
}
}
}
Expand Down

0 comments on commit 1102451

Please sign in to comment.