1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2021 Intel Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21bf215546Sopenharmony_ci * IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci#ifndef VK_SYNC_H
24bf215546Sopenharmony_ci#define VK_SYNC_H
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#include <stdbool.h>
27bf215546Sopenharmony_ci#include <vulkan/vulkan_core.h>
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#include "util/macros.h"
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ci#ifdef __cplusplus
32bf215546Sopenharmony_ciextern "C" {
33bf215546Sopenharmony_ci#endif
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_cistruct vk_device;
36bf215546Sopenharmony_cistruct vk_sync;
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_cienum vk_sync_features {
39bf215546Sopenharmony_ci   /** Set if a sync type supports the binary mode of operation
40bf215546Sopenharmony_ci    *
41bf215546Sopenharmony_ci    * In binary mode, a vk_sync has two modes: signaled and unsignaled.  If
42bf215546Sopenharmony_ci    * it supports CPU_RESET, it can be changed from signaled to unsignaled on
43bf215546Sopenharmony_ci    * the CPU via vk_sync_reset().  If it supports CPU_SIGNAL, it can be
44bf215546Sopenharmony_ci    * changed from unsignaled to signaled on the CPU via vk_sync_signal().
45bf215546Sopenharmony_ci    *
46bf215546Sopenharmony_ci    * Binary vk_sync types may also support WAIT_PENDING in which they have a
47bf215546Sopenharmony_ci    * third hidden pending state.  Once such a vk_sync has been submitted to
48bf215546Sopenharmony_ci    * the kernel driver for signaling, it is in the pending state and remains
49bf215546Sopenharmony_ci    * there until the work is complete at which point it enters the signaled
50bf215546Sopenharmony_ci    * state.  This pending state is visible across processes for shared
51bf215546Sopenharmony_ci    * vk_sync types.  This is used to by the threaded submit mode to ensure
52bf215546Sopenharmony_ci    * that everything gets submitted to the kernel driver in-order.
53bf215546Sopenharmony_ci    *
54bf215546Sopenharmony_ci    * A vk_sync operates in binary mode if VK_SYNC_IS_TIMELINE is not set
55bf215546Sopenharmony_ci    * in vk_sync::flags.
56bf215546Sopenharmony_ci    */
57bf215546Sopenharmony_ci   VK_SYNC_FEATURE_BINARY              = (1 << 0),
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_ci   /** Set if a sync type supports the timeline mode of operation
60bf215546Sopenharmony_ci    *
61bf215546Sopenharmony_ci    * In timeline mode, a vk_sync has a monotonically increasing 64-bit value
62bf215546Sopenharmony_ci    * which represents most recently signaled time point.  Waits are relative
63bf215546Sopenharmony_ci    * to time points.  Instead of waiting for the vk_sync to enter a signaled
64bf215546Sopenharmony_ci    * state, you wait for its 64-bit value to be at least some wait value.
65bf215546Sopenharmony_ci    *
66bf215546Sopenharmony_ci    * Timeline vk_sync types can also support WAIT_PENDING.  In this case, the
67bf215546Sopenharmony_ci    * wait is not for a pending state, as such, but rather for someone to have
68bf215546Sopenharmony_ci    * submitted a kernel request which will signal a time point with at least
69bf215546Sopenharmony_ci    * that value.  Logically, you can think of this as having two timelines,
70bf215546Sopenharmony_ci    * the real timeline and a pending timeline which runs slightly ahead of
71bf215546Sopenharmony_ci    * the real one.  As with binary vk_sync types, this is used by threaded
72bf215546Sopenharmony_ci    * submit to re-order things so that the kernel requests happen in a valid
73bf215546Sopenharmony_ci    * linear order.
74bf215546Sopenharmony_ci    *
75bf215546Sopenharmony_ci    * A vk_sync operates in timeline mode if VK_SYNC_IS_TIMELINE is set in
76bf215546Sopenharmony_ci    * vk_sync::flags.
77bf215546Sopenharmony_ci    */
78bf215546Sopenharmony_ci   VK_SYNC_FEATURE_TIMELINE            = (1 << 1),
79bf215546Sopenharmony_ci
80bf215546Sopenharmony_ci   /** Set if this sync supports GPU waits */
81bf215546Sopenharmony_ci   VK_SYNC_FEATURE_GPU_WAIT            = (1 << 2),
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ci   /** Set if a sync type supports multiple GPU waits on one signal state
84bf215546Sopenharmony_ci    *
85bf215546Sopenharmony_ci    * The Vulkan spec for VkSemaphore requires GPU wait and signal operations
86bf215546Sopenharmony_ci    * to have a one-to-one relationship.  This formally described by saying
87bf215546Sopenharmony_ci    * that the VkSemaphore gets implicitly reset on wait.  However, it is
88bf215546Sopenharmony_ci    * often useful to have well-defined multi-wait.  If binary vk_sync
89bf215546Sopenharmony_ci    * supports multi-wait then any number of kernel requests can be submitted
90bf215546Sopenharmony_ci    * which wait on one signal operation.  This also implies that you can
91bf215546Sopenharmony_ci    * signal twice back-to-back (there are 0 waits on the first signal).
92bf215546Sopenharmony_ci    *
93bf215546Sopenharmony_ci    * This feature only applies to binary vk_sync objects.
94bf215546Sopenharmony_ci    */
95bf215546Sopenharmony_ci   VK_SYNC_FEATURE_GPU_MULTI_WAIT      = (1 << 3),
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci   /** Set if a sync type supports vk_sync_wait() and vk_sync_wait_many() */
98bf215546Sopenharmony_ci   VK_SYNC_FEATURE_CPU_WAIT            = (1 << 4),
99bf215546Sopenharmony_ci
100bf215546Sopenharmony_ci   /** Set if a sync type supports vk_sync_reset()
101bf215546Sopenharmony_ci    *
102bf215546Sopenharmony_ci    * This feature only applies to binary vk_sync objects.
103bf215546Sopenharmony_ci    */
104bf215546Sopenharmony_ci   VK_SYNC_FEATURE_CPU_RESET           = (1 << 5),
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_ci   /** Set if a sync type supports vk_sync_signal() */
107bf215546Sopenharmony_ci   VK_SYNC_FEATURE_CPU_SIGNAL          = (1 << 6),
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ci   /** Set if sync_type::wait_many supports the VK_SYNC_WAIT_ANY bit
110bf215546Sopenharmony_ci    *
111bf215546Sopenharmony_ci    * vk_sync_wait_many() will support the bit regardless.  If the sync type
112bf215546Sopenharmony_ci    * doesn't support it natively, it will be emulated.
113bf215546Sopenharmony_ci    */
114bf215546Sopenharmony_ci   VK_SYNC_FEATURE_WAIT_ANY            = (1 << 7),
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_ci   /** Set if a sync type supports the VK_SYNC_WAIT_PENDING bit
117bf215546Sopenharmony_ci    *
118bf215546Sopenharmony_ci    * See VK_SYNC_FEATURE_BINARY and VK_SYNC_FEATURE_TIMELINE for descriptions
119bf215546Sopenharmony_ci    * of what this does in each case.
120bf215546Sopenharmony_ci    */
121bf215546Sopenharmony_ci   VK_SYNC_FEATURE_WAIT_PENDING        = (1 << 8),
122bf215546Sopenharmony_ci
123bf215546Sopenharmony_ci   /** Set if a sync type natively supports wait-before-signal
124bf215546Sopenharmony_ci    *
125bf215546Sopenharmony_ci    * If this is set then the underlying OS primitive supports submitting
126bf215546Sopenharmony_ci    * kernel requests which wait on the vk_sync before submitting a kernel
127bf215546Sopenharmony_ci    * request which would cause that wait to unblock.
128bf215546Sopenharmony_ci    */
129bf215546Sopenharmony_ci   VK_SYNC_FEATURE_WAIT_BEFORE_SIGNAL  = (1 << 9),
130bf215546Sopenharmony_ci};
131bf215546Sopenharmony_ci
132bf215546Sopenharmony_cistruct vk_sync_wait;
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_cienum vk_sync_wait_flags {
135bf215546Sopenharmony_ci   /** Placeholder for 0 to make vk_sync_wait() calls more clear */
136bf215546Sopenharmony_ci   VK_SYNC_WAIT_COMPLETE   = 0,
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci   /** If set, only wait for the vk_sync operation to be pending
139bf215546Sopenharmony_ci    *
140bf215546Sopenharmony_ci    * See VK_SYNC_FEATURE_BINARY and VK_SYNC_FEATURE_TIMELINE for descriptions
141bf215546Sopenharmony_ci    * of what this does in each case.
142bf215546Sopenharmony_ci    */
143bf215546Sopenharmony_ci   VK_SYNC_WAIT_PENDING    = (1 << 0),
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_ci   /** If set, wait for any of of the vk_sync operations to complete
146bf215546Sopenharmony_ci    *
147bf215546Sopenharmony_ci    * This is as opposed to waiting for all of them.  There is no guarantee
148bf215546Sopenharmony_ci    * that vk_sync_wait_many() will return immediately after the first
149bf215546Sopenharmony_ci    * operation completes but it will make a best effort to return as soon as
150bf215546Sopenharmony_ci    * possible.
151bf215546Sopenharmony_ci    */
152bf215546Sopenharmony_ci   VK_SYNC_WAIT_ANY        = (1 << 1),
153bf215546Sopenharmony_ci};
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_cistruct vk_sync_type {
156bf215546Sopenharmony_ci   /** Size of this sync type */
157bf215546Sopenharmony_ci   size_t size;
158bf215546Sopenharmony_ci
159bf215546Sopenharmony_ci   /** Features supported by this sync type */
160bf215546Sopenharmony_ci   enum vk_sync_features features;
161bf215546Sopenharmony_ci
162bf215546Sopenharmony_ci   /** Initialize a vk_sync
163bf215546Sopenharmony_ci    *
164bf215546Sopenharmony_ci    * The base vk_sync will already be initialized and the sync type set
165bf215546Sopenharmony_ci    * before this function is called.  If any OS primitives need to be
166bf215546Sopenharmony_ci    * allocated, that should be done here.
167bf215546Sopenharmony_ci    */
168bf215546Sopenharmony_ci   VkResult (*init)(struct vk_device *device,
169bf215546Sopenharmony_ci                    struct vk_sync *sync,
170bf215546Sopenharmony_ci                    uint64_t initial_value);
171bf215546Sopenharmony_ci
172bf215546Sopenharmony_ci   /** Finish a vk_sync
173bf215546Sopenharmony_ci    *
174bf215546Sopenharmony_ci    * This should free any internal data stored in this vk_sync.
175bf215546Sopenharmony_ci    */
176bf215546Sopenharmony_ci   void (*finish)(struct vk_device *device,
177bf215546Sopenharmony_ci                  struct vk_sync *sync);
178bf215546Sopenharmony_ci
179bf215546Sopenharmony_ci   /** Signal a vk_sync
180bf215546Sopenharmony_ci    *
181bf215546Sopenharmony_ci    * For non-timeline sync types, value == 0.
182bf215546Sopenharmony_ci    */
183bf215546Sopenharmony_ci   VkResult (*signal)(struct vk_device *device,
184bf215546Sopenharmony_ci                      struct vk_sync *sync,
185bf215546Sopenharmony_ci                      uint64_t value);
186bf215546Sopenharmony_ci
187bf215546Sopenharmony_ci   /** Get the timeline value for a vk_sync */
188bf215546Sopenharmony_ci   VkResult (*get_value)(struct vk_device *device,
189bf215546Sopenharmony_ci                         struct vk_sync *sync,
190bf215546Sopenharmony_ci                         uint64_t *value);
191bf215546Sopenharmony_ci
192bf215546Sopenharmony_ci   /** Reset a non-timeline vk_sync */
193bf215546Sopenharmony_ci   VkResult (*reset)(struct vk_device *device,
194bf215546Sopenharmony_ci                     struct vk_sync *sync);
195bf215546Sopenharmony_ci
196bf215546Sopenharmony_ci   /** Moves the guts of one binary vk_sync to another
197bf215546Sopenharmony_ci    *
198bf215546Sopenharmony_ci    * This moves the current binary vk_sync event from src to dst and resets
199bf215546Sopenharmony_ci    * src.  If dst contained an event, it is discarded.
200bf215546Sopenharmony_ci    *
201bf215546Sopenharmony_ci    * This is required for all binary vk_sync types that can be used for a
202bf215546Sopenharmony_ci    * semaphore wait in conjunction with real timeline semaphores.
203bf215546Sopenharmony_ci    */
204bf215546Sopenharmony_ci   VkResult (*move)(struct vk_device *device,
205bf215546Sopenharmony_ci                    struct vk_sync *dst,
206bf215546Sopenharmony_ci                    struct vk_sync *src);
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_ci   /** Wait on a vk_sync
209bf215546Sopenharmony_ci    *
210bf215546Sopenharmony_ci    * For a timeline vk_sync, wait_value is the timeline value to wait for.
211bf215546Sopenharmony_ci    * This function should not return VK_SUCCESS until get_value on that
212bf215546Sopenharmony_ci    * vk_sync would return a value >= wait_value.  A wait_value of zero is
213bf215546Sopenharmony_ci    * allowed in which case the wait is a no-op.  For a non-timeline vk_sync,
214bf215546Sopenharmony_ci    * wait_value should be ignored.
215bf215546Sopenharmony_ci    *
216bf215546Sopenharmony_ci    * This function is optional.  If the sync type needs to support CPU waits,
217bf215546Sopenharmony_ci    * at least one of wait or wait_many must be provided.  If one is missing,
218bf215546Sopenharmony_ci    * it will be implemented in terms of the other.
219bf215546Sopenharmony_ci    */
220bf215546Sopenharmony_ci   VkResult (*wait)(struct vk_device *device,
221bf215546Sopenharmony_ci                    struct vk_sync *sync,
222bf215546Sopenharmony_ci                    uint64_t wait_value,
223bf215546Sopenharmony_ci                    enum vk_sync_wait_flags wait_flags,
224bf215546Sopenharmony_ci                    uint64_t abs_timeout_ns);
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci   /** Wait for multiple vk_sync events
227bf215546Sopenharmony_ci    *
228bf215546Sopenharmony_ci    * If VK_SYNC_WAIT_ANY is set, it will return after at least one of the
229bf215546Sopenharmony_ci    * wait events is complete instead of waiting for all of them.
230bf215546Sopenharmony_ci    *
231bf215546Sopenharmony_ci    * See wait for more details.
232bf215546Sopenharmony_ci    */
233bf215546Sopenharmony_ci   VkResult (*wait_many)(struct vk_device *device,
234bf215546Sopenharmony_ci                         uint32_t wait_count,
235bf215546Sopenharmony_ci                         const struct vk_sync_wait *waits,
236bf215546Sopenharmony_ci                         enum vk_sync_wait_flags wait_flags,
237bf215546Sopenharmony_ci                         uint64_t abs_timeout_ns);
238bf215546Sopenharmony_ci
239bf215546Sopenharmony_ci   /** Permanently imports the given FD into this vk_sync
240bf215546Sopenharmony_ci    *
241bf215546Sopenharmony_ci    * This replaces the guts of the given vk_sync with whatever is in the FD.
242bf215546Sopenharmony_ci    * In a sense, this vk_sync now aliases whatever vk_sync the FD was
243bf215546Sopenharmony_ci    * exported from.
244bf215546Sopenharmony_ci    */
245bf215546Sopenharmony_ci   VkResult (*import_opaque_fd)(struct vk_device *device,
246bf215546Sopenharmony_ci                                struct vk_sync *sync,
247bf215546Sopenharmony_ci                                int fd);
248bf215546Sopenharmony_ci
249bf215546Sopenharmony_ci   /** Export the guts of this vk_sync to an FD */
250bf215546Sopenharmony_ci   VkResult (*export_opaque_fd)(struct vk_device *device,
251bf215546Sopenharmony_ci                                struct vk_sync *sync,
252bf215546Sopenharmony_ci                                int *fd);
253bf215546Sopenharmony_ci
254bf215546Sopenharmony_ci   /** Imports a sync file into this binary vk_sync
255bf215546Sopenharmony_ci    *
256bf215546Sopenharmony_ci    * If this completes successfully, the vk_sync will now signal whenever
257bf215546Sopenharmony_ci    * the sync file signals.
258bf215546Sopenharmony_ci    *
259bf215546Sopenharmony_ci    * If sync_file == -1, the vk_sync should be signaled immediately.  If
260bf215546Sopenharmony_ci    * the vk_sync_type implements signal, sync_file will never be -1.
261bf215546Sopenharmony_ci    */
262bf215546Sopenharmony_ci   VkResult (*import_sync_file)(struct vk_device *device,
263bf215546Sopenharmony_ci                                struct vk_sync *sync,
264bf215546Sopenharmony_ci                                int sync_file);
265bf215546Sopenharmony_ci
266bf215546Sopenharmony_ci   /** Exports the current binary vk_sync state as a sync file.
267bf215546Sopenharmony_ci    *
268bf215546Sopenharmony_ci    * The resulting sync file will contain the current event stored in this
269bf215546Sopenharmony_ci    * binary vk_sync must be turned into a sync file.  If the vk_sync is later
270bf215546Sopenharmony_ci    * modified to contain a new event, the sync file is unaffected.
271bf215546Sopenharmony_ci    */
272bf215546Sopenharmony_ci   VkResult (*export_sync_file)(struct vk_device *device,
273bf215546Sopenharmony_ci                                struct vk_sync *sync,
274bf215546Sopenharmony_ci                                int *sync_file);
275bf215546Sopenharmony_ci};
276bf215546Sopenharmony_ci
277bf215546Sopenharmony_cienum vk_sync_flags {
278bf215546Sopenharmony_ci   /** Set if the vk_sync is a timeline */
279bf215546Sopenharmony_ci   VK_SYNC_IS_TIMELINE  = (1 << 0),
280bf215546Sopenharmony_ci
281bf215546Sopenharmony_ci   /** Set if the vk_sync can have its payload shared */
282bf215546Sopenharmony_ci   VK_SYNC_IS_SHAREABLE = (1 << 1),
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_ci   /** Set if the vk_sync has a shared payload */
285bf215546Sopenharmony_ci   VK_SYNC_IS_SHARED    = (1 << 2),
286bf215546Sopenharmony_ci};
287bf215546Sopenharmony_ci
288bf215546Sopenharmony_cistruct vk_sync {
289bf215546Sopenharmony_ci   const struct vk_sync_type *type;
290bf215546Sopenharmony_ci   enum vk_sync_flags flags;
291bf215546Sopenharmony_ci};
292bf215546Sopenharmony_ci
293bf215546Sopenharmony_ci/* See VkSemaphoreSubmitInfo */
294bf215546Sopenharmony_cistruct vk_sync_wait {
295bf215546Sopenharmony_ci   struct vk_sync *sync;
296bf215546Sopenharmony_ci   VkPipelineStageFlags2 stage_mask;
297bf215546Sopenharmony_ci   uint64_t wait_value;
298bf215546Sopenharmony_ci};
299bf215546Sopenharmony_ci
300bf215546Sopenharmony_ci/* See VkSemaphoreSubmitInfo */
301bf215546Sopenharmony_cistruct vk_sync_signal {
302bf215546Sopenharmony_ci   struct vk_sync *sync;
303bf215546Sopenharmony_ci   VkPipelineStageFlags2 stage_mask;
304bf215546Sopenharmony_ci   uint64_t signal_value;
305bf215546Sopenharmony_ci};
306bf215546Sopenharmony_ci
307bf215546Sopenharmony_ciVkResult MUST_CHECK vk_sync_init(struct vk_device *device,
308bf215546Sopenharmony_ci                                 struct vk_sync *sync,
309bf215546Sopenharmony_ci                                 const struct vk_sync_type *type,
310bf215546Sopenharmony_ci                                 enum vk_sync_flags flags,
311bf215546Sopenharmony_ci                                 uint64_t initial_value);
312bf215546Sopenharmony_ci
313bf215546Sopenharmony_civoid vk_sync_finish(struct vk_device *device,
314bf215546Sopenharmony_ci                    struct vk_sync *sync);
315bf215546Sopenharmony_ci
316bf215546Sopenharmony_ciVkResult MUST_CHECK vk_sync_create(struct vk_device *device,
317bf215546Sopenharmony_ci                                   const struct vk_sync_type *type,
318bf215546Sopenharmony_ci                                   enum vk_sync_flags flags,
319bf215546Sopenharmony_ci                                   uint64_t initial_value,
320bf215546Sopenharmony_ci                                   struct vk_sync **sync_out);
321bf215546Sopenharmony_ci
322bf215546Sopenharmony_civoid vk_sync_destroy(struct vk_device *device,
323bf215546Sopenharmony_ci                     struct vk_sync *sync);
324bf215546Sopenharmony_ci
325bf215546Sopenharmony_ciVkResult MUST_CHECK vk_sync_signal(struct vk_device *device,
326bf215546Sopenharmony_ci                                   struct vk_sync *sync,
327bf215546Sopenharmony_ci                                   uint64_t value);
328bf215546Sopenharmony_ci
329bf215546Sopenharmony_ciVkResult MUST_CHECK vk_sync_get_value(struct vk_device *device,
330bf215546Sopenharmony_ci                                      struct vk_sync *sync,
331bf215546Sopenharmony_ci                                      uint64_t *value);
332bf215546Sopenharmony_ci
333bf215546Sopenharmony_ciVkResult MUST_CHECK vk_sync_reset(struct vk_device *device,
334bf215546Sopenharmony_ci                                  struct vk_sync *sync);
335bf215546Sopenharmony_ci
336bf215546Sopenharmony_ciVkResult MUST_CHECK vk_sync_wait(struct vk_device *device,
337bf215546Sopenharmony_ci                                 struct vk_sync *sync,
338bf215546Sopenharmony_ci                                 uint64_t wait_value,
339bf215546Sopenharmony_ci                                 enum vk_sync_wait_flags wait_flags,
340bf215546Sopenharmony_ci                                 uint64_t abs_timeout_ns);
341bf215546Sopenharmony_ci
342bf215546Sopenharmony_ciVkResult MUST_CHECK vk_sync_wait_many(struct vk_device *device,
343bf215546Sopenharmony_ci                                      uint32_t wait_count,
344bf215546Sopenharmony_ci                                      const struct vk_sync_wait *waits,
345bf215546Sopenharmony_ci                                      enum vk_sync_wait_flags wait_flags,
346bf215546Sopenharmony_ci                                      uint64_t abs_timeout_ns);
347bf215546Sopenharmony_ci
348bf215546Sopenharmony_ciVkResult MUST_CHECK vk_sync_import_opaque_fd(struct vk_device *device,
349bf215546Sopenharmony_ci                                             struct vk_sync *sync,
350bf215546Sopenharmony_ci                                             int fd);
351bf215546Sopenharmony_ci
352bf215546Sopenharmony_ciVkResult MUST_CHECK vk_sync_export_opaque_fd(struct vk_device *device,
353bf215546Sopenharmony_ci                                             struct vk_sync *sync,
354bf215546Sopenharmony_ci                                             int *fd);
355bf215546Sopenharmony_ci
356bf215546Sopenharmony_ciVkResult MUST_CHECK vk_sync_import_sync_file(struct vk_device *device,
357bf215546Sopenharmony_ci                                             struct vk_sync *sync,
358bf215546Sopenharmony_ci                                             int sync_file);
359bf215546Sopenharmony_ci
360bf215546Sopenharmony_ciVkResult MUST_CHECK vk_sync_export_sync_file(struct vk_device *device,
361bf215546Sopenharmony_ci                                             struct vk_sync *sync,
362bf215546Sopenharmony_ci                                             int *sync_file);
363bf215546Sopenharmony_ci
364bf215546Sopenharmony_ciVkResult MUST_CHECK vk_sync_move(struct vk_device *device,
365bf215546Sopenharmony_ci                                 struct vk_sync *dst,
366bf215546Sopenharmony_ci                                 struct vk_sync *src);
367bf215546Sopenharmony_ci
368bf215546Sopenharmony_ci#ifdef __cplusplus
369bf215546Sopenharmony_ci}
370bf215546Sopenharmony_ci#endif
371bf215546Sopenharmony_ci
372bf215546Sopenharmony_ci#endif /* VK_SYNC_H */
373