xref: /aosp_15_r20/external/mesa3d/src/vulkan/runtime/vk_sync.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2021 Intel Corporation
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #include "vk_sync.h"
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker #include <assert.h>
27*61046927SAndroid Build Coastguard Worker #include <string.h>
28*61046927SAndroid Build Coastguard Worker 
29*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
30*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
31*61046927SAndroid Build Coastguard Worker #include "util/os_time.h"
32*61046927SAndroid Build Coastguard Worker 
33*61046927SAndroid Build Coastguard Worker #include "vk_alloc.h"
34*61046927SAndroid Build Coastguard Worker #include "vk_device.h"
35*61046927SAndroid Build Coastguard Worker #include "vk_log.h"
36*61046927SAndroid Build Coastguard Worker 
37*61046927SAndroid Build Coastguard Worker static void
vk_sync_type_validate(const struct vk_sync_type * type)38*61046927SAndroid Build Coastguard Worker vk_sync_type_validate(const struct vk_sync_type *type)
39*61046927SAndroid Build Coastguard Worker {
40*61046927SAndroid Build Coastguard Worker    assert(type->init);
41*61046927SAndroid Build Coastguard Worker    assert(type->finish);
42*61046927SAndroid Build Coastguard Worker 
43*61046927SAndroid Build Coastguard Worker    assert(type->features & (VK_SYNC_FEATURE_BINARY |
44*61046927SAndroid Build Coastguard Worker                             VK_SYNC_FEATURE_TIMELINE));
45*61046927SAndroid Build Coastguard Worker 
46*61046927SAndroid Build Coastguard Worker    if (type->features & VK_SYNC_FEATURE_TIMELINE) {
47*61046927SAndroid Build Coastguard Worker       assert(type->features & VK_SYNC_FEATURE_GPU_WAIT);
48*61046927SAndroid Build Coastguard Worker       assert(type->features & VK_SYNC_FEATURE_CPU_WAIT);
49*61046927SAndroid Build Coastguard Worker       assert(type->features & VK_SYNC_FEATURE_CPU_SIGNAL);
50*61046927SAndroid Build Coastguard Worker       assert(type->features & (VK_SYNC_FEATURE_WAIT_BEFORE_SIGNAL |
51*61046927SAndroid Build Coastguard Worker                                VK_SYNC_FEATURE_WAIT_PENDING));
52*61046927SAndroid Build Coastguard Worker       assert(type->signal);
53*61046927SAndroid Build Coastguard Worker       assert(type->get_value);
54*61046927SAndroid Build Coastguard Worker    }
55*61046927SAndroid Build Coastguard Worker 
56*61046927SAndroid Build Coastguard Worker    if (!(type->features & VK_SYNC_FEATURE_BINARY)) {
57*61046927SAndroid Build Coastguard Worker       assert(!(type->features & (VK_SYNC_FEATURE_GPU_MULTI_WAIT |
58*61046927SAndroid Build Coastguard Worker                                  VK_SYNC_FEATURE_CPU_RESET)));
59*61046927SAndroid Build Coastguard Worker       assert(!type->import_sync_file);
60*61046927SAndroid Build Coastguard Worker       assert(!type->export_sync_file);
61*61046927SAndroid Build Coastguard Worker    }
62*61046927SAndroid Build Coastguard Worker 
63*61046927SAndroid Build Coastguard Worker    if (type->features & VK_SYNC_FEATURE_CPU_WAIT) {
64*61046927SAndroid Build Coastguard Worker       assert(type->wait || type->wait_many);
65*61046927SAndroid Build Coastguard Worker    } else {
66*61046927SAndroid Build Coastguard Worker       assert(!(type->features & (VK_SYNC_FEATURE_WAIT_ANY |
67*61046927SAndroid Build Coastguard Worker                                  VK_SYNC_FEATURE_WAIT_PENDING)));
68*61046927SAndroid Build Coastguard Worker    }
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker    if (type->features & VK_SYNC_FEATURE_GPU_MULTI_WAIT)
71*61046927SAndroid Build Coastguard Worker       assert(type->features & VK_SYNC_FEATURE_GPU_WAIT);
72*61046927SAndroid Build Coastguard Worker 
73*61046927SAndroid Build Coastguard Worker    if (type->features & VK_SYNC_FEATURE_CPU_RESET)
74*61046927SAndroid Build Coastguard Worker       assert(type->reset);
75*61046927SAndroid Build Coastguard Worker 
76*61046927SAndroid Build Coastguard Worker    if (type->features & VK_SYNC_FEATURE_CPU_SIGNAL)
77*61046927SAndroid Build Coastguard Worker       assert(type->signal);
78*61046927SAndroid Build Coastguard Worker }
79*61046927SAndroid Build Coastguard Worker 
80*61046927SAndroid Build Coastguard Worker VkResult
vk_sync_init(struct vk_device * device,struct vk_sync * sync,const struct vk_sync_type * type,enum vk_sync_flags flags,uint64_t initial_value)81*61046927SAndroid Build Coastguard Worker vk_sync_init(struct vk_device *device,
82*61046927SAndroid Build Coastguard Worker              struct vk_sync *sync,
83*61046927SAndroid Build Coastguard Worker              const struct vk_sync_type *type,
84*61046927SAndroid Build Coastguard Worker              enum vk_sync_flags flags,
85*61046927SAndroid Build Coastguard Worker              uint64_t initial_value)
86*61046927SAndroid Build Coastguard Worker {
87*61046927SAndroid Build Coastguard Worker    vk_sync_type_validate(type);
88*61046927SAndroid Build Coastguard Worker 
89*61046927SAndroid Build Coastguard Worker    if (flags & VK_SYNC_IS_TIMELINE)
90*61046927SAndroid Build Coastguard Worker       assert(type->features & VK_SYNC_FEATURE_TIMELINE);
91*61046927SAndroid Build Coastguard Worker    else
92*61046927SAndroid Build Coastguard Worker       assert(type->features & VK_SYNC_FEATURE_BINARY);
93*61046927SAndroid Build Coastguard Worker 
94*61046927SAndroid Build Coastguard Worker    assert(type->size >= sizeof(*sync));
95*61046927SAndroid Build Coastguard Worker    memset(sync, 0, type->size);
96*61046927SAndroid Build Coastguard Worker    sync->type = type;
97*61046927SAndroid Build Coastguard Worker    sync->flags = flags;
98*61046927SAndroid Build Coastguard Worker 
99*61046927SAndroid Build Coastguard Worker    return type->init(device, sync, initial_value);
100*61046927SAndroid Build Coastguard Worker }
101*61046927SAndroid Build Coastguard Worker 
102*61046927SAndroid Build Coastguard Worker void
vk_sync_finish(struct vk_device * device,struct vk_sync * sync)103*61046927SAndroid Build Coastguard Worker vk_sync_finish(struct vk_device *device,
104*61046927SAndroid Build Coastguard Worker                struct vk_sync *sync)
105*61046927SAndroid Build Coastguard Worker {
106*61046927SAndroid Build Coastguard Worker    sync->type->finish(device, sync);
107*61046927SAndroid Build Coastguard Worker }
108*61046927SAndroid Build Coastguard Worker 
109*61046927SAndroid Build Coastguard Worker VkResult
vk_sync_create(struct vk_device * device,const struct vk_sync_type * type,enum vk_sync_flags flags,uint64_t initial_value,struct vk_sync ** sync_out)110*61046927SAndroid Build Coastguard Worker vk_sync_create(struct vk_device *device,
111*61046927SAndroid Build Coastguard Worker                const struct vk_sync_type *type,
112*61046927SAndroid Build Coastguard Worker                enum vk_sync_flags flags,
113*61046927SAndroid Build Coastguard Worker                uint64_t initial_value,
114*61046927SAndroid Build Coastguard Worker                struct vk_sync **sync_out)
115*61046927SAndroid Build Coastguard Worker {
116*61046927SAndroid Build Coastguard Worker    struct vk_sync *sync;
117*61046927SAndroid Build Coastguard Worker 
118*61046927SAndroid Build Coastguard Worker    sync = vk_alloc(&device->alloc, type->size, 8,
119*61046927SAndroid Build Coastguard Worker                    VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
120*61046927SAndroid Build Coastguard Worker    if (sync == NULL)
121*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
122*61046927SAndroid Build Coastguard Worker 
123*61046927SAndroid Build Coastguard Worker    VkResult result = vk_sync_init(device, sync, type, flags, initial_value);
124*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
125*61046927SAndroid Build Coastguard Worker       vk_free(&device->alloc, sync);
126*61046927SAndroid Build Coastguard Worker       return result;
127*61046927SAndroid Build Coastguard Worker    }
128*61046927SAndroid Build Coastguard Worker 
129*61046927SAndroid Build Coastguard Worker    *sync_out = sync;
130*61046927SAndroid Build Coastguard Worker 
131*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
132*61046927SAndroid Build Coastguard Worker }
133*61046927SAndroid Build Coastguard Worker 
134*61046927SAndroid Build Coastguard Worker void
vk_sync_destroy(struct vk_device * device,struct vk_sync * sync)135*61046927SAndroid Build Coastguard Worker vk_sync_destroy(struct vk_device *device,
136*61046927SAndroid Build Coastguard Worker                 struct vk_sync *sync)
137*61046927SAndroid Build Coastguard Worker {
138*61046927SAndroid Build Coastguard Worker    vk_sync_finish(device, sync);
139*61046927SAndroid Build Coastguard Worker    vk_free(&device->alloc, sync);
140*61046927SAndroid Build Coastguard Worker }
141*61046927SAndroid Build Coastguard Worker 
142*61046927SAndroid Build Coastguard Worker VkResult
vk_sync_signal(struct vk_device * device,struct vk_sync * sync,uint64_t value)143*61046927SAndroid Build Coastguard Worker vk_sync_signal(struct vk_device *device,
144*61046927SAndroid Build Coastguard Worker                struct vk_sync *sync,
145*61046927SAndroid Build Coastguard Worker                uint64_t value)
146*61046927SAndroid Build Coastguard Worker {
147*61046927SAndroid Build Coastguard Worker    assert(sync->type->features & VK_SYNC_FEATURE_CPU_SIGNAL);
148*61046927SAndroid Build Coastguard Worker 
149*61046927SAndroid Build Coastguard Worker    if (sync->flags & VK_SYNC_IS_TIMELINE)
150*61046927SAndroid Build Coastguard Worker       assert(value > 0);
151*61046927SAndroid Build Coastguard Worker    else
152*61046927SAndroid Build Coastguard Worker       assert(value == 0);
153*61046927SAndroid Build Coastguard Worker 
154*61046927SAndroid Build Coastguard Worker    return sync->type->signal(device, sync, value);
155*61046927SAndroid Build Coastguard Worker }
156*61046927SAndroid Build Coastguard Worker 
157*61046927SAndroid Build Coastguard Worker VkResult
vk_sync_get_value(struct vk_device * device,struct vk_sync * sync,uint64_t * value)158*61046927SAndroid Build Coastguard Worker vk_sync_get_value(struct vk_device *device,
159*61046927SAndroid Build Coastguard Worker                   struct vk_sync *sync,
160*61046927SAndroid Build Coastguard Worker                   uint64_t *value)
161*61046927SAndroid Build Coastguard Worker {
162*61046927SAndroid Build Coastguard Worker    assert(sync->flags & VK_SYNC_IS_TIMELINE);
163*61046927SAndroid Build Coastguard Worker    return sync->type->get_value(device, sync, value);
164*61046927SAndroid Build Coastguard Worker }
165*61046927SAndroid Build Coastguard Worker 
166*61046927SAndroid Build Coastguard Worker VkResult
vk_sync_reset(struct vk_device * device,struct vk_sync * sync)167*61046927SAndroid Build Coastguard Worker vk_sync_reset(struct vk_device *device,
168*61046927SAndroid Build Coastguard Worker               struct vk_sync *sync)
169*61046927SAndroid Build Coastguard Worker {
170*61046927SAndroid Build Coastguard Worker    assert(sync->type->features & VK_SYNC_FEATURE_CPU_RESET);
171*61046927SAndroid Build Coastguard Worker    assert(!(sync->flags & VK_SYNC_IS_TIMELINE));
172*61046927SAndroid Build Coastguard Worker    return sync->type->reset(device, sync);
173*61046927SAndroid Build Coastguard Worker }
174*61046927SAndroid Build Coastguard Worker 
vk_sync_move(struct vk_device * device,struct vk_sync * dst,struct vk_sync * src)175*61046927SAndroid Build Coastguard Worker VkResult vk_sync_move(struct vk_device *device,
176*61046927SAndroid Build Coastguard Worker                       struct vk_sync *dst,
177*61046927SAndroid Build Coastguard Worker                       struct vk_sync *src)
178*61046927SAndroid Build Coastguard Worker {
179*61046927SAndroid Build Coastguard Worker    assert(!(dst->flags & VK_SYNC_IS_TIMELINE));
180*61046927SAndroid Build Coastguard Worker    assert(!(src->flags & VK_SYNC_IS_TIMELINE));
181*61046927SAndroid Build Coastguard Worker    assert(dst->type == src->type);
182*61046927SAndroid Build Coastguard Worker 
183*61046927SAndroid Build Coastguard Worker    return src->type->move(device, dst, src);
184*61046927SAndroid Build Coastguard Worker }
185*61046927SAndroid Build Coastguard Worker 
186*61046927SAndroid Build Coastguard Worker static void
assert_valid_wait(struct vk_sync * sync,uint64_t wait_value,enum vk_sync_wait_flags wait_flags)187*61046927SAndroid Build Coastguard Worker assert_valid_wait(struct vk_sync *sync,
188*61046927SAndroid Build Coastguard Worker                   uint64_t wait_value,
189*61046927SAndroid Build Coastguard Worker                   enum vk_sync_wait_flags wait_flags)
190*61046927SAndroid Build Coastguard Worker {
191*61046927SAndroid Build Coastguard Worker    assert(sync->type->features & VK_SYNC_FEATURE_CPU_WAIT);
192*61046927SAndroid Build Coastguard Worker 
193*61046927SAndroid Build Coastguard Worker    if (!(sync->flags & VK_SYNC_IS_TIMELINE))
194*61046927SAndroid Build Coastguard Worker       assert(wait_value == 0);
195*61046927SAndroid Build Coastguard Worker 
196*61046927SAndroid Build Coastguard Worker    if (wait_flags & VK_SYNC_WAIT_PENDING)
197*61046927SAndroid Build Coastguard Worker       assert(sync->type->features & VK_SYNC_FEATURE_WAIT_PENDING);
198*61046927SAndroid Build Coastguard Worker }
199*61046927SAndroid Build Coastguard Worker 
200*61046927SAndroid Build Coastguard Worker static uint64_t
get_max_abs_timeout_ns(void)201*61046927SAndroid Build Coastguard Worker get_max_abs_timeout_ns(void)
202*61046927SAndroid Build Coastguard Worker {
203*61046927SAndroid Build Coastguard Worker    static int max_timeout_ms = -1;
204*61046927SAndroid Build Coastguard Worker    if (max_timeout_ms < 0)
205*61046927SAndroid Build Coastguard Worker       max_timeout_ms = debug_get_num_option("MESA_VK_MAX_TIMEOUT", 0);
206*61046927SAndroid Build Coastguard Worker 
207*61046927SAndroid Build Coastguard Worker    if (max_timeout_ms == 0)
208*61046927SAndroid Build Coastguard Worker       return UINT64_MAX;
209*61046927SAndroid Build Coastguard Worker    else
210*61046927SAndroid Build Coastguard Worker       return os_time_get_absolute_timeout(max_timeout_ms * 1000000ull);
211*61046927SAndroid Build Coastguard Worker }
212*61046927SAndroid Build Coastguard Worker 
213*61046927SAndroid Build Coastguard Worker static VkResult
__vk_sync_wait(struct vk_device * device,struct vk_sync * sync,uint64_t wait_value,enum vk_sync_wait_flags wait_flags,uint64_t abs_timeout_ns)214*61046927SAndroid Build Coastguard Worker __vk_sync_wait(struct vk_device *device,
215*61046927SAndroid Build Coastguard Worker                struct vk_sync *sync,
216*61046927SAndroid Build Coastguard Worker                uint64_t wait_value,
217*61046927SAndroid Build Coastguard Worker                enum vk_sync_wait_flags wait_flags,
218*61046927SAndroid Build Coastguard Worker                uint64_t abs_timeout_ns)
219*61046927SAndroid Build Coastguard Worker {
220*61046927SAndroid Build Coastguard Worker    assert_valid_wait(sync, wait_value, wait_flags);
221*61046927SAndroid Build Coastguard Worker 
222*61046927SAndroid Build Coastguard Worker    /* This doesn't make sense for a single wait */
223*61046927SAndroid Build Coastguard Worker    assert(!(wait_flags & VK_SYNC_WAIT_ANY));
224*61046927SAndroid Build Coastguard Worker 
225*61046927SAndroid Build Coastguard Worker    if (sync->type->wait) {
226*61046927SAndroid Build Coastguard Worker       return sync->type->wait(device, sync, wait_value,
227*61046927SAndroid Build Coastguard Worker                               wait_flags, abs_timeout_ns);
228*61046927SAndroid Build Coastguard Worker    } else {
229*61046927SAndroid Build Coastguard Worker       struct vk_sync_wait wait = {
230*61046927SAndroid Build Coastguard Worker          .sync = sync,
231*61046927SAndroid Build Coastguard Worker          .stage_mask = ~(VkPipelineStageFlags2)0,
232*61046927SAndroid Build Coastguard Worker          .wait_value = wait_value,
233*61046927SAndroid Build Coastguard Worker       };
234*61046927SAndroid Build Coastguard Worker       return sync->type->wait_many(device, 1, &wait, wait_flags,
235*61046927SAndroid Build Coastguard Worker                                    abs_timeout_ns);
236*61046927SAndroid Build Coastguard Worker    }
237*61046927SAndroid Build Coastguard Worker }
238*61046927SAndroid Build Coastguard Worker 
239*61046927SAndroid Build Coastguard Worker VkResult
vk_sync_wait(struct vk_device * device,struct vk_sync * sync,uint64_t wait_value,enum vk_sync_wait_flags wait_flags,uint64_t abs_timeout_ns)240*61046927SAndroid Build Coastguard Worker vk_sync_wait(struct vk_device *device,
241*61046927SAndroid Build Coastguard Worker              struct vk_sync *sync,
242*61046927SAndroid Build Coastguard Worker              uint64_t wait_value,
243*61046927SAndroid Build Coastguard Worker              enum vk_sync_wait_flags wait_flags,
244*61046927SAndroid Build Coastguard Worker              uint64_t abs_timeout_ns)
245*61046927SAndroid Build Coastguard Worker {
246*61046927SAndroid Build Coastguard Worker    uint64_t max_abs_timeout_ns = get_max_abs_timeout_ns();
247*61046927SAndroid Build Coastguard Worker    if (abs_timeout_ns > max_abs_timeout_ns) {
248*61046927SAndroid Build Coastguard Worker       VkResult result =
249*61046927SAndroid Build Coastguard Worker          __vk_sync_wait(device, sync, wait_value, wait_flags,
250*61046927SAndroid Build Coastguard Worker                         max_abs_timeout_ns);
251*61046927SAndroid Build Coastguard Worker       if (unlikely(result == VK_TIMEOUT))
252*61046927SAndroid Build Coastguard Worker          return vk_device_set_lost(device, "Maximum timeout exceeded!");
253*61046927SAndroid Build Coastguard Worker       return result;
254*61046927SAndroid Build Coastguard Worker    } else {
255*61046927SAndroid Build Coastguard Worker       return __vk_sync_wait(device, sync, wait_value, wait_flags,
256*61046927SAndroid Build Coastguard Worker                             abs_timeout_ns);
257*61046927SAndroid Build Coastguard Worker    }
258*61046927SAndroid Build Coastguard Worker }
259*61046927SAndroid Build Coastguard Worker 
260*61046927SAndroid Build Coastguard Worker static bool
can_wait_many(uint32_t wait_count,const struct vk_sync_wait * waits,enum vk_sync_wait_flags wait_flags)261*61046927SAndroid Build Coastguard Worker can_wait_many(uint32_t wait_count,
262*61046927SAndroid Build Coastguard Worker               const struct vk_sync_wait *waits,
263*61046927SAndroid Build Coastguard Worker               enum vk_sync_wait_flags wait_flags)
264*61046927SAndroid Build Coastguard Worker {
265*61046927SAndroid Build Coastguard Worker    if (waits[0].sync->type->wait_many == NULL)
266*61046927SAndroid Build Coastguard Worker       return false;
267*61046927SAndroid Build Coastguard Worker 
268*61046927SAndroid Build Coastguard Worker    if ((wait_flags & VK_SYNC_WAIT_ANY) &&
269*61046927SAndroid Build Coastguard Worker        !(waits[0].sync->type->features & VK_SYNC_FEATURE_WAIT_ANY))
270*61046927SAndroid Build Coastguard Worker       return false;
271*61046927SAndroid Build Coastguard Worker 
272*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < wait_count; i++) {
273*61046927SAndroid Build Coastguard Worker       assert_valid_wait(waits[i].sync, waits[i].wait_value, wait_flags);
274*61046927SAndroid Build Coastguard Worker       if (waits[i].sync->type != waits[0].sync->type)
275*61046927SAndroid Build Coastguard Worker          return false;
276*61046927SAndroid Build Coastguard Worker    }
277*61046927SAndroid Build Coastguard Worker 
278*61046927SAndroid Build Coastguard Worker    return true;
279*61046927SAndroid Build Coastguard Worker }
280*61046927SAndroid Build Coastguard Worker 
281*61046927SAndroid Build Coastguard Worker static VkResult
__vk_sync_wait_many(struct vk_device * device,uint32_t wait_count,const struct vk_sync_wait * waits,enum vk_sync_wait_flags wait_flags,uint64_t abs_timeout_ns)282*61046927SAndroid Build Coastguard Worker __vk_sync_wait_many(struct vk_device *device,
283*61046927SAndroid Build Coastguard Worker                     uint32_t wait_count,
284*61046927SAndroid Build Coastguard Worker                     const struct vk_sync_wait *waits,
285*61046927SAndroid Build Coastguard Worker                     enum vk_sync_wait_flags wait_flags,
286*61046927SAndroid Build Coastguard Worker                     uint64_t abs_timeout_ns)
287*61046927SAndroid Build Coastguard Worker {
288*61046927SAndroid Build Coastguard Worker    if (wait_count == 0)
289*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
290*61046927SAndroid Build Coastguard Worker 
291*61046927SAndroid Build Coastguard Worker    if (wait_count == 1) {
292*61046927SAndroid Build Coastguard Worker       return __vk_sync_wait(device, waits[0].sync, waits[0].wait_value,
293*61046927SAndroid Build Coastguard Worker                             wait_flags & ~VK_SYNC_WAIT_ANY, abs_timeout_ns);
294*61046927SAndroid Build Coastguard Worker    }
295*61046927SAndroid Build Coastguard Worker 
296*61046927SAndroid Build Coastguard Worker    if (can_wait_many(wait_count, waits, wait_flags)) {
297*61046927SAndroid Build Coastguard Worker       return waits[0].sync->type->wait_many(device, wait_count, waits,
298*61046927SAndroid Build Coastguard Worker                                             wait_flags, abs_timeout_ns);
299*61046927SAndroid Build Coastguard Worker    } else if (wait_flags & VK_SYNC_WAIT_ANY) {
300*61046927SAndroid Build Coastguard Worker       /* If we have multiple syncs and they don't support wait_any or they're
301*61046927SAndroid Build Coastguard Worker        * not all the same type, there's nothing better we can do than spin.
302*61046927SAndroid Build Coastguard Worker        */
303*61046927SAndroid Build Coastguard Worker       do {
304*61046927SAndroid Build Coastguard Worker          for (uint32_t i = 0; i < wait_count; i++) {
305*61046927SAndroid Build Coastguard Worker             VkResult result = __vk_sync_wait(device, waits[i].sync,
306*61046927SAndroid Build Coastguard Worker                                              waits[i].wait_value,
307*61046927SAndroid Build Coastguard Worker                                              wait_flags & ~VK_SYNC_WAIT_ANY,
308*61046927SAndroid Build Coastguard Worker                                              0 /* abs_timeout_ns */);
309*61046927SAndroid Build Coastguard Worker             if (result != VK_TIMEOUT)
310*61046927SAndroid Build Coastguard Worker                return result;
311*61046927SAndroid Build Coastguard Worker          }
312*61046927SAndroid Build Coastguard Worker       } while (os_time_get_nano() < abs_timeout_ns);
313*61046927SAndroid Build Coastguard Worker 
314*61046927SAndroid Build Coastguard Worker       return VK_TIMEOUT;
315*61046927SAndroid Build Coastguard Worker    } else {
316*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < wait_count; i++) {
317*61046927SAndroid Build Coastguard Worker          VkResult result = __vk_sync_wait(device, waits[i].sync,
318*61046927SAndroid Build Coastguard Worker                                           waits[i].wait_value,
319*61046927SAndroid Build Coastguard Worker                                           wait_flags, abs_timeout_ns);
320*61046927SAndroid Build Coastguard Worker          if (result != VK_SUCCESS)
321*61046927SAndroid Build Coastguard Worker             return result;
322*61046927SAndroid Build Coastguard Worker       }
323*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
324*61046927SAndroid Build Coastguard Worker    }
325*61046927SAndroid Build Coastguard Worker }
326*61046927SAndroid Build Coastguard Worker 
327*61046927SAndroid Build Coastguard Worker VkResult
vk_sync_wait_many(struct vk_device * device,uint32_t wait_count,const struct vk_sync_wait * waits,enum vk_sync_wait_flags wait_flags,uint64_t abs_timeout_ns)328*61046927SAndroid Build Coastguard Worker vk_sync_wait_many(struct vk_device *device,
329*61046927SAndroid Build Coastguard Worker                   uint32_t wait_count,
330*61046927SAndroid Build Coastguard Worker                   const struct vk_sync_wait *waits,
331*61046927SAndroid Build Coastguard Worker                   enum vk_sync_wait_flags wait_flags,
332*61046927SAndroid Build Coastguard Worker                   uint64_t abs_timeout_ns)
333*61046927SAndroid Build Coastguard Worker {
334*61046927SAndroid Build Coastguard Worker    uint64_t max_abs_timeout_ns = get_max_abs_timeout_ns();
335*61046927SAndroid Build Coastguard Worker    if (abs_timeout_ns > max_abs_timeout_ns) {
336*61046927SAndroid Build Coastguard Worker       VkResult result =
337*61046927SAndroid Build Coastguard Worker          __vk_sync_wait_many(device, wait_count, waits, wait_flags,
338*61046927SAndroid Build Coastguard Worker                              max_abs_timeout_ns);
339*61046927SAndroid Build Coastguard Worker       if (unlikely(result == VK_TIMEOUT))
340*61046927SAndroid Build Coastguard Worker          return vk_device_set_lost(device, "Maximum timeout exceeded!");
341*61046927SAndroid Build Coastguard Worker       return result;
342*61046927SAndroid Build Coastguard Worker    } else {
343*61046927SAndroid Build Coastguard Worker       return __vk_sync_wait_many(device, wait_count, waits, wait_flags,
344*61046927SAndroid Build Coastguard Worker                                  abs_timeout_ns);
345*61046927SAndroid Build Coastguard Worker    }
346*61046927SAndroid Build Coastguard Worker }
347*61046927SAndroid Build Coastguard Worker 
348*61046927SAndroid Build Coastguard Worker VkResult
vk_sync_import_opaque_fd(struct vk_device * device,struct vk_sync * sync,int fd)349*61046927SAndroid Build Coastguard Worker vk_sync_import_opaque_fd(struct vk_device *device,
350*61046927SAndroid Build Coastguard Worker                          struct vk_sync *sync,
351*61046927SAndroid Build Coastguard Worker                          int fd)
352*61046927SAndroid Build Coastguard Worker {
353*61046927SAndroid Build Coastguard Worker    VkResult result = sync->type->import_opaque_fd(device, sync, fd);
354*61046927SAndroid Build Coastguard Worker    if (unlikely(result != VK_SUCCESS))
355*61046927SAndroid Build Coastguard Worker       return result;
356*61046927SAndroid Build Coastguard Worker 
357*61046927SAndroid Build Coastguard Worker    sync->flags |= VK_SYNC_IS_SHAREABLE |
358*61046927SAndroid Build Coastguard Worker                   VK_SYNC_IS_SHARED;
359*61046927SAndroid Build Coastguard Worker 
360*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
361*61046927SAndroid Build Coastguard Worker }
362*61046927SAndroid Build Coastguard Worker 
363*61046927SAndroid Build Coastguard Worker VkResult
vk_sync_export_opaque_fd(struct vk_device * device,struct vk_sync * sync,int * fd)364*61046927SAndroid Build Coastguard Worker vk_sync_export_opaque_fd(struct vk_device *device,
365*61046927SAndroid Build Coastguard Worker                          struct vk_sync *sync,
366*61046927SAndroid Build Coastguard Worker                          int *fd)
367*61046927SAndroid Build Coastguard Worker {
368*61046927SAndroid Build Coastguard Worker    assert(sync->flags & VK_SYNC_IS_SHAREABLE);
369*61046927SAndroid Build Coastguard Worker 
370*61046927SAndroid Build Coastguard Worker    VkResult result = sync->type->export_opaque_fd(device, sync, fd);
371*61046927SAndroid Build Coastguard Worker    if (unlikely(result != VK_SUCCESS))
372*61046927SAndroid Build Coastguard Worker       return result;
373*61046927SAndroid Build Coastguard Worker 
374*61046927SAndroid Build Coastguard Worker    sync->flags |= VK_SYNC_IS_SHARED;
375*61046927SAndroid Build Coastguard Worker 
376*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
377*61046927SAndroid Build Coastguard Worker }
378*61046927SAndroid Build Coastguard Worker 
379*61046927SAndroid Build Coastguard Worker VkResult
vk_sync_import_sync_file(struct vk_device * device,struct vk_sync * sync,int sync_file)380*61046927SAndroid Build Coastguard Worker vk_sync_import_sync_file(struct vk_device *device,
381*61046927SAndroid Build Coastguard Worker                          struct vk_sync *sync,
382*61046927SAndroid Build Coastguard Worker                          int sync_file)
383*61046927SAndroid Build Coastguard Worker {
384*61046927SAndroid Build Coastguard Worker    assert(!(sync->flags & VK_SYNC_IS_TIMELINE));
385*61046927SAndroid Build Coastguard Worker 
386*61046927SAndroid Build Coastguard Worker    /* Silently handle negative file descriptors in case the driver doesn't
387*61046927SAndroid Build Coastguard Worker     * want to bother.
388*61046927SAndroid Build Coastguard Worker     */
389*61046927SAndroid Build Coastguard Worker    if (sync_file < 0 && sync->type->signal)
390*61046927SAndroid Build Coastguard Worker       return sync->type->signal(device, sync, 0);
391*61046927SAndroid Build Coastguard Worker 
392*61046927SAndroid Build Coastguard Worker    return sync->type->import_sync_file(device, sync, sync_file);
393*61046927SAndroid Build Coastguard Worker }
394*61046927SAndroid Build Coastguard Worker 
395*61046927SAndroid Build Coastguard Worker VkResult
vk_sync_export_sync_file(struct vk_device * device,struct vk_sync * sync,int * sync_file)396*61046927SAndroid Build Coastguard Worker vk_sync_export_sync_file(struct vk_device *device,
397*61046927SAndroid Build Coastguard Worker                          struct vk_sync *sync,
398*61046927SAndroid Build Coastguard Worker                          int *sync_file)
399*61046927SAndroid Build Coastguard Worker {
400*61046927SAndroid Build Coastguard Worker    assert(!(sync->flags & VK_SYNC_IS_TIMELINE));
401*61046927SAndroid Build Coastguard Worker    return sync->type->export_sync_file(device, sync, sync_file);
402*61046927SAndroid Build Coastguard Worker }
403*61046927SAndroid Build Coastguard Worker 
404*61046927SAndroid Build Coastguard Worker VkResult
vk_sync_import_win32_handle(struct vk_device * device,struct vk_sync * sync,void * handle,const wchar_t * name)405*61046927SAndroid Build Coastguard Worker vk_sync_import_win32_handle(struct vk_device *device,
406*61046927SAndroid Build Coastguard Worker                             struct vk_sync *sync,
407*61046927SAndroid Build Coastguard Worker                             void *handle,
408*61046927SAndroid Build Coastguard Worker                             const wchar_t *name)
409*61046927SAndroid Build Coastguard Worker {
410*61046927SAndroid Build Coastguard Worker    VkResult result = sync->type->import_win32_handle(device, sync, handle, name);
411*61046927SAndroid Build Coastguard Worker    if (unlikely(result != VK_SUCCESS))
412*61046927SAndroid Build Coastguard Worker       return result;
413*61046927SAndroid Build Coastguard Worker 
414*61046927SAndroid Build Coastguard Worker    sync->flags |= VK_SYNC_IS_SHAREABLE |
415*61046927SAndroid Build Coastguard Worker                   VK_SYNC_IS_SHARED;
416*61046927SAndroid Build Coastguard Worker 
417*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
418*61046927SAndroid Build Coastguard Worker }
419*61046927SAndroid Build Coastguard Worker 
420*61046927SAndroid Build Coastguard Worker VkResult
vk_sync_export_win32_handle(struct vk_device * device,struct vk_sync * sync,void ** handle)421*61046927SAndroid Build Coastguard Worker vk_sync_export_win32_handle(struct vk_device *device,
422*61046927SAndroid Build Coastguard Worker                             struct vk_sync *sync,
423*61046927SAndroid Build Coastguard Worker                             void **handle)
424*61046927SAndroid Build Coastguard Worker {
425*61046927SAndroid Build Coastguard Worker    assert(sync->flags & VK_SYNC_IS_SHAREABLE);
426*61046927SAndroid Build Coastguard Worker 
427*61046927SAndroid Build Coastguard Worker    VkResult result = sync->type->export_win32_handle(device, sync, handle);
428*61046927SAndroid Build Coastguard Worker    if (unlikely(result != VK_SUCCESS))
429*61046927SAndroid Build Coastguard Worker       return result;
430*61046927SAndroid Build Coastguard Worker 
431*61046927SAndroid Build Coastguard Worker    sync->flags |= VK_SYNC_IS_SHARED;
432*61046927SAndroid Build Coastguard Worker 
433*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
434*61046927SAndroid Build Coastguard Worker }
435*61046927SAndroid Build Coastguard Worker 
436*61046927SAndroid Build Coastguard Worker VkResult
vk_sync_set_win32_export_params(struct vk_device * device,struct vk_sync * sync,const void * security_attributes,uint32_t access,const wchar_t * name)437*61046927SAndroid Build Coastguard Worker vk_sync_set_win32_export_params(struct vk_device *device,
438*61046927SAndroid Build Coastguard Worker                                 struct vk_sync *sync,
439*61046927SAndroid Build Coastguard Worker                                 const void *security_attributes,
440*61046927SAndroid Build Coastguard Worker                                 uint32_t access,
441*61046927SAndroid Build Coastguard Worker                                 const wchar_t *name)
442*61046927SAndroid Build Coastguard Worker {
443*61046927SAndroid Build Coastguard Worker    assert(sync->flags & VK_SYNC_IS_SHARED);
444*61046927SAndroid Build Coastguard Worker 
445*61046927SAndroid Build Coastguard Worker    return sync->type->set_win32_export_params(device, sync, security_attributes, access, name);
446*61046927SAndroid Build Coastguard Worker }
447