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
#![warn(
missing_docs,
trivial_casts,
trivial_numeric_casts,
unused_extern_crates,
unused_import_braces,
unused_qualifications
)]
mod allocator;
mod block;
mod heaps;
mod mapping;
mod memory;
mod stats;
mod usage;
pub use crate::{
allocator::*,
block::Block,
heaps::{Heaps, HeapsError, MemoryBlock},
mapping::{MappedRange, Writer},
memory::Memory,
stats::*,
usage::MemoryUsage,
};
use std::ops::Range;
pub type Size = u64;
pub type AtomSize = std::num::NonZeroU64;
fn is_non_coherent_visible(properties: hal::memory::Properties) -> bool {
properties.contains(hal::memory::Properties::CPU_VISIBLE)
&& !properties.contains(hal::memory::Properties::COHERENT)
}
fn align_range(range: &Range<Size>, align: AtomSize) -> Range<Size> {
let start = range.start - range.start % align.get();
let end = ((range.end - 1) / align.get() + 1) * align.get();
start..end
}
fn align_size(size: Size, align: AtomSize) -> Size {
((size - 1) / align.get() + 1) * align.get()
}
fn align_offset(value: Size, align: AtomSize) -> Size {
debug_assert_eq!(align.get().count_ones(), 1);
if value == 0 {
0
} else {
1 + ((value - 1) | (align.get() - 1))
}
}
fn segment_to_sub_range(
segment: hal::memory::Segment,
whole: &Range<Size>,
) -> Result<Range<Size>, hal::device::MapError> {
let start = whole.start + segment.offset;
match segment.size {
Some(s) if start + s <= whole.end => Ok(start..start + s),
None if start < whole.end => Ok(start..whole.end),
_ => Err(hal::device::MapError::OutOfBounds),
}
}
fn is_sub_range(sub: &Range<Size>, range: &Range<Size>) -> bool {
sub.start >= range.start && sub.end <= range.end
}