-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbuffer.rs
More file actions
84 lines (78 loc) · 2.49 KB
/
buffer.rs
File metadata and controls
84 lines (78 loc) · 2.49 KB
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
use crate::ash_renderer::device::MyDevice;
use ash::vk;
use bytemuck::NoUninit;
use gpu_allocator::MemoryLocation;
use gpu_allocator::vulkan::{Allocation, AllocationCreateDesc, AllocationScheme};
use std::borrow::Cow;
use std::sync::Arc;
pub struct MyBuffer {
pub buffer: vk::Buffer,
pub allocation: Allocation,
pub name: String,
destroyed: bool,
}
#[derive(Clone)]
pub struct BufferCreateInfo<'a> {
pub usage: vk::BufferUsageFlags,
pub location: MemoryLocation,
pub name: Option<Cow<'a, str>>,
}
impl MyBuffer {
pub fn from_data<T: NoUninit>(
device: &Arc<MyDevice>,
info: BufferCreateInfo<'_>,
data: &T,
) -> anyhow::Result<Self> {
Self::from_slice(device, info, bytemuck::bytes_of(data))
}
pub fn from_slice<T: NoUninit>(
device: &Arc<MyDevice>,
info: BufferCreateInfo<'_>,
data: &[T],
) -> anyhow::Result<Self> {
unsafe {
let buffer = device.create_buffer(
&vk::BufferCreateInfo::default()
.size(size_of_val(data) as u64)
.usage(vk::BufferUsageFlags::STORAGE_BUFFER),
None,
)?;
let name = info.name.map(|a| a.into_owned()).unwrap_or_default();
let mut allocation = device.borrow_allocator().allocate(&AllocationCreateDesc {
name: &name,
requirements: device.get_buffer_memory_requirements(buffer),
location: MemoryLocation::CpuToGpu,
linear: true,
allocation_scheme: AllocationScheme::GpuAllocatorManaged,
})?;
device.bind_buffer_memory(buffer, allocation.memory(), allocation.offset())?;
let mapped = &mut allocation.mapped_slice_mut().unwrap()[..size_of_val(data)];
mapped.copy_from_slice(bytemuck::cast_slice(data));
Ok(Self {
buffer,
allocation,
name,
destroyed: false,
})
}
}
/// Destroy this buffer
///
/// # Safety
/// Buffer must not be in use
pub unsafe fn destroy(&mut self, device: &Arc<MyDevice>) {
if !self.destroyed {
self.destroyed = true;
unsafe {
device.destroy_buffer(self.buffer, None);
}
}
}
}
impl Drop for MyBuffer {
fn drop(&mut self) {
if !self.destroyed {
panic!("dropping Buffer {} without destroying it", &self.name);
}
}
}