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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
pub use gfx_hal::buffer::*;
use {
crate::{
memory::{Block, Heaps, MappedRange, MemoryBlock, MemoryUsage},
util::{device_owned, Device, DeviceId},
},
gfx_hal::{Backend, Device as _},
relevant::Relevant,
};
#[derive(Clone, Copy, Debug)]
pub struct BufferInfo {
pub size: u64,
pub usage: Usage,
}
#[derive(Debug)]
pub struct Buffer<B: Backend> {
device: DeviceId,
raw: B::Buffer,
block: MemoryBlock<B>,
info: BufferInfo,
relevant: Relevant,
}
device_owned!(Buffer<B>);
impl<B> Buffer<B>
where
B: Backend,
{
pub unsafe fn create(
device: &Device<B>,
heaps: &mut Heaps<B>,
info: BufferInfo,
memory_usage: impl MemoryUsage,
) -> Result<Self, failure::Error> {
log::trace!("{:#?}@{:#?}", info, memory_usage);
assert_ne!(info.size, 0);
let mut buf = device.create_buffer(info.size, info.usage)?;
let reqs = device.get_buffer_requirements(&buf);
let block = heaps.allocate(
device,
reqs.type_mask as u32,
memory_usage,
reqs.size,
reqs.alignment,
)?;
device.bind_buffer_memory(block.memory(), block.range().start, &mut buf)?;
Ok(Buffer {
device: device.id(),
raw: buf,
block,
info,
relevant: Relevant,
})
}
pub unsafe fn dispose(self, device: &Device<B>, heaps: &mut Heaps<B>) {
self.assert_device_owner(device);
device.destroy_buffer(self.raw);
heaps.free(device, self.block);
self.relevant.dispose();
}
pub fn raw(&self) -> &B::Buffer {
&self.raw
}
pub unsafe fn raw_mut(&mut self) -> &mut B::Buffer {
&mut self.raw
}
pub fn block(&self) -> &MemoryBlock<B> {
&self.block
}
pub unsafe fn block_mut(&mut self) -> &mut MemoryBlock<B> {
&mut self.block
}
pub fn info(&self) -> &BufferInfo {
&self.info
}
pub fn visible(&self) -> bool {
self.block
.properties()
.contains(gfx_hal::memory::Properties::CPU_VISIBLE)
}
pub fn map<'a>(
&'a mut self,
device: &Device<B>,
range: std::ops::Range<u64>,
) -> Result<MappedRange<'a, B>, gfx_hal::mapping::Error> {
self.block.map(device, range)
}
pub fn size(&self) -> u64 {
self.info().size
}
}