1
0
Fork 0
forked from wry/wry

Merge pull request #788 from mahkoh/jorth/refactorings

Various sync refactorings
This commit is contained in:
mahkoh 2026-03-11 12:07:23 +01:00 committed by GitHub
commit 67554f1213
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 43 additions and 33 deletions

View file

@ -8,12 +8,12 @@ use {
rect::{Rect, Region}, rect::{Rect, Region},
utils::{ utils::{
clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell, clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell,
oserror::OsError, queue::AsyncQueue, stack::Stack, queue::AsyncQueue, stack::Stack,
}, },
video::{ video::{
LINEAR_MODIFIER, LINEAR_STRIDE_ALIGN, Modifier, LINEAR_MODIFIER, LINEAR_STRIDE_ALIGN, Modifier,
dmabuf::{DmaBuf, DmaBufIds, DmaBufPlane, PlaneVec}, dmabuf::{DmaBuf, DmaBufIds, DmaBufPlane, PlaneVec},
drm::{NodeType, get_drm_nodes_from_dev, syncobj::SyncobjCtx}, drm::{DrmError, syncobj::SyncobjCtx},
}, },
vulkan_core::{ vulkan_core::{
self, VULKAN_API_VERSION, VulkanCoreError, VulkanCoreInstance, device::VulkanDeviceInf, self, VULKAN_API_VERSION, VulkanCoreError, VulkanCoreInstance, device::VulkanDeviceInf,
@ -166,12 +166,8 @@ pub enum CopyDeviceError {
BothOffDevice, BothOffDevice,
#[error("Cannot blit between these formats")] #[error("Cannot blit between these formats")]
BlitNotSupported, BlitNotSupported,
#[error("Could not get DRM nodes")] #[error("Could not create syncobj ctx")]
GetDrmNodes(#[source] OsError), CreateSyncobjCtx(#[source] DrmError),
#[error("Device has no device nodes")]
NoDeviceNodes,
#[error("Could not open device node")]
OpenDeviceNode(#[source] OsError),
} }
type Keyed<T> = StaticMap<TransferType, T>; type Keyed<T> = StaticMap<TransferType, T>;
@ -422,16 +418,9 @@ impl PhysicalCopyDevice {
} }
return Err(CopyDeviceError::NoVulkanDevice); return Err(CopyDeviceError::NoVulkanDevice);
} }
let nodes = get_drm_nodes_from_dev(uapi::major(dev), uapi::minor(dev)) let sync_ctx = SyncobjCtx::from_dev_t(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)
.map(Rc::new) .map(Rc::new)
.map_err(Into::into) .map_err(CopyDeviceError::CreateSyncobjCtx)?;
.map_err(CopyDeviceError::OpenDeviceNode)?;
if device_properties.api_version < VULKAN_API_VERSION { if device_properties.api_version < VULKAN_API_VERSION {
return Err(CopyDeviceError::NoVulkan13); return Err(CopyDeviceError::NoVulkan13);
} }
@ -641,7 +630,7 @@ impl PhysicalCopyDevice {
ring: ring.clone(), ring: ring.clone(),
eng: eng.clone(), eng: eng.clone(),
eventfd_cache: eventfd_cache.clone(), eventfd_cache: eventfd_cache.clone(),
sync_ctx: Rc::new(SyncobjCtx::new(&device_fd)), sync_ctx,
instance: core_instance, instance: core_instance,
physical_device, physical_device,
support, support,
@ -2048,8 +2037,8 @@ impl VulkanDeviceInf for CopyDeviceInner {
self.phy.supports_timeline_opaque_export self.phy.supports_timeline_opaque_export
} }
fn sync_ctx(&self) -> &Rc<SyncobjCtx> { fn sync_ctx(&self) -> Option<&Rc<SyncobjCtx>> {
&self.phy.sync_ctx Some(&self.phy.sync_ctx)
} }
fn eventfd_cache(&self) -> &Rc<EventfdCache> { fn eventfd_cache(&self) -> &Rc<EventfdCache> {

View file

@ -671,8 +671,8 @@ impl VulkanDeviceInf for VulkanDevice {
self.supports_timeline_opaque_export self.supports_timeline_opaque_export
} }
fn sync_ctx(&self) -> &Rc<SyncobjCtx> { fn sync_ctx(&self) -> Option<&Rc<SyncobjCtx>> {
&self.sync_ctx Some(&self.sync_ctx)
} }
fn eventfd_cache(&self) -> &Rc<EventfdCache> { fn eventfd_cache(&self) -> &Rc<EventfdCache> {

View file

@ -151,6 +151,8 @@ pub enum DrmError {
QueueSequence(#[source] OsError), QueueSequence(#[source] OsError),
#[error("Could not stat the DRM fd")] #[error("Could not stat the DRM fd")]
Stat(#[source] OsError), Stat(#[source] OsError),
#[error("Device has no device nodes")]
NoDeviceNodes,
} }
fn render_node_name(fd: c::c_int) -> Result<Ustring, DrmError> { fn render_node_name(fd: c::c_int) -> Result<Ustring, DrmError> {

View file

@ -10,7 +10,7 @@ use {
oserror::OsError, oserror::OsError,
}, },
video::drm::{ video::drm::{
DrmError, DrmError, NodeType, get_drm_nodes_from_dev,
sys::{ sys::{
DRM_SYNCOBJ_CREATE_SIGNALED, DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE, DRM_SYNCOBJ_CREATE_SIGNALED, DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE,
DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_TIMELINE, DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_TIMELINE,
@ -107,6 +107,20 @@ impl SyncobjCtx {
} }
} }
pub fn from_dev_t(dev: c::dev_t) -> Result<Self, DrmError> {
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<SyncobjHandle, DrmError> { fn get_handle(&self, syncobj: &Syncobj) -> Result<SyncobjHandle, DrmError> {
if let Some(handle) = self.inner.handles.get(&syncobj.id) { if let Some(handle) = self.inner.handles.get(&syncobj.id) {
return Ok(handle); return Ok(handle);

View file

@ -76,6 +76,8 @@ pub enum VulkanCoreError {
AcquireEventfd(#[source] EventfdError), AcquireEventfd(#[source] EventfdError),
#[error("Could not create a sync obj eventfd wait")] #[error("Could not create a sync obj eventfd wait")]
CreateSyncobjWait(#[source] DrmError), CreateSyncobjWait(#[source] DrmError),
#[error("Device does not have a syncobj ctx")]
NoSyncobjCtx,
} }
pub struct VulkanCoreInstance { pub struct VulkanCoreInstance {

View file

@ -16,6 +16,6 @@ pub trait VulkanDeviceInf: Sized {
fn external_fence_fd(&self) -> &external_fence_fd::Device; fn external_fence_fd(&self) -> &external_fence_fd::Device;
fn external_semaphore_fd(&self) -> &external_semaphore_fd::Device; fn external_semaphore_fd(&self) -> &external_semaphore_fd::Device;
fn supports_timeline_opaque_export(&self) -> bool; fn supports_timeline_opaque_export(&self) -> bool;
fn sync_ctx(&self) -> &Rc<SyncobjCtx>; fn sync_ctx(&self) -> Option<&Rc<SyncobjCtx>>;
fn eventfd_cache(&self) -> &Rc<EventfdCache>; fn eventfd_cache(&self) -> &Rc<EventfdCache>;
} }

View file

@ -113,12 +113,11 @@ where
.eventfd_cache() .eventfd_cache()
.acquire() .acquire()
.map_err(VulkanCoreError::AcquireEventfd)?; .map_err(VulkanCoreError::AcquireEventfd)?;
device tls.sync_ctx
.sync_ctx()
.wait_for_point(&eventfd.fd, &tls.syncobj, point, true) .wait_for_point(&eventfd.fd, &tls.syncobj, point, true)
.map_err(VulkanCoreError::CreateSyncobjWait)?; .map_err(VulkanCoreError::CreateSyncobjWait)?;
let pending = Rc::new(ReservedSyncobjPoint { let pending = Rc::new(ReservedSyncobjPoint {
ctx: device.sync_ctx().clone(), ctx: tls.sync_ctx.clone(),
syncobj: tls.syncobj.clone(), syncobj: tls.syncobj.clone(),
point, point,
sync_file: Default::default(), sync_file: Default::default(),

View file

@ -1,7 +1,7 @@
use { use {
crate::{ crate::{
utils::{errorfmt::ErrorFmt, numcell::NumCell}, utils::{errorfmt::ErrorFmt, numcell::NumCell},
video::drm::syncobj::Syncobj, video::drm::syncobj::{Syncobj, SyncobjCtx},
vulkan_core::{VulkanCoreError, device::VulkanDeviceInf}, vulkan_core::{VulkanCoreError, device::VulkanDeviceInf},
}, },
ash::vk::{ ash::vk::{
@ -20,6 +20,7 @@ where
{ {
pub(super) device: Rc<D>, pub(super) device: Rc<D>,
pub(super) semaphore: Semaphore, pub(super) semaphore: Semaphore,
pub(super) sync_ctx: Rc<SyncobjCtx>,
pub(super) syncobj: Rc<Syncobj>, pub(super) syncobj: Rc<Syncobj>,
pub(super) next_point: NumCell<u64>, pub(super) next_point: NumCell<u64>,
} }
@ -55,6 +56,9 @@ where
if !self.supports_timeline_opaque_export() { if !self.supports_timeline_opaque_export() {
return Err(VulkanCoreError::TimelineExportNotSupported); return Err(VulkanCoreError::TimelineExportNotSupported);
} }
let Some(sync_ctx) = self.sync_ctx() else {
return Err(VulkanCoreError::NoSyncobjCtx);
};
let sem = { let sem = {
let mut export_info = ExportSemaphoreCreateInfo::default() let mut export_info = ExportSemaphoreCreateInfo::default()
.handle_types(ExternalSemaphoreHandleTypeFlags::OPAQUE_FD); .handle_types(ExternalSemaphoreHandleTypeFlags::OPAQUE_FD);
@ -87,8 +91,7 @@ where
for _ in 0..2 { for _ in 0..2 {
let n = next_point.fetch_add(1); let n = next_point.fetch_add(1);
signal(n)?; signal(n)?;
let signaled = self let signaled = sync_ctx
.sync_ctx()
.query_last_signaled(&syncobj) .query_last_signaled(&syncobj)
.map_err(VulkanCoreError::QueryLastSignaled)?; .map_err(VulkanCoreError::QueryLastSignaled)?;
if signaled != n { if signaled != n {
@ -99,6 +102,7 @@ where
Ok(Rc::new(VulkanTimelineSemaphore { Ok(Rc::new(VulkanTimelineSemaphore {
device: self.clone(), device: self.clone(),
semaphore: sem, semaphore: sem,
sync_ctx: sync_ctx.clone(),
syncobj: Rc::new(syncobj), syncobj: Rc::new(syncobj),
next_point, next_point,
})) }))

View file

@ -1,6 +1,6 @@
use { use {
crate::{ crate::{
gfx_api::SyncFile, gfx_api::FdSync,
object::Version, object::Version,
wire::{JaySyncFileSurfaceId, jay_sync_file_surface::*}, wire::{JaySyncFileSurfaceId, jay_sync_file_surface::*},
wl_usr::{ wl_usr::{
@ -19,8 +19,8 @@ pub struct UsrJaySyncFileSurface {
impl UsrJaySyncFileSurface { impl UsrJaySyncFileSurface {
#[expect(dead_code)] #[expect(dead_code)]
pub fn set_acquire(&self, sf: Option<&SyncFile>) { pub fn set_acquire(&self, sf: Option<&FdSync>) {
match sf { match sf.and_then(|s| s.get_sync_file()) {
None => { None => {
self.con.request(SetAcquireImmediate { self_id: self.id }); self.con.request(SetAcquireImmediate { self_id: self.id });
} }