1 //!
2 //! Bindings for DRM sync objects
3 //!
4
5 use crate::ioctl;
6 use drm_sys::*;
7
8 use std::{
9 io,
10 os::unix::io::{AsRawFd, BorrowedFd},
11 };
12
13 /// Creates a syncobj.
create(fd: BorrowedFd<'_>, signaled: bool) -> io::Result<drm_syncobj_create>14 pub 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.
destroy(fd: BorrowedFd<'_>, handle: u32) -> io::Result<drm_syncobj_destroy>32 pub 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.
handle_to_fd( fd: BorrowedFd<'_>, handle: u32, export_sync_file: bool, ) -> io::Result<drm_syncobj_handle>43 pub 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.
fd_to_handle( fd: BorrowedFd<'_>, syncobj_fd: BorrowedFd<'_>, import_sync_file: bool, ) -> io::Result<drm_syncobj_handle>67 pub 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.
wait( fd: BorrowedFd<'_>, handles: &[u32], timeout_nsec: i64, wait_all: bool, wait_for_submit: bool, ) -> io::Result<drm_syncobj_wait>91 pub 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 deadline_nsec: 0,
114 };
115
116 unsafe {
117 ioctl::syncobj::wait(fd, &mut args)?;
118 }
119
120 Ok(args)
121 }
122
123 /// Resets (un-signals) one or more syncobjs.
reset(fd: BorrowedFd<'_>, handles: &[u32]) -> io::Result<drm_syncobj_array>124 pub fn reset(fd: BorrowedFd<'_>, handles: &[u32]) -> io::Result<drm_syncobj_array> {
125 let mut args = drm_syncobj_array {
126 handles: handles.as_ptr() as _,
127 count_handles: handles.len() as _,
128 pad: 0,
129 };
130
131 unsafe {
132 ioctl::syncobj::reset(fd, &mut args)?;
133 }
134
135 Ok(args)
136 }
137
138 /// Signals one or more syncobjs.
signal(fd: BorrowedFd<'_>, handles: &[u32]) -> io::Result<drm_syncobj_array>139 pub fn signal(fd: BorrowedFd<'_>, handles: &[u32]) -> io::Result<drm_syncobj_array> {
140 let mut args = drm_syncobj_array {
141 handles: handles.as_ptr() as _,
142 count_handles: handles.len() as _,
143 pad: 0,
144 };
145
146 unsafe {
147 ioctl::syncobj::signal(fd, &mut args)?;
148 }
149
150 Ok(args)
151 }
152
153 /// Waits for one or more specific timeline syncobj points.
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>154 pub fn timeline_wait(
155 fd: BorrowedFd<'_>,
156 handles: &[u32],
157 points: &[u64],
158 timeout_nsec: i64,
159 wait_all: bool,
160 wait_for_submit: bool,
161 wait_available: bool,
162 ) -> io::Result<drm_syncobj_timeline_wait> {
163 debug_assert_eq!(handles.len(), points.len());
164
165 let mut args = drm_syncobj_timeline_wait {
166 handles: handles.as_ptr() as _,
167 points: points.as_ptr() as _,
168 timeout_nsec,
169 count_handles: handles.len() as _,
170 flags: if wait_all {
171 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL
172 } else {
173 0
174 } | if wait_for_submit {
175 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT
176 } else {
177 0
178 } | if wait_available {
179 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE
180 } else {
181 0
182 },
183 first_signaled: 0,
184 pad: 0,
185 deadline_nsec: 0,
186 };
187
188 unsafe {
189 ioctl::syncobj::timeline_wait(fd, &mut args)?;
190 }
191
192 Ok(args)
193 }
194
195 /// Queries for state of one or more timeline syncobjs.
query( fd: BorrowedFd<'_>, handles: &[u32], points: &mut [u64], last_submitted: bool, ) -> io::Result<drm_syncobj_timeline_array>196 pub fn query(
197 fd: BorrowedFd<'_>,
198 handles: &[u32],
199 points: &mut [u64],
200 last_submitted: bool,
201 ) -> io::Result<drm_syncobj_timeline_array> {
202 debug_assert_eq!(handles.len(), points.len());
203
204 let mut args = drm_syncobj_timeline_array {
205 handles: handles.as_ptr() as _,
206 points: points.as_mut_ptr() as _,
207 count_handles: handles.len() as _,
208 flags: if last_submitted {
209 DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED
210 } else {
211 0
212 },
213 };
214
215 unsafe {
216 ioctl::syncobj::query(fd, &mut args)?;
217 }
218
219 Ok(args)
220 }
221
222 /// Transfers one timeline syncobj point to another.
transfer( fd: BorrowedFd<'_>, src_handle: u32, dst_handle: u32, src_point: u64, dst_point: u64, ) -> io::Result<drm_syncobj_transfer>223 pub fn transfer(
224 fd: BorrowedFd<'_>,
225 src_handle: u32,
226 dst_handle: u32,
227 src_point: u64,
228 dst_point: u64,
229 ) -> io::Result<drm_syncobj_transfer> {
230 let mut args = drm_syncobj_transfer {
231 src_handle,
232 dst_handle,
233 src_point,
234 dst_point,
235 flags: 0,
236 pad: 0,
237 };
238
239 unsafe {
240 ioctl::syncobj::transfer(fd, &mut args)?;
241 }
242
243 Ok(args)
244 }
245
246 /// Signals one or more specific timeline syncobj points.
timeline_signal( fd: BorrowedFd<'_>, handles: &[u32], points: &[u64], ) -> io::Result<drm_syncobj_timeline_array>247 pub fn timeline_signal(
248 fd: BorrowedFd<'_>,
249 handles: &[u32],
250 points: &[u64],
251 ) -> io::Result<drm_syncobj_timeline_array> {
252 debug_assert_eq!(handles.len(), points.len());
253
254 let mut args = drm_syncobj_timeline_array {
255 handles: handles.as_ptr() as _,
256 points: points.as_ptr() as _,
257 count_handles: handles.len() as _,
258 flags: 0,
259 };
260
261 unsafe {
262 ioctl::syncobj::timeline_signal(fd, &mut args)?;
263 }
264
265 Ok(args)
266 }
267
268 /// Register an eventfd to be signalled by a syncobj.
eventfd( fd: BorrowedFd<'_>, handle: u32, point: u64, eventfd: BorrowedFd<'_>, wait_available: bool, ) -> io::Result<drm_syncobj_eventfd>269 pub fn eventfd(
270 fd: BorrowedFd<'_>,
271 handle: u32,
272 point: u64,
273 eventfd: BorrowedFd<'_>,
274 wait_available: bool,
275 ) -> io::Result<drm_syncobj_eventfd> {
276 let flags = if wait_available {
277 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE
278 } else {
279 0
280 };
281 let mut args = drm_syncobj_eventfd {
282 handle,
283 point,
284 flags,
285 fd: eventfd.as_raw_fd(),
286 pad: 0,
287 };
288
289 unsafe {
290 ioctl::syncobj::eventfd(fd, &mut args)?;
291 }
292
293 Ok(args)
294 }
295