1
0
Fork 0
forked from wry/wry

vulkan: move fence to core

This commit is contained in:
Julian Orth 2026-03-02 10:45:14 +01:00
parent 7e6facf4e3
commit 3ecee1b17f
9 changed files with 89 additions and 91 deletions

View file

@ -14,7 +14,8 @@ use {
dmabuf::{DmaBuf, DmaBufIds, DmaBufPlane, PlaneVec}, dmabuf::{DmaBuf, DmaBufIds, DmaBufPlane, PlaneVec},
}, },
vulkan_core::{ 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}, ahash::{AHashMap, AHashSet},
@ -34,14 +35,13 @@ use {
CommandPoolCreateInfo, CopyBufferInfo2, CopyBufferToImageInfo2, CopyImageInfo2, CommandPoolCreateInfo, CopyBufferInfo2, CopyBufferToImageInfo2, CopyImageInfo2,
CopyImageToBufferInfo2, DependencyInfo, DeviceCreateInfo, DeviceMemory, CopyImageToBufferInfo2, DependencyInfo, DeviceCreateInfo, DeviceMemory,
DeviceQueueCreateInfo, DrmFormatModifierPropertiesEXT, DeviceQueueCreateInfo, DrmFormatModifierPropertiesEXT,
DrmFormatModifierPropertiesListEXT, ExportFenceCreateInfo, ExportMemoryAllocateInfo, DrmFormatModifierPropertiesListEXT, ExportMemoryAllocateInfo, Extent3D,
Extent3D, ExternalBufferProperties, ExternalFenceFeatureFlags, ExternalBufferProperties, ExternalFenceFeatureFlags, ExternalFenceHandleTypeFlags,
ExternalFenceHandleTypeFlags, ExternalFenceProperties, ExternalFenceProperties, ExternalImageFormatPropertiesKHR,
ExternalImageFormatPropertiesKHR, ExternalMemoryBufferCreateInfo, ExternalMemoryBufferCreateInfo, ExternalMemoryBufferCreateInfoKHR,
ExternalMemoryBufferCreateInfoKHR, ExternalMemoryFeatureFlags, ExternalMemoryFeatureFlags, ExternalMemoryHandleTypeFlags,
ExternalMemoryHandleTypeFlags, ExternalMemoryImageCreateInfo, ExternalMemoryImageCreateInfo, ExternalSemaphoreFeatureFlags,
ExternalSemaphoreFeatureFlags, ExternalSemaphoreHandleTypeFlags, ExternalSemaphoreHandleTypeFlags, ExternalSemaphoreProperties, Filter,
ExternalSemaphoreProperties, Fence, FenceCreateInfo, FenceGetFdInfoKHR, Filter,
FormatFeatureFlags, FormatProperties2, ImageAspectFlags, ImageBlit2, ImageCopy2, FormatFeatureFlags, FormatProperties2, ImageAspectFlags, ImageBlit2, ImageCopy2,
ImageCreateFlags, ImageCreateInfo, ImageDrmFormatModifierExplicitCreateInfoEXT, ImageCreateFlags, ImageCreateInfo, ImageDrmFormatModifierExplicitCreateInfoEXT,
ImageFormatProperties2, ImageLayout, ImageMemoryBarrier2, ImageMemoryRequirementsInfo2, ImageFormatProperties2, ImageLayout, ImageMemoryBarrier2, ImageMemoryRequirementsInfo2,
@ -84,16 +84,12 @@ pub enum CopyDeviceError {
Core(#[from] VulkanCoreError), Core(#[from] VulkanCoreError),
#[error("Could not create a semaphore")] #[error("Could not create a semaphore")]
CreateSemaphore(#[source] vk::Result), CreateSemaphore(#[source] vk::Result),
#[error("Could not create a fence")]
CreateFence(#[source] vk::Result),
#[error("Could not dup a sync file")] #[error("Could not dup a sync file")]
DupSyncFile(#[source] io::Error), DupSyncFile(#[source] io::Error),
#[error("Could not dup a dma buf")] #[error("Could not dup a dma buf")]
DupDmaBuf(#[source] io::Error), DupDmaBuf(#[source] io::Error),
#[error("Could not import a sync file")] #[error("Could not import a sync file")]
ImportSyncFile(#[source] vk::Result), ImportSyncFile(#[source] vk::Result),
#[error("Could not export a sync file")]
ExportSyncFile(#[source] vk::Result),
#[error("Could not submit the copy")] #[error("Could not submit the copy")]
SubmitCopy(#[source] vk::Result), SubmitCopy(#[source] vk::Result),
#[error("Could not enumerate the physical devices")] #[error("Could not enumerate the physical devices")]
@ -217,7 +213,7 @@ struct CopyDeviceInner {
external_fence_fd: external_fence_fd::Device, external_fence_fd: external_fence_fd::Device,
external_memory_fd: external_memory_fd::Device, external_memory_fd: external_memory_fd::Device,
semaphores: Stack<VulkanSemaphore>, semaphores: Stack<VulkanSemaphore>,
fences: Stack<VulkanFence>, fences: Stack<Rc<VulkanFence>>,
submissions: Keyed<Rc<PendingSubmissions>>, submissions: Keyed<Rc<PendingSubmissions>>,
} }
@ -276,7 +272,7 @@ struct Pending {
sync_file: Option<SyncFile>, sync_file: Option<SyncFile>,
copy: Rc<CopyDeviceCopyInner>, copy: Rc<CopyDeviceCopyInner>,
semaphore: Option<VulkanSemaphore>, semaphore: Option<VulkanSemaphore>,
fence: Option<VulkanFence>, fence: Option<Rc<VulkanFence>>,
} }
struct VulkanSemaphore { struct VulkanSemaphore {
@ -284,10 +280,7 @@ struct VulkanSemaphore {
semaphore: Semaphore, semaphore: Semaphore,
} }
struct VulkanFence { type VulkanFence = vulkan_core::fence::VulkanFence<CopyDeviceInner>;
dev: Rc<CopyDeviceInner>,
fence: Fence,
}
struct VulkanBuffer { struct VulkanBuffer {
dev: Rc<CopyDeviceInner>, dev: Rc<CopyDeviceInner>,
@ -1258,21 +1251,6 @@ impl CopyDeviceInner {
semaphore, semaphore,
}) })
} }
fn create_fence(self: &Rc<Self>) -> Result<VulkanFence, CopyDeviceError> {
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 { impl CopyDeviceCopy {
@ -1688,7 +1666,7 @@ impl CopyDeviceCopy {
) )
.map_err(CopyDeviceError::SubmitCopy)?; .map_err(CopyDeviceError::SubmitCopy)?;
} }
let sync_file = match signal_fence.export() { let sync_file = match signal_fence.export_sync_file() {
Ok(f) => f, Ok(f) => f,
Err(e) => { Err(e) => {
log::error!("Could not export signal fence: {}", ErrorFmt(e)); log::error!("Could not export signal fence: {}", ErrorFmt(e));
@ -1730,26 +1708,6 @@ impl VulkanSemaphore {
} }
} }
impl VulkanFence {
fn export(&self) -> Result<Option<SyncFile>, 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 { impl CopyDeviceRegistry {
pub fn new(ring: &Rc<IoUring>, eng: &Rc<AsyncEngine>) -> Self { pub fn new(ring: &Rc<IoUring>, eng: &Rc<AsyncEngine>) -> Self {
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 { impl Drop for CopyDeviceCopyInner {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
@ -2039,3 +1989,13 @@ fn allocate_queues(
}; };
(queues_to_allocate, queue_indices) (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
}
}

View file

@ -9,7 +9,6 @@ mod descriptor_buffer;
mod device; mod device;
mod dmabuf_buffer; mod dmabuf_buffer;
mod eotfs; mod eotfs;
mod fence;
mod format; mod format;
mod gpu_alloc_ash; mod gpu_alloc_ash;
mod image; mod image;
@ -35,7 +34,8 @@ use {
STAGING_DOWNLOAD, STAGING_UPLOAD, ShmGfxTexture, StagingBufferUsecase, STAGING_DOWNLOAD, STAGING_UPLOAD, ShmGfxTexture, StagingBufferUsecase,
}, },
gfx_apis::vulkan::{ gfx_apis::vulkan::{
image::VulkanImageMemory, instance::VulkanInstance, renderer::VulkanRenderer, device::VulkanDevice, image::VulkanImageMemory, instance::VulkanInstance,
renderer::VulkanRenderer,
}, },
io_uring::IoUring, io_uring::IoUring,
pr_caps::PrCapsThread, pr_caps::PrCapsThread,
@ -46,7 +46,7 @@ use {
drm::{Drm, DrmError, syncobj::SyncobjCtx}, drm::{Drm, DrmError, syncobj::SyncobjCtx},
gbm::GbmError, gbm::GbmError,
}, },
vulkan_core::VulkanCoreError, vulkan_core::{self, VulkanCoreError},
}, },
ahash::AHashMap, ahash::AHashMap,
ash::vk, ash::vk,
@ -73,8 +73,6 @@ pub enum VulkanError {
CreateDevice(#[source] vk::Result), CreateDevice(#[source] vk::Result),
#[error("Could not create a semaphore")] #[error("Could not create a semaphore")]
CreateSemaphore(#[source] vk::Result), CreateSemaphore(#[source] vk::Result),
#[error("Could not create a fence")]
CreateFence(#[source] vk::Result),
#[error("Could not create the buffer")] #[error("Could not create the buffer")]
CreateBuffer(#[source] vk::Result), CreateBuffer(#[source] vk::Result),
#[error("Could not create a shader module")] #[error("Could not create a shader module")]
@ -157,8 +155,6 @@ pub enum VulkanError {
IoctlExportSyncFile(#[source] OsError), IoctlExportSyncFile(#[source] OsError),
#[error("Could not import a sync file into a semaphore")] #[error("Could not import a sync file into a semaphore")]
ImportSyncFile(#[source] vk::Result), 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")] #[error("Could not fetch the render node of the device")]
FetchRenderNode(#[source] DrmError), FetchRenderNode(#[source] DrmError),
#[error("Device has no render node")] #[error("Device has no render node")]
@ -215,6 +211,8 @@ pub enum VulkanError {
DmaBufBufferOffsetAlignment, DmaBufBufferOffsetAlignment,
} }
type VulkanFence = vulkan_core::fence::VulkanFence<VulkanDevice>;
impl From<VulkanError> for GfxError { impl From<VulkanError> for GfxError {
fn from(value: VulkanError) -> Self { fn from(value: VulkanError) -> Self {
Self(Box::new(value)) Self(Box::new(value))

View file

@ -14,7 +14,8 @@ use {
gbm::{GBM_BO_USE_RENDERING, GbmDevice}, gbm::{GBM_BO_USE_RENDERING, GbmDevice},
}, },
vulkan_core::{ vulkan_core::{
ApiVersionDisplay, Extensions, VULKAN_API_VERSION, map_extension_properties, ApiVersionDisplay, Extensions, VULKAN_API_VERSION, device::VulkanDeviceInf,
map_extension_properties,
}, },
}, },
ahash::AHashMap, 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
}
}

View file

@ -12,7 +12,7 @@ use {
GfxFormat, GfxTexture, GfxWriteModifier, ReleaseSync, SyncFile, GfxFormat, GfxTexture, GfxWriteModifier, ReleaseSync, SyncFile,
}, },
gfx_apis::vulkan::{ gfx_apis::vulkan::{
VulkanError, VulkanError, VulkanFence,
allocator::{VulkanAllocator, VulkanThreadedAllocator}, allocator::{VulkanAllocator, VulkanThreadedAllocator},
buffer_cache::{GenericBufferWriter, VulkanBuffer, VulkanBufferCache}, buffer_cache::{GenericBufferWriter, VulkanBuffer, VulkanBufferCache},
command::{VulkanCommandBuffer, VulkanCommandPool}, command::{VulkanCommandBuffer, VulkanCommandPool},
@ -20,7 +20,6 @@ use {
descriptor_buffer::VulkanDescriptorBufferWriter, descriptor_buffer::VulkanDescriptorBufferWriter,
device::VulkanDevice, device::VulkanDevice,
eotfs::{EOTF_LINEAR, EotfExt, VulkanEotf}, eotfs::{EOTF_LINEAR, EotfExt, VulkanEotf},
fence::VulkanFence,
image::{QueueFamily, QueueState, QueueTransfer, VulkanImage, VulkanImageMemory}, image::{QueueFamily, QueueState, QueueTransfer, VulkanImage, VulkanImageMemory},
pipeline::{PipelineCreateInfo, VulkanPipeline}, pipeline::{PipelineCreateInfo, VulkanPipeline},
sampler::VulkanSampler, sampler::VulkanSampler,
@ -40,6 +39,7 @@ use {
stack::Stack, stack::Stack,
}, },
video::dmabuf::{DMA_BUF_SYNC_READ, DMA_BUF_SYNC_WRITE, dma_buf_export_sync_file}, video::dmabuf::{DMA_BUF_SYNC_READ, DMA_BUF_SYNC_WRITE, dma_buf_export_sync_file},
vulkan_core::fence::VulkanDeviceFenceExt,
}, },
ahash::AHashMap, ahash::AHashMap,
arrayvec::ArrayVec, arrayvec::ArrayVec,

View file

@ -4,10 +4,9 @@ use {
format::Format, format::Format,
gfx_api::SyncFile, gfx_api::SyncFile,
gfx_apis::vulkan::{ gfx_apis::vulkan::{
VulkanError, VulkanError, VulkanFence,
allocator::VulkanAllocation, allocator::VulkanAllocation,
command::VulkanCommandBuffer, command::VulkanCommandBuffer,
fence::VulkanFence,
image::{QueueFamily, QueueState, VulkanImage, VulkanImageMemory}, image::{QueueFamily, QueueState, VulkanImage, VulkanImageMemory},
renderer::{VulkanRenderer, image_barrier}, renderer::{VulkanRenderer, image_barrier},
staging::VulkanStagingBuffer, staging::VulkanStagingBuffer,
@ -15,6 +14,7 @@ use {
}, },
rect::Rect, rect::Rect,
utils::errorfmt::ErrorFmt, utils::errorfmt::ErrorFmt,
vulkan_core::fence::VulkanDeviceFenceExt,
}, },
ash::vk::{ ash::vk::{
AccessFlags2, Buffer, BufferImageCopy2, BufferMemoryBarrier2, CommandBufferBeginInfo, AccessFlags2, Buffer, BufferImageCopy2, BufferMemoryBarrier2, CommandBufferBeginInfo,

View file

@ -11,10 +11,9 @@ use {
AsyncShmGfxTextureCallback, PendingShmTransfer, ShmMemory, ShmMemoryBacking, SyncFile, AsyncShmGfxTextureCallback, PendingShmTransfer, ShmMemory, ShmMemoryBacking, SyncFile,
}, },
gfx_apis::vulkan::{ gfx_apis::vulkan::{
VulkanError, VulkanError, VulkanFence,
command::VulkanCommandBuffer, command::VulkanCommandBuffer,
dmabuf_buffer::{TRANSFER_QUEUE_BUFFER_ALIGNMENT, VulkanDmabufBuffer}, dmabuf_buffer::{TRANSFER_QUEUE_BUFFER_ALIGNMENT, VulkanDmabufBuffer},
fence::VulkanFence,
image::{QueueFamily, QueueState, QueueTransfer, VulkanImage, VulkanImageMemory}, image::{QueueFamily, QueueState, QueueTransfer, VulkanImage, VulkanImageMemory},
renderer::image_barrier, renderer::image_barrier,
shm_image::VulkanShmImage, shm_image::VulkanShmImage,
@ -22,6 +21,7 @@ use {
}, },
rect::{Rect, Region}, rect::{Rect, Region},
utils::{clonecell::CloneCell, errorfmt::ErrorFmt}, utils::{clonecell::CloneCell, errorfmt::ErrorFmt},
vulkan_core::fence::VulkanDeviceFenceExt,
}, },
arrayvec::ArrayVec, arrayvec::ArrayVec,
ash::vk::{ ash::vk::{

View file

@ -25,6 +25,9 @@ use {
uapi::{Ustr, ustr}, uapi::{Ustr, ustr},
}; };
pub mod device;
pub mod fence;
static VULKAN_ENTRY: Lazy<Result<Entry, Arc<LoadingError>>> = static VULKAN_ENTRY: Lazy<Result<Entry, Arc<LoadingError>>> =
Lazy::new(|| unsafe { Entry::load() }.map_err(Arc::new)); Lazy::new(|| unsafe { Entry::load() }.map_err(Arc::new));
@ -45,6 +48,10 @@ pub enum VulkanCoreError {
CreateInstance(#[source] vk::Result), CreateInstance(#[source] vk::Result),
#[error("Could not create a debug-utils messenger")] #[error("Could not create a debug-utils messenger")]
Messenger(#[source] vk::Result), 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 { pub struct VulkanCoreInstance {

View file

@ -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;
}

View file

@ -1,7 +1,7 @@
use { use {
crate::{ crate::{
gfx_api::SyncFile, gfx_api::SyncFile,
gfx_apis::vulkan::{VulkanError, device::VulkanDevice}, vulkan_core::{VulkanCoreError, device::VulkanDeviceInf},
}, },
ash::vk::{ ash::vk::{
ExportFenceCreateInfo, ExternalFenceHandleTypeFlags, Fence, FenceCreateInfo, ExportFenceCreateInfo, ExternalFenceHandleTypeFlags, Fence, FenceCreateInfo,
@ -11,27 +11,40 @@ use {
uapi::OwnedFd, uapi::OwnedFd,
}; };
pub struct VulkanFence { pub struct VulkanFence<D>
pub(super) device: Rc<VulkanDevice>, where
pub(super) fence: Fence, D: VulkanDeviceInf,
{
pub device: Rc<D>,
pub fence: Fence,
} }
impl Drop for VulkanFence { pub trait VulkanDeviceFenceExt: VulkanDeviceInf {
fn create_fence(self: &Rc<Self>) -> Result<Rc<VulkanFence<Self>>, VulkanCoreError>;
}
impl<D> Drop for VulkanFence<D>
where
D: VulkanDeviceInf,
{
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
self.device.device.destroy_fence(self.fence, None); self.device.device().destroy_fence(self.fence, None);
} }
} }
} }
impl VulkanDevice { impl<D> VulkanDeviceFenceExt for D
pub fn create_fence(self: &Rc<Self>) -> Result<Rc<VulkanFence>, VulkanError> { where
D: VulkanDeviceInf,
{
fn create_fence(self: &Rc<Self>) -> Result<Rc<VulkanFence<Self>>, VulkanCoreError> {
let fence = { let fence = {
let mut export_info = ExportFenceCreateInfo::default() let mut export_info = ExportFenceCreateInfo::default()
.handle_types(ExternalFenceHandleTypeFlags::SYNC_FD); .handle_types(ExternalFenceHandleTypeFlags::SYNC_FD);
let create_info = FenceCreateInfo::default().push_next(&mut export_info); let create_info = FenceCreateInfo::default().push_next(&mut export_info);
let fence = unsafe { self.device.create_fence(&create_info, None) }; let fence = unsafe { self.device().create_fence(&create_info, None) };
fence.map_err(VulkanError::CreateFence)? fence.map_err(VulkanCoreError::CreateFence)?
}; };
Ok(Rc::new(VulkanFence { Ok(Rc::new(VulkanFence {
device: self.clone(), device: self.clone(),
@ -40,13 +53,16 @@ impl VulkanDevice {
} }
} }
impl VulkanFence { impl<D> VulkanFence<D>
pub fn export_sync_file(&self) -> Result<Option<SyncFile>, VulkanError> { where
D: VulkanDeviceInf,
{
pub fn export_sync_file(&self) -> Result<Option<SyncFile>, VulkanCoreError> {
let info = FenceGetFdInfoKHR::default() let info = FenceGetFdInfoKHR::default()
.fence(self.fence) .fence(self.fence)
.handle_type(ExternalFenceHandleTypeFlags::SYNC_FD); .handle_type(ExternalFenceHandleTypeFlags::SYNC_FD);
let res = unsafe { self.device.external_fence_fd.get_fence_fd(&info) }; let res = unsafe { self.device.external_fence_fd().get_fence_fd(&info) };
let fd = res.map_err(VulkanError::ExportSyncFile)?; let fd = res.map_err(VulkanCoreError::ExportSyncFile)?;
if fd == -1 { if fd == -1 {
Ok(None) Ok(None)
} else { } else {