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
24bf215546Sopenharmony_ci#include "vk_sync.h"
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#include <assert.h>
27bf215546Sopenharmony_ci#include <string.h>
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#include "util/debug.h"
30bf215546Sopenharmony_ci#include "util/macros.h"
31bf215546Sopenharmony_ci#include "util/os_time.h"
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ci#include "vk_alloc.h"
34bf215546Sopenharmony_ci#include "vk_device.h"
35bf215546Sopenharmony_ci#include "vk_log.h"
36bf215546Sopenharmony_ci
37bf215546Sopenharmony_cistatic void
38bf215546Sopenharmony_civk_sync_type_validate(const struct vk_sync_type *type)
39bf215546Sopenharmony_ci{
40bf215546Sopenharmony_ci   assert(type->init);
41bf215546Sopenharmony_ci   assert(type->finish);
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_ci   assert(type->features & (VK_SYNC_FEATURE_BINARY |
44bf215546Sopenharmony_ci                            VK_SYNC_FEATURE_TIMELINE));
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_ci   if (type->features & VK_SYNC_FEATURE_TIMELINE) {
47bf215546Sopenharmony_ci      assert(type->features & VK_SYNC_FEATURE_GPU_WAIT);
48bf215546Sopenharmony_ci      assert(type->features & VK_SYNC_FEATURE_CPU_WAIT);
49bf215546Sopenharmony_ci      assert(type->features & VK_SYNC_FEATURE_CPU_SIGNAL);
50bf215546Sopenharmony_ci      assert(type->features & (VK_SYNC_FEATURE_WAIT_BEFORE_SIGNAL |
51bf215546Sopenharmony_ci                               VK_SYNC_FEATURE_WAIT_PENDING));
52bf215546Sopenharmony_ci      assert(type->signal);
53bf215546Sopenharmony_ci      assert(type->get_value);
54bf215546Sopenharmony_ci   }
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_ci   if (!(type->features & VK_SYNC_FEATURE_BINARY)) {
57bf215546Sopenharmony_ci      assert(!(type->features & (VK_SYNC_FEATURE_GPU_MULTI_WAIT |
58bf215546Sopenharmony_ci                                 VK_SYNC_FEATURE_CPU_RESET)));
59bf215546Sopenharmony_ci      assert(!type->import_sync_file);
60bf215546Sopenharmony_ci      assert(!type->export_sync_file);
61bf215546Sopenharmony_ci   }
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_ci   if (type->features & VK_SYNC_FEATURE_CPU_WAIT) {
64bf215546Sopenharmony_ci      assert(type->wait || type->wait_many);
65bf215546Sopenharmony_ci   } else {
66bf215546Sopenharmony_ci      assert(!(type->features & (VK_SYNC_FEATURE_WAIT_ANY |
67bf215546Sopenharmony_ci                                 VK_SYNC_FEATURE_WAIT_PENDING)));
68bf215546Sopenharmony_ci   }
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ci   if (type->features & VK_SYNC_FEATURE_GPU_MULTI_WAIT)
71bf215546Sopenharmony_ci      assert(type->features & VK_SYNC_FEATURE_GPU_WAIT);
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ci   if (type->features & VK_SYNC_FEATURE_CPU_RESET)
74bf215546Sopenharmony_ci      assert(type->reset);
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_ci   if (type->features & VK_SYNC_FEATURE_CPU_SIGNAL)
77bf215546Sopenharmony_ci      assert(type->signal);
78bf215546Sopenharmony_ci}
79bf215546Sopenharmony_ci
80bf215546Sopenharmony_ciVkResult
81bf215546Sopenharmony_civk_sync_init(struct vk_device *device,
82bf215546Sopenharmony_ci             struct vk_sync *sync,
83bf215546Sopenharmony_ci             const struct vk_sync_type *type,
84bf215546Sopenharmony_ci             enum vk_sync_flags flags,
85bf215546Sopenharmony_ci             uint64_t initial_value)
86bf215546Sopenharmony_ci{
87bf215546Sopenharmony_ci   vk_sync_type_validate(type);
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ci   if (flags & VK_SYNC_IS_TIMELINE)
90bf215546Sopenharmony_ci      assert(type->features & VK_SYNC_FEATURE_TIMELINE);
91bf215546Sopenharmony_ci   else
92bf215546Sopenharmony_ci      assert(type->features & VK_SYNC_FEATURE_BINARY);
93bf215546Sopenharmony_ci
94bf215546Sopenharmony_ci   assert(type->size >= sizeof(*sync));
95bf215546Sopenharmony_ci   memset(sync, 0, type->size);
96bf215546Sopenharmony_ci   sync->type = type;
97bf215546Sopenharmony_ci   sync->flags = flags;
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci   return type->init(device, sync, initial_value);
100bf215546Sopenharmony_ci}
101bf215546Sopenharmony_ci
102bf215546Sopenharmony_civoid
103bf215546Sopenharmony_civk_sync_finish(struct vk_device *device,
104bf215546Sopenharmony_ci               struct vk_sync *sync)
105bf215546Sopenharmony_ci{
106bf215546Sopenharmony_ci   sync->type->finish(device, sync);
107bf215546Sopenharmony_ci}
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ciVkResult
110bf215546Sopenharmony_civk_sync_create(struct vk_device *device,
111bf215546Sopenharmony_ci               const struct vk_sync_type *type,
112bf215546Sopenharmony_ci               enum vk_sync_flags flags,
113bf215546Sopenharmony_ci               uint64_t initial_value,
114bf215546Sopenharmony_ci               struct vk_sync **sync_out)
115bf215546Sopenharmony_ci{
116bf215546Sopenharmony_ci   struct vk_sync *sync;
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_ci   sync = vk_alloc(&device->alloc, type->size, 8,
119bf215546Sopenharmony_ci                   VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
120bf215546Sopenharmony_ci   if (sync == NULL)
121bf215546Sopenharmony_ci      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
122bf215546Sopenharmony_ci
123bf215546Sopenharmony_ci   VkResult result = vk_sync_init(device, sync, type, flags, initial_value);
124bf215546Sopenharmony_ci   if (result != VK_SUCCESS) {
125bf215546Sopenharmony_ci      vk_free(&device->alloc, sync);
126bf215546Sopenharmony_ci      return result;
127bf215546Sopenharmony_ci   }
128bf215546Sopenharmony_ci
129bf215546Sopenharmony_ci   *sync_out = sync;
130bf215546Sopenharmony_ci
131bf215546Sopenharmony_ci   return VK_SUCCESS;
132bf215546Sopenharmony_ci}
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_civoid
135bf215546Sopenharmony_civk_sync_destroy(struct vk_device *device,
136bf215546Sopenharmony_ci                struct vk_sync *sync)
137bf215546Sopenharmony_ci{
138bf215546Sopenharmony_ci   vk_sync_finish(device, sync);
139bf215546Sopenharmony_ci   vk_free(&device->alloc, sync);
140bf215546Sopenharmony_ci}
141bf215546Sopenharmony_ci
142bf215546Sopenharmony_ciVkResult
143bf215546Sopenharmony_civk_sync_signal(struct vk_device *device,
144bf215546Sopenharmony_ci               struct vk_sync *sync,
145bf215546Sopenharmony_ci               uint64_t value)
146bf215546Sopenharmony_ci{
147bf215546Sopenharmony_ci   assert(sync->type->features & VK_SYNC_FEATURE_CPU_SIGNAL);
148bf215546Sopenharmony_ci
149bf215546Sopenharmony_ci   if (sync->flags & VK_SYNC_IS_TIMELINE)
150bf215546Sopenharmony_ci      assert(value > 0);
151bf215546Sopenharmony_ci   else
152bf215546Sopenharmony_ci      assert(value == 0);
153bf215546Sopenharmony_ci
154bf215546Sopenharmony_ci   return sync->type->signal(device, sync, value);
155bf215546Sopenharmony_ci}
156bf215546Sopenharmony_ci
157bf215546Sopenharmony_ciVkResult
158bf215546Sopenharmony_civk_sync_get_value(struct vk_device *device,
159bf215546Sopenharmony_ci                  struct vk_sync *sync,
160bf215546Sopenharmony_ci                  uint64_t *value)
161bf215546Sopenharmony_ci{
162bf215546Sopenharmony_ci   assert(sync->flags & VK_SYNC_IS_TIMELINE);
163bf215546Sopenharmony_ci   return sync->type->get_value(device, sync, value);
164bf215546Sopenharmony_ci}
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_ciVkResult
167bf215546Sopenharmony_civk_sync_reset(struct vk_device *device,
168bf215546Sopenharmony_ci              struct vk_sync *sync)
169bf215546Sopenharmony_ci{
170bf215546Sopenharmony_ci   assert(sync->type->features & VK_SYNC_FEATURE_CPU_RESET);
171bf215546Sopenharmony_ci   assert(!(sync->flags & VK_SYNC_IS_TIMELINE));
172bf215546Sopenharmony_ci   return sync->type->reset(device, sync);
173bf215546Sopenharmony_ci}
174bf215546Sopenharmony_ci
175bf215546Sopenharmony_ciVkResult vk_sync_move(struct vk_device *device,
176bf215546Sopenharmony_ci                      struct vk_sync *dst,
177bf215546Sopenharmony_ci                      struct vk_sync *src)
178bf215546Sopenharmony_ci{
179bf215546Sopenharmony_ci   assert(!(dst->flags & VK_SYNC_IS_TIMELINE));
180bf215546Sopenharmony_ci   assert(!(src->flags & VK_SYNC_IS_TIMELINE));
181bf215546Sopenharmony_ci   assert(dst->type == src->type);
182bf215546Sopenharmony_ci
183bf215546Sopenharmony_ci   return src->type->move(device, dst, src);
184bf215546Sopenharmony_ci}
185bf215546Sopenharmony_ci
186bf215546Sopenharmony_cistatic void
187bf215546Sopenharmony_ciassert_valid_wait(struct vk_sync *sync,
188bf215546Sopenharmony_ci                  uint64_t wait_value,
189bf215546Sopenharmony_ci                  enum vk_sync_wait_flags wait_flags)
190bf215546Sopenharmony_ci{
191bf215546Sopenharmony_ci   assert(sync->type->features & VK_SYNC_FEATURE_CPU_WAIT);
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_ci   if (!(sync->flags & VK_SYNC_IS_TIMELINE))
194bf215546Sopenharmony_ci      assert(wait_value == 0);
195bf215546Sopenharmony_ci
196bf215546Sopenharmony_ci   if (wait_flags & VK_SYNC_WAIT_PENDING)
197bf215546Sopenharmony_ci      assert(sync->type->features & VK_SYNC_FEATURE_WAIT_PENDING);
198bf215546Sopenharmony_ci}
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_cistatic uint64_t
201bf215546Sopenharmony_ciget_max_abs_timeout_ns(void)
202bf215546Sopenharmony_ci{
203bf215546Sopenharmony_ci   static int max_timeout_ms = -1;
204bf215546Sopenharmony_ci   if (max_timeout_ms < 0)
205bf215546Sopenharmony_ci      max_timeout_ms = env_var_as_unsigned("MESA_VK_MAX_TIMEOUT", 0);
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_ci   if (max_timeout_ms == 0)
208bf215546Sopenharmony_ci      return UINT64_MAX;
209bf215546Sopenharmony_ci   else
210bf215546Sopenharmony_ci      return os_time_get_absolute_timeout(max_timeout_ms * 1000000ull);
211bf215546Sopenharmony_ci}
212bf215546Sopenharmony_ci
213bf215546Sopenharmony_cistatic VkResult
214bf215546Sopenharmony_ci__vk_sync_wait(struct vk_device *device,
215bf215546Sopenharmony_ci               struct vk_sync *sync,
216bf215546Sopenharmony_ci               uint64_t wait_value,
217bf215546Sopenharmony_ci               enum vk_sync_wait_flags wait_flags,
218bf215546Sopenharmony_ci               uint64_t abs_timeout_ns)
219bf215546Sopenharmony_ci{
220bf215546Sopenharmony_ci   assert_valid_wait(sync, wait_value, wait_flags);
221bf215546Sopenharmony_ci
222bf215546Sopenharmony_ci   /* This doesn't make sense for a single wait */
223bf215546Sopenharmony_ci   assert(!(wait_flags & VK_SYNC_WAIT_ANY));
224bf215546Sopenharmony_ci
225bf215546Sopenharmony_ci   if (sync->type->wait) {
226bf215546Sopenharmony_ci      return sync->type->wait(device, sync, wait_value,
227bf215546Sopenharmony_ci                              wait_flags, abs_timeout_ns);
228bf215546Sopenharmony_ci   } else {
229bf215546Sopenharmony_ci      struct vk_sync_wait wait = {
230bf215546Sopenharmony_ci         .sync = sync,
231bf215546Sopenharmony_ci         .stage_mask = ~(VkPipelineStageFlags2)0,
232bf215546Sopenharmony_ci         .wait_value = wait_value,
233bf215546Sopenharmony_ci      };
234bf215546Sopenharmony_ci      return sync->type->wait_many(device, 1, &wait, wait_flags,
235bf215546Sopenharmony_ci                                   abs_timeout_ns);
236bf215546Sopenharmony_ci   }
237bf215546Sopenharmony_ci}
238bf215546Sopenharmony_ci
239bf215546Sopenharmony_ciVkResult
240bf215546Sopenharmony_civk_sync_wait(struct vk_device *device,
241bf215546Sopenharmony_ci             struct vk_sync *sync,
242bf215546Sopenharmony_ci             uint64_t wait_value,
243bf215546Sopenharmony_ci             enum vk_sync_wait_flags wait_flags,
244bf215546Sopenharmony_ci             uint64_t abs_timeout_ns)
245bf215546Sopenharmony_ci{
246bf215546Sopenharmony_ci   uint64_t max_abs_timeout_ns = get_max_abs_timeout_ns();
247bf215546Sopenharmony_ci   if (abs_timeout_ns > max_abs_timeout_ns) {
248bf215546Sopenharmony_ci      VkResult result =
249bf215546Sopenharmony_ci         __vk_sync_wait(device, sync, wait_value, wait_flags,
250bf215546Sopenharmony_ci                        max_abs_timeout_ns);
251bf215546Sopenharmony_ci      if (unlikely(result == VK_TIMEOUT))
252bf215546Sopenharmony_ci         return vk_device_set_lost(device, "Maximum timeout exceeded!");
253bf215546Sopenharmony_ci      return result;
254bf215546Sopenharmony_ci   } else {
255bf215546Sopenharmony_ci      return __vk_sync_wait(device, sync, wait_value, wait_flags,
256bf215546Sopenharmony_ci                            abs_timeout_ns);
257bf215546Sopenharmony_ci   }
258bf215546Sopenharmony_ci}
259bf215546Sopenharmony_ci
260bf215546Sopenharmony_cistatic bool
261bf215546Sopenharmony_cican_wait_many(uint32_t wait_count,
262bf215546Sopenharmony_ci              const struct vk_sync_wait *waits,
263bf215546Sopenharmony_ci              enum vk_sync_wait_flags wait_flags)
264bf215546Sopenharmony_ci{
265bf215546Sopenharmony_ci   if (waits[0].sync->type->wait_many == NULL)
266bf215546Sopenharmony_ci      return false;
267bf215546Sopenharmony_ci
268bf215546Sopenharmony_ci   if ((wait_flags & VK_SYNC_WAIT_ANY) &&
269bf215546Sopenharmony_ci       !(waits[0].sync->type->features & VK_SYNC_FEATURE_WAIT_ANY))
270bf215546Sopenharmony_ci      return false;
271bf215546Sopenharmony_ci
272bf215546Sopenharmony_ci   for (uint32_t i = 0; i < wait_count; i++) {
273bf215546Sopenharmony_ci      assert_valid_wait(waits[i].sync, waits[i].wait_value, wait_flags);
274bf215546Sopenharmony_ci      if (waits[i].sync->type != waits[0].sync->type)
275bf215546Sopenharmony_ci         return false;
276bf215546Sopenharmony_ci   }
277bf215546Sopenharmony_ci
278bf215546Sopenharmony_ci   return true;
279bf215546Sopenharmony_ci}
280bf215546Sopenharmony_ci
281bf215546Sopenharmony_cistatic VkResult
282bf215546Sopenharmony_ci__vk_sync_wait_many(struct vk_device *device,
283bf215546Sopenharmony_ci                    uint32_t wait_count,
284bf215546Sopenharmony_ci                    const struct vk_sync_wait *waits,
285bf215546Sopenharmony_ci                    enum vk_sync_wait_flags wait_flags,
286bf215546Sopenharmony_ci                    uint64_t abs_timeout_ns)
287bf215546Sopenharmony_ci{
288bf215546Sopenharmony_ci   if (wait_count == 0)
289bf215546Sopenharmony_ci      return VK_SUCCESS;
290bf215546Sopenharmony_ci
291bf215546Sopenharmony_ci   if (wait_count == 1) {
292bf215546Sopenharmony_ci      return __vk_sync_wait(device, waits[0].sync, waits[0].wait_value,
293bf215546Sopenharmony_ci                            wait_flags & ~VK_SYNC_WAIT_ANY, abs_timeout_ns);
294bf215546Sopenharmony_ci   }
295bf215546Sopenharmony_ci
296bf215546Sopenharmony_ci   if (can_wait_many(wait_count, waits, wait_flags)) {
297bf215546Sopenharmony_ci      return waits[0].sync->type->wait_many(device, wait_count, waits,
298bf215546Sopenharmony_ci                                            wait_flags, abs_timeout_ns);
299bf215546Sopenharmony_ci   } else if (wait_flags & VK_SYNC_WAIT_ANY) {
300bf215546Sopenharmony_ci      /* If we have multiple syncs and they don't support wait_any or they're
301bf215546Sopenharmony_ci       * not all the same type, there's nothing better we can do than spin.
302bf215546Sopenharmony_ci       */
303bf215546Sopenharmony_ci      do {
304bf215546Sopenharmony_ci         for (uint32_t i = 0; i < wait_count; i++) {
305bf215546Sopenharmony_ci            VkResult result = __vk_sync_wait(device, waits[i].sync,
306bf215546Sopenharmony_ci                                             waits[i].wait_value,
307bf215546Sopenharmony_ci                                             wait_flags & ~VK_SYNC_WAIT_ANY,
308bf215546Sopenharmony_ci                                             0 /* abs_timeout_ns */);
309bf215546Sopenharmony_ci            if (result != VK_TIMEOUT)
310bf215546Sopenharmony_ci               return result;
311bf215546Sopenharmony_ci         }
312bf215546Sopenharmony_ci      } while (os_time_get_nano() < abs_timeout_ns);
313bf215546Sopenharmony_ci
314bf215546Sopenharmony_ci      return VK_TIMEOUT;
315bf215546Sopenharmony_ci   } else {
316bf215546Sopenharmony_ci      for (uint32_t i = 0; i < wait_count; i++) {
317bf215546Sopenharmony_ci         VkResult result = __vk_sync_wait(device, waits[i].sync,
318bf215546Sopenharmony_ci                                          waits[i].wait_value,
319bf215546Sopenharmony_ci                                          wait_flags, abs_timeout_ns);
320bf215546Sopenharmony_ci         if (result != VK_SUCCESS)
321bf215546Sopenharmony_ci            return result;
322bf215546Sopenharmony_ci      }
323bf215546Sopenharmony_ci      return VK_SUCCESS;
324bf215546Sopenharmony_ci   }
325bf215546Sopenharmony_ci}
326bf215546Sopenharmony_ci
327bf215546Sopenharmony_ciVkResult
328bf215546Sopenharmony_civk_sync_wait_many(struct vk_device *device,
329bf215546Sopenharmony_ci                  uint32_t wait_count,
330bf215546Sopenharmony_ci                  const struct vk_sync_wait *waits,
331bf215546Sopenharmony_ci                  enum vk_sync_wait_flags wait_flags,
332bf215546Sopenharmony_ci                  uint64_t abs_timeout_ns)
333bf215546Sopenharmony_ci{
334bf215546Sopenharmony_ci   uint64_t max_abs_timeout_ns = get_max_abs_timeout_ns();
335bf215546Sopenharmony_ci   if (abs_timeout_ns > max_abs_timeout_ns) {
336bf215546Sopenharmony_ci      VkResult result =
337bf215546Sopenharmony_ci         __vk_sync_wait_many(device, wait_count, waits, wait_flags,
338bf215546Sopenharmony_ci                             max_abs_timeout_ns);
339bf215546Sopenharmony_ci      if (unlikely(result == VK_TIMEOUT))
340bf215546Sopenharmony_ci         return vk_device_set_lost(device, "Maximum timeout exceeded!");
341bf215546Sopenharmony_ci      return result;
342bf215546Sopenharmony_ci   } else {
343bf215546Sopenharmony_ci      return __vk_sync_wait_many(device, wait_count, waits, wait_flags,
344bf215546Sopenharmony_ci                                 abs_timeout_ns);
345bf215546Sopenharmony_ci   }
346bf215546Sopenharmony_ci}
347bf215546Sopenharmony_ci
348bf215546Sopenharmony_ciVkResult
349bf215546Sopenharmony_civk_sync_import_opaque_fd(struct vk_device *device,
350bf215546Sopenharmony_ci                         struct vk_sync *sync,
351bf215546Sopenharmony_ci                         int fd)
352bf215546Sopenharmony_ci{
353bf215546Sopenharmony_ci   VkResult result = sync->type->import_opaque_fd(device, sync, fd);
354bf215546Sopenharmony_ci   if (unlikely(result != VK_SUCCESS))
355bf215546Sopenharmony_ci      return result;
356bf215546Sopenharmony_ci
357bf215546Sopenharmony_ci   sync->flags |= VK_SYNC_IS_SHAREABLE |
358bf215546Sopenharmony_ci                  VK_SYNC_IS_SHARED;
359bf215546Sopenharmony_ci
360bf215546Sopenharmony_ci   return VK_SUCCESS;
361bf215546Sopenharmony_ci}
362bf215546Sopenharmony_ci
363bf215546Sopenharmony_ciVkResult
364bf215546Sopenharmony_civk_sync_export_opaque_fd(struct vk_device *device,
365bf215546Sopenharmony_ci                         struct vk_sync *sync,
366bf215546Sopenharmony_ci                         int *fd)
367bf215546Sopenharmony_ci{
368bf215546Sopenharmony_ci   assert(sync->flags & VK_SYNC_IS_SHAREABLE);
369bf215546Sopenharmony_ci
370bf215546Sopenharmony_ci   VkResult result = sync->type->export_opaque_fd(device, sync, fd);
371bf215546Sopenharmony_ci   if (unlikely(result != VK_SUCCESS))
372bf215546Sopenharmony_ci      return result;
373bf215546Sopenharmony_ci
374bf215546Sopenharmony_ci   sync->flags |= VK_SYNC_IS_SHARED;
375bf215546Sopenharmony_ci
376bf215546Sopenharmony_ci   return VK_SUCCESS;
377bf215546Sopenharmony_ci}
378bf215546Sopenharmony_ci
379bf215546Sopenharmony_ciVkResult
380bf215546Sopenharmony_civk_sync_import_sync_file(struct vk_device *device,
381bf215546Sopenharmony_ci                         struct vk_sync *sync,
382bf215546Sopenharmony_ci                         int sync_file)
383bf215546Sopenharmony_ci{
384bf215546Sopenharmony_ci   assert(!(sync->flags & VK_SYNC_IS_TIMELINE));
385bf215546Sopenharmony_ci
386bf215546Sopenharmony_ci   /* Silently handle negative file descriptors in case the driver doesn't
387bf215546Sopenharmony_ci    * want to bother.
388bf215546Sopenharmony_ci    */
389bf215546Sopenharmony_ci   if (sync_file < 0 && sync->type->signal)
390bf215546Sopenharmony_ci      return sync->type->signal(device, sync, 0);
391bf215546Sopenharmony_ci
392bf215546Sopenharmony_ci   return sync->type->import_sync_file(device, sync, sync_file);
393bf215546Sopenharmony_ci}
394bf215546Sopenharmony_ci
395bf215546Sopenharmony_ciVkResult
396bf215546Sopenharmony_civk_sync_export_sync_file(struct vk_device *device,
397bf215546Sopenharmony_ci                         struct vk_sync *sync,
398bf215546Sopenharmony_ci                         int *sync_file)
399bf215546Sopenharmony_ci{
400bf215546Sopenharmony_ci   assert(!(sync->flags & VK_SYNC_IS_TIMELINE));
401bf215546Sopenharmony_ci   return sync->type->export_sync_file(device, sync, sync_file);
402bf215546Sopenharmony_ci}
403