vidya/crates/renderer/src/buffers.rs
Janis f0fff72bce idek so much when i thought i was only doing egui integration
egui cant draw yet, but textures are loaded/updated
2024-12-29 15:48:55 +01:00

114 lines
2.5 KiB
Rust

use std::{
ops::{Deref, DerefMut},
sync::Arc,
};
use ash::{prelude::VkResult, vk};
use vk_mem::Alloc;
use crate::Device;
pub struct Buffer {
device: Device,
buffer: vk::Buffer,
allocation: vk_mem::Allocation,
usage: vk::BufferUsageFlags,
size: u64,
}
impl Drop for Buffer {
fn drop(&mut self) {
unsafe {
self.device
.alloc()
.destroy_buffer(self.buffer, &mut self.allocation);
}
}
}
impl Buffer {
pub fn new(
device: Device,
size: usize,
usage: vk::BufferUsageFlags,
queue_families: &[u32],
memory_usage: vk_mem::MemoryUsage,
alloc_flags: vk_mem::AllocationCreateFlags,
) -> VkResult<Arc<Self>> {
let sharing_mode = if queue_families.len() > 1 {
vk::SharingMode::CONCURRENT
} else {
vk::SharingMode::EXCLUSIVE
};
let (buffer, allocation) = unsafe {
device.alloc().create_buffer(
&vk::BufferCreateInfo::default()
.size(size as u64)
.usage(usage)
.queue_family_indices(queue_families)
.sharing_mode(sharing_mode),
&vk_mem::AllocationCreateInfo {
flags: alloc_flags,
usage: memory_usage,
..Default::default()
},
)?
};
let buffer = Self {
device,
buffer,
allocation,
usage,
size: size as u64,
};
Ok(Arc::new(buffer))
}
pub fn map(&mut self) -> VkResult<MappedBuffer<'_>> {
let bytes = unsafe {
let data = self.device.alloc().map_memory(&mut self.allocation)?;
let slice = core::slice::from_raw_parts_mut(data, self.size as usize);
slice
};
Ok(MappedBuffer { inner: self, bytes })
}
pub fn buffer(&self) -> vk::Buffer {
self.buffer
}
}
pub struct MappedBuffer<'a> {
bytes: &'a mut [u8],
inner: &'a mut Buffer,
}
impl Drop for MappedBuffer<'_> {
fn drop(&mut self) {
unsafe {
self.inner
.device
.alloc()
.unmap_memory(&mut self.inner.allocation);
}
}
}
impl Deref for MappedBuffer<'_> {
type Target = [u8];
fn deref(&self) -> &Self::Target {
self.bytes
}
}
impl DerefMut for MappedBuffer<'_> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.bytes
}
}