1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2020 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_device.h"
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker #include "vk_common_entrypoints.h"
27*61046927SAndroid Build Coastguard Worker #include "vk_instance.h"
28*61046927SAndroid Build Coastguard Worker #include "vk_log.h"
29*61046927SAndroid Build Coastguard Worker #include "vk_physical_device.h"
30*61046927SAndroid Build Coastguard Worker #include "vk_queue.h"
31*61046927SAndroid Build Coastguard Worker #include "vk_sync.h"
32*61046927SAndroid Build Coastguard Worker #include "vk_sync_timeline.h"
33*61046927SAndroid Build Coastguard Worker #include "vk_util.h"
34*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
35*61046927SAndroid Build Coastguard Worker #include "util/hash_table.h"
36*61046927SAndroid Build Coastguard Worker #include "util/perf/cpu_trace.h"
37*61046927SAndroid Build Coastguard Worker #include "util/ralloc.h"
38*61046927SAndroid Build Coastguard Worker
39*61046927SAndroid Build Coastguard Worker static enum vk_device_timeline_mode
get_timeline_mode(struct vk_physical_device * physical_device)40*61046927SAndroid Build Coastguard Worker get_timeline_mode(struct vk_physical_device *physical_device)
41*61046927SAndroid Build Coastguard Worker {
42*61046927SAndroid Build Coastguard Worker if (physical_device->supported_sync_types == NULL)
43*61046927SAndroid Build Coastguard Worker return VK_DEVICE_TIMELINE_MODE_NONE;
44*61046927SAndroid Build Coastguard Worker
45*61046927SAndroid Build Coastguard Worker const struct vk_sync_type *timeline_type = NULL;
46*61046927SAndroid Build Coastguard Worker for (const struct vk_sync_type *const *t =
47*61046927SAndroid Build Coastguard Worker physical_device->supported_sync_types; *t; t++) {
48*61046927SAndroid Build Coastguard Worker if ((*t)->features & VK_SYNC_FEATURE_TIMELINE) {
49*61046927SAndroid Build Coastguard Worker /* We can only have one timeline mode */
50*61046927SAndroid Build Coastguard Worker assert(timeline_type == NULL);
51*61046927SAndroid Build Coastguard Worker timeline_type = *t;
52*61046927SAndroid Build Coastguard Worker }
53*61046927SAndroid Build Coastguard Worker }
54*61046927SAndroid Build Coastguard Worker
55*61046927SAndroid Build Coastguard Worker if (timeline_type == NULL)
56*61046927SAndroid Build Coastguard Worker return VK_DEVICE_TIMELINE_MODE_NONE;
57*61046927SAndroid Build Coastguard Worker
58*61046927SAndroid Build Coastguard Worker if (vk_sync_type_is_vk_sync_timeline(timeline_type))
59*61046927SAndroid Build Coastguard Worker return VK_DEVICE_TIMELINE_MODE_EMULATED;
60*61046927SAndroid Build Coastguard Worker
61*61046927SAndroid Build Coastguard Worker if (timeline_type->features & VK_SYNC_FEATURE_WAIT_BEFORE_SIGNAL)
62*61046927SAndroid Build Coastguard Worker return VK_DEVICE_TIMELINE_MODE_NATIVE;
63*61046927SAndroid Build Coastguard Worker
64*61046927SAndroid Build Coastguard Worker /* For assisted mode, we require a few additional things of all sync types
65*61046927SAndroid Build Coastguard Worker * which may be used as semaphores.
66*61046927SAndroid Build Coastguard Worker */
67*61046927SAndroid Build Coastguard Worker for (const struct vk_sync_type *const *t =
68*61046927SAndroid Build Coastguard Worker physical_device->supported_sync_types; *t; t++) {
69*61046927SAndroid Build Coastguard Worker if ((*t)->features & VK_SYNC_FEATURE_GPU_WAIT) {
70*61046927SAndroid Build Coastguard Worker assert((*t)->features & VK_SYNC_FEATURE_WAIT_PENDING);
71*61046927SAndroid Build Coastguard Worker if ((*t)->features & VK_SYNC_FEATURE_BINARY)
72*61046927SAndroid Build Coastguard Worker assert((*t)->features & VK_SYNC_FEATURE_CPU_RESET);
73*61046927SAndroid Build Coastguard Worker }
74*61046927SAndroid Build Coastguard Worker }
75*61046927SAndroid Build Coastguard Worker
76*61046927SAndroid Build Coastguard Worker return VK_DEVICE_TIMELINE_MODE_ASSISTED;
77*61046927SAndroid Build Coastguard Worker }
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard Worker static void
collect_enabled_features(struct vk_device * device,const VkDeviceCreateInfo * pCreateInfo)80*61046927SAndroid Build Coastguard Worker collect_enabled_features(struct vk_device *device,
81*61046927SAndroid Build Coastguard Worker const VkDeviceCreateInfo *pCreateInfo)
82*61046927SAndroid Build Coastguard Worker {
83*61046927SAndroid Build Coastguard Worker if (pCreateInfo->pEnabledFeatures)
84*61046927SAndroid Build Coastguard Worker vk_set_physical_device_features_1_0(&device->enabled_features, pCreateInfo->pEnabledFeatures);
85*61046927SAndroid Build Coastguard Worker vk_set_physical_device_features(&device->enabled_features, pCreateInfo->pNext);
86*61046927SAndroid Build Coastguard Worker }
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker VkResult
vk_device_init(struct vk_device * device,struct vk_physical_device * physical_device,const struct vk_device_dispatch_table * dispatch_table,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * alloc)89*61046927SAndroid Build Coastguard Worker vk_device_init(struct vk_device *device,
90*61046927SAndroid Build Coastguard Worker struct vk_physical_device *physical_device,
91*61046927SAndroid Build Coastguard Worker const struct vk_device_dispatch_table *dispatch_table,
92*61046927SAndroid Build Coastguard Worker const VkDeviceCreateInfo *pCreateInfo,
93*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc)
94*61046927SAndroid Build Coastguard Worker {
95*61046927SAndroid Build Coastguard Worker memset(device, 0, sizeof(*device));
96*61046927SAndroid Build Coastguard Worker vk_object_base_init(device, &device->base, VK_OBJECT_TYPE_DEVICE);
97*61046927SAndroid Build Coastguard Worker if (alloc != NULL)
98*61046927SAndroid Build Coastguard Worker device->alloc = *alloc;
99*61046927SAndroid Build Coastguard Worker else
100*61046927SAndroid Build Coastguard Worker device->alloc = physical_device->instance->alloc;
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Worker device->physical = physical_device;
103*61046927SAndroid Build Coastguard Worker
104*61046927SAndroid Build Coastguard Worker if (dispatch_table) {
105*61046927SAndroid Build Coastguard Worker device->dispatch_table = *dispatch_table;
106*61046927SAndroid Build Coastguard Worker
107*61046927SAndroid Build Coastguard Worker /* Add common entrypoints without overwriting driver-provided ones. */
108*61046927SAndroid Build Coastguard Worker vk_device_dispatch_table_from_entrypoints(
109*61046927SAndroid Build Coastguard Worker &device->dispatch_table, &vk_common_device_entrypoints, false);
110*61046927SAndroid Build Coastguard Worker }
111*61046927SAndroid Build Coastguard Worker
112*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
113*61046927SAndroid Build Coastguard Worker int idx;
114*61046927SAndroid Build Coastguard Worker for (idx = 0; idx < VK_DEVICE_EXTENSION_COUNT; idx++) {
115*61046927SAndroid Build Coastguard Worker if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
116*61046927SAndroid Build Coastguard Worker vk_device_extensions[idx].extensionName) == 0)
117*61046927SAndroid Build Coastguard Worker break;
118*61046927SAndroid Build Coastguard Worker }
119*61046927SAndroid Build Coastguard Worker
120*61046927SAndroid Build Coastguard Worker if (idx >= VK_DEVICE_EXTENSION_COUNT)
121*61046927SAndroid Build Coastguard Worker return vk_errorf(physical_device, VK_ERROR_EXTENSION_NOT_PRESENT,
122*61046927SAndroid Build Coastguard Worker "%s not supported",
123*61046927SAndroid Build Coastguard Worker pCreateInfo->ppEnabledExtensionNames[i]);
124*61046927SAndroid Build Coastguard Worker
125*61046927SAndroid Build Coastguard Worker if (!physical_device->supported_extensions.extensions[idx])
126*61046927SAndroid Build Coastguard Worker return vk_errorf(physical_device, VK_ERROR_EXTENSION_NOT_PRESENT,
127*61046927SAndroid Build Coastguard Worker "%s not supported",
128*61046927SAndroid Build Coastguard Worker pCreateInfo->ppEnabledExtensionNames[i]);
129*61046927SAndroid Build Coastguard Worker
130*61046927SAndroid Build Coastguard Worker #ifdef ANDROID_STRICT
131*61046927SAndroid Build Coastguard Worker if (!vk_android_allowed_device_extensions.extensions[idx])
132*61046927SAndroid Build Coastguard Worker return vk_errorf(physical_device, VK_ERROR_EXTENSION_NOT_PRESENT,
133*61046927SAndroid Build Coastguard Worker "%s not supported",
134*61046927SAndroid Build Coastguard Worker pCreateInfo->ppEnabledExtensionNames[i]);
135*61046927SAndroid Build Coastguard Worker #endif
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Worker device->enabled_extensions.extensions[idx] = true;
138*61046927SAndroid Build Coastguard Worker }
139*61046927SAndroid Build Coastguard Worker
140*61046927SAndroid Build Coastguard Worker VkResult result =
141*61046927SAndroid Build Coastguard Worker vk_physical_device_check_device_features(physical_device,
142*61046927SAndroid Build Coastguard Worker pCreateInfo);
143*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
144*61046927SAndroid Build Coastguard Worker return result;
145*61046927SAndroid Build Coastguard Worker
146*61046927SAndroid Build Coastguard Worker collect_enabled_features(device, pCreateInfo);
147*61046927SAndroid Build Coastguard Worker
148*61046927SAndroid Build Coastguard Worker p_atomic_set(&device->private_data_next_index, 0);
149*61046927SAndroid Build Coastguard Worker
150*61046927SAndroid Build Coastguard Worker list_inithead(&device->queues);
151*61046927SAndroid Build Coastguard Worker
152*61046927SAndroid Build Coastguard Worker device->drm_fd = -1;
153*61046927SAndroid Build Coastguard Worker device->mem_cache = NULL;
154*61046927SAndroid Build Coastguard Worker
155*61046927SAndroid Build Coastguard Worker device->timeline_mode = get_timeline_mode(physical_device);
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker switch (device->timeline_mode) {
158*61046927SAndroid Build Coastguard Worker case VK_DEVICE_TIMELINE_MODE_NONE:
159*61046927SAndroid Build Coastguard Worker case VK_DEVICE_TIMELINE_MODE_NATIVE:
160*61046927SAndroid Build Coastguard Worker device->submit_mode = VK_QUEUE_SUBMIT_MODE_IMMEDIATE;
161*61046927SAndroid Build Coastguard Worker break;
162*61046927SAndroid Build Coastguard Worker
163*61046927SAndroid Build Coastguard Worker case VK_DEVICE_TIMELINE_MODE_EMULATED:
164*61046927SAndroid Build Coastguard Worker device->submit_mode = VK_QUEUE_SUBMIT_MODE_DEFERRED;
165*61046927SAndroid Build Coastguard Worker break;
166*61046927SAndroid Build Coastguard Worker
167*61046927SAndroid Build Coastguard Worker case VK_DEVICE_TIMELINE_MODE_ASSISTED:
168*61046927SAndroid Build Coastguard Worker if (os_get_option("MESA_VK_ENABLE_SUBMIT_THREAD")) {
169*61046927SAndroid Build Coastguard Worker if (debug_get_bool_option("MESA_VK_ENABLE_SUBMIT_THREAD", false)) {
170*61046927SAndroid Build Coastguard Worker device->submit_mode = VK_QUEUE_SUBMIT_MODE_THREADED;
171*61046927SAndroid Build Coastguard Worker } else {
172*61046927SAndroid Build Coastguard Worker device->submit_mode = VK_QUEUE_SUBMIT_MODE_IMMEDIATE;
173*61046927SAndroid Build Coastguard Worker }
174*61046927SAndroid Build Coastguard Worker } else {
175*61046927SAndroid Build Coastguard Worker device->submit_mode = VK_QUEUE_SUBMIT_MODE_THREADED_ON_DEMAND;
176*61046927SAndroid Build Coastguard Worker }
177*61046927SAndroid Build Coastguard Worker break;
178*61046927SAndroid Build Coastguard Worker
179*61046927SAndroid Build Coastguard Worker default:
180*61046927SAndroid Build Coastguard Worker unreachable("Invalid timeline mode");
181*61046927SAndroid Build Coastguard Worker }
182*61046927SAndroid Build Coastguard Worker
183*61046927SAndroid Build Coastguard Worker #if DETECT_OS_ANDROID
184*61046927SAndroid Build Coastguard Worker mtx_init(&device->swapchain_private_mtx, mtx_plain);
185*61046927SAndroid Build Coastguard Worker device->swapchain_private = NULL;
186*61046927SAndroid Build Coastguard Worker #endif /* DETECT_OS_ANDROID */
187*61046927SAndroid Build Coastguard Worker
188*61046927SAndroid Build Coastguard Worker simple_mtx_init(&device->trace_mtx, mtx_plain);
189*61046927SAndroid Build Coastguard Worker
190*61046927SAndroid Build Coastguard Worker vk_foreach_struct_const (ext, pCreateInfo->pNext) {
191*61046927SAndroid Build Coastguard Worker switch (ext->sType) {
192*61046927SAndroid Build Coastguard Worker case VK_STRUCTURE_TYPE_DEVICE_PIPELINE_BINARY_INTERNAL_CACHE_CONTROL_KHR: {
193*61046927SAndroid Build Coastguard Worker const VkDevicePipelineBinaryInternalCacheControlKHR *cache_control = (const void *)ext;
194*61046927SAndroid Build Coastguard Worker if (cache_control->disableInternalCache)
195*61046927SAndroid Build Coastguard Worker device->disable_internal_cache = true;
196*61046927SAndroid Build Coastguard Worker break;
197*61046927SAndroid Build Coastguard Worker }
198*61046927SAndroid Build Coastguard Worker default:
199*61046927SAndroid Build Coastguard Worker break;
200*61046927SAndroid Build Coastguard Worker }
201*61046927SAndroid Build Coastguard Worker }
202*61046927SAndroid Build Coastguard Worker
203*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
204*61046927SAndroid Build Coastguard Worker }
205*61046927SAndroid Build Coastguard Worker
206*61046927SAndroid Build Coastguard Worker void
vk_device_finish(struct vk_device * device)207*61046927SAndroid Build Coastguard Worker vk_device_finish(struct vk_device *device)
208*61046927SAndroid Build Coastguard Worker {
209*61046927SAndroid Build Coastguard Worker /* Drivers should tear down their own queues */
210*61046927SAndroid Build Coastguard Worker assert(list_is_empty(&device->queues));
211*61046927SAndroid Build Coastguard Worker
212*61046927SAndroid Build Coastguard Worker vk_memory_trace_finish(device);
213*61046927SAndroid Build Coastguard Worker
214*61046927SAndroid Build Coastguard Worker #if DETECT_OS_ANDROID
215*61046927SAndroid Build Coastguard Worker if (device->swapchain_private) {
216*61046927SAndroid Build Coastguard Worker hash_table_foreach(device->swapchain_private, entry)
217*61046927SAndroid Build Coastguard Worker util_sparse_array_finish(entry->data);
218*61046927SAndroid Build Coastguard Worker ralloc_free(device->swapchain_private);
219*61046927SAndroid Build Coastguard Worker }
220*61046927SAndroid Build Coastguard Worker #endif /* DETECT_OS_ANDROID */
221*61046927SAndroid Build Coastguard Worker
222*61046927SAndroid Build Coastguard Worker simple_mtx_destroy(&device->trace_mtx);
223*61046927SAndroid Build Coastguard Worker
224*61046927SAndroid Build Coastguard Worker vk_object_base_finish(&device->base);
225*61046927SAndroid Build Coastguard Worker }
226*61046927SAndroid Build Coastguard Worker
227*61046927SAndroid Build Coastguard Worker void
vk_device_enable_threaded_submit(struct vk_device * device)228*61046927SAndroid Build Coastguard Worker vk_device_enable_threaded_submit(struct vk_device *device)
229*61046927SAndroid Build Coastguard Worker {
230*61046927SAndroid Build Coastguard Worker /* This must be called before any queues are created */
231*61046927SAndroid Build Coastguard Worker assert(list_is_empty(&device->queues));
232*61046927SAndroid Build Coastguard Worker
233*61046927SAndroid Build Coastguard Worker /* In order to use threaded submit, we need every sync type that can be
234*61046927SAndroid Build Coastguard Worker * used as a wait fence for vkQueueSubmit() to support WAIT_PENDING.
235*61046927SAndroid Build Coastguard Worker * It's required for cross-thread/process submit re-ordering.
236*61046927SAndroid Build Coastguard Worker */
237*61046927SAndroid Build Coastguard Worker for (const struct vk_sync_type *const *t =
238*61046927SAndroid Build Coastguard Worker device->physical->supported_sync_types; *t; t++) {
239*61046927SAndroid Build Coastguard Worker if ((*t)->features & VK_SYNC_FEATURE_GPU_WAIT)
240*61046927SAndroid Build Coastguard Worker assert((*t)->features & VK_SYNC_FEATURE_WAIT_PENDING);
241*61046927SAndroid Build Coastguard Worker }
242*61046927SAndroid Build Coastguard Worker
243*61046927SAndroid Build Coastguard Worker /* Any binary vk_sync types which will be used as permanent semaphore
244*61046927SAndroid Build Coastguard Worker * payloads also need to support vk_sync_type::move, but that's a lot
245*61046927SAndroid Build Coastguard Worker * harder to assert since it only applies to permanent semaphore payloads.
246*61046927SAndroid Build Coastguard Worker */
247*61046927SAndroid Build Coastguard Worker
248*61046927SAndroid Build Coastguard Worker if (device->submit_mode != VK_QUEUE_SUBMIT_MODE_THREADED)
249*61046927SAndroid Build Coastguard Worker device->submit_mode = VK_QUEUE_SUBMIT_MODE_THREADED_ON_DEMAND;
250*61046927SAndroid Build Coastguard Worker }
251*61046927SAndroid Build Coastguard Worker
252*61046927SAndroid Build Coastguard Worker VkResult
vk_device_flush(struct vk_device * device)253*61046927SAndroid Build Coastguard Worker vk_device_flush(struct vk_device *device)
254*61046927SAndroid Build Coastguard Worker {
255*61046927SAndroid Build Coastguard Worker if (device->submit_mode != VK_QUEUE_SUBMIT_MODE_DEFERRED)
256*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
257*61046927SAndroid Build Coastguard Worker
258*61046927SAndroid Build Coastguard Worker bool progress;
259*61046927SAndroid Build Coastguard Worker do {
260*61046927SAndroid Build Coastguard Worker progress = false;
261*61046927SAndroid Build Coastguard Worker
262*61046927SAndroid Build Coastguard Worker vk_foreach_queue(queue, device) {
263*61046927SAndroid Build Coastguard Worker uint32_t queue_submit_count;
264*61046927SAndroid Build Coastguard Worker VkResult result = vk_queue_flush(queue, &queue_submit_count);
265*61046927SAndroid Build Coastguard Worker if (unlikely(result != VK_SUCCESS))
266*61046927SAndroid Build Coastguard Worker return result;
267*61046927SAndroid Build Coastguard Worker
268*61046927SAndroid Build Coastguard Worker if (queue_submit_count)
269*61046927SAndroid Build Coastguard Worker progress = true;
270*61046927SAndroid Build Coastguard Worker }
271*61046927SAndroid Build Coastguard Worker } while (progress);
272*61046927SAndroid Build Coastguard Worker
273*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
274*61046927SAndroid Build Coastguard Worker }
275*61046927SAndroid Build Coastguard Worker
276*61046927SAndroid Build Coastguard Worker static const char *
timeline_mode_str(struct vk_device * device)277*61046927SAndroid Build Coastguard Worker timeline_mode_str(struct vk_device *device)
278*61046927SAndroid Build Coastguard Worker {
279*61046927SAndroid Build Coastguard Worker switch (device->timeline_mode) {
280*61046927SAndroid Build Coastguard Worker #define CASE(X) case VK_DEVICE_TIMELINE_MODE_##X: return #X;
281*61046927SAndroid Build Coastguard Worker CASE(NONE)
282*61046927SAndroid Build Coastguard Worker CASE(EMULATED)
283*61046927SAndroid Build Coastguard Worker CASE(ASSISTED)
284*61046927SAndroid Build Coastguard Worker CASE(NATIVE)
285*61046927SAndroid Build Coastguard Worker #undef CASE
286*61046927SAndroid Build Coastguard Worker default: return "UNKNOWN";
287*61046927SAndroid Build Coastguard Worker }
288*61046927SAndroid Build Coastguard Worker }
289*61046927SAndroid Build Coastguard Worker
290*61046927SAndroid Build Coastguard Worker void
_vk_device_report_lost(struct vk_device * device)291*61046927SAndroid Build Coastguard Worker _vk_device_report_lost(struct vk_device *device)
292*61046927SAndroid Build Coastguard Worker {
293*61046927SAndroid Build Coastguard Worker assert(p_atomic_read(&device->_lost.lost) > 0);
294*61046927SAndroid Build Coastguard Worker
295*61046927SAndroid Build Coastguard Worker device->_lost.reported = true;
296*61046927SAndroid Build Coastguard Worker
297*61046927SAndroid Build Coastguard Worker vk_foreach_queue(queue, device) {
298*61046927SAndroid Build Coastguard Worker if (queue->_lost.lost) {
299*61046927SAndroid Build Coastguard Worker __vk_errorf(queue, VK_ERROR_DEVICE_LOST,
300*61046927SAndroid Build Coastguard Worker queue->_lost.error_file, queue->_lost.error_line,
301*61046927SAndroid Build Coastguard Worker "%s", queue->_lost.error_msg);
302*61046927SAndroid Build Coastguard Worker }
303*61046927SAndroid Build Coastguard Worker }
304*61046927SAndroid Build Coastguard Worker
305*61046927SAndroid Build Coastguard Worker vk_logd(VK_LOG_OBJS(device), "Timeline mode is %s.",
306*61046927SAndroid Build Coastguard Worker timeline_mode_str(device));
307*61046927SAndroid Build Coastguard Worker }
308*61046927SAndroid Build Coastguard Worker
309*61046927SAndroid Build Coastguard Worker VkResult
_vk_device_set_lost(struct vk_device * device,const char * file,int line,const char * msg,...)310*61046927SAndroid Build Coastguard Worker _vk_device_set_lost(struct vk_device *device,
311*61046927SAndroid Build Coastguard Worker const char *file, int line,
312*61046927SAndroid Build Coastguard Worker const char *msg, ...)
313*61046927SAndroid Build Coastguard Worker {
314*61046927SAndroid Build Coastguard Worker /* This flushes out any per-queue device lost messages */
315*61046927SAndroid Build Coastguard Worker if (vk_device_is_lost(device))
316*61046927SAndroid Build Coastguard Worker return VK_ERROR_DEVICE_LOST;
317*61046927SAndroid Build Coastguard Worker
318*61046927SAndroid Build Coastguard Worker p_atomic_inc(&device->_lost.lost);
319*61046927SAndroid Build Coastguard Worker device->_lost.reported = true;
320*61046927SAndroid Build Coastguard Worker
321*61046927SAndroid Build Coastguard Worker va_list ap;
322*61046927SAndroid Build Coastguard Worker va_start(ap, msg);
323*61046927SAndroid Build Coastguard Worker __vk_errorv(device, VK_ERROR_DEVICE_LOST, file, line, msg, ap);
324*61046927SAndroid Build Coastguard Worker va_end(ap);
325*61046927SAndroid Build Coastguard Worker
326*61046927SAndroid Build Coastguard Worker vk_logd(VK_LOG_OBJS(device), "Timeline mode is %s.",
327*61046927SAndroid Build Coastguard Worker timeline_mode_str(device));
328*61046927SAndroid Build Coastguard Worker
329*61046927SAndroid Build Coastguard Worker if (debug_get_bool_option("MESA_VK_ABORT_ON_DEVICE_LOSS", false))
330*61046927SAndroid Build Coastguard Worker abort();
331*61046927SAndroid Build Coastguard Worker
332*61046927SAndroid Build Coastguard Worker return VK_ERROR_DEVICE_LOST;
333*61046927SAndroid Build Coastguard Worker }
334*61046927SAndroid Build Coastguard Worker
335*61046927SAndroid Build Coastguard Worker PFN_vkVoidFunction
vk_device_get_proc_addr(const struct vk_device * device,const char * name)336*61046927SAndroid Build Coastguard Worker vk_device_get_proc_addr(const struct vk_device *device,
337*61046927SAndroid Build Coastguard Worker const char *name)
338*61046927SAndroid Build Coastguard Worker {
339*61046927SAndroid Build Coastguard Worker if (device == NULL || name == NULL)
340*61046927SAndroid Build Coastguard Worker return NULL;
341*61046927SAndroid Build Coastguard Worker
342*61046927SAndroid Build Coastguard Worker struct vk_instance *instance = device->physical->instance;
343*61046927SAndroid Build Coastguard Worker return vk_device_dispatch_table_get_if_supported(&device->dispatch_table,
344*61046927SAndroid Build Coastguard Worker name,
345*61046927SAndroid Build Coastguard Worker instance->app_info.api_version,
346*61046927SAndroid Build Coastguard Worker &instance->enabled_extensions,
347*61046927SAndroid Build Coastguard Worker &device->enabled_extensions);
348*61046927SAndroid Build Coastguard Worker }
349*61046927SAndroid Build Coastguard Worker
350*61046927SAndroid Build Coastguard Worker VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
vk_common_GetDeviceProcAddr(VkDevice _device,const char * pName)351*61046927SAndroid Build Coastguard Worker vk_common_GetDeviceProcAddr(VkDevice _device,
352*61046927SAndroid Build Coastguard Worker const char *pName)
353*61046927SAndroid Build Coastguard Worker {
354*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(vk_device, device, _device);
355*61046927SAndroid Build Coastguard Worker return vk_device_get_proc_addr(device, pName);
356*61046927SAndroid Build Coastguard Worker }
357*61046927SAndroid Build Coastguard Worker
358*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
vk_common_GetDeviceQueue(VkDevice _device,uint32_t queueFamilyIndex,uint32_t queueIndex,VkQueue * pQueue)359*61046927SAndroid Build Coastguard Worker vk_common_GetDeviceQueue(VkDevice _device,
360*61046927SAndroid Build Coastguard Worker uint32_t queueFamilyIndex,
361*61046927SAndroid Build Coastguard Worker uint32_t queueIndex,
362*61046927SAndroid Build Coastguard Worker VkQueue *pQueue)
363*61046927SAndroid Build Coastguard Worker {
364*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(vk_device, device, _device);
365*61046927SAndroid Build Coastguard Worker
366*61046927SAndroid Build Coastguard Worker const VkDeviceQueueInfo2 info = {
367*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,
368*61046927SAndroid Build Coastguard Worker .pNext = NULL,
369*61046927SAndroid Build Coastguard Worker /* flags = 0 because (Vulkan spec 1.2.170 - vkGetDeviceQueue):
370*61046927SAndroid Build Coastguard Worker *
371*61046927SAndroid Build Coastguard Worker * "vkGetDeviceQueue must only be used to get queues that were
372*61046927SAndroid Build Coastguard Worker * created with the flags parameter of VkDeviceQueueCreateInfo set
373*61046927SAndroid Build Coastguard Worker * to zero. To get queues that were created with a non-zero flags
374*61046927SAndroid Build Coastguard Worker * parameter use vkGetDeviceQueue2."
375*61046927SAndroid Build Coastguard Worker */
376*61046927SAndroid Build Coastguard Worker .flags = 0,
377*61046927SAndroid Build Coastguard Worker .queueFamilyIndex = queueFamilyIndex,
378*61046927SAndroid Build Coastguard Worker .queueIndex = queueIndex,
379*61046927SAndroid Build Coastguard Worker };
380*61046927SAndroid Build Coastguard Worker
381*61046927SAndroid Build Coastguard Worker device->dispatch_table.GetDeviceQueue2(_device, &info, pQueue);
382*61046927SAndroid Build Coastguard Worker }
383*61046927SAndroid Build Coastguard Worker
384*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
vk_common_GetDeviceQueue2(VkDevice _device,const VkDeviceQueueInfo2 * pQueueInfo,VkQueue * pQueue)385*61046927SAndroid Build Coastguard Worker vk_common_GetDeviceQueue2(VkDevice _device,
386*61046927SAndroid Build Coastguard Worker const VkDeviceQueueInfo2 *pQueueInfo,
387*61046927SAndroid Build Coastguard Worker VkQueue *pQueue)
388*61046927SAndroid Build Coastguard Worker {
389*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(vk_device, device, _device);
390*61046927SAndroid Build Coastguard Worker
391*61046927SAndroid Build Coastguard Worker struct vk_queue *queue = NULL;
392*61046927SAndroid Build Coastguard Worker vk_foreach_queue(iter, device) {
393*61046927SAndroid Build Coastguard Worker if (iter->queue_family_index == pQueueInfo->queueFamilyIndex &&
394*61046927SAndroid Build Coastguard Worker iter->index_in_family == pQueueInfo->queueIndex) {
395*61046927SAndroid Build Coastguard Worker queue = iter;
396*61046927SAndroid Build Coastguard Worker break;
397*61046927SAndroid Build Coastguard Worker }
398*61046927SAndroid Build Coastguard Worker }
399*61046927SAndroid Build Coastguard Worker
400*61046927SAndroid Build Coastguard Worker /* From the Vulkan 1.1.70 spec:
401*61046927SAndroid Build Coastguard Worker *
402*61046927SAndroid Build Coastguard Worker * "The queue returned by vkGetDeviceQueue2 must have the same flags
403*61046927SAndroid Build Coastguard Worker * value from this structure as that used at device creation time in a
404*61046927SAndroid Build Coastguard Worker * VkDeviceQueueCreateInfo instance. If no matching flags were specified
405*61046927SAndroid Build Coastguard Worker * at device creation time then pQueue will return VK_NULL_HANDLE."
406*61046927SAndroid Build Coastguard Worker */
407*61046927SAndroid Build Coastguard Worker if (queue && queue->flags == pQueueInfo->flags)
408*61046927SAndroid Build Coastguard Worker *pQueue = vk_queue_to_handle(queue);
409*61046927SAndroid Build Coastguard Worker else
410*61046927SAndroid Build Coastguard Worker *pQueue = VK_NULL_HANDLE;
411*61046927SAndroid Build Coastguard Worker }
412*61046927SAndroid Build Coastguard Worker
413*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
vk_common_MapMemory(VkDevice _device,VkDeviceMemory memory,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags,void ** ppData)414*61046927SAndroid Build Coastguard Worker vk_common_MapMemory(VkDevice _device,
415*61046927SAndroid Build Coastguard Worker VkDeviceMemory memory,
416*61046927SAndroid Build Coastguard Worker VkDeviceSize offset,
417*61046927SAndroid Build Coastguard Worker VkDeviceSize size,
418*61046927SAndroid Build Coastguard Worker VkMemoryMapFlags flags,
419*61046927SAndroid Build Coastguard Worker void **ppData)
420*61046927SAndroid Build Coastguard Worker {
421*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(vk_device, device, _device);
422*61046927SAndroid Build Coastguard Worker
423*61046927SAndroid Build Coastguard Worker const VkMemoryMapInfoKHR info = {
424*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_MEMORY_MAP_INFO_KHR,
425*61046927SAndroid Build Coastguard Worker .flags = flags,
426*61046927SAndroid Build Coastguard Worker .memory = memory,
427*61046927SAndroid Build Coastguard Worker .offset = offset,
428*61046927SAndroid Build Coastguard Worker .size = size,
429*61046927SAndroid Build Coastguard Worker };
430*61046927SAndroid Build Coastguard Worker
431*61046927SAndroid Build Coastguard Worker return device->dispatch_table.MapMemory2KHR(_device, &info, ppData);
432*61046927SAndroid Build Coastguard Worker }
433*61046927SAndroid Build Coastguard Worker
434*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
vk_common_UnmapMemory(VkDevice _device,VkDeviceMemory memory)435*61046927SAndroid Build Coastguard Worker vk_common_UnmapMemory(VkDevice _device,
436*61046927SAndroid Build Coastguard Worker VkDeviceMemory memory)
437*61046927SAndroid Build Coastguard Worker {
438*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(vk_device, device, _device);
439*61046927SAndroid Build Coastguard Worker ASSERTED VkResult result;
440*61046927SAndroid Build Coastguard Worker
441*61046927SAndroid Build Coastguard Worker const VkMemoryUnmapInfoKHR info = {
442*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_MEMORY_UNMAP_INFO_KHR,
443*61046927SAndroid Build Coastguard Worker .memory = memory,
444*61046927SAndroid Build Coastguard Worker };
445*61046927SAndroid Build Coastguard Worker
446*61046927SAndroid Build Coastguard Worker result = device->dispatch_table.UnmapMemory2KHR(_device, &info);
447*61046927SAndroid Build Coastguard Worker assert(result == VK_SUCCESS);
448*61046927SAndroid Build Coastguard Worker }
449*61046927SAndroid Build Coastguard Worker
450*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
vk_common_GetDeviceGroupPeerMemoryFeatures(VkDevice device,uint32_t heapIndex,uint32_t localDeviceIndex,uint32_t remoteDeviceIndex,VkPeerMemoryFeatureFlags * pPeerMemoryFeatures)451*61046927SAndroid Build Coastguard Worker vk_common_GetDeviceGroupPeerMemoryFeatures(
452*61046927SAndroid Build Coastguard Worker VkDevice device,
453*61046927SAndroid Build Coastguard Worker uint32_t heapIndex,
454*61046927SAndroid Build Coastguard Worker uint32_t localDeviceIndex,
455*61046927SAndroid Build Coastguard Worker uint32_t remoteDeviceIndex,
456*61046927SAndroid Build Coastguard Worker VkPeerMemoryFeatureFlags *pPeerMemoryFeatures)
457*61046927SAndroid Build Coastguard Worker {
458*61046927SAndroid Build Coastguard Worker assert(localDeviceIndex == 0 && remoteDeviceIndex == 0);
459*61046927SAndroid Build Coastguard Worker *pPeerMemoryFeatures = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT |
460*61046927SAndroid Build Coastguard Worker VK_PEER_MEMORY_FEATURE_COPY_DST_BIT |
461*61046927SAndroid Build Coastguard Worker VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
462*61046927SAndroid Build Coastguard Worker VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
463*61046927SAndroid Build Coastguard Worker }
464*61046927SAndroid Build Coastguard Worker
465*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
vk_common_GetImageMemoryRequirements(VkDevice _device,VkImage image,VkMemoryRequirements * pMemoryRequirements)466*61046927SAndroid Build Coastguard Worker vk_common_GetImageMemoryRequirements(VkDevice _device,
467*61046927SAndroid Build Coastguard Worker VkImage image,
468*61046927SAndroid Build Coastguard Worker VkMemoryRequirements *pMemoryRequirements)
469*61046927SAndroid Build Coastguard Worker {
470*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(vk_device, device, _device);
471*61046927SAndroid Build Coastguard Worker
472*61046927SAndroid Build Coastguard Worker VkImageMemoryRequirementsInfo2 info = {
473*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
474*61046927SAndroid Build Coastguard Worker .image = image,
475*61046927SAndroid Build Coastguard Worker };
476*61046927SAndroid Build Coastguard Worker VkMemoryRequirements2 reqs = {
477*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
478*61046927SAndroid Build Coastguard Worker };
479*61046927SAndroid Build Coastguard Worker device->dispatch_table.GetImageMemoryRequirements2(_device, &info, &reqs);
480*61046927SAndroid Build Coastguard Worker
481*61046927SAndroid Build Coastguard Worker *pMemoryRequirements = reqs.memoryRequirements;
482*61046927SAndroid Build Coastguard Worker }
483*61046927SAndroid Build Coastguard Worker
484*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
vk_common_BindImageMemory(VkDevice _device,VkImage image,VkDeviceMemory memory,VkDeviceSize memoryOffset)485*61046927SAndroid Build Coastguard Worker vk_common_BindImageMemory(VkDevice _device,
486*61046927SAndroid Build Coastguard Worker VkImage image,
487*61046927SAndroid Build Coastguard Worker VkDeviceMemory memory,
488*61046927SAndroid Build Coastguard Worker VkDeviceSize memoryOffset)
489*61046927SAndroid Build Coastguard Worker {
490*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(vk_device, device, _device);
491*61046927SAndroid Build Coastguard Worker
492*61046927SAndroid Build Coastguard Worker VkBindImageMemoryInfo bind = {
493*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
494*61046927SAndroid Build Coastguard Worker .image = image,
495*61046927SAndroid Build Coastguard Worker .memory = memory,
496*61046927SAndroid Build Coastguard Worker .memoryOffset = memoryOffset,
497*61046927SAndroid Build Coastguard Worker };
498*61046927SAndroid Build Coastguard Worker
499*61046927SAndroid Build Coastguard Worker return device->dispatch_table.BindImageMemory2(_device, 1, &bind);
500*61046927SAndroid Build Coastguard Worker }
501*61046927SAndroid Build Coastguard Worker
502*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
vk_common_GetImageSparseMemoryRequirements(VkDevice _device,VkImage image,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements * pSparseMemoryRequirements)503*61046927SAndroid Build Coastguard Worker vk_common_GetImageSparseMemoryRequirements(VkDevice _device,
504*61046927SAndroid Build Coastguard Worker VkImage image,
505*61046927SAndroid Build Coastguard Worker uint32_t *pSparseMemoryRequirementCount,
506*61046927SAndroid Build Coastguard Worker VkSparseImageMemoryRequirements *pSparseMemoryRequirements)
507*61046927SAndroid Build Coastguard Worker {
508*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(vk_device, device, _device);
509*61046927SAndroid Build Coastguard Worker
510*61046927SAndroid Build Coastguard Worker VkImageSparseMemoryRequirementsInfo2 info = {
511*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2,
512*61046927SAndroid Build Coastguard Worker .image = image,
513*61046927SAndroid Build Coastguard Worker };
514*61046927SAndroid Build Coastguard Worker
515*61046927SAndroid Build Coastguard Worker if (!pSparseMemoryRequirements) {
516*61046927SAndroid Build Coastguard Worker device->dispatch_table.GetImageSparseMemoryRequirements2(_device,
517*61046927SAndroid Build Coastguard Worker &info,
518*61046927SAndroid Build Coastguard Worker pSparseMemoryRequirementCount,
519*61046927SAndroid Build Coastguard Worker NULL);
520*61046927SAndroid Build Coastguard Worker return;
521*61046927SAndroid Build Coastguard Worker }
522*61046927SAndroid Build Coastguard Worker
523*61046927SAndroid Build Coastguard Worker STACK_ARRAY(VkSparseImageMemoryRequirements2, mem_reqs2, *pSparseMemoryRequirementCount);
524*61046927SAndroid Build Coastguard Worker
525*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < *pSparseMemoryRequirementCount; ++i) {
526*61046927SAndroid Build Coastguard Worker mem_reqs2[i].sType = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2;
527*61046927SAndroid Build Coastguard Worker mem_reqs2[i].pNext = NULL;
528*61046927SAndroid Build Coastguard Worker }
529*61046927SAndroid Build Coastguard Worker
530*61046927SAndroid Build Coastguard Worker device->dispatch_table.GetImageSparseMemoryRequirements2(_device,
531*61046927SAndroid Build Coastguard Worker &info,
532*61046927SAndroid Build Coastguard Worker pSparseMemoryRequirementCount,
533*61046927SAndroid Build Coastguard Worker mem_reqs2);
534*61046927SAndroid Build Coastguard Worker
535*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < *pSparseMemoryRequirementCount; ++i)
536*61046927SAndroid Build Coastguard Worker pSparseMemoryRequirements[i] = mem_reqs2[i].memoryRequirements;
537*61046927SAndroid Build Coastguard Worker
538*61046927SAndroid Build Coastguard Worker STACK_ARRAY_FINISH(mem_reqs2);
539*61046927SAndroid Build Coastguard Worker }
540*61046927SAndroid Build Coastguard Worker
541*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
vk_common_DeviceWaitIdle(VkDevice _device)542*61046927SAndroid Build Coastguard Worker vk_common_DeviceWaitIdle(VkDevice _device)
543*61046927SAndroid Build Coastguard Worker {
544*61046927SAndroid Build Coastguard Worker MESA_TRACE_FUNC();
545*61046927SAndroid Build Coastguard Worker
546*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(vk_device, device, _device);
547*61046927SAndroid Build Coastguard Worker const struct vk_device_dispatch_table *disp = &device->dispatch_table;
548*61046927SAndroid Build Coastguard Worker
549*61046927SAndroid Build Coastguard Worker vk_foreach_queue(queue, device) {
550*61046927SAndroid Build Coastguard Worker VkResult result = disp->QueueWaitIdle(vk_queue_to_handle(queue));
551*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
552*61046927SAndroid Build Coastguard Worker return result;
553*61046927SAndroid Build Coastguard Worker }
554*61046927SAndroid Build Coastguard Worker
555*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
556*61046927SAndroid Build Coastguard Worker }
557*61046927SAndroid Build Coastguard Worker
558*61046927SAndroid Build Coastguard Worker #ifndef _WIN32
559*61046927SAndroid Build Coastguard Worker
560*61046927SAndroid Build Coastguard Worker uint64_t
vk_clock_gettime(clockid_t clock_id)561*61046927SAndroid Build Coastguard Worker vk_clock_gettime(clockid_t clock_id)
562*61046927SAndroid Build Coastguard Worker {
563*61046927SAndroid Build Coastguard Worker struct timespec current;
564*61046927SAndroid Build Coastguard Worker int ret;
565*61046927SAndroid Build Coastguard Worker
566*61046927SAndroid Build Coastguard Worker ret = clock_gettime(clock_id, ¤t);
567*61046927SAndroid Build Coastguard Worker #ifdef CLOCK_MONOTONIC_RAW
568*61046927SAndroid Build Coastguard Worker if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
569*61046927SAndroid Build Coastguard Worker ret = clock_gettime(CLOCK_MONOTONIC, ¤t);
570*61046927SAndroid Build Coastguard Worker #endif
571*61046927SAndroid Build Coastguard Worker if (ret < 0)
572*61046927SAndroid Build Coastguard Worker return 0;
573*61046927SAndroid Build Coastguard Worker
574*61046927SAndroid Build Coastguard Worker return (uint64_t)current.tv_sec * 1000000000ULL + current.tv_nsec;
575*61046927SAndroid Build Coastguard Worker }
576*61046927SAndroid Build Coastguard Worker
577*61046927SAndroid Build Coastguard Worker #endif //!_WIN32
578