1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use std::iter::Iterator;
use std::marker::PhantomData;
use std::mem::size_of;
use vk;
#[derive(Debug, Clone)]
pub struct Align<T> {
ptr: *mut vk::c_void,
elem_size: vk::DeviceSize,
size: vk::DeviceSize,
_m: PhantomData<T>,
}
#[derive(Debug)]
pub struct AlignIter<'a, T: 'a> {
align: &'a mut Align<T>,
current: vk::DeviceSize,
}
impl<T: Copy> Align<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().take(slice.len()) {
*val = slice[i];
}
}
}
}
fn calc_padding(adr: vk::DeviceSize, align: vk::DeviceSize) -> vk::DeviceSize {
(align - adr % align) % align
}
impl<T> Align<T> {
pub unsafe fn new(
ptr: *mut vk::c_void,
alignment: vk::DeviceSize,
size: vk::DeviceSize,
) -> Self {
let padding = calc_padding(size_of::<T>() as vk::DeviceSize, alignment);
let elem_size = size_of::<T>() as vk::DeviceSize + padding;
assert!(calc_padding(size, alignment) == 0, "size must be aligned");
Align {
ptr,
elem_size,
size,
_m: PhantomData,
}
}
pub fn iter_mut(&mut self) -> AlignIter<T> {
AlignIter {
current: 0,
align: self,
}
}
}
impl<'a, T: Copy + 'a> Iterator for AlignIter<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
if self.current == self.align.size {
return None;
}
unsafe {
let ptr = (self.align.ptr as *mut u8).offset(self.current as isize) as *mut T;
self.current += self.align.elem_size;
Some(&mut *ptr)
}
}
}