diff options
Diffstat (limited to 'src/syncobj.rs')
-rw-r--r-- | src/syncobj.rs | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/src/syncobj.rs b/src/syncobj.rs new file mode 100644 index 0000000..6cb45a9 --- /dev/null +++ b/src/syncobj.rs @@ -0,0 +1,264 @@ +//! +//! Bindings for DRM sync objects +//! + +use crate::ioctl; +use drm_sys::*; + +use std::{ + io, + os::unix::io::{AsRawFd, BorrowedFd}, +}; + +/// Creates a syncobj. +pub fn create(fd: BorrowedFd<'_>, signaled: bool) -> io::Result<drm_syncobj_create> { + let mut args = drm_syncobj_create { + handle: 0, + flags: if signaled { + DRM_SYNCOBJ_CREATE_SIGNALED + } else { + 0 + }, + }; + + unsafe { + ioctl::syncobj::create(fd, &mut args)?; + } + + Ok(args) +} + +/// Destroys a syncobj. +pub fn destroy(fd: BorrowedFd<'_>, handle: u32) -> io::Result<drm_syncobj_destroy> { + let mut args = drm_syncobj_destroy { handle, pad: 0 }; + + unsafe { + ioctl::syncobj::destroy(fd, &mut args)?; + } + + Ok(args) +} + +/// Exports a syncobj as an inter-process file descriptor or as a poll()-able sync file. +pub fn handle_to_fd( + fd: BorrowedFd<'_>, + handle: u32, + export_sync_file: bool, +) -> io::Result<drm_syncobj_handle> { + let mut args = drm_syncobj_handle { + handle, + flags: if export_sync_file { + DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE + } else { + 0 + }, + fd: 0, + pad: 0, + }; + + unsafe { + ioctl::syncobj::handle_to_fd(fd, &mut args)?; + } + + Ok(args) +} + +/// Imports a file descriptor exported by [`handle_to_fd`] back into a process-local handle. +pub fn fd_to_handle( + fd: BorrowedFd<'_>, + syncobj_fd: BorrowedFd<'_>, + import_sync_file: bool, +) -> io::Result<drm_syncobj_handle> { + let mut args = drm_syncobj_handle { + handle: 0, + flags: if import_sync_file { + DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE + } else { + 0 + }, + fd: syncobj_fd.as_raw_fd(), + pad: 0, + }; + + unsafe { + ioctl::syncobj::fd_to_handle(fd, &mut args)?; + } + + Ok(args) +} + +/// Waits for one or more syncobjs to become signalled. +pub fn wait( + fd: BorrowedFd<'_>, + handles: &[u32], + timeout_nsec: i64, + wait_all: bool, + wait_for_submit: bool, +) -> io::Result<drm_syncobj_wait> { + let mut args = drm_syncobj_wait { + handles: handles.as_ptr() as _, + timeout_nsec, + count_handles: handles.len() as _, + flags: if wait_all { + DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL + } else { + 0 + } | if wait_for_submit { + DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT + } else { + 0 + }, + first_signaled: 0, + pad: 0, + }; + + unsafe { + ioctl::syncobj::wait(fd, &mut args)?; + } + + Ok(args) +} + +/// Resets (un-signals) one or more syncobjs. +pub fn reset(fd: BorrowedFd<'_>, handles: &[u32]) -> io::Result<drm_syncobj_array> { + let mut args = drm_syncobj_array { + handles: handles.as_ptr() as _, + count_handles: handles.len() as _, + pad: 0, + }; + + unsafe { + ioctl::syncobj::reset(fd, &mut args)?; + } + + Ok(args) +} + +/// Signals one or more syncobjs. +pub fn signal(fd: BorrowedFd<'_>, handles: &[u32]) -> io::Result<drm_syncobj_array> { + let mut args = drm_syncobj_array { + handles: handles.as_ptr() as _, + count_handles: handles.len() as _, + pad: 0, + }; + + unsafe { + ioctl::syncobj::signal(fd, &mut args)?; + } + + Ok(args) +} + +/// Waits for one or more specific timeline syncobj points. +pub fn timeline_wait( + fd: BorrowedFd<'_>, + handles: &[u32], + points: &[u64], + timeout_nsec: i64, + wait_all: bool, + wait_for_submit: bool, + wait_available: bool, +) -> io::Result<drm_syncobj_timeline_wait> { + debug_assert_eq!(handles.len(), points.len()); + + let mut args = drm_syncobj_timeline_wait { + handles: handles.as_ptr() as _, + points: points.as_ptr() as _, + timeout_nsec, + count_handles: handles.len() as _, + flags: if wait_all { + DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL + } else { + 0 + } | if wait_for_submit { + DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT + } else { + 0 + } | if wait_available { + DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE + } else { + 0 + }, + first_signaled: 0, + pad: 0, + }; + + unsafe { + ioctl::syncobj::timeline_wait(fd, &mut args)?; + } + + Ok(args) +} + +/// Queries for state of one or more timeline syncobjs. +pub fn query( + fd: BorrowedFd<'_>, + handles: &[u32], + points: &mut [u64], + last_submitted: bool, +) -> io::Result<drm_syncobj_timeline_array> { + debug_assert_eq!(handles.len(), points.len()); + + let mut args = drm_syncobj_timeline_array { + handles: handles.as_ptr() as _, + points: points.as_mut_ptr() as _, + count_handles: handles.len() as _, + flags: if last_submitted { + DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED + } else { + 0 + }, + }; + + unsafe { + ioctl::syncobj::query(fd, &mut args)?; + } + + Ok(args) +} + +/// Transfers one timeline syncobj point to another. +pub fn transfer( + fd: BorrowedFd<'_>, + src_handle: u32, + dst_handle: u32, + src_point: u64, + dst_point: u64, +) -> io::Result<drm_syncobj_transfer> { + let mut args = drm_syncobj_transfer { + src_handle, + dst_handle, + src_point, + dst_point, + flags: 0, + pad: 0, + }; + + unsafe { + ioctl::syncobj::transfer(fd, &mut args)?; + } + + Ok(args) +} + +/// Signals one or more specific timeline syncobj points. +pub fn timeline_signal( + fd: BorrowedFd<'_>, + handles: &[u32], + points: &[u64], +) -> io::Result<drm_syncobj_timeline_array> { + debug_assert_eq!(handles.len(), points.len()); + + let mut args = drm_syncobj_timeline_array { + handles: handles.as_ptr() as _, + points: points.as_ptr() as _, + count_handles: handles.len() as _, + flags: 0, + }; + + unsafe { + ioctl::syncobj::timeline_signal(fd, &mut args)?; + } + + Ok(args) +} |