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 #ifndef VK_DEVICE_H
24*61046927SAndroid Build Coastguard Worker #define VK_DEVICE_H
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker #include "rmv/vk_rmv_common.h"
27*61046927SAndroid Build Coastguard Worker #include "vk_dispatch_table.h"
28*61046927SAndroid Build Coastguard Worker #include "vk_extensions.h"
29*61046927SAndroid Build Coastguard Worker #include "vk_object.h"
30*61046927SAndroid Build Coastguard Worker #include "vk_physical_device_features.h"
31*61046927SAndroid Build Coastguard Worker
32*61046927SAndroid Build Coastguard Worker #include "util/list.h"
33*61046927SAndroid Build Coastguard Worker #include "util/simple_mtx.h"
34*61046927SAndroid Build Coastguard Worker #include "util/u_atomic.h"
35*61046927SAndroid Build Coastguard Worker
36*61046927SAndroid Build Coastguard Worker #ifdef __cplusplus
37*61046927SAndroid Build Coastguard Worker extern "C" {
38*61046927SAndroid Build Coastguard Worker #endif
39*61046927SAndroid Build Coastguard Worker
40*61046927SAndroid Build Coastguard Worker struct vk_command_buffer_ops;
41*61046927SAndroid Build Coastguard Worker struct vk_device_shader_ops;
42*61046927SAndroid Build Coastguard Worker struct vk_sync;
43*61046927SAndroid Build Coastguard Worker
44*61046927SAndroid Build Coastguard Worker enum vk_queue_submit_mode {
45*61046927SAndroid Build Coastguard Worker /** Submits happen immediately
46*61046927SAndroid Build Coastguard Worker *
47*61046927SAndroid Build Coastguard Worker * `vkQueueSubmit()` and `vkQueueBindSparse()` call
48*61046927SAndroid Build Coastguard Worker * ``vk_queue::driver_submit`` directly for all submits and the last call to
49*61046927SAndroid Build Coastguard Worker * ``vk_queue::driver_submit`` will have completed by the time
50*61046927SAndroid Build Coastguard Worker * `vkQueueSubmit()` or `vkQueueBindSparse()` return.
51*61046927SAndroid Build Coastguard Worker */
52*61046927SAndroid Build Coastguard Worker VK_QUEUE_SUBMIT_MODE_IMMEDIATE,
53*61046927SAndroid Build Coastguard Worker
54*61046927SAndroid Build Coastguard Worker /** Submits may be deferred until a future `vk_queue_flush()`
55*61046927SAndroid Build Coastguard Worker *
56*61046927SAndroid Build Coastguard Worker * Submits are added to the queue and `vk_queue_flush()` is called.
57*61046927SAndroid Build Coastguard Worker * However, any submits with unsatisfied dependencies will be left on the
58*61046927SAndroid Build Coastguard Worker * queue until a future `vk_queue_flush()` call. This is used for
59*61046927SAndroid Build Coastguard Worker * implementing emulated timeline semaphores without threading.
60*61046927SAndroid Build Coastguard Worker */
61*61046927SAndroid Build Coastguard Worker VK_QUEUE_SUBMIT_MODE_DEFERRED,
62*61046927SAndroid Build Coastguard Worker
63*61046927SAndroid Build Coastguard Worker /** Submits will be added to the queue and handled later by a thread
64*61046927SAndroid Build Coastguard Worker *
65*61046927SAndroid Build Coastguard Worker * This places additional requirements on the vk_sync types used by the
66*61046927SAndroid Build Coastguard Worker * driver:
67*61046927SAndroid Build Coastguard Worker *
68*61046927SAndroid Build Coastguard Worker * 1. All `vk_sync` types which support `VK_SYNC_FEATURE_GPU_WAIT` also
69*61046927SAndroid Build Coastguard Worker * support `VK_SYNC_FEATURE_WAIT_PENDING` so that the threads can
70*61046927SAndroid Build Coastguard Worker * sort out when a given submit has all its dependencies resolved.
71*61046927SAndroid Build Coastguard Worker *
72*61046927SAndroid Build Coastguard Worker * 2. All binary `vk_sync` types which support `VK_SYNC_FEATURE_GPU_WAIT`
73*61046927SAndroid Build Coastguard Worker * also support `VK_SYNC_FEATURE_CPU_RESET` so we can reset
74*61046927SAndroid Build Coastguard Worker * semaphores after waiting on them.
75*61046927SAndroid Build Coastguard Worker *
76*61046927SAndroid Build Coastguard Worker * 3. All vk_sync types used as permanent payloads of semaphores support
77*61046927SAndroid Build Coastguard Worker * ``vk_sync_type::move`` so that it can move the pending signal into a
78*61046927SAndroid Build Coastguard Worker * temporary vk_sync and reset the semaphore.
79*61046927SAndroid Build Coastguard Worker *
80*61046927SAndroid Build Coastguard Worker * This is requied for shared timeline semaphores where we need to handle
81*61046927SAndroid Build Coastguard Worker * wait-before-signal by threading in the driver if we ever see an
82*61046927SAndroid Build Coastguard Worker * unresolve dependency.
83*61046927SAndroid Build Coastguard Worker */
84*61046927SAndroid Build Coastguard Worker VK_QUEUE_SUBMIT_MODE_THREADED,
85*61046927SAndroid Build Coastguard Worker
86*61046927SAndroid Build Coastguard Worker /** Threaded but only if we need it to resolve dependencies
87*61046927SAndroid Build Coastguard Worker *
88*61046927SAndroid Build Coastguard Worker * This imposes all the same requirements on `vk_sync` types as
89*61046927SAndroid Build Coastguard Worker * `VK_QUEUE_SUBMIT_MODE_THREADED`.
90*61046927SAndroid Build Coastguard Worker */
91*61046927SAndroid Build Coastguard Worker VK_QUEUE_SUBMIT_MODE_THREADED_ON_DEMAND,
92*61046927SAndroid Build Coastguard Worker };
93*61046927SAndroid Build Coastguard Worker
94*61046927SAndroid Build Coastguard Worker /** Base struct for VkDevice */
95*61046927SAndroid Build Coastguard Worker struct vk_device {
96*61046927SAndroid Build Coastguard Worker struct vk_object_base base;
97*61046927SAndroid Build Coastguard Worker
98*61046927SAndroid Build Coastguard Worker /** Allocator used to create this device
99*61046927SAndroid Build Coastguard Worker *
100*61046927SAndroid Build Coastguard Worker * This is used as a fall-back for when a NULL pAllocator is passed into a
101*61046927SAndroid Build Coastguard Worker * device-level create function such as vkCreateImage().
102*61046927SAndroid Build Coastguard Worker */
103*61046927SAndroid Build Coastguard Worker VkAllocationCallbacks alloc;
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Worker /** Pointer to the physical device */
106*61046927SAndroid Build Coastguard Worker struct vk_physical_device *physical;
107*61046927SAndroid Build Coastguard Worker
108*61046927SAndroid Build Coastguard Worker /** Table of enabled extensions */
109*61046927SAndroid Build Coastguard Worker struct vk_device_extension_table enabled_extensions;
110*61046927SAndroid Build Coastguard Worker
111*61046927SAndroid Build Coastguard Worker /** Table of enabled features */
112*61046927SAndroid Build Coastguard Worker struct vk_features enabled_features;
113*61046927SAndroid Build Coastguard Worker
114*61046927SAndroid Build Coastguard Worker /** Device-level dispatch table */
115*61046927SAndroid Build Coastguard Worker struct vk_device_dispatch_table dispatch_table;
116*61046927SAndroid Build Coastguard Worker
117*61046927SAndroid Build Coastguard Worker /** Command dispatch table
118*61046927SAndroid Build Coastguard Worker *
119*61046927SAndroid Build Coastguard Worker * This is used for emulated secondary command buffer support. To use
120*61046927SAndroid Build Coastguard Worker * emulated (trace/replay) secondary command buffers:
121*61046927SAndroid Build Coastguard Worker *
122*61046927SAndroid Build Coastguard Worker * 1. Provide your "real" command buffer dispatch table here. Because
123*61046927SAndroid Build Coastguard Worker * this doesn't get populated by vk_device_init(), the driver will have
124*61046927SAndroid Build Coastguard Worker * to add the vk_common entrypoints to this table itself.
125*61046927SAndroid Build Coastguard Worker *
126*61046927SAndroid Build Coastguard Worker * 2. Add vk_enqueue_unless_primary_device_entrypoint_table to your device
127*61046927SAndroid Build Coastguard Worker * level dispatch table.
128*61046927SAndroid Build Coastguard Worker */
129*61046927SAndroid Build Coastguard Worker const struct vk_device_dispatch_table *command_dispatch_table;
130*61046927SAndroid Build Coastguard Worker
131*61046927SAndroid Build Coastguard Worker /** Command buffer vtable when using the common command pool */
132*61046927SAndroid Build Coastguard Worker const struct vk_command_buffer_ops *command_buffer_ops;
133*61046927SAndroid Build Coastguard Worker
134*61046927SAndroid Build Coastguard Worker /** Shader vtable for VK_EXT_shader_object and common pipelines */
135*61046927SAndroid Build Coastguard Worker const struct vk_device_shader_ops *shader_ops;
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Worker /** Driver provided callback for capturing traces
138*61046927SAndroid Build Coastguard Worker *
139*61046927SAndroid Build Coastguard Worker * Triggers for this callback are:
140*61046927SAndroid Build Coastguard Worker * - Keyboard input (F12)
141*61046927SAndroid Build Coastguard Worker * - Creation of a trigger file
142*61046927SAndroid Build Coastguard Worker * - Reaching the trace frame
143*61046927SAndroid Build Coastguard Worker */
144*61046927SAndroid Build Coastguard Worker VkResult (*capture_trace)(VkQueue queue);
145*61046927SAndroid Build Coastguard Worker
146*61046927SAndroid Build Coastguard Worker uint32_t current_frame;
147*61046927SAndroid Build Coastguard Worker bool trace_hotkey_trigger;
148*61046927SAndroid Build Coastguard Worker simple_mtx_t trace_mtx;
149*61046927SAndroid Build Coastguard Worker
150*61046927SAndroid Build Coastguard Worker /* For VK_EXT_private_data */
151*61046927SAndroid Build Coastguard Worker uint32_t private_data_next_index;
152*61046927SAndroid Build Coastguard Worker
153*61046927SAndroid Build Coastguard Worker struct list_head queues;
154*61046927SAndroid Build Coastguard Worker
155*61046927SAndroid Build Coastguard Worker struct {
156*61046927SAndroid Build Coastguard Worker int lost;
157*61046927SAndroid Build Coastguard Worker bool reported;
158*61046927SAndroid Build Coastguard Worker } _lost;
159*61046927SAndroid Build Coastguard Worker
160*61046927SAndroid Build Coastguard Worker /** Checks the status of this device
161*61046927SAndroid Build Coastguard Worker *
162*61046927SAndroid Build Coastguard Worker * This is expected to return either VK_SUCCESS or VK_ERROR_DEVICE_LOST.
163*61046927SAndroid Build Coastguard Worker * It is called before ``vk_queue::driver_submit`` and after every non-trivial
164*61046927SAndroid Build Coastguard Worker * wait operation to ensure the device is still around. This gives the
165*61046927SAndroid Build Coastguard Worker * driver a hook to ask the kernel if its device is still valid. If the
166*61046927SAndroid Build Coastguard Worker * kernel says the device has been lost, it MUST call vk_device_set_lost().
167*61046927SAndroid Build Coastguard Worker *
168*61046927SAndroid Build Coastguard Worker * This function may be called from any thread at any time.
169*61046927SAndroid Build Coastguard Worker */
170*61046927SAndroid Build Coastguard Worker VkResult (*check_status)(struct vk_device *device);
171*61046927SAndroid Build Coastguard Worker
172*61046927SAndroid Build Coastguard Worker /** Creates a vk_sync that wraps a memory object
173*61046927SAndroid Build Coastguard Worker *
174*61046927SAndroid Build Coastguard Worker * This is always a one-shot object so it need not track any additional
175*61046927SAndroid Build Coastguard Worker * state. Since it's intended for synchronizing between processes using
176*61046927SAndroid Build Coastguard Worker * implicit synchronization mechanisms, no such tracking would be valid
177*61046927SAndroid Build Coastguard Worker * anyway.
178*61046927SAndroid Build Coastguard Worker *
179*61046927SAndroid Build Coastguard Worker * If `signal_memory` is set, the resulting vk_sync will be used to signal
180*61046927SAndroid Build Coastguard Worker * the memory object from a queue ``via vk_queue_submit::signals``. The common
181*61046927SAndroid Build Coastguard Worker * code guarantees that, by the time vkQueueSubmit() returns, the signal
182*61046927SAndroid Build Coastguard Worker * operation has been submitted to the kernel via the driver's
183*61046927SAndroid Build Coastguard Worker * ``vk_queue::driver_submit`` hook. This means that any vkQueueSubmit() call
184*61046927SAndroid Build Coastguard Worker * which needs implicit synchronization may block.
185*61046927SAndroid Build Coastguard Worker *
186*61046927SAndroid Build Coastguard Worker * If `signal_memory` is not set, it can be assumed that memory object
187*61046927SAndroid Build Coastguard Worker * already has a signal operation pending from some other process and we
188*61046927SAndroid Build Coastguard Worker * need only wait on it.
189*61046927SAndroid Build Coastguard Worker */
190*61046927SAndroid Build Coastguard Worker VkResult (*create_sync_for_memory)(struct vk_device *device,
191*61046927SAndroid Build Coastguard Worker VkDeviceMemory memory,
192*61046927SAndroid Build Coastguard Worker bool signal_memory,
193*61046927SAndroid Build Coastguard Worker struct vk_sync **sync_out);
194*61046927SAndroid Build Coastguard Worker
195*61046927SAndroid Build Coastguard Worker /* Set by vk_device_set_drm_fd() */
196*61046927SAndroid Build Coastguard Worker int drm_fd;
197*61046927SAndroid Build Coastguard Worker
198*61046927SAndroid Build Coastguard Worker /** Implicit pipeline cache, or NULL */
199*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *mem_cache;
200*61046927SAndroid Build Coastguard Worker
201*61046927SAndroid Build Coastguard Worker /** An enum describing how timeline semaphores work */
202*61046927SAndroid Build Coastguard Worker enum vk_device_timeline_mode {
203*61046927SAndroid Build Coastguard Worker /** Timeline semaphores are not supported */
204*61046927SAndroid Build Coastguard Worker VK_DEVICE_TIMELINE_MODE_NONE,
205*61046927SAndroid Build Coastguard Worker
206*61046927SAndroid Build Coastguard Worker /** Timeline semaphores are emulated with vk_timeline
207*61046927SAndroid Build Coastguard Worker *
208*61046927SAndroid Build Coastguard Worker * In this mode, timeline semaphores are emulated using vk_timeline
209*61046927SAndroid Build Coastguard Worker * which is a collection of binary semaphores, one per time point.
210*61046927SAndroid Build Coastguard Worker * These timeline semaphores cannot be shared because the data structure
211*61046927SAndroid Build Coastguard Worker * exists entirely in userspace. These timelines are virtually
212*61046927SAndroid Build Coastguard Worker * invisible to the driver; all it sees are the binary vk_syncs, one per
213*61046927SAndroid Build Coastguard Worker * time point.
214*61046927SAndroid Build Coastguard Worker *
215*61046927SAndroid Build Coastguard Worker * To handle wait-before-signal, we place all vk_queue_submits in the
216*61046927SAndroid Build Coastguard Worker * queue's submit list in vkQueueSubmit() and call vk_device_flush() at
217*61046927SAndroid Build Coastguard Worker * key points such as the end of vkQueueSubmit() and vkSemaphoreSignal().
218*61046927SAndroid Build Coastguard Worker * This ensures that, as soon as a given submit's dependencies are fully
219*61046927SAndroid Build Coastguard Worker * resolvable, it gets submitted to the driver.
220*61046927SAndroid Build Coastguard Worker */
221*61046927SAndroid Build Coastguard Worker VK_DEVICE_TIMELINE_MODE_EMULATED,
222*61046927SAndroid Build Coastguard Worker
223*61046927SAndroid Build Coastguard Worker /** Timeline semaphores are a kernel-assisted emulation
224*61046927SAndroid Build Coastguard Worker *
225*61046927SAndroid Build Coastguard Worker * In this mode, timeline semaphores are still technically an emulation
226*61046927SAndroid Build Coastguard Worker * in the sense that they don't support wait-before-signal natively.
227*61046927SAndroid Build Coastguard Worker * Instead, all GPU-waitable objects support a CPU wait-for-pending
228*61046927SAndroid Build Coastguard Worker * operation which lets the userspace driver wait until a given event
229*61046927SAndroid Build Coastguard Worker * on the (possibly shared) vk_sync is pending. The event is "pending"
230*61046927SAndroid Build Coastguard Worker * if a job has been submitted to the kernel (possibly from a different
231*61046927SAndroid Build Coastguard Worker * process) which will signal it. In vkQueueSubit, we use this wait
232*61046927SAndroid Build Coastguard Worker * mode to detect waits which are not yet pending and, the first time we
233*61046927SAndroid Build Coastguard Worker * do, spawn a thread to manage the queue. That thread waits for each
234*61046927SAndroid Build Coastguard Worker * submit's waits to all be pending before submitting to the driver
235*61046927SAndroid Build Coastguard Worker * queue.
236*61046927SAndroid Build Coastguard Worker *
237*61046927SAndroid Build Coastguard Worker * We have to be a bit more careful about a few things in this mode.
238*61046927SAndroid Build Coastguard Worker * In particular, we can never assume that any given wait operation is
239*61046927SAndroid Build Coastguard Worker * pending. For instance, when we go to export a sync file from a
240*61046927SAndroid Build Coastguard Worker * binary semaphore, we need to first wait for it to be pending. The
241*61046927SAndroid Build Coastguard Worker * spec guarantees that the vast majority of these waits return almost
242*61046927SAndroid Build Coastguard Worker * immediately, but we do need to insert them for correctness.
243*61046927SAndroid Build Coastguard Worker */
244*61046927SAndroid Build Coastguard Worker VK_DEVICE_TIMELINE_MODE_ASSISTED,
245*61046927SAndroid Build Coastguard Worker
246*61046927SAndroid Build Coastguard Worker /** Timeline semaphores are 100% native
247*61046927SAndroid Build Coastguard Worker *
248*61046927SAndroid Build Coastguard Worker * In this mode, wait-before-signal is natively supported by the
249*61046927SAndroid Build Coastguard Worker * underlying timeline implementation. We can submit-and-forget and
250*61046927SAndroid Build Coastguard Worker * assume that dependencies will get resolved for us by the kernel.
251*61046927SAndroid Build Coastguard Worker * Currently, this isn't supported by any Linux primitives.
252*61046927SAndroid Build Coastguard Worker */
253*61046927SAndroid Build Coastguard Worker VK_DEVICE_TIMELINE_MODE_NATIVE,
254*61046927SAndroid Build Coastguard Worker } timeline_mode;
255*61046927SAndroid Build Coastguard Worker
256*61046927SAndroid Build Coastguard Worker /** Per-device submit mode
257*61046927SAndroid Build Coastguard Worker *
258*61046927SAndroid Build Coastguard Worker * This represents the device-wide submit strategy which may be different
259*61046927SAndroid Build Coastguard Worker * from the per-queue submit mode. See vk_queue.submit.mode for more
260*61046927SAndroid Build Coastguard Worker * details.
261*61046927SAndroid Build Coastguard Worker */
262*61046927SAndroid Build Coastguard Worker enum vk_queue_submit_mode submit_mode;
263*61046927SAndroid Build Coastguard Worker
264*61046927SAndroid Build Coastguard Worker struct vk_memory_trace_data memory_trace_data;
265*61046927SAndroid Build Coastguard Worker
266*61046927SAndroid Build Coastguard Worker mtx_t swapchain_private_mtx;
267*61046927SAndroid Build Coastguard Worker struct hash_table *swapchain_private;
268*61046927SAndroid Build Coastguard Worker mtx_t swapchain_name_mtx;
269*61046927SAndroid Build Coastguard Worker struct hash_table *swapchain_name;
270*61046927SAndroid Build Coastguard Worker
271*61046927SAndroid Build Coastguard Worker /* For VK_KHR_pipeline_binary */
272*61046927SAndroid Build Coastguard Worker bool disable_internal_cache;
273*61046927SAndroid Build Coastguard Worker };
274*61046927SAndroid Build Coastguard Worker
275*61046927SAndroid Build Coastguard Worker VK_DEFINE_HANDLE_CASTS(vk_device, base, VkDevice,
276*61046927SAndroid Build Coastguard Worker VK_OBJECT_TYPE_DEVICE);
277*61046927SAndroid Build Coastguard Worker
278*61046927SAndroid Build Coastguard Worker /** Initialize a vk_device
279*61046927SAndroid Build Coastguard Worker *
280*61046927SAndroid Build Coastguard Worker * Along with initializing the data structures in `vk_device`, this function
281*61046927SAndroid Build Coastguard Worker * checks that every extension specified by
282*61046927SAndroid Build Coastguard Worker * ``VkInstanceCreateInfo::ppEnabledExtensionNames`` is actually supported by
283*61046927SAndroid Build Coastguard Worker * the physical device and returns `VK_ERROR_EXTENSION_NOT_PRESENT` if an
284*61046927SAndroid Build Coastguard Worker * unsupported extension is requested. It also checks all the feature struct
285*61046927SAndroid Build Coastguard Worker * chained into the `pCreateInfo->pNext` chain against the features returned
286*61046927SAndroid Build Coastguard Worker * by `vkGetPhysicalDeviceFeatures2` and returns
287*61046927SAndroid Build Coastguard Worker * `VK_ERROR_FEATURE_NOT_PRESENT` if an unsupported feature is requested.
288*61046927SAndroid Build Coastguard Worker *
289*61046927SAndroid Build Coastguard Worker * :param device: |out| The device to initialize
290*61046927SAndroid Build Coastguard Worker * :param physical_device: |in| The physical device
291*61046927SAndroid Build Coastguard Worker * :param dispatch_table: |in| Device-level dispatch table
292*61046927SAndroid Build Coastguard Worker * :param pCreateInfo: |in| VkDeviceCreateInfo pointer passed to
293*61046927SAndroid Build Coastguard Worker * `vkCreateDevice()`
294*61046927SAndroid Build Coastguard Worker * :param alloc: |in| Allocation callbacks passed to
295*61046927SAndroid Build Coastguard Worker * `vkCreateDevice()`
296*61046927SAndroid Build Coastguard Worker */
297*61046927SAndroid Build Coastguard Worker VkResult MUST_CHECK
298*61046927SAndroid Build Coastguard Worker vk_device_init(struct vk_device *device,
299*61046927SAndroid Build Coastguard Worker struct vk_physical_device *physical_device,
300*61046927SAndroid Build Coastguard Worker const struct vk_device_dispatch_table *dispatch_table,
301*61046927SAndroid Build Coastguard Worker const VkDeviceCreateInfo *pCreateInfo,
302*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc);
303*61046927SAndroid Build Coastguard Worker
304*61046927SAndroid Build Coastguard Worker static inline void
vk_device_set_drm_fd(struct vk_device * device,int drm_fd)305*61046927SAndroid Build Coastguard Worker vk_device_set_drm_fd(struct vk_device *device, int drm_fd)
306*61046927SAndroid Build Coastguard Worker {
307*61046927SAndroid Build Coastguard Worker device->drm_fd = drm_fd;
308*61046927SAndroid Build Coastguard Worker }
309*61046927SAndroid Build Coastguard Worker
310*61046927SAndroid Build Coastguard Worker /** Tears down a vk_device
311*61046927SAndroid Build Coastguard Worker *
312*61046927SAndroid Build Coastguard Worker * :param device: |out| The device to tear down
313*61046927SAndroid Build Coastguard Worker */
314*61046927SAndroid Build Coastguard Worker void
315*61046927SAndroid Build Coastguard Worker vk_device_finish(struct vk_device *device);
316*61046927SAndroid Build Coastguard Worker
317*61046927SAndroid Build Coastguard Worker /** Enables threaded submit on this device
318*61046927SAndroid Build Coastguard Worker *
319*61046927SAndroid Build Coastguard Worker * This doesn't ensure that threaded submit will be used. It just disables
320*61046927SAndroid Build Coastguard Worker * the deferred submit option for emulated timeline semaphores and forces them
321*61046927SAndroid Build Coastguard Worker * to always use the threaded path. It also does some checks that the vk_sync
322*61046927SAndroid Build Coastguard Worker * types used by the driver work for threaded submit.
323*61046927SAndroid Build Coastguard Worker *
324*61046927SAndroid Build Coastguard Worker * This must be called before any queues are created.
325*61046927SAndroid Build Coastguard Worker */
326*61046927SAndroid Build Coastguard Worker void vk_device_enable_threaded_submit(struct vk_device *device);
327*61046927SAndroid Build Coastguard Worker
328*61046927SAndroid Build Coastguard Worker static inline bool
vk_device_supports_threaded_submit(const struct vk_device * device)329*61046927SAndroid Build Coastguard Worker vk_device_supports_threaded_submit(const struct vk_device *device)
330*61046927SAndroid Build Coastguard Worker {
331*61046927SAndroid Build Coastguard Worker return device->submit_mode == VK_QUEUE_SUBMIT_MODE_THREADED ||
332*61046927SAndroid Build Coastguard Worker device->submit_mode == VK_QUEUE_SUBMIT_MODE_THREADED_ON_DEMAND;
333*61046927SAndroid Build Coastguard Worker }
334*61046927SAndroid Build Coastguard Worker
335*61046927SAndroid Build Coastguard Worker VkResult vk_device_flush(struct vk_device *device);
336*61046927SAndroid Build Coastguard Worker
337*61046927SAndroid Build Coastguard Worker VkResult PRINTFLIKE(4, 5)
338*61046927SAndroid Build Coastguard Worker _vk_device_set_lost(struct vk_device *device,
339*61046927SAndroid Build Coastguard Worker const char *file, int line,
340*61046927SAndroid Build Coastguard Worker const char *msg, ...);
341*61046927SAndroid Build Coastguard Worker
342*61046927SAndroid Build Coastguard Worker #define vk_device_set_lost(device, ...) \
343*61046927SAndroid Build Coastguard Worker _vk_device_set_lost(device, __FILE__, __LINE__, __VA_ARGS__)
344*61046927SAndroid Build Coastguard Worker
345*61046927SAndroid Build Coastguard Worker void _vk_device_report_lost(struct vk_device *device);
346*61046927SAndroid Build Coastguard Worker
347*61046927SAndroid Build Coastguard Worker static inline bool
vk_device_is_lost_no_report(struct vk_device * device)348*61046927SAndroid Build Coastguard Worker vk_device_is_lost_no_report(struct vk_device *device)
349*61046927SAndroid Build Coastguard Worker {
350*61046927SAndroid Build Coastguard Worker return p_atomic_read(&device->_lost.lost) > 0;
351*61046927SAndroid Build Coastguard Worker }
352*61046927SAndroid Build Coastguard Worker
353*61046927SAndroid Build Coastguard Worker static inline bool
vk_device_is_lost(struct vk_device * device)354*61046927SAndroid Build Coastguard Worker vk_device_is_lost(struct vk_device *device)
355*61046927SAndroid Build Coastguard Worker {
356*61046927SAndroid Build Coastguard Worker int lost = vk_device_is_lost_no_report(device);
357*61046927SAndroid Build Coastguard Worker if (unlikely(lost && !device->_lost.reported))
358*61046927SAndroid Build Coastguard Worker _vk_device_report_lost(device);
359*61046927SAndroid Build Coastguard Worker return lost;
360*61046927SAndroid Build Coastguard Worker }
361*61046927SAndroid Build Coastguard Worker
362*61046927SAndroid Build Coastguard Worker static inline VkResult
vk_device_check_status(struct vk_device * device)363*61046927SAndroid Build Coastguard Worker vk_device_check_status(struct vk_device *device)
364*61046927SAndroid Build Coastguard Worker {
365*61046927SAndroid Build Coastguard Worker if (vk_device_is_lost(device))
366*61046927SAndroid Build Coastguard Worker return VK_ERROR_DEVICE_LOST;
367*61046927SAndroid Build Coastguard Worker
368*61046927SAndroid Build Coastguard Worker if (!device->check_status)
369*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
370*61046927SAndroid Build Coastguard Worker
371*61046927SAndroid Build Coastguard Worker VkResult result = device->check_status(device);
372*61046927SAndroid Build Coastguard Worker
373*61046927SAndroid Build Coastguard Worker assert(result == VK_SUCCESS || result == VK_ERROR_DEVICE_LOST);
374*61046927SAndroid Build Coastguard Worker if (result == VK_ERROR_DEVICE_LOST)
375*61046927SAndroid Build Coastguard Worker assert(vk_device_is_lost_no_report(device));
376*61046927SAndroid Build Coastguard Worker
377*61046927SAndroid Build Coastguard Worker return result;
378*61046927SAndroid Build Coastguard Worker }
379*61046927SAndroid Build Coastguard Worker
380*61046927SAndroid Build Coastguard Worker #ifndef _WIN32
381*61046927SAndroid Build Coastguard Worker
382*61046927SAndroid Build Coastguard Worker uint64_t
383*61046927SAndroid Build Coastguard Worker vk_clock_gettime(clockid_t clock_id);
384*61046927SAndroid Build Coastguard Worker
385*61046927SAndroid Build Coastguard Worker static inline uint64_t
vk_time_max_deviation(uint64_t begin,uint64_t end,uint64_t max_clock_period)386*61046927SAndroid Build Coastguard Worker vk_time_max_deviation(uint64_t begin, uint64_t end, uint64_t max_clock_period)
387*61046927SAndroid Build Coastguard Worker {
388*61046927SAndroid Build Coastguard Worker /*
389*61046927SAndroid Build Coastguard Worker * The maximum deviation is the sum of the interval over which we
390*61046927SAndroid Build Coastguard Worker * perform the sampling and the maximum period of any sampled
391*61046927SAndroid Build Coastguard Worker * clock. That's because the maximum skew between any two sampled
392*61046927SAndroid Build Coastguard Worker * clock edges is when the sampled clock with the largest period is
393*61046927SAndroid Build Coastguard Worker * sampled at the end of that period but right at the beginning of the
394*61046927SAndroid Build Coastguard Worker * sampling interval and some other clock is sampled right at the
395*61046927SAndroid Build Coastguard Worker * beginning of its sampling period and right at the end of the
396*61046927SAndroid Build Coastguard Worker * sampling interval. Let's assume the GPU has the longest clock
397*61046927SAndroid Build Coastguard Worker * period and that the application is sampling GPU and monotonic:
398*61046927SAndroid Build Coastguard Worker *
399*61046927SAndroid Build Coastguard Worker * s e
400*61046927SAndroid Build Coastguard Worker * w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f
401*61046927SAndroid Build Coastguard Worker * Raw -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
402*61046927SAndroid Build Coastguard Worker *
403*61046927SAndroid Build Coastguard Worker * g
404*61046927SAndroid Build Coastguard Worker * 0 1 2 3
405*61046927SAndroid Build Coastguard Worker * GPU -----_____-----_____-----_____-----_____
406*61046927SAndroid Build Coastguard Worker *
407*61046927SAndroid Build Coastguard Worker * m
408*61046927SAndroid Build Coastguard Worker * x y z 0 1 2 3 4 5 6 7 8 9 a b c
409*61046927SAndroid Build Coastguard Worker * Monotonic -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
410*61046927SAndroid Build Coastguard Worker *
411*61046927SAndroid Build Coastguard Worker * Interval <----------------->
412*61046927SAndroid Build Coastguard Worker * Deviation <-------------------------->
413*61046927SAndroid Build Coastguard Worker *
414*61046927SAndroid Build Coastguard Worker * s = read(raw) 2
415*61046927SAndroid Build Coastguard Worker * g = read(GPU) 1
416*61046927SAndroid Build Coastguard Worker * m = read(monotonic) 2
417*61046927SAndroid Build Coastguard Worker * e = read(raw) b
418*61046927SAndroid Build Coastguard Worker *
419*61046927SAndroid Build Coastguard Worker * We round the sample interval up by one tick to cover sampling error
420*61046927SAndroid Build Coastguard Worker * in the interval clock
421*61046927SAndroid Build Coastguard Worker */
422*61046927SAndroid Build Coastguard Worker
423*61046927SAndroid Build Coastguard Worker uint64_t sample_interval = end - begin + 1;
424*61046927SAndroid Build Coastguard Worker
425*61046927SAndroid Build Coastguard Worker return sample_interval + max_clock_period;
426*61046927SAndroid Build Coastguard Worker }
427*61046927SAndroid Build Coastguard Worker
428*61046927SAndroid Build Coastguard Worker #endif //!_WIN32
429*61046927SAndroid Build Coastguard Worker
430*61046927SAndroid Build Coastguard Worker PFN_vkVoidFunction
431*61046927SAndroid Build Coastguard Worker vk_device_get_proc_addr(const struct vk_device *device,
432*61046927SAndroid Build Coastguard Worker const char *name);
433*61046927SAndroid Build Coastguard Worker
434*61046927SAndroid Build Coastguard Worker #ifdef __cplusplus
435*61046927SAndroid Build Coastguard Worker }
436*61046927SAndroid Build Coastguard Worker #endif
437*61046927SAndroid Build Coastguard Worker
438*61046927SAndroid Build Coastguard Worker #endif /* VK_DEVICE_H */
439