summaryrefslogtreecommitdiff
path: root/src/syncobj.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/syncobj.rs')
-rw-r--r--src/syncobj.rs264
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)
+}