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