Align now uses "copy_from_slice" for C aligned slices

This commit is contained in:
Maik Klein 2017-06-16 13:18:18 +02:00
parent cdc2fa94d9
commit d22e1b1fe3

View file

@ -53,7 +53,7 @@ impl AlignByteSlice {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Align<T> { pub struct Align<T> {
ptr: *mut (), ptr: *mut (),
offset: vk::DeviceSize, elem_size: vk::DeviceSize,
size: vk::DeviceSize, size: vk::DeviceSize,
_m: PhantomData<T>, _m: PhantomData<T>,
} }
@ -66,10 +66,19 @@ pub struct AlignIter<'a, T: 'a> {
impl<T: Copy> Align<T> { impl<T: Copy> Align<T> {
pub fn copy_from_slice(&mut self, slice: &[T]) { pub fn copy_from_slice(&mut self, slice: &[T]) {
use std::slice::from_raw_parts_mut;
if self.elem_size == size_of::<T>() as u64 {
unsafe {
let mapped_slice = from_raw_parts_mut(self.ptr as *mut T, slice.len());
mapped_slice.copy_from_slice(slice);
}
}
else{
for (i, val) in self.iter_mut().enumerate() { for (i, val) in self.iter_mut().enumerate() {
*val = slice[i]; *val = slice[i];
} }
} }
}
} }
fn calc_padding(adr: vk::DeviceSize, align: vk::DeviceSize) -> vk::DeviceSize { fn calc_padding(adr: vk::DeviceSize, align: vk::DeviceSize) -> vk::DeviceSize {
@ -79,11 +88,11 @@ fn calc_padding(adr: vk::DeviceSize, align: vk::DeviceSize) -> vk::DeviceSize {
impl<T> Align<T> { impl<T> Align<T> {
pub unsafe fn new(ptr: *mut (), alignment: vk::DeviceSize, size: vk::DeviceSize) -> Self { pub unsafe fn new(ptr: *mut (), alignment: vk::DeviceSize, size: vk::DeviceSize) -> Self {
let padding = calc_padding(size_of::<T>() as vk::DeviceSize, alignment); let padding = calc_padding(size_of::<T>() as vk::DeviceSize, alignment);
let offset = size_of::<T>() as vk::DeviceSize + padding; let elem_size = size_of::<T>() as vk::DeviceSize + padding;
assert!(calc_padding(size, alignment) == 0, "size must be aligned"); assert!(calc_padding(size, alignment) == 0, "size must be aligned");
Align { Align {
ptr, ptr,
offset, elem_size,
size, size,
_m: PhantomData, _m: PhantomData,
} }
@ -106,7 +115,7 @@ impl<'a, T: Copy + 'a> Iterator for AlignIter<'a, T> {
unsafe { unsafe {
// Need to cast to *mut u8 because () has size 0 // Need to cast to *mut u8 because () has size 0
let ptr = (self.align.ptr as *mut u8).offset(self.current as isize) as *mut T; let ptr = (self.align.ptr as *mut u8).offset(self.current as isize) as *mut T;
self.current += self.align.offset; self.current += self.align.elem_size;
Some(&mut *ptr) Some(&mut *ptr)
} }
} }