From 3ecee1b17fea22d1b02e178ad52821e57957d986 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Mon, 2 Mar 2026 10:45:14 +0100 Subject: [PATCH] vulkan: move fence to core --- src/copy_device.rs | 86 +++++-------------- src/gfx_apis/vulkan.rs | 12 ++- src/gfx_apis/vulkan/device.rs | 13 ++- src/gfx_apis/vulkan/renderer.rs | 4 +- src/gfx_apis/vulkan/shm_image.rs | 4 +- src/gfx_apis/vulkan/transfer.rs | 4 +- src/vulkan_core.rs | 7 ++ src/vulkan_core/device.rs | 6 ++ src/{gfx_apis/vulkan => vulkan_core}/fence.rs | 44 +++++++--- 9 files changed, 89 insertions(+), 91 deletions(-) create mode 100644 src/vulkan_core/device.rs rename src/{gfx_apis/vulkan => vulkan_core}/fence.rs (51%) diff --git a/src/copy_device.rs b/src/copy_device.rs index b35442b8..8c0504e5 100644 --- a/src/copy_device.rs +++ b/src/copy_device.rs @@ -14,7 +14,8 @@ use { dmabuf::{DmaBuf, DmaBufIds, DmaBufPlane, PlaneVec}, }, vulkan_core::{ - VULKAN_API_VERSION, VulkanCoreError, VulkanCoreInstance, map_extension_properties, + self, VULKAN_API_VERSION, VulkanCoreError, VulkanCoreInstance, device::VulkanDeviceInf, + fence::VulkanDeviceFenceExt, map_extension_properties, }, }, ahash::{AHashMap, AHashSet}, @@ -34,14 +35,13 @@ use { CommandPoolCreateInfo, CopyBufferInfo2, CopyBufferToImageInfo2, CopyImageInfo2, CopyImageToBufferInfo2, DependencyInfo, DeviceCreateInfo, DeviceMemory, DeviceQueueCreateInfo, DrmFormatModifierPropertiesEXT, - DrmFormatModifierPropertiesListEXT, ExportFenceCreateInfo, ExportMemoryAllocateInfo, - Extent3D, ExternalBufferProperties, ExternalFenceFeatureFlags, - ExternalFenceHandleTypeFlags, ExternalFenceProperties, - ExternalImageFormatPropertiesKHR, ExternalMemoryBufferCreateInfo, - ExternalMemoryBufferCreateInfoKHR, ExternalMemoryFeatureFlags, - ExternalMemoryHandleTypeFlags, ExternalMemoryImageCreateInfo, - ExternalSemaphoreFeatureFlags, ExternalSemaphoreHandleTypeFlags, - ExternalSemaphoreProperties, Fence, FenceCreateInfo, FenceGetFdInfoKHR, Filter, + DrmFormatModifierPropertiesListEXT, ExportMemoryAllocateInfo, Extent3D, + ExternalBufferProperties, ExternalFenceFeatureFlags, ExternalFenceHandleTypeFlags, + ExternalFenceProperties, ExternalImageFormatPropertiesKHR, + ExternalMemoryBufferCreateInfo, ExternalMemoryBufferCreateInfoKHR, + ExternalMemoryFeatureFlags, ExternalMemoryHandleTypeFlags, + ExternalMemoryImageCreateInfo, ExternalSemaphoreFeatureFlags, + ExternalSemaphoreHandleTypeFlags, ExternalSemaphoreProperties, Filter, FormatFeatureFlags, FormatProperties2, ImageAspectFlags, ImageBlit2, ImageCopy2, ImageCreateFlags, ImageCreateInfo, ImageDrmFormatModifierExplicitCreateInfoEXT, ImageFormatProperties2, ImageLayout, ImageMemoryBarrier2, ImageMemoryRequirementsInfo2, @@ -84,16 +84,12 @@ pub enum CopyDeviceError { Core(#[from] VulkanCoreError), #[error("Could not create a semaphore")] CreateSemaphore(#[source] vk::Result), - #[error("Could not create a fence")] - CreateFence(#[source] vk::Result), #[error("Could not dup a sync file")] DupSyncFile(#[source] io::Error), #[error("Could not dup a dma buf")] DupDmaBuf(#[source] io::Error), #[error("Could not import a sync file")] ImportSyncFile(#[source] vk::Result), - #[error("Could not export a sync file")] - ExportSyncFile(#[source] vk::Result), #[error("Could not submit the copy")] SubmitCopy(#[source] vk::Result), #[error("Could not enumerate the physical devices")] @@ -217,7 +213,7 @@ struct CopyDeviceInner { external_fence_fd: external_fence_fd::Device, external_memory_fd: external_memory_fd::Device, semaphores: Stack, - fences: Stack, + fences: Stack>, submissions: Keyed>, } @@ -276,7 +272,7 @@ struct Pending { sync_file: Option, copy: Rc, semaphore: Option, - fence: Option, + fence: Option>, } struct VulkanSemaphore { @@ -284,10 +280,7 @@ struct VulkanSemaphore { semaphore: Semaphore, } -struct VulkanFence { - dev: Rc, - fence: Fence, -} +type VulkanFence = vulkan_core::fence::VulkanFence; struct VulkanBuffer { dev: Rc, @@ -1258,21 +1251,6 @@ impl CopyDeviceInner { semaphore, }) } - - fn create_fence(self: &Rc) -> Result { - let mut export_info = - ExportFenceCreateInfo::default().handle_types(ExternalFenceHandleTypeFlags::SYNC_FD); - let create_info = FenceCreateInfo::default().push_next(&mut export_info); - let fence = unsafe { - self.dev - .create_fence(&create_info, None) - .map_err(CopyDeviceError::CreateFence)? - }; - Ok(VulkanFence { - dev: self.clone(), - fence, - }) - } } impl CopyDeviceCopy { @@ -1688,7 +1666,7 @@ impl CopyDeviceCopy { ) .map_err(CopyDeviceError::SubmitCopy)?; } - let sync_file = match signal_fence.export() { + let sync_file = match signal_fence.export_sync_file() { Ok(f) => f, Err(e) => { log::error!("Could not export signal fence: {}", ErrorFmt(e)); @@ -1730,26 +1708,6 @@ impl VulkanSemaphore { } } -impl VulkanFence { - fn export(&self) -> Result, CopyDeviceError> { - let info = FenceGetFdInfoKHR::default() - .fence(self.fence) - .handle_type(ExternalFenceHandleTypeFlags::SYNC_FD); - let fd = unsafe { - self.dev - .external_fence_fd - .get_fence_fd(&info) - .map_err(CopyDeviceError::ExportSyncFile)? - }; - let fd = if fd == -1 { - None - } else { - Some(SyncFile(Rc::new(OwnedFd::new(fd)))) - }; - Ok(fd) - } -} - impl CopyDeviceRegistry { pub fn new(ring: &Rc, eng: &Rc) -> Self { Self { @@ -1794,14 +1752,6 @@ impl Drop for VulkanSemaphore { } } -impl Drop for VulkanFence { - fn drop(&mut self) { - unsafe { - self.dev.dev.destroy_fence(self.fence, None); - } - } -} - impl Drop for CopyDeviceCopyInner { fn drop(&mut self) { unsafe { @@ -2039,3 +1989,13 @@ fn allocate_queues( }; (queues_to_allocate, queue_indices) } + +impl VulkanDeviceInf for CopyDeviceInner { + fn device(&self) -> &Device { + &self.dev + } + + fn external_fence_fd(&self) -> &external_fence_fd::Device { + &self.external_fence_fd + } +} diff --git a/src/gfx_apis/vulkan.rs b/src/gfx_apis/vulkan.rs index 2b3ec089..12033da8 100644 --- a/src/gfx_apis/vulkan.rs +++ b/src/gfx_apis/vulkan.rs @@ -9,7 +9,6 @@ mod descriptor_buffer; mod device; mod dmabuf_buffer; mod eotfs; -mod fence; mod format; mod gpu_alloc_ash; mod image; @@ -35,7 +34,8 @@ use { STAGING_DOWNLOAD, STAGING_UPLOAD, ShmGfxTexture, StagingBufferUsecase, }, gfx_apis::vulkan::{ - image::VulkanImageMemory, instance::VulkanInstance, renderer::VulkanRenderer, + device::VulkanDevice, image::VulkanImageMemory, instance::VulkanInstance, + renderer::VulkanRenderer, }, io_uring::IoUring, pr_caps::PrCapsThread, @@ -46,7 +46,7 @@ use { drm::{Drm, DrmError, syncobj::SyncobjCtx}, gbm::GbmError, }, - vulkan_core::VulkanCoreError, + vulkan_core::{self, VulkanCoreError}, }, ahash::AHashMap, ash::vk, @@ -73,8 +73,6 @@ pub enum VulkanError { CreateDevice(#[source] vk::Result), #[error("Could not create a semaphore")] CreateSemaphore(#[source] vk::Result), - #[error("Could not create a fence")] - CreateFence(#[source] vk::Result), #[error("Could not create the buffer")] CreateBuffer(#[source] vk::Result), #[error("Could not create a shader module")] @@ -157,8 +155,6 @@ pub enum VulkanError { IoctlExportSyncFile(#[source] OsError), #[error("Could not import a sync file into a semaphore")] ImportSyncFile(#[source] vk::Result), - #[error("Could not export a sync file from a semaphore")] - ExportSyncFile(#[source] vk::Result), #[error("Could not fetch the render node of the device")] FetchRenderNode(#[source] DrmError), #[error("Device has no render node")] @@ -215,6 +211,8 @@ pub enum VulkanError { DmaBufBufferOffsetAlignment, } +type VulkanFence = vulkan_core::fence::VulkanFence; + impl From for GfxError { fn from(value: VulkanError) -> Self { Self(Box::new(value)) diff --git a/src/gfx_apis/vulkan/device.rs b/src/gfx_apis/vulkan/device.rs index 671b4d52..3d1927e1 100644 --- a/src/gfx_apis/vulkan/device.rs +++ b/src/gfx_apis/vulkan/device.rs @@ -14,7 +14,8 @@ use { gbm::{GBM_BO_USE_RENDERING, GbmDevice}, }, vulkan_core::{ - ApiVersionDisplay, Extensions, VULKAN_API_VERSION, map_extension_properties, + ApiVersionDisplay, Extensions, VULKAN_API_VERSION, device::VulkanDeviceInf, + map_extension_properties, }, }, ahash::AHashMap, @@ -639,3 +640,13 @@ fn log_device( } } } + +impl VulkanDeviceInf for VulkanDevice { + fn device(&self) -> &Device { + &self.device + } + + fn external_fence_fd(&self) -> &external_fence_fd::Device { + &self.external_fence_fd + } +} diff --git a/src/gfx_apis/vulkan/renderer.rs b/src/gfx_apis/vulkan/renderer.rs index 0adea473..1ffd0a31 100644 --- a/src/gfx_apis/vulkan/renderer.rs +++ b/src/gfx_apis/vulkan/renderer.rs @@ -12,7 +12,7 @@ use { GfxFormat, GfxTexture, GfxWriteModifier, ReleaseSync, SyncFile, }, gfx_apis::vulkan::{ - VulkanError, + VulkanError, VulkanFence, allocator::{VulkanAllocator, VulkanThreadedAllocator}, buffer_cache::{GenericBufferWriter, VulkanBuffer, VulkanBufferCache}, command::{VulkanCommandBuffer, VulkanCommandPool}, @@ -20,7 +20,6 @@ use { descriptor_buffer::VulkanDescriptorBufferWriter, device::VulkanDevice, eotfs::{EOTF_LINEAR, EotfExt, VulkanEotf}, - fence::VulkanFence, image::{QueueFamily, QueueState, QueueTransfer, VulkanImage, VulkanImageMemory}, pipeline::{PipelineCreateInfo, VulkanPipeline}, sampler::VulkanSampler, @@ -40,6 +39,7 @@ use { stack::Stack, }, video::dmabuf::{DMA_BUF_SYNC_READ, DMA_BUF_SYNC_WRITE, dma_buf_export_sync_file}, + vulkan_core::fence::VulkanDeviceFenceExt, }, ahash::AHashMap, arrayvec::ArrayVec, diff --git a/src/gfx_apis/vulkan/shm_image.rs b/src/gfx_apis/vulkan/shm_image.rs index 37ba16ff..74fb5ca4 100644 --- a/src/gfx_apis/vulkan/shm_image.rs +++ b/src/gfx_apis/vulkan/shm_image.rs @@ -4,10 +4,9 @@ use { format::Format, gfx_api::SyncFile, gfx_apis::vulkan::{ - VulkanError, + VulkanError, VulkanFence, allocator::VulkanAllocation, command::VulkanCommandBuffer, - fence::VulkanFence, image::{QueueFamily, QueueState, VulkanImage, VulkanImageMemory}, renderer::{VulkanRenderer, image_barrier}, staging::VulkanStagingBuffer, @@ -15,6 +14,7 @@ use { }, rect::Rect, utils::errorfmt::ErrorFmt, + vulkan_core::fence::VulkanDeviceFenceExt, }, ash::vk::{ AccessFlags2, Buffer, BufferImageCopy2, BufferMemoryBarrier2, CommandBufferBeginInfo, diff --git a/src/gfx_apis/vulkan/transfer.rs b/src/gfx_apis/vulkan/transfer.rs index eca55277..d63640c8 100644 --- a/src/gfx_apis/vulkan/transfer.rs +++ b/src/gfx_apis/vulkan/transfer.rs @@ -11,10 +11,9 @@ use { AsyncShmGfxTextureCallback, PendingShmTransfer, ShmMemory, ShmMemoryBacking, SyncFile, }, gfx_apis::vulkan::{ - VulkanError, + VulkanError, VulkanFence, command::VulkanCommandBuffer, dmabuf_buffer::{TRANSFER_QUEUE_BUFFER_ALIGNMENT, VulkanDmabufBuffer}, - fence::VulkanFence, image::{QueueFamily, QueueState, QueueTransfer, VulkanImage, VulkanImageMemory}, renderer::image_barrier, shm_image::VulkanShmImage, @@ -22,6 +21,7 @@ use { }, rect::{Rect, Region}, utils::{clonecell::CloneCell, errorfmt::ErrorFmt}, + vulkan_core::fence::VulkanDeviceFenceExt, }, arrayvec::ArrayVec, ash::vk::{ diff --git a/src/vulkan_core.rs b/src/vulkan_core.rs index b9261c3b..23103819 100644 --- a/src/vulkan_core.rs +++ b/src/vulkan_core.rs @@ -25,6 +25,9 @@ use { uapi::{Ustr, ustr}, }; +pub mod device; +pub mod fence; + static VULKAN_ENTRY: Lazy>> = Lazy::new(|| unsafe { Entry::load() }.map_err(Arc::new)); @@ -45,6 +48,10 @@ pub enum VulkanCoreError { CreateInstance(#[source] vk::Result), #[error("Could not create a debug-utils messenger")] Messenger(#[source] vk::Result), + #[error("Could not create a fence")] + CreateFence(#[source] vk::Result), + #[error("Could not export a sync file from a semaphore")] + ExportSyncFile(#[source] vk::Result), } pub struct VulkanCoreInstance { diff --git a/src/vulkan_core/device.rs b/src/vulkan_core/device.rs new file mode 100644 index 00000000..69fed856 --- /dev/null +++ b/src/vulkan_core/device.rs @@ -0,0 +1,6 @@ +use ash::{Device, khr::external_fence_fd}; + +pub trait VulkanDeviceInf: Sized { + fn device(&self) -> &Device; + fn external_fence_fd(&self) -> &external_fence_fd::Device; +} diff --git a/src/gfx_apis/vulkan/fence.rs b/src/vulkan_core/fence.rs similarity index 51% rename from src/gfx_apis/vulkan/fence.rs rename to src/vulkan_core/fence.rs index ad0fde1e..324a8f01 100644 --- a/src/gfx_apis/vulkan/fence.rs +++ b/src/vulkan_core/fence.rs @@ -1,7 +1,7 @@ use { crate::{ gfx_api::SyncFile, - gfx_apis::vulkan::{VulkanError, device::VulkanDevice}, + vulkan_core::{VulkanCoreError, device::VulkanDeviceInf}, }, ash::vk::{ ExportFenceCreateInfo, ExternalFenceHandleTypeFlags, Fence, FenceCreateInfo, @@ -11,27 +11,40 @@ use { uapi::OwnedFd, }; -pub struct VulkanFence { - pub(super) device: Rc, - pub(super) fence: Fence, +pub struct VulkanFence +where + D: VulkanDeviceInf, +{ + pub device: Rc, + pub fence: Fence, } -impl Drop for VulkanFence { +pub trait VulkanDeviceFenceExt: VulkanDeviceInf { + fn create_fence(self: &Rc) -> Result>, VulkanCoreError>; +} + +impl Drop for VulkanFence +where + D: VulkanDeviceInf, +{ fn drop(&mut self) { unsafe { - self.device.device.destroy_fence(self.fence, None); + self.device.device().destroy_fence(self.fence, None); } } } -impl VulkanDevice { - pub fn create_fence(self: &Rc) -> Result, VulkanError> { +impl VulkanDeviceFenceExt for D +where + D: VulkanDeviceInf, +{ + fn create_fence(self: &Rc) -> Result>, VulkanCoreError> { let fence = { let mut export_info = ExportFenceCreateInfo::default() .handle_types(ExternalFenceHandleTypeFlags::SYNC_FD); let create_info = FenceCreateInfo::default().push_next(&mut export_info); - let fence = unsafe { self.device.create_fence(&create_info, None) }; - fence.map_err(VulkanError::CreateFence)? + let fence = unsafe { self.device().create_fence(&create_info, None) }; + fence.map_err(VulkanCoreError::CreateFence)? }; Ok(Rc::new(VulkanFence { device: self.clone(), @@ -40,13 +53,16 @@ impl VulkanDevice { } } -impl VulkanFence { - pub fn export_sync_file(&self) -> Result, VulkanError> { +impl VulkanFence +where + D: VulkanDeviceInf, +{ + pub fn export_sync_file(&self) -> Result, VulkanCoreError> { let info = FenceGetFdInfoKHR::default() .fence(self.fence) .handle_type(ExternalFenceHandleTypeFlags::SYNC_FD); - let res = unsafe { self.device.external_fence_fd.get_fence_fd(&info) }; - let fd = res.map_err(VulkanError::ExportSyncFile)?; + let res = unsafe { self.device.external_fence_fd().get_fence_fd(&info) }; + let fd = res.map_err(VulkanCoreError::ExportSyncFile)?; if fd == -1 { Ok(None) } else {