1
0
Fork 0
forked from wry/wry

vulkan: add async staging buffer allocation

This commit is contained in:
Julian Orth 2024-09-07 17:42:29 +02:00
parent 37fb45df00
commit b57d86c1bc
4 changed files with 72 additions and 23 deletions

View file

@ -199,7 +199,6 @@ impl VulkanAllocator {
}
impl VulkanThreadedAllocator {
#[expect(dead_code)]
pub fn async_alloc(
self: &Rc<Self>,
renderer: &Rc<VulkanRenderer>,

View file

@ -81,7 +81,6 @@ pub struct VulkanRenderer {
pub(super) tex_descriptor_set_layout: Rc<VulkanDescriptorSetLayout>,
pub(super) defunct: Cell<bool>,
pub(super) pending_cpu_jobs: CopyHashMap<u64, PendingJob>,
#[expect(dead_code)]
pub(super) shm_allocator: Rc<VulkanThreadedAllocator>,
}

View file

@ -1,11 +1,13 @@
use {
crate::{
cpu_worker::CpuWorker,
gfx_apis::vulkan::{
allocator::{VulkanAllocation, VulkanAllocator},
device::VulkanDevice,
renderer::VulkanRenderer,
VulkanError,
},
utils::on_drop::OnDrop,
utils::on_drop::{OnDrop, OnDrop2},
},
ash::vk::{Buffer, BufferCreateInfo, BufferUsageFlags, MappedMemoryRange},
gpu_alloc::UsageFlags,
@ -28,24 +30,8 @@ impl VulkanDevice {
download: bool,
transient: bool,
) -> Result<VulkanStagingBuffer, VulkanError> {
let mut vk_usage = BufferUsageFlags::empty();
let mut usage = UsageFlags::empty();
if upload {
vk_usage |= BufferUsageFlags::TRANSFER_SRC;
usage |= UsageFlags::UPLOAD;
}
if download {
vk_usage |= BufferUsageFlags::TRANSFER_DST;
usage |= UsageFlags::DOWNLOAD;
}
if transient {
usage |= UsageFlags::TRANSIENT;
}
let buffer = {
let create_info = BufferCreateInfo::default().size(size).usage(vk_usage);
let buffer = unsafe { self.device.create_buffer(&create_info, None) };
buffer.map_err(VulkanError::CreateBuffer)?
};
let (vk_usage, usage) = get_usage(upload, download, transient);
let buffer = self.create_buffer(size, vk_usage)?;
let destroy_buffer = OnDrop(|| unsafe { self.device.destroy_buffer(buffer, None) });
let memory_requirements = unsafe { self.device.get_buffer_memory_requirements(buffer) };
let allocation = allocator.alloc(&memory_requirements, usage, true)?;
@ -64,6 +50,73 @@ impl VulkanDevice {
size,
})
}
#[expect(dead_code)]
pub(super) fn create_shm_staging(
self: &Rc<Self>,
renderer: &Rc<VulkanRenderer>,
cpu: &Rc<CpuWorker>,
size: u64,
upload: bool,
download: bool,
cb: impl FnOnce(Result<VulkanStagingBuffer, VulkanError>) + 'static,
) -> Result<(), VulkanError> {
let (vk_usage, usage) = get_usage(upload, download, false);
let buffer = self.create_buffer(size, vk_usage)?;
let memory_requirements = unsafe { self.device.get_buffer_memory_requirements(buffer) };
let slf = self.clone();
let destroy_buffer =
OnDrop2::new(move || unsafe { slf.device.destroy_buffer(buffer, None) });
let slf = self.clone();
let finish_allocation = move |res| {
let allocation: VulkanAllocation = res?;
{
let res = unsafe {
slf.device
.bind_buffer_memory(buffer, allocation.memory, allocation.offset)
};
res.map_err(VulkanError::BindBufferMemory)?;
}
destroy_buffer.forget();
Ok(VulkanStagingBuffer {
device: slf.clone(),
allocation,
buffer,
size,
})
};
renderer.shm_allocator.async_alloc(
renderer,
cpu,
memory_requirements,
usage,
true,
move |res| cb(finish_allocation(res)),
)
}
fn create_buffer(&self, size: u64, usage: BufferUsageFlags) -> Result<Buffer, VulkanError> {
let create_info = BufferCreateInfo::default().size(size).usage(usage);
let buffer = unsafe { self.device.create_buffer(&create_info, None) };
buffer.map_err(VulkanError::CreateBuffer)
}
}
fn get_usage(upload: bool, download: bool, transient: bool) -> (BufferUsageFlags, UsageFlags) {
let mut vk_usage = BufferUsageFlags::empty();
let mut usage = UsageFlags::empty();
if upload {
vk_usage |= BufferUsageFlags::TRANSFER_SRC;
usage |= UsageFlags::UPLOAD;
}
if download {
vk_usage |= BufferUsageFlags::TRANSFER_DST;
usage |= UsageFlags::DOWNLOAD;
}
if transient {
usage |= UsageFlags::TRANSIENT;
}
(vk_usage, usage)
}
impl VulkanStagingBuffer {

View file

@ -24,14 +24,12 @@ where
}
impl<F: FnOnce()> OnDrop2<F> {
#[expect(dead_code)]
pub fn new(f: F) -> Self {
Self {
f: ManuallyDrop::new(f),
}
}
#[expect(dead_code)]
pub fn forget(mut self) {
unsafe {
ManuallyDrop::drop(&mut self.f);