drm_ffi/
syncobj.rs

1//!
2//! Bindings for DRM sync objects
3//!
4
5use crate::ioctl;
6use drm_sys::*;
7
8use std::{
9    io,
10    os::unix::io::{AsRawFd, BorrowedFd},
11};
12
13/// Creates a syncobj.
14pub fn create(fd: BorrowedFd<'_>, signaled: bool) -> io::Result<drm_syncobj_create> {
15    let mut args = drm_syncobj_create {
16        handle: 0,
17        flags: if signaled {
18            DRM_SYNCOBJ_CREATE_SIGNALED
19        } else {
20            0
21        },
22    };
23
24    unsafe {
25        ioctl::syncobj::create(fd, &mut args)?;
26    }
27
28    Ok(args)
29}
30
31/// Destroys a syncobj.
32pub fn destroy(fd: BorrowedFd<'_>, handle: u32) -> io::Result<drm_syncobj_destroy> {
33    let mut args = drm_syncobj_destroy { handle, pad: 0 };
34
35    unsafe {
36        ioctl::syncobj::destroy(fd, &mut args)?;
37    }
38
39    Ok(args)
40}
41
42/// Exports a syncobj as an inter-process file descriptor or as a poll()-able sync file.
43pub fn handle_to_fd(
44    fd: BorrowedFd<'_>,
45    handle: u32,
46    export_sync_file: bool,
47) -> io::Result<drm_syncobj_handle> {
48    let mut args = drm_syncobj_handle {
49        handle,
50        flags: if export_sync_file {
51            DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE
52        } else {
53            0
54        },
55        fd: 0,
56        pad: 0,
57    };
58
59    unsafe {
60        ioctl::syncobj::handle_to_fd(fd, &mut args)?;
61    }
62
63    Ok(args)
64}
65
66/// Imports a file descriptor exported by [`handle_to_fd`] back into a process-local handle.
67pub fn fd_to_handle(
68    fd: BorrowedFd<'_>,
69    syncobj_fd: BorrowedFd<'_>,
70    import_sync_file: bool,
71) -> io::Result<drm_syncobj_handle> {
72    let mut args = drm_syncobj_handle {
73        handle: 0,
74        flags: if import_sync_file {
75            DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE
76        } else {
77            0
78        },
79        fd: syncobj_fd.as_raw_fd(),
80        pad: 0,
81    };
82
83    unsafe {
84        ioctl::syncobj::fd_to_handle(fd, &mut args)?;
85    }
86
87    Ok(args)
88}
89
90/// Waits for one or more syncobjs to become signalled.
91pub fn wait(
92    fd: BorrowedFd<'_>,
93    handles: &[u32],
94    timeout_nsec: i64,
95    wait_all: bool,
96    wait_for_submit: bool,
97) -> io::Result<drm_syncobj_wait> {
98    let mut args = drm_syncobj_wait {
99        handles: handles.as_ptr() as _,
100        timeout_nsec,
101        count_handles: handles.len() as _,
102        flags: if wait_all {
103            DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL
104        } else {
105            0
106        } | if wait_for_submit {
107            DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT
108        } else {
109            0
110        },
111        first_signaled: 0,
112        pad: 0,
113    };
114
115    unsafe {
116        ioctl::syncobj::wait(fd, &mut args)?;
117    }
118
119    Ok(args)
120}
121
122/// Resets (un-signals) one or more syncobjs.
123pub fn reset(fd: BorrowedFd<'_>, handles: &[u32]) -> io::Result<drm_syncobj_array> {
124    let mut args = drm_syncobj_array {
125        handles: handles.as_ptr() as _,
126        count_handles: handles.len() as _,
127        pad: 0,
128    };
129
130    unsafe {
131        ioctl::syncobj::reset(fd, &mut args)?;
132    }
133
134    Ok(args)
135}
136
137/// Signals one or more syncobjs.
138pub fn signal(fd: BorrowedFd<'_>, handles: &[u32]) -> io::Result<drm_syncobj_array> {
139    let mut args = drm_syncobj_array {
140        handles: handles.as_ptr() as _,
141        count_handles: handles.len() as _,
142        pad: 0,
143    };
144
145    unsafe {
146        ioctl::syncobj::signal(fd, &mut args)?;
147    }
148
149    Ok(args)
150}
151
152/// Waits for one or more specific timeline syncobj points.
153pub fn timeline_wait(
154    fd: BorrowedFd<'_>,
155    handles: &[u32],
156    points: &[u64],
157    timeout_nsec: i64,
158    wait_all: bool,
159    wait_for_submit: bool,
160    wait_available: bool,
161) -> io::Result<drm_syncobj_timeline_wait> {
162    debug_assert_eq!(handles.len(), points.len());
163
164    let mut args = drm_syncobj_timeline_wait {
165        handles: handles.as_ptr() as _,
166        points: points.as_ptr() as _,
167        timeout_nsec,
168        count_handles: handles.len() as _,
169        flags: if wait_all {
170            DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL
171        } else {
172            0
173        } | if wait_for_submit {
174            DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT
175        } else {
176            0
177        } | if wait_available {
178            DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE
179        } else {
180            0
181        },
182        first_signaled: 0,
183        pad: 0,
184    };
185
186    unsafe {
187        ioctl::syncobj::timeline_wait(fd, &mut args)?;
188    }
189
190    Ok(args)
191}
192
193/// Queries for state of one or more timeline syncobjs.
194pub fn query(
195    fd: BorrowedFd<'_>,
196    handles: &[u32],
197    points: &mut [u64],
198    last_submitted: bool,
199) -> io::Result<drm_syncobj_timeline_array> {
200    debug_assert_eq!(handles.len(), points.len());
201
202    let mut args = drm_syncobj_timeline_array {
203        handles: handles.as_ptr() as _,
204        points: points.as_mut_ptr() as _,
205        count_handles: handles.len() as _,
206        flags: if last_submitted {
207            DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED
208        } else {
209            0
210        },
211    };
212
213    unsafe {
214        ioctl::syncobj::query(fd, &mut args)?;
215    }
216
217    Ok(args)
218}
219
220/// Transfers one timeline syncobj point to another.
221pub fn transfer(
222    fd: BorrowedFd<'_>,
223    src_handle: u32,
224    dst_handle: u32,
225    src_point: u64,
226    dst_point: u64,
227) -> io::Result<drm_syncobj_transfer> {
228    let mut args = drm_syncobj_transfer {
229        src_handle,
230        dst_handle,
231        src_point,
232        dst_point,
233        flags: 0,
234        pad: 0,
235    };
236
237    unsafe {
238        ioctl::syncobj::transfer(fd, &mut args)?;
239    }
240
241    Ok(args)
242}
243
244/// Signals one or more specific timeline syncobj points.
245pub fn timeline_signal(
246    fd: BorrowedFd<'_>,
247    handles: &[u32],
248    points: &[u64],
249) -> io::Result<drm_syncobj_timeline_array> {
250    debug_assert_eq!(handles.len(), points.len());
251
252    let mut args = drm_syncobj_timeline_array {
253        handles: handles.as_ptr() as _,
254        points: points.as_ptr() as _,
255        count_handles: handles.len() as _,
256        flags: 0,
257    };
258
259    unsafe {
260        ioctl::syncobj::timeline_signal(fd, &mut args)?;
261    }
262
263    Ok(args)
264}