diff --git a/crates/renderer/src/buffers.rs b/crates/renderer/src/buffers.rs index 7ea570b..ca2e099 100644 --- a/crates/renderer/src/buffers.rs +++ b/crates/renderer/src/buffers.rs @@ -5,13 +5,10 @@ use std::{ }; use ash::{prelude::VkResult, vk}; -use itertools::Itertools; -use vk_mem::Alloc; use crate::{ - define_device_owned_handle, - device::{DeviceOwned, QueueFlags}, Device, + device::{Allocation, DeviceObject, QueueFlags}, }; #[derive(Clone)] @@ -21,9 +18,7 @@ pub struct BufferDesc { pub size: u64, pub usage: vk::BufferUsageFlags, pub queue_families: QueueFlags, - - pub mem_usage: vk_mem::MemoryUsage, - pub alloc_flags: vk_mem::AllocationCreateFlags, + pub mem_location: gpu_allocator::MemoryLocation, } impl std::hash::Hash for BufferDesc { @@ -32,8 +27,7 @@ impl std::hash::Hash for BufferDesc { self.size.hash(state); self.usage.hash(state); self.queue_families.hash(state); - self.mem_usage.hash(state); - self.alloc_flags.bits().hash(state); + self.mem_location.hash(state); } } @@ -45,17 +39,7 @@ impl std::fmt::Debug for BufferDesc { .field("size", &self.size) .field("usage", &self.usage) .field("queue_families", &self.queue_families) - .field("mem_usage", &self.mem_usage) - .field_with("alloc_flags", |f| { - write!( - f, - "{}", - self.alloc_flags - .iter_names() - .map(|(name, _)| name) - .format(" | ") - ) - }) + .field("mem_location", &self.mem_location) .finish() } } @@ -69,8 +53,7 @@ impl PartialEq for BufferDesc { && self.size == other.size && self.usage == other.usage && self.queue_families == other.queue_families - && self.mem_usage == other.mem_usage - && self.alloc_flags.bits() == other.alloc_flags.bits() + && self.mem_location == other.mem_location } } @@ -82,109 +65,91 @@ impl Default for BufferDesc { size: Default::default(), usage: Default::default(), queue_families: QueueFlags::empty(), - alloc_flags: vk_mem::AllocationCreateFlags::empty(), - mem_usage: vk_mem::MemoryUsage::Auto, + mem_location: gpu_allocator::MemoryLocation::Unknown, } } } -define_device_owned_handle! { - #[derive(Debug)] - pub Buffer(vk::Buffer) { - alloc: vk_mem::Allocation, - size: u64, - } => |this| unsafe { - this.device().clone().alloc().destroy_buffer(this.handle(), &mut this.alloc); - } +#[derive(Debug)] +pub struct Buffer { + buffer: DeviceObject, + desc: BufferDesc, + alloc: Allocation, } impl Eq for Buffer {} impl PartialEq for Buffer { fn eq(&self, other: &Self) -> bool { - self.inner == other.inner + *self.buffer == *other.buffer } } impl Buffer { - pub fn new(device: Device, desc: BufferDesc) -> VkResult { - let queue_families = device.queue_families().family_indices(desc.queue_families); + pub fn new(device: Device, desc: BufferDesc) -> crate::Result { + let (buffer, requirements) = Self::new_raw(device.clone(), &desc)?; + + let alloc = + device + .alloc2 + .lock() + .allocate(&gpu_allocator::vulkan::AllocationCreateDesc { + name: desc.name.as_deref().unwrap_or_default(), + requirements, + location: desc.mem_location, + linear: true, + allocation_scheme: gpu_allocator::vulkan::AllocationScheme::GpuAllocatorManaged, + })?; + + Ok(Self { + buffer: DeviceObject::new(buffer, device.clone(), desc.name.clone()), + desc, + alloc: Allocation::Owned(DeviceObject::new_without_name(alloc, device)), + }) + } + + fn new_raw( + device: Device, + desc: &BufferDesc, + ) -> crate::Result<(vk::Buffer, vk::MemoryRequirements)> { + let queue_families = device.queues.family_indices(desc.queue_families); let sharing_mode = if queue_families.len() > 1 { vk::SharingMode::CONCURRENT } else { vk::SharingMode::EXCLUSIVE }; + let create_info = vk::BufferCreateInfo::default() + .size(desc.size) + .usage(desc.usage) + .queue_family_indices(&queue_families) + .sharing_mode(sharing_mode); - let (buffer, allocation) = unsafe { - device.alloc().create_buffer( - &vk::BufferCreateInfo::default() - .size(desc.size) - .usage(desc.usage) - .queue_family_indices(&queue_families) - .sharing_mode(sharing_mode), - &vk_mem::AllocationCreateInfo { - flags: desc.alloc_flags, - usage: desc.mem_usage, - ..Default::default() - }, - )? - }; + let buffer = unsafe { device.dev().create_buffer(&create_info, None)? }; + let mem_reqs = unsafe { device.dev().get_buffer_memory_requirements(buffer) }; - Ok(Self::construct( - device, buffer, desc.name, allocation, desc.size, - )?) + Ok((buffer, mem_reqs)) } - #[allow(dead_code)] - pub fn map_arc(self: &mut Arc) -> VkResult> { - Arc::get_mut(self).map(Self::map).unwrap() - } - - pub fn map(&mut self) -> VkResult> { - let bytes = unsafe { - let data = self.inner.dev().alloc().map_memory(&mut self.alloc)?; - 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.handle() - } - pub fn len(&self) -> u64 { - self.size - } -} - -pub struct MappedBuffer<'a> { - bytes: &'a mut [u8], - inner: &'a mut Buffer, -} - -impl Drop for MappedBuffer<'_> { - fn drop(&mut self) { - unsafe { - self.inner - .inner - .dev() - .alloc() - .unmap_memory(&mut self.inner.alloc); + pub fn map(&mut self) -> Option<&[u8]> { + if let Some(alloc) = self.alloc.allocation() { + alloc.mapped_slice() + } else { + None } } -} -impl Deref for MappedBuffer<'_> { - type Target = [u8]; + pub fn map_mut(&mut self) -> Option<&mut [u8]> { + if let Some(alloc) = self.alloc.allocation_mut() { + alloc.mapped_slice_mut() + } else { + None + } + } - fn deref(&self) -> &Self::Target { - self.bytes - } -} - -impl DerefMut for MappedBuffer<'_> { - fn deref_mut(&mut self) -> &mut Self::Target { - self.bytes + pub fn buffer(&self) -> vk::Buffer { + *self.buffer + } + pub fn len(&self) -> u64 { + self.desc.size } } diff --git a/crates/renderer/src/device.rs b/crates/renderer/src/device.rs index 19baf26..4babdc6 100644 --- a/crates/renderer/src/device.rs +++ b/crates/renderer/src/device.rs @@ -133,6 +133,14 @@ impl Allocation { Allocation::Unmanaged => None, } } + + pub(crate) fn allocation_mut(&mut self) -> Option<&mut GpuAllocation> { + match self { + Allocation::Owned(obj) => Some(obj), + Allocation::Shared(arc) => Arc::get_mut(arc).map(|alloc| &mut alloc.inner), + Allocation::Unmanaged => None, + } + } } pub struct DeviceInner {