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. |
14 | pub fn create(fd: BorrowedFd<'_>, signaled: bool) -> io::Result<drm_syncobj_create> { |
15 | let mut args: drm_syncobj_create = 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. |
32 | pub fn destroy(fd: BorrowedFd<'_>, handle: u32) -> io::Result<drm_syncobj_destroy> { |
33 | let mut args: drm_syncobj_destroy = 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. |
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 = 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. |
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 = 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. |
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. |
124 | pub fn reset(fd: BorrowedFd<'_>, handles: &[u32]) -> io::Result<drm_syncobj_array> { |
125 | let mut args: drm_syncobj_array = 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. |
139 | pub fn signal(fd: BorrowedFd<'_>, handles: &[u32]) -> io::Result<drm_syncobj_array> { |
140 | let mut args: drm_syncobj_array = 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. |
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. |
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 = 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. |
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 = 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. |
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 = 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. |
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: u32 = if wait_available { |
277 | DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE |
278 | } else { |
279 | 0 |
280 | }; |
281 | let mut args: drm_syncobj_eventfd = 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 | |