buffers
This commit is contained in:
parent
55d22e3164
commit
d91ba8c1b7
|
|
@ -5,13 +5,10 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use ash::{prelude::VkResult, vk};
|
use ash::{prelude::VkResult, vk};
|
||||||
use itertools::Itertools;
|
|
||||||
use vk_mem::Alloc;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
define_device_owned_handle,
|
|
||||||
device::{DeviceOwned, QueueFlags},
|
|
||||||
Device,
|
Device,
|
||||||
|
device::{Allocation, DeviceObject, QueueFlags},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
@ -21,9 +18,7 @@ pub struct BufferDesc {
|
||||||
pub size: u64,
|
pub size: u64,
|
||||||
pub usage: vk::BufferUsageFlags,
|
pub usage: vk::BufferUsageFlags,
|
||||||
pub queue_families: QueueFlags,
|
pub queue_families: QueueFlags,
|
||||||
|
pub mem_location: gpu_allocator::MemoryLocation,
|
||||||
pub mem_usage: vk_mem::MemoryUsage,
|
|
||||||
pub alloc_flags: vk_mem::AllocationCreateFlags,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::hash::Hash for BufferDesc {
|
impl std::hash::Hash for BufferDesc {
|
||||||
|
|
@ -32,8 +27,7 @@ impl std::hash::Hash for BufferDesc {
|
||||||
self.size.hash(state);
|
self.size.hash(state);
|
||||||
self.usage.hash(state);
|
self.usage.hash(state);
|
||||||
self.queue_families.hash(state);
|
self.queue_families.hash(state);
|
||||||
self.mem_usage.hash(state);
|
self.mem_location.hash(state);
|
||||||
self.alloc_flags.bits().hash(state);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,17 +39,7 @@ impl std::fmt::Debug for BufferDesc {
|
||||||
.field("size", &self.size)
|
.field("size", &self.size)
|
||||||
.field("usage", &self.usage)
|
.field("usage", &self.usage)
|
||||||
.field("queue_families", &self.queue_families)
|
.field("queue_families", &self.queue_families)
|
||||||
.field("mem_usage", &self.mem_usage)
|
.field("mem_location", &self.mem_location)
|
||||||
.field_with("alloc_flags", |f| {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
self.alloc_flags
|
|
||||||
.iter_names()
|
|
||||||
.map(|(name, _)| name)
|
|
||||||
.format(" | ")
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -69,8 +53,7 @@ impl PartialEq for BufferDesc {
|
||||||
&& self.size == other.size
|
&& self.size == other.size
|
||||||
&& self.usage == other.usage
|
&& self.usage == other.usage
|
||||||
&& self.queue_families == other.queue_families
|
&& self.queue_families == other.queue_families
|
||||||
&& self.mem_usage == other.mem_usage
|
&& self.mem_location == other.mem_location
|
||||||
&& self.alloc_flags.bits() == other.alloc_flags.bits()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,109 +65,91 @@ impl Default for BufferDesc {
|
||||||
size: Default::default(),
|
size: Default::default(),
|
||||||
usage: Default::default(),
|
usage: Default::default(),
|
||||||
queue_families: QueueFlags::empty(),
|
queue_families: QueueFlags::empty(),
|
||||||
alloc_flags: vk_mem::AllocationCreateFlags::empty(),
|
mem_location: gpu_allocator::MemoryLocation::Unknown,
|
||||||
mem_usage: vk_mem::MemoryUsage::Auto,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
define_device_owned_handle! {
|
#[derive(Debug)]
|
||||||
#[derive(Debug)]
|
pub struct Buffer {
|
||||||
pub Buffer(vk::Buffer) {
|
buffer: DeviceObject<vk::Buffer>,
|
||||||
alloc: vk_mem::Allocation,
|
desc: BufferDesc,
|
||||||
size: u64,
|
alloc: Allocation,
|
||||||
} => |this| unsafe {
|
|
||||||
this.device().clone().alloc().destroy_buffer(this.handle(), &mut this.alloc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for Buffer {}
|
impl Eq for Buffer {}
|
||||||
impl PartialEq for Buffer {
|
impl PartialEq for Buffer {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.inner == other.inner
|
*self.buffer == *other.buffer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Buffer {
|
impl Buffer {
|
||||||
pub fn new(device: Device, desc: BufferDesc) -> VkResult<Self> {
|
pub fn new(device: Device, desc: BufferDesc) -> crate::Result<Self> {
|
||||||
let queue_families = device.queue_families().family_indices(desc.queue_families);
|
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 {
|
let sharing_mode = if queue_families.len() > 1 {
|
||||||
vk::SharingMode::CONCURRENT
|
vk::SharingMode::CONCURRENT
|
||||||
} else {
|
} else {
|
||||||
vk::SharingMode::EXCLUSIVE
|
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 {
|
let buffer = unsafe { device.dev().create_buffer(&create_info, None)? };
|
||||||
device.alloc().create_buffer(
|
let mem_reqs = unsafe { device.dev().get_buffer_memory_requirements(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()
|
|
||||||
},
|
|
||||||
)?
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Self::construct(
|
Ok((buffer, mem_reqs))
|
||||||
device, buffer, desc.name, allocation, desc.size,
|
|
||||||
)?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
pub fn map(&mut self) -> Option<&[u8]> {
|
||||||
pub fn map_arc(self: &mut Arc<Self>) -> VkResult<MappedBuffer<'_>> {
|
if let Some(alloc) = self.alloc.allocation() {
|
||||||
Arc::get_mut(self).map(Self::map).unwrap()
|
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 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for MappedBuffer<'_> {
|
pub fn map_mut(&mut self) -> Option<&mut [u8]> {
|
||||||
type Target = [u8];
|
if let Some(alloc) = self.alloc.allocation_mut() {
|
||||||
|
alloc.mapped_slice_mut()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
pub fn buffer(&self) -> vk::Buffer {
|
||||||
self.bytes
|
*self.buffer
|
||||||
}
|
}
|
||||||
}
|
pub fn len(&self) -> u64 {
|
||||||
|
self.desc.size
|
||||||
impl DerefMut for MappedBuffer<'_> {
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
||||||
self.bytes
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,14 @@ impl Allocation {
|
||||||
Allocation::Unmanaged => None,
|
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 {
|
pub struct DeviceInner {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue