This commit is contained in:
janis 2026-04-02 14:09:42 +02:00
parent 55d22e3164
commit d91ba8c1b7
2 changed files with 72 additions and 99 deletions

View file

@ -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<vk::Buffer>,
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<Self> {
let queue_families = device.queue_families().family_indices(desc.queue_families);
pub fn new(device: Device, desc: BufferDesc) -> crate::Result<Self> {
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 (buffer, allocation) = unsafe {
device.alloc().create_buffer(
&vk::BufferCreateInfo::default()
let create_info = 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()
},
)?
};
.sharing_mode(sharing_mode);
Ok(Self::construct(
device, buffer, desc.name, allocation, desc.size,
)?)
let buffer = unsafe { device.dev().create_buffer(&create_info, None)? };
let mem_reqs = unsafe { device.dev().get_buffer_memory_requirements(buffer) };
Ok((buffer, mem_reqs))
}
#[allow(dead_code)]
pub fn map_arc(self: &mut Arc<Self>) -> VkResult<MappedBuffer<'_>> {
Arc::get_mut(self).map(Self::map).unwrap()
pub fn map(&mut self) -> Option<&[u8]> {
if let Some(alloc) = self.alloc.allocation() {
alloc.mapped_slice()
} else {
None
}
}
pub fn map(&mut self) -> VkResult<MappedBuffer<'_>> {
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 map_mut(&mut self) -> Option<&mut [u8]> {
if let Some(alloc) = self.alloc.allocation_mut() {
alloc.mapped_slice_mut()
} else {
None
}
}
pub fn buffer(&self) -> vk::Buffer {
self.handle()
*self.buffer
}
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);
}
}
}
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
self.desc.size
}
}

View file

@ -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 {