From 2ac3519f2d592b91580f452f39a9ada8eed44999 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Sun, 1 Mar 2026 21:39:06 +0100 Subject: [PATCH] vulkan: abstract over the release sync type --- src/copy_device.rs | 66 +++++++++++++------------------- src/gfx_api.rs | 1 - src/gfx_apis/vulkan.rs | 2 +- src/gfx_apis/vulkan/renderer.rs | 65 +++++++++++++++---------------- src/gfx_apis/vulkan/shm_image.rs | 44 ++++++++------------- src/gfx_apis/vulkan/transfer.rs | 59 ++++++++++++++-------------- src/vulkan_core.rs | 1 + src/vulkan_core/sync.rs | 65 +++++++++++++++++++++++++++++++ 8 files changed, 166 insertions(+), 137 deletions(-) create mode 100644 src/vulkan_core/sync.rs diff --git a/src/copy_device.rs b/src/copy_device.rs index 8c0504e5..84fa9fe6 100644 --- a/src/copy_device.rs +++ b/src/copy_device.rs @@ -2,12 +2,12 @@ use { crate::{ async_engine::{AsyncEngine, SpawnedFuture}, format::{FORMATS, Format}, - gfx_api::{FdSync, SyncFile}, + gfx_api::FdSync, io_uring::IoUring, rect::{Rect, Region}, utils::{ - clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, queue::AsyncQueue, - stack::Stack, + clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell, + queue::AsyncQueue, stack::Stack, }, video::{ LINEAR_MODIFIER, LINEAR_STRIDE_ALIGN, Modifier, @@ -15,7 +15,7 @@ use { }, vulkan_core::{ self, VULKAN_API_VERSION, VulkanCoreError, VulkanCoreInstance, device::VulkanDeviceInf, - fence::VulkanDeviceFenceExt, map_extension_properties, + map_extension_properties, sync::VulkanDeviceSyncExt, }, }, ahash::{AHashMap, AHashSet}, @@ -230,7 +230,8 @@ pub struct CopyDeviceCopy { struct CopyDeviceCopyInner { dev: Rc, - busy: CloneCell>, + busy_id: NumCell, + busy: CloneCell>, width: u32, height: u32, command_buffer: CommandBuffer, @@ -269,10 +270,11 @@ enum CopyDeviceCopyType { struct Pending { dev: Rc, - sync_file: Option, + busy_id: u64, + sync: Option, copy: Rc, semaphore: Option, - fence: Option>, + vulkan_sync: VulkanSync, } struct VulkanSemaphore { @@ -281,6 +283,7 @@ struct VulkanSemaphore { } type VulkanFence = vulkan_core::fence::VulkanFence; +type VulkanSync = vulkan_core::sync::VulkanSync; struct VulkanBuffer { dev: Rc, @@ -733,8 +736,8 @@ async fn wait_for_submissions( submissions.task_has_pending.set(false); let pending = submissions.pending.pop().await; submissions.task_has_pending.set(true); - if let Some(sync_file) = &pending.sync_file - && let Err(e) = ring.readable(sync_file).await + if let Some(sync) = &pending.sync + && let Err(e) = sync.try_signaled(&ring).await { log::warn!( "Could not wait for sync file to become readable: {}", @@ -742,6 +745,7 @@ async fn wait_for_submissions( ); dev.wait_idle(); } + pending.vulkan_sync.handle_validation(); } } @@ -1117,6 +1121,7 @@ impl CopyDevice { Ok(CopyDeviceCopy { inner: Rc::new(CopyDeviceCopyInner { dev: self.dev.clone(), + busy_id: Default::default(), busy: Default::default(), width: src.width as _, height: src.height as _, @@ -1256,16 +1261,9 @@ impl CopyDeviceInner { impl CopyDeviceCopy { fn ensure_not_busy(&self) -> Result<(), CopyDeviceError> { let slf = &*self.inner; - let Some(busy) = slf.busy.get() else { - return Ok(()); - }; - let mut pollfd = c::pollfd { - fd: busy.raw(), - events: c::POLLIN, - revents: 0, - }; - let res = uapi::poll(slice::from_mut(&mut pollfd), 0); - if res != Ok(1) { + if let Some(sync) = slf.busy.get() + && sync.is_unsignaled() + { return Err(CopyDeviceError::Busy); } slf.busy.take(); @@ -1648,42 +1646,33 @@ impl CopyDeviceCopy { wait_semaphores.push(info); wait_semaphore = Some(semaphore); } - let signal_fence = match slf.dev.fences.pop() { - Some(s) => s, - _ => slf.dev.create_fence()?, - }; let command_buffer_info = CommandBufferSubmitInfo::default().command_buffer(cmd); let submit_info = SubmitInfo2::default() .command_buffer_infos(slice::from_ref(&command_buffer_info)) .wait_semaphore_infos(&wait_semaphores); + let vulkan_sync = slf.dev.create_sync()?; unsafe { slf.dev .dev .queue_submit2( slf.dev.queues[tt], slice::from_ref(&submit_info), - signal_fence.fence, + vulkan_sync.fence(), ) .map_err(CopyDeviceError::SubmitCopy)?; } - let sync_file = match signal_fence.export_sync_file() { - Ok(f) => f, - Err(e) => { - log::error!("Could not export signal fence: {}", ErrorFmt(e)); - slf.dev.wait_idle(); - None - } - }; - slf.busy.set(sync_file.clone()); + let sync = vulkan_sync.to_sync(|| slf.dev.wait_idle()); + slf.busy.set(sync.clone()); let pending = Pending { dev: slf.dev.clone(), - sync_file: sync_file.clone(), + busy_id: slf.busy_id.add_fetch(1), + sync: sync.clone(), copy: self.inner.clone(), semaphore: wait_semaphore, - fence: Some(signal_fence), + vulkan_sync, }; slf.dev.submissions[tt].pending.push(pending); - Ok(sync_file.map(FdSync::SyncFile)) + Ok(sync) } } @@ -1794,10 +1783,7 @@ impl Drop for Pending { if let Some(v) = self.semaphore.take() { self.dev.semaphores.push(v); } - if let Some(v) = self.fence.take() { - self.dev.fences.push(v); - } - if self.copy.busy.get() == self.sync_file { + if self.copy.busy_id.get() == self.busy_id { self.copy.busy.take(); } } diff --git a/src/gfx_api.rs b/src/gfx_api.rs index d5f7bcfb..43a61c7f 100644 --- a/src/gfx_api.rs +++ b/src/gfx_api.rs @@ -1169,7 +1169,6 @@ impl FdSync { } } - #[expect(dead_code)] pub fn is_unsignaled(&self) -> bool { !self.is_signaled() } diff --git a/src/gfx_apis/vulkan.rs b/src/gfx_apis/vulkan.rs index 12033da8..0297f0ca 100644 --- a/src/gfx_apis/vulkan.rs +++ b/src/gfx_apis/vulkan.rs @@ -211,7 +211,7 @@ pub enum VulkanError { DmaBufBufferOffsetAlignment, } -type VulkanFence = vulkan_core::fence::VulkanFence; +type VulkanSync = vulkan_core::sync::VulkanSync; impl From for GfxError { fn from(value: VulkanError) -> Self { diff --git a/src/gfx_apis/vulkan/renderer.rs b/src/gfx_apis/vulkan/renderer.rs index 1ffd0a31..4841674a 100644 --- a/src/gfx_apis/vulkan/renderer.rs +++ b/src/gfx_apis/vulkan/renderer.rs @@ -9,10 +9,10 @@ use { cpu_worker::PendingJob, gfx_api::{ AcquireSync, AlphaMode, BufferResv, BufferResvUser, FdSync, GfxApiOpt, GfxBlendBuffer, - GfxFormat, GfxTexture, GfxWriteModifier, ReleaseSync, SyncFile, + GfxFormat, GfxTexture, GfxWriteModifier, ReleaseSync, }, gfx_apis::vulkan::{ - VulkanError, VulkanFence, + VulkanError, VulkanSync, allocator::{VulkanAllocator, VulkanThreadedAllocator}, buffer_cache::{GenericBufferWriter, VulkanBuffer, VulkanBufferCache}, command::{VulkanCommandBuffer, VulkanCommandPool}, @@ -39,7 +39,7 @@ use { stack::Stack, }, video::dmabuf::{DMA_BUF_SYNC_READ, DMA_BUF_SYNC_WRITE, dma_buf_export_sync_file}, - vulkan_core::fence::VulkanDeviceFenceExt, + vulkan_core::sync::VulkanDeviceSyncExt, }, ahash::AHashMap, arrayvec::ArrayVec, @@ -65,7 +65,7 @@ use { std::{ any::Any, borrow::Cow, - cell::{Cell, RefCell}, + cell::{Cell, LazyCell, RefCell}, collections::hash_map::Entry, fmt::{Debug, Formatter}, mem, @@ -162,8 +162,8 @@ pub(super) struct Memory { image_barriers: Vec>, wait_semaphores: Vec>, wait_semaphore_infos: Vec>, - release_fence: Option>, - release_sync_file: Option, + release_vulkan_sync: Option, + release_sync: Option, used_buffers: ArrayVec, paint_bounds: StaticMap>, paint_regions: StaticMap>, @@ -249,7 +249,7 @@ pub(super) struct PendingFrame { _textures: Vec, wait_semaphores: Cell>>, waiter: Cell>>, - _release_fence: Option>, + vulkan_sync: Option, _used_buffers: ArrayVec, } @@ -1705,11 +1705,11 @@ impl VulkanRenderer { fn import_release_semaphore(&self, fb: &VulkanImage, fb_release_sync: ReleaseSync) { zone!("import_release_semaphore"); let memory = &mut *self.memory.borrow_mut(); - let sync_file = match memory.release_sync_file.as_ref() { - Some(sync_file) => sync_file, + let fd_sync = match memory.release_sync.as_ref() { + Some(sync) => sync, _ => return, }; - let fd_sync = FdSync::SyncFile(sync_file.clone()); + let sync_file = LazyCell::new(|| fd_sync.get_sync_file()); let import = |img: &VulkanImage, sync: ReleaseSync, resv: Option>, flag: u32| { if sync == ReleaseSync::None { @@ -1719,7 +1719,8 @@ impl VulkanRenderer { resv.set_sync(self.buffer_resv_user, &fd_sync); } else if sync == ReleaseSync::Implicit { if let VulkanImageMemory::DmaBuf(buf) = &img.ty - && let Err(e) = buf.template.dmabuf.import_sync_file(flag, sync_file) + && let Some(fd) = &*sync_file + && let Err(e) = buf.template.dmabuf.import_sync_file(flag, fd) { log::error!("Could not import sync file into dmabuf: {}", ErrorFmt(e)); log::warn!("Relying on implicit sync"); @@ -1739,14 +1740,14 @@ impl VulkanRenderer { && let VulkanImageMemory::Internal(shm) = &texture.tex.ty && let Some(data) = &shm.async_data { - data.last_gfx_use.set(Some(sync_file.clone())); + data.last_gfx_use.set(Some(fd_sync.clone())); } } if attach_async_shm_sync_file && let VulkanImageMemory::Internal(shm) = &fb.ty && let Some(data) = &shm.async_data { - data.last_gfx_use.set(Some(sync_file.clone())); + data.last_gfx_use.set(Some(fd_sync.clone())); } import(fb, fb_release_sync, None, DMA_BUF_SYNC_WRITE); } @@ -1754,33 +1755,24 @@ impl VulkanRenderer { fn submit(&self, buf: CommandBuffer) -> Result<(), VulkanError> { zone!("submit"); let mut memory = self.memory.borrow_mut(); - let release_fence = self.device.create_fence()?; let command_buffer_info = CommandBufferSubmitInfo::default().command_buffer(buf); let submit_info = SubmitInfo2::default() .wait_semaphore_infos(&memory.wait_semaphore_infos) .command_buffer_infos(slice::from_ref(&command_buffer_info)); + let vulkan_sync = self.device.create_sync()?; unsafe { self.device .device .queue_submit2( self.device.graphics_queue, slice::from_ref(&submit_info), - release_fence.fence, + vulkan_sync.fence(), ) .inspect_err(self.device.idl()) .map_err(VulkanError::Submit)?; } - zone!("export_sync_file"); - let release_sync_file = match release_fence.export_sync_file() { - Ok(s) => s, - Err(e) => { - log::error!("Could not export sync file from fence: {}", ErrorFmt(e)); - self.block(); - None - } - }; - memory.release_fence = Some(release_fence); - memory.release_sync_file = release_sync_file; + memory.release_sync = vulkan_sync.to_sync(|| self.block()); + memory.release_vulkan_sync = Some(vulkan_sync); Ok(()) } @@ -1819,14 +1811,14 @@ impl VulkanRenderer { _textures: mem::take(&mut memory.textures), wait_semaphores: Cell::new(mem::take(&mut memory.wait_semaphores)), waiter: Cell::new(None), - _release_fence: memory.release_fence.take(), + vulkan_sync: memory.release_vulkan_sync.take(), _used_buffers: mem::take(&mut memory.used_buffers), }); self.pending_frames.set(frame.point, frame.clone()); let future = self.eng.spawn( "await release", await_release( - memory.release_sync_file.clone(), + memory.release_sync.clone(), self.ring.clone(), frame.clone(), self.clone(), @@ -1861,19 +1853,19 @@ impl VulkanRenderer { blend_buffer, blend_cd, ); - let sync_file = { + let sync = { let mut memory = self.memory.borrow_mut(); memory.textures.clear(); memory.dmabuf_sample.clear(); memory.queue_transfer.clear(); memory.wait_semaphores.clear(); - memory.release_fence.take(); + memory.release_vulkan_sync.take(); memory.used_buffers.clear(); memory.ops.clear(); memory.ops_tmp.clear(); - memory.release_sync_file.take() + memory.release_sync.take() }; - res.map(|_| sync_file.map(FdSync::SyncFile)) + res.map(|_| sync) } fn allocate_semaphore(&self) -> Result, VulkanError> { @@ -2190,13 +2182,13 @@ pub(super) fn image_barrier() -> ImageMemoryBarrier2<'static> { } async fn await_release( - sync_file: Option, + sync: Option, ring: Rc, frame: Rc, renderer: Rc, ) { - if let Some(sync_file) = sync_file - && let Err(e) = ring.readable(&sync_file).await + if let Some(sync) = sync + && let Err(e) = sync.try_signaled(&ring).await { log::error!( "Could not wait for release semaphore to be signaled: {}", @@ -2204,6 +2196,9 @@ async fn await_release( ); frame.renderer.block(); } + if let Some(vs) = &frame.vulkan_sync { + vs.handle_validation(); + } if let Some(buf) = frame.cmd.take() { frame.renderer.gfx_command_buffers.buffers.push(buf); } diff --git a/src/gfx_apis/vulkan/shm_image.rs b/src/gfx_apis/vulkan/shm_image.rs index 74fb5ca4..f2694118 100644 --- a/src/gfx_apis/vulkan/shm_image.rs +++ b/src/gfx_apis/vulkan/shm_image.rs @@ -2,9 +2,9 @@ use { crate::{ cpu_worker::CpuWorker, format::Format, - gfx_api::SyncFile, + gfx_api::FdSync, gfx_apis::vulkan::{ - VulkanError, VulkanFence, + VulkanError, VulkanSync, allocator::VulkanAllocation, command::VulkanCommandBuffer, image::{QueueFamily, QueueState, VulkanImage, VulkanImageMemory}, @@ -14,7 +14,7 @@ use { }, rect::Rect, utils::errorfmt::ErrorFmt, - vulkan_core::fence::VulkanDeviceFenceExt, + vulkan_core::sync::VulkanDeviceSyncExt, }, ash::vk::{ AccessFlags2, Buffer, BufferImageCopy2, BufferMemoryBarrier2, CommandBufferBeginInfo, @@ -136,7 +136,7 @@ impl VulkanShmImage { ptr::copy_nonoverlapping(buf, mem, total_size as usize); } })?; - let (cmd, fence, sync_file, point) = self.submit_buffer_image_copy( + let (cmd, vulkan_sync, sync, point) = self.submit_buffer_image_copy( img, staging.buffer, staging.size, @@ -147,7 +147,7 @@ impl VulkanShmImage { )?; let future = img.renderer.eng.spawn( "await upload", - await_upload(point, img.clone(), cmd, sync_file, fence, staging), + await_upload(point, img.clone(), cmd, sync, vulkan_sync, staging), ); img.renderer.pending_submits.set(point, future); Ok(()) @@ -162,15 +162,7 @@ impl VulkanShmImage { use_transfer_queue: bool, tt: TransferType, foreign_buffer: bool, - ) -> Result< - ( - Rc, - Rc, - Option, - u64, - ), - VulkanError, - > { + ) -> Result<(Rc, VulkanSync, Option, u64), VulkanError> { let mut transfer_queue_family_idx = img.renderer.device.graphics_queue_idx; if use_transfer_queue && let Some(idx) = img.renderer.device.distinct_transfer_queue_family_idx @@ -281,7 +273,7 @@ impl VulkanShmImage { SubmitInfo2::default().command_buffer_infos(slice::from_ref(&command_buffer_info)); let begin_info = CommandBufferBeginInfo::default().flags(CommandBufferUsageFlags::ONE_TIME_SUBMIT); - let release_fence = img.renderer.device.create_fence()?; + let vulkan_sync = img.renderer.device.create_sync()?; unsafe { dev.begin_command_buffer(cmd.buffer, &begin_info) .map_err(VulkanError::BeginCommandBuffer)?; @@ -313,7 +305,7 @@ impl VulkanShmImage { _ => img.renderer.device.graphics_queue, }, slice::from_ref(&submit_info), - release_fence.fence, + vulkan_sync.fence(), ) .inspect_err(img.renderer.device.idl()) .map_err(VulkanError::Submit)?; @@ -322,16 +314,9 @@ impl VulkanShmImage { img.is_undefined.set(false); img.contents_are_undefined.set(false); } - let release_sync_file = match release_fence.export_sync_file() { - Ok(s) => s, - Err(e) => { - log::error!("Could not export sync file from fence: {}", ErrorFmt(e)); - img.renderer.block(); - None - } - }; + let release_sync = vulkan_sync.to_sync(|| img.renderer.block()); let point = img.renderer.allocate_point(); - Ok((cmd, release_fence, release_sync_file, point)) + Ok((cmd, vulkan_sync, release_sync, point)) } } @@ -339,12 +324,12 @@ async fn await_upload( id: u64, img: Rc, buf: Rc, - sync_file: Option, - _fence: Rc, + sync: Option, + vulkan_sync: VulkanSync, _staging: VulkanStagingBuffer, ) { - if let Some(sync_file) = sync_file - && let Err(e) = img.renderer.ring.readable(&sync_file.0).await + if let Some(sync) = &sync + && let Err(e) = sync.try_signaled(&img.renderer.ring).await { log::error!( "Could not wait for sync file to become readable: {}", @@ -352,6 +337,7 @@ async fn await_upload( ); img.renderer.block(); } + vulkan_sync.handle_validation(); img.renderer.gfx_command_buffers.buffers.push(buf); img.renderer.pending_submits.remove(&id); } diff --git a/src/gfx_apis/vulkan/transfer.rs b/src/gfx_apis/vulkan/transfer.rs index d63640c8..eefb396e 100644 --- a/src/gfx_apis/vulkan/transfer.rs +++ b/src/gfx_apis/vulkan/transfer.rs @@ -8,10 +8,10 @@ use { }, }, gfx_api::{ - AsyncShmGfxTextureCallback, PendingShmTransfer, ShmMemory, ShmMemoryBacking, SyncFile, + AsyncShmGfxTextureCallback, FdSync, PendingShmTransfer, ShmMemory, ShmMemoryBacking, }, gfx_apis::vulkan::{ - VulkanError, VulkanFence, + VulkanError, VulkanSync, command::VulkanCommandBuffer, dmabuf_buffer::{TRANSFER_QUEUE_BUFFER_ALIGNMENT, VulkanDmabufBuffer}, image::{QueueFamily, QueueState, QueueTransfer, VulkanImage, VulkanImageMemory}, @@ -21,7 +21,7 @@ use { }, rect::{Rect, Region}, utils::{clonecell::CloneCell, errorfmt::ErrorFmt}, - vulkan_core::fence::VulkanDeviceFenceExt, + vulkan_core::sync::VulkanDeviceSyncExt, }, arrayvec::ArrayVec, ash::vk::{ @@ -48,7 +48,7 @@ pub struct VulkanShmImageAsyncData { pub(super) callback_id: Cell, pub(super) regions: RefCell>>, pub(super) cpu: Rc, - pub(super) last_gfx_use: Cell>, + pub(super) last_gfx_use: Cell>, pub(super) data_copied: Cell, } @@ -314,7 +314,7 @@ impl VulkanShmImage { img.renderer.check_defunct()?; let Some(transfer_queue_idx) = img.renderer.device.distinct_transfer_queue_family_idx else { - let Some(sync_file) = data.last_gfx_use.take() else { + let Some(sync) = data.last_gfx_use.take() else { img.queue_state.set(QueueState::Released { to: QueueFamily::Transfer, }); @@ -323,7 +323,7 @@ impl VulkanShmImage { let id = img.renderer.allocate_point(); let pending = img.renderer.eng.spawn( "await_transfer_to_transfer", - await_gfx_queue_release(id, img.clone(), None, None, Some(sync_file), tt), + await_gfx_queue_release(id, img.clone(), None, None, Some(sync), tt), ); img.renderer.pending_submits.set(id, pending); img.queue_state.set(QueueState::Releasing); @@ -375,7 +375,6 @@ impl VulkanShmImage { .new_layout(transfer_layout); barriers.push(barrier); let dep_info = DependencyInfo::default().image_memory_barriers(&barriers); - let release_fence = img.renderer.device.create_fence()?; let dev = &img.renderer.device.device; let begin_info = CommandBufferBeginInfo::default().flags(CommandBufferUsageFlags::ONE_TIME_SUBMIT); @@ -383,6 +382,7 @@ impl VulkanShmImage { let command_buffer_info = CommandBufferSubmitInfo::default().command_buffer(cmd.buffer); let submit_info = SubmitInfo2::default().command_buffer_infos(slice::from_ref(&command_buffer_info)); + let vulkan_sync = img.renderer.device.create_sync()?; unsafe { dev.begin_command_buffer(cmd.buffer, &begin_info) .map_err(VulkanError::BeginCommandBuffer)?; @@ -392,23 +392,16 @@ impl VulkanShmImage { dev.queue_submit2( img.renderer.device.graphics_queue, slice::from_ref(&submit_info), - release_fence.fence, + vulkan_sync.fence(), ) .inspect_err(img.renderer.device.idl()) .map_err(VulkanError::Submit)?; } - let sync_file = release_fence.export_sync_file()?; + let sync = vulkan_sync.to_sync(|| img.renderer.block()); let id = img.renderer.allocate_point(); let pending = img.renderer.eng.spawn( "await_transfer_to_transfer", - await_gfx_queue_release( - id, - img.clone(), - Some(cmd), - Some(release_fence), - sync_file, - tt, - ), + await_gfx_queue_release(id, img.clone(), Some(cmd), Some(vulkan_sync), sync, tt), ); img.renderer.pending_submits.set(id, pending); img.queue_state.set(QueueState::Releasing); @@ -555,7 +548,7 @@ impl VulkanShmImage { (host_buffer.buffer, host_buffer.size, true) } }; - let (cmd, fence, sync_file, point) = self.submit_buffer_image_copy( + let (cmd, vulkan_sync, sync, point) = self.submit_buffer_image_copy( img, buffer, size, @@ -571,8 +564,8 @@ impl VulkanShmImage { point, img.clone(), cmd, - fence, - sync_file, + vulkan_sync, + sync, TransferType::Upload, ), ); @@ -590,7 +583,7 @@ impl VulkanShmImage { return Ok(()); } img.renderer.check_defunct()?; - let (cmd, fence, sync_file, point) = self.submit_buffer_image_copy( + let (cmd, vulkan_sync, sync, point) = self.submit_buffer_image_copy( img, staging.buffer, staging.size, @@ -606,8 +599,8 @@ impl VulkanShmImage { point, img.clone(), cmd, - fence, - sync_file, + vulkan_sync, + sync, TransferType::Download, ), ); @@ -695,12 +688,12 @@ async fn await_gfx_queue_release( id: u64, img: Rc, buf: Option>, - _fence: Option>, - sync_file: Option, + vulkan_sync: Option, + sync: Option, tt: TransferType, ) { - if let Some(sync_file) = sync_file - && let Err(e) = img.renderer.ring.readable(&sync_file.0).await + if let Some(sync) = &sync + && let Err(e) = sync.try_signaled(&img.renderer.ring).await { log::error!( "Could not wait for sync file to become readable: {}", @@ -708,6 +701,9 @@ async fn await_gfx_queue_release( ); img.renderer.block(); } + if let Some(vs) = vulkan_sync { + vs.handle_validation(); + } if let Some(buf) = buf { img.renderer.gfx_command_buffers.buffers.push(buf); } @@ -738,12 +734,12 @@ pub async fn await_async_transfer_release_to_gfx( id: u64, img: Rc, buf: Rc, - _fence: Rc, - sync_file: Option, + vulkan_sync: VulkanSync, + sync: Option, tt: TransferType, ) { - if let Some(sync_file) = sync_file - && let Err(e) = img.renderer.ring.readable(&sync_file.0).await + if let Some(sync) = &sync + && let Err(e) = sync.try_signaled(&img.renderer.ring).await { log::error!( "Could not wait for sync file to become readable: {}", @@ -751,6 +747,7 @@ pub async fn await_async_transfer_release_to_gfx( ); img.renderer.block(); } + vulkan_sync.handle_validation(); match &img.renderer.transfer_command_buffers { Some(b) => b.buffers.push(buf), None => img.renderer.gfx_command_buffers.buffers.push(buf), diff --git a/src/vulkan_core.rs b/src/vulkan_core.rs index 23103819..b4c4264b 100644 --- a/src/vulkan_core.rs +++ b/src/vulkan_core.rs @@ -27,6 +27,7 @@ use { pub mod device; pub mod fence; +pub mod sync; static VULKAN_ENTRY: Lazy>> = Lazy::new(|| unsafe { Entry::load() }.map_err(Arc::new)); diff --git a/src/vulkan_core/sync.rs b/src/vulkan_core/sync.rs new file mode 100644 index 00000000..eca2df83 --- /dev/null +++ b/src/vulkan_core/sync.rs @@ -0,0 +1,65 @@ +use { + crate::{ + gfx_api::FdSync, + utils::errorfmt::ErrorFmt, + vulkan_core::{ + VulkanCoreError, + device::VulkanDeviceInf, + fence::{VulkanDeviceFenceExt, VulkanFence}, + }, + }, + ash::vk::Fence, + std::rc::Rc, +}; + +pub enum VulkanSync +where + D: VulkanDeviceInf, +{ + Fence(Rc>), +} + +impl VulkanSync +where + D: VulkanDeviceInf, +{ + pub fn handle_validation(&self) { + // nothing + } + + pub fn fence(&self) -> Fence { + match self { + VulkanSync::Fence(f) => f.fence, + } + } + + pub fn to_sync(&self, block: impl FnOnce()) -> Option { + match self { + VulkanSync::Fence(release_fence) => { + zone!("export_sync_file"); + let release_sync_file = match release_fence.export_sync_file() { + Ok(s) => s, + Err(e) => { + log::error!("Could not export sync file from fence: {}", ErrorFmt(e)); + block(); + None + } + }; + release_sync_file.map(FdSync::SyncFile) + } + } + } +} + +pub trait VulkanDeviceSyncExt: VulkanDeviceInf { + fn create_sync(self: &Rc) -> Result, VulkanCoreError>; +} + +impl VulkanDeviceSyncExt for D +where + D: VulkanDeviceInf, +{ + fn create_sync(self: &Rc) -> Result, VulkanCoreError> { + self.create_fence().map(VulkanSync::Fence) + } +}