diff --git a/src/copy_device.rs b/src/copy_device.rs index 9313ed03..fe935e20 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, 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);