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
use super::Buffer;
use crate::graphics::vulkan::{device_allocator::Allocation, Device};
use anyhow::Result;
use ash::{version::DeviceV1_0, vk};
use std::sync::Arc;
pub struct StaticBuffer {
raw: vk::Buffer,
allocation: Allocation,
usage: vk::BufferUsageFlags,
properties: vk::MemoryPropertyFlags,
pub(super) device: Arc<Device>,
}
impl StaticBuffer {
pub fn empty(
device: Arc<Device>,
usage: vk::BufferUsageFlags,
properties: vk::MemoryPropertyFlags,
) -> Result<Self> {
Ok(Self {
raw: vk::Buffer::null(),
allocation: Allocation::null(),
usage,
properties,
device,
})
}
pub fn allocate(&self, size: u64) -> Result<Self> {
Self::create(self.device.clone(), self.usage, self.properties, size)
}
pub fn create(
device: Arc<Device>,
usage: vk::BufferUsageFlags,
properties: vk::MemoryPropertyFlags,
size: u64,
) -> Result<Self> {
let create_info = vk::BufferCreateInfo {
size,
usage,
sharing_mode: vk::SharingMode::EXCLUSIVE,
..Default::default()
};
let raw =
unsafe { device.logical_device.create_buffer(&create_info, None)? };
let buffer_memory_requirements = unsafe {
device.logical_device.get_buffer_memory_requirements(raw)
};
let allocation = unsafe {
device.allocate_memory(buffer_memory_requirements, properties)?
};
unsafe {
device.logical_device.bind_buffer_memory(
raw,
allocation.memory,
allocation.offset,
)?;
}
Ok(Self {
raw,
allocation,
usage,
properties,
device,
})
}
}
impl Buffer for StaticBuffer {
unsafe fn raw(&self) -> ash::vk::Buffer {
self.raw
}
unsafe fn allocation(&self) -> &Allocation {
&self.allocation
}
fn size_in_bytes(&self) -> u64 {
self.allocation.byte_size
}
}
impl Drop for StaticBuffer {
fn drop(&mut self) {
unsafe {
if self.raw != vk::Buffer::null() {
self.device.logical_device.destroy_buffer(self.raw, None);
self.raw = vk::Buffer::null();
}
self.device.free_memory(&self.allocation).unwrap();
}
}
}