diff --git a/src/copy_device.rs b/src/copy_device.rs index 9313ed03..6ab005cc 100644 --- a/src/copy_device.rs +++ b/src/copy_device.rs @@ -8,12 +8,12 @@ use { rect::{Rect, Region}, utils::{ clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell, - oserror::OsError, queue::AsyncQueue, stack::Stack, + queue::AsyncQueue, stack::Stack, }, video::{ LINEAR_MODIFIER, LINEAR_STRIDE_ALIGN, Modifier, dmabuf::{DmaBuf, DmaBufIds, DmaBufPlane, PlaneVec}, - drm::{NodeType, get_drm_nodes_from_dev, syncobj::SyncobjCtx}, + drm::{DrmError, syncobj::SyncobjCtx}, }, vulkan_core::{ self, VULKAN_API_VERSION, VulkanCoreError, VulkanCoreInstance, device::VulkanDeviceInf, @@ -166,12 +166,8 @@ pub enum CopyDeviceError { BothOffDevice, #[error("Cannot blit between these formats")] BlitNotSupported, - #[error("Could not get DRM nodes")] - GetDrmNodes(#[source] OsError), - #[error("Device has no device nodes")] - NoDeviceNodes, - #[error("Could not open device node")] - OpenDeviceNode(#[source] OsError), + #[error("Could not create syncobj ctx")] + CreateSyncobjCtx(#[source] DrmError), } type Keyed = StaticMap; @@ -422,16 +418,9 @@ impl PhysicalCopyDevice { } return Err(CopyDeviceError::NoVulkanDevice); } - let nodes = get_drm_nodes_from_dev(uapi::major(dev), uapi::minor(dev)) - .map_err(CopyDeviceError::GetDrmNodes)?; - let path = nodes - .get(&NodeType::Render) - .or_else(|| nodes.get(&NodeType::Primary)) - .ok_or(CopyDeviceError::NoDeviceNodes)?; - let device_fd = uapi::open(path.as_c_str(), c::O_RDWR, 0) + let sync_ctx = SyncobjCtx::from_dev_t(dev) .map(Rc::new) - .map_err(Into::into) - .map_err(CopyDeviceError::OpenDeviceNode)?; + .map_err(CopyDeviceError::CreateSyncobjCtx)?; if device_properties.api_version < VULKAN_API_VERSION { return Err(CopyDeviceError::NoVulkan13); } @@ -641,7 +630,7 @@ impl PhysicalCopyDevice { ring: ring.clone(), eng: eng.clone(), eventfd_cache: eventfd_cache.clone(), - sync_ctx: Rc::new(SyncobjCtx::new(&device_fd)), + sync_ctx, instance: core_instance, physical_device, support, @@ -2048,8 +2037,8 @@ impl VulkanDeviceInf for CopyDeviceInner { self.phy.supports_timeline_opaque_export } - fn sync_ctx(&self) -> &Rc { - &self.phy.sync_ctx + fn sync_ctx(&self) -> Option<&Rc> { + Some(&self.phy.sync_ctx) } fn eventfd_cache(&self) -> &Rc { diff --git a/src/gfx_apis/vulkan/device.rs b/src/gfx_apis/vulkan/device.rs index f65e8e06..afd159cc 100644 --- a/src/gfx_apis/vulkan/device.rs +++ b/src/gfx_apis/vulkan/device.rs @@ -671,8 +671,8 @@ impl VulkanDeviceInf for VulkanDevice { self.supports_timeline_opaque_export } - fn sync_ctx(&self) -> &Rc { - &self.sync_ctx + fn sync_ctx(&self) -> Option<&Rc> { + Some(&self.sync_ctx) } fn eventfd_cache(&self) -> &Rc { diff --git a/src/video/drm.rs b/src/video/drm.rs index f70b5497..a4396d08 100644 --- a/src/video/drm.rs +++ b/src/video/drm.rs @@ -151,6 +151,8 @@ pub enum DrmError { QueueSequence(#[source] OsError), #[error("Could not stat the DRM fd")] Stat(#[source] OsError), + #[error("Device has no device nodes")] + NoDeviceNodes, } fn render_node_name(fd: c::c_int) -> Result { diff --git a/src/video/drm/syncobj.rs b/src/video/drm/syncobj.rs index 23529748..d6887dc3 100644 --- a/src/video/drm/syncobj.rs +++ b/src/video/drm/syncobj.rs @@ -10,7 +10,7 @@ use { oserror::OsError, }, video::drm::{ - DrmError, + DrmError, NodeType, get_drm_nodes_from_dev, sys::{ DRM_SYNCOBJ_CREATE_SIGNALED, DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE, DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_TIMELINE, @@ -107,6 +107,20 @@ impl SyncobjCtx { } } + pub fn from_dev_t(dev: c::dev_t) -> Result { + let nodes = get_drm_nodes_from_dev(uapi::major(dev), uapi::minor(dev)) + .map_err(DrmError::GetNodes)?; + let path = nodes + .get(&NodeType::Render) + .or_else(|| nodes.get(&NodeType::Primary)) + .ok_or(DrmError::NoDeviceNodes)?; + let device_fd = uapi::open(path.as_c_str(), c::O_RDWR | c::O_CLOEXEC, 0) + .map(Rc::new) + .map_err(Into::into) + .map_err(DrmError::ReopenNode)?; + Ok(Self::new(&device_fd)) + } + fn get_handle(&self, syncobj: &Syncobj) -> Result { if let Some(handle) = self.inner.handles.get(&syncobj.id) { return Ok(handle); diff --git a/src/vulkan_core.rs b/src/vulkan_core.rs index 00dac433..546e820d 100644 --- a/src/vulkan_core.rs +++ b/src/vulkan_core.rs @@ -76,6 +76,8 @@ pub enum VulkanCoreError { AcquireEventfd(#[source] EventfdError), #[error("Could not create a sync obj eventfd wait")] CreateSyncobjWait(#[source] DrmError), + #[error("Device does not have a syncobj ctx")] + NoSyncobjCtx, } pub struct VulkanCoreInstance { diff --git a/src/vulkan_core/device.rs b/src/vulkan_core/device.rs index ab4ceb1a..83a4c73f 100644 --- a/src/vulkan_core/device.rs +++ b/src/vulkan_core/device.rs @@ -16,6 +16,6 @@ pub trait VulkanDeviceInf: Sized { fn external_fence_fd(&self) -> &external_fence_fd::Device; fn external_semaphore_fd(&self) -> &external_semaphore_fd::Device; fn supports_timeline_opaque_export(&self) -> bool; - fn sync_ctx(&self) -> &Rc; + fn sync_ctx(&self) -> Option<&Rc>; fn eventfd_cache(&self) -> &Rc; } diff --git a/src/vulkan_core/sync.rs b/src/vulkan_core/sync.rs index aaa7e317..e78d88c2 100644 --- a/src/vulkan_core/sync.rs +++ b/src/vulkan_core/sync.rs @@ -113,12 +113,11 @@ where .eventfd_cache() .acquire() .map_err(VulkanCoreError::AcquireEventfd)?; - device - .sync_ctx() + tls.sync_ctx .wait_for_point(&eventfd.fd, &tls.syncobj, point, true) .map_err(VulkanCoreError::CreateSyncobjWait)?; let pending = Rc::new(ReservedSyncobjPoint { - ctx: device.sync_ctx().clone(), + ctx: tls.sync_ctx.clone(), syncobj: tls.syncobj.clone(), point, sync_file: Default::default(), diff --git a/src/vulkan_core/timeline_semaphore.rs b/src/vulkan_core/timeline_semaphore.rs index 7f46c689..63340578 100644 --- a/src/vulkan_core/timeline_semaphore.rs +++ b/src/vulkan_core/timeline_semaphore.rs @@ -1,7 +1,7 @@ use { crate::{ utils::{errorfmt::ErrorFmt, numcell::NumCell}, - video::drm::syncobj::Syncobj, + video::drm::syncobj::{Syncobj, SyncobjCtx}, vulkan_core::{VulkanCoreError, device::VulkanDeviceInf}, }, ash::vk::{ @@ -20,6 +20,7 @@ where { pub(super) device: Rc, pub(super) semaphore: Semaphore, + pub(super) sync_ctx: Rc, pub(super) syncobj: Rc, pub(super) next_point: NumCell, } @@ -55,6 +56,9 @@ where if !self.supports_timeline_opaque_export() { return Err(VulkanCoreError::TimelineExportNotSupported); } + let Some(sync_ctx) = self.sync_ctx() else { + return Err(VulkanCoreError::NoSyncobjCtx); + }; let sem = { let mut export_info = ExportSemaphoreCreateInfo::default() .handle_types(ExternalSemaphoreHandleTypeFlags::OPAQUE_FD); @@ -87,8 +91,7 @@ where for _ in 0..2 { let n = next_point.fetch_add(1); signal(n)?; - let signaled = self - .sync_ctx() + let signaled = sync_ctx .query_last_signaled(&syncobj) .map_err(VulkanCoreError::QueryLastSignaled)?; if signaled != n { @@ -99,6 +102,7 @@ where Ok(Rc::new(VulkanTimelineSemaphore { device: self.clone(), semaphore: sem, + sync_ctx: sync_ctx.clone(), syncobj: Rc::new(syncobj), next_point, })) diff --git a/src/wl_usr/usr_ifs/usr_jay_sync_file_surface.rs b/src/wl_usr/usr_ifs/usr_jay_sync_file_surface.rs index 533cfdf2..8aa184f4 100644 --- a/src/wl_usr/usr_ifs/usr_jay_sync_file_surface.rs +++ b/src/wl_usr/usr_ifs/usr_jay_sync_file_surface.rs @@ -1,6 +1,6 @@ use { crate::{ - gfx_api::SyncFile, + gfx_api::FdSync, object::Version, wire::{JaySyncFileSurfaceId, jay_sync_file_surface::*}, wl_usr::{ @@ -19,8 +19,8 @@ pub struct UsrJaySyncFileSurface { impl UsrJaySyncFileSurface { #[expect(dead_code)] - pub fn set_acquire(&self, sf: Option<&SyncFile>) { - match sf { + pub fn set_acquire(&self, sf: Option<&FdSync>) { + match sf.and_then(|s| s.get_sync_file()) { None => { self.con.request(SetAcquireImmediate { self_id: self.id }); }