xref: /aosp_15_r20/external/mesa3d/src/vulkan/runtime/vk_queue.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2021 Intel Corporation
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #include "vk_queue.h"
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker #include "util/perf/cpu_trace.h"
27*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
28*61046927SAndroid Build Coastguard Worker #include <inttypes.h>
29*61046927SAndroid Build Coastguard Worker 
30*61046927SAndroid Build Coastguard Worker #include "vk_alloc.h"
31*61046927SAndroid Build Coastguard Worker #include "vk_command_buffer.h"
32*61046927SAndroid Build Coastguard Worker #include "vk_command_pool.h"
33*61046927SAndroid Build Coastguard Worker #include "vk_common_entrypoints.h"
34*61046927SAndroid Build Coastguard Worker #include "vk_device.h"
35*61046927SAndroid Build Coastguard Worker #include "vk_fence.h"
36*61046927SAndroid Build Coastguard Worker #include "vk_log.h"
37*61046927SAndroid Build Coastguard Worker #include "vk_physical_device.h"
38*61046927SAndroid Build Coastguard Worker #include "vk_semaphore.h"
39*61046927SAndroid Build Coastguard Worker #include "vk_sync.h"
40*61046927SAndroid Build Coastguard Worker #include "vk_sync_binary.h"
41*61046927SAndroid Build Coastguard Worker #include "vk_sync_dummy.h"
42*61046927SAndroid Build Coastguard Worker #include "vk_sync_timeline.h"
43*61046927SAndroid Build Coastguard Worker #include "vk_util.h"
44*61046927SAndroid Build Coastguard Worker 
45*61046927SAndroid Build Coastguard Worker #include "vulkan/wsi/wsi_common.h"
46*61046927SAndroid Build Coastguard Worker 
47*61046927SAndroid Build Coastguard Worker static VkResult
48*61046927SAndroid Build Coastguard Worker vk_queue_start_submit_thread(struct vk_queue *queue);
49*61046927SAndroid Build Coastguard Worker 
50*61046927SAndroid Build Coastguard Worker VkResult
vk_queue_init(struct vk_queue * queue,struct vk_device * device,const VkDeviceQueueCreateInfo * pCreateInfo,uint32_t index_in_family)51*61046927SAndroid Build Coastguard Worker vk_queue_init(struct vk_queue *queue, struct vk_device *device,
52*61046927SAndroid Build Coastguard Worker               const VkDeviceQueueCreateInfo *pCreateInfo,
53*61046927SAndroid Build Coastguard Worker               uint32_t index_in_family)
54*61046927SAndroid Build Coastguard Worker {
55*61046927SAndroid Build Coastguard Worker    VkResult result = VK_SUCCESS;
56*61046927SAndroid Build Coastguard Worker    int ret;
57*61046927SAndroid Build Coastguard Worker 
58*61046927SAndroid Build Coastguard Worker    memset(queue, 0, sizeof(*queue));
59*61046927SAndroid Build Coastguard Worker    vk_object_base_init(device, &queue->base, VK_OBJECT_TYPE_QUEUE);
60*61046927SAndroid Build Coastguard Worker 
61*61046927SAndroid Build Coastguard Worker    list_addtail(&queue->link, &device->queues);
62*61046927SAndroid Build Coastguard Worker 
63*61046927SAndroid Build Coastguard Worker    queue->flags = pCreateInfo->flags;
64*61046927SAndroid Build Coastguard Worker    queue->queue_family_index = pCreateInfo->queueFamilyIndex;
65*61046927SAndroid Build Coastguard Worker 
66*61046927SAndroid Build Coastguard Worker    assert(index_in_family < pCreateInfo->queueCount);
67*61046927SAndroid Build Coastguard Worker    queue->index_in_family = index_in_family;
68*61046927SAndroid Build Coastguard Worker 
69*61046927SAndroid Build Coastguard Worker    queue->submit.mode = device->submit_mode;
70*61046927SAndroid Build Coastguard Worker    if (queue->submit.mode == VK_QUEUE_SUBMIT_MODE_THREADED_ON_DEMAND)
71*61046927SAndroid Build Coastguard Worker       queue->submit.mode = VK_QUEUE_SUBMIT_MODE_IMMEDIATE;
72*61046927SAndroid Build Coastguard Worker 
73*61046927SAndroid Build Coastguard Worker    list_inithead(&queue->submit.submits);
74*61046927SAndroid Build Coastguard Worker 
75*61046927SAndroid Build Coastguard Worker    ret = mtx_init(&queue->submit.mutex, mtx_plain);
76*61046927SAndroid Build Coastguard Worker    if (ret == thrd_error) {
77*61046927SAndroid Build Coastguard Worker       result = vk_errorf(queue, VK_ERROR_UNKNOWN, "mtx_init failed");
78*61046927SAndroid Build Coastguard Worker       goto fail_mutex;
79*61046927SAndroid Build Coastguard Worker    }
80*61046927SAndroid Build Coastguard Worker 
81*61046927SAndroid Build Coastguard Worker    ret = cnd_init(&queue->submit.push);
82*61046927SAndroid Build Coastguard Worker    if (ret == thrd_error) {
83*61046927SAndroid Build Coastguard Worker       result = vk_errorf(queue, VK_ERROR_UNKNOWN, "cnd_init failed");
84*61046927SAndroid Build Coastguard Worker       goto fail_push;
85*61046927SAndroid Build Coastguard Worker    }
86*61046927SAndroid Build Coastguard Worker 
87*61046927SAndroid Build Coastguard Worker    ret = cnd_init(&queue->submit.pop);
88*61046927SAndroid Build Coastguard Worker    if (ret == thrd_error) {
89*61046927SAndroid Build Coastguard Worker       result = vk_errorf(queue, VK_ERROR_UNKNOWN, "cnd_init failed");
90*61046927SAndroid Build Coastguard Worker       goto fail_pop;
91*61046927SAndroid Build Coastguard Worker    }
92*61046927SAndroid Build Coastguard Worker 
93*61046927SAndroid Build Coastguard Worker    if (queue->submit.mode == VK_QUEUE_SUBMIT_MODE_THREADED) {
94*61046927SAndroid Build Coastguard Worker       result = vk_queue_start_submit_thread(queue);
95*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
96*61046927SAndroid Build Coastguard Worker          goto fail_thread;
97*61046927SAndroid Build Coastguard Worker    }
98*61046927SAndroid Build Coastguard Worker 
99*61046927SAndroid Build Coastguard Worker    util_dynarray_init(&queue->labels, NULL);
100*61046927SAndroid Build Coastguard Worker    queue->region_begin = true;
101*61046927SAndroid Build Coastguard Worker 
102*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
103*61046927SAndroid Build Coastguard Worker 
104*61046927SAndroid Build Coastguard Worker fail_thread:
105*61046927SAndroid Build Coastguard Worker    cnd_destroy(&queue->submit.pop);
106*61046927SAndroid Build Coastguard Worker fail_pop:
107*61046927SAndroid Build Coastguard Worker    cnd_destroy(&queue->submit.push);
108*61046927SAndroid Build Coastguard Worker fail_push:
109*61046927SAndroid Build Coastguard Worker    mtx_destroy(&queue->submit.mutex);
110*61046927SAndroid Build Coastguard Worker fail_mutex:
111*61046927SAndroid Build Coastguard Worker    return result;
112*61046927SAndroid Build Coastguard Worker }
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker VkResult
_vk_queue_set_lost(struct vk_queue * queue,const char * file,int line,const char * msg,...)115*61046927SAndroid Build Coastguard Worker _vk_queue_set_lost(struct vk_queue *queue,
116*61046927SAndroid Build Coastguard Worker                    const char *file, int line,
117*61046927SAndroid Build Coastguard Worker                    const char *msg, ...)
118*61046927SAndroid Build Coastguard Worker {
119*61046927SAndroid Build Coastguard Worker    if (queue->_lost.lost)
120*61046927SAndroid Build Coastguard Worker       return VK_ERROR_DEVICE_LOST;
121*61046927SAndroid Build Coastguard Worker 
122*61046927SAndroid Build Coastguard Worker    queue->_lost.lost = true;
123*61046927SAndroid Build Coastguard Worker    queue->_lost.error_file = file;
124*61046927SAndroid Build Coastguard Worker    queue->_lost.error_line = line;
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker    va_list ap;
127*61046927SAndroid Build Coastguard Worker    va_start(ap, msg);
128*61046927SAndroid Build Coastguard Worker    vsnprintf(queue->_lost.error_msg, sizeof(queue->_lost.error_msg), msg, ap);
129*61046927SAndroid Build Coastguard Worker    va_end(ap);
130*61046927SAndroid Build Coastguard Worker 
131*61046927SAndroid Build Coastguard Worker    p_atomic_inc(&queue->base.device->_lost.lost);
132*61046927SAndroid Build Coastguard Worker 
133*61046927SAndroid Build Coastguard Worker    if (debug_get_bool_option("MESA_VK_ABORT_ON_DEVICE_LOSS", false)) {
134*61046927SAndroid Build Coastguard Worker       _vk_device_report_lost(queue->base.device);
135*61046927SAndroid Build Coastguard Worker       abort();
136*61046927SAndroid Build Coastguard Worker    }
137*61046927SAndroid Build Coastguard Worker 
138*61046927SAndroid Build Coastguard Worker    return VK_ERROR_DEVICE_LOST;
139*61046927SAndroid Build Coastguard Worker }
140*61046927SAndroid Build Coastguard Worker 
141*61046927SAndroid Build Coastguard Worker static struct vk_queue_submit *
vk_queue_submit_alloc(struct vk_queue * queue,uint32_t wait_count,uint32_t command_buffer_count,uint32_t buffer_bind_count,uint32_t image_opaque_bind_count,uint32_t image_bind_count,uint32_t bind_entry_count,uint32_t image_bind_entry_count,uint32_t signal_count,VkSparseMemoryBind ** bind_entries,VkSparseImageMemoryBind ** image_bind_entries)142*61046927SAndroid Build Coastguard Worker vk_queue_submit_alloc(struct vk_queue *queue,
143*61046927SAndroid Build Coastguard Worker                       uint32_t wait_count,
144*61046927SAndroid Build Coastguard Worker                       uint32_t command_buffer_count,
145*61046927SAndroid Build Coastguard Worker                       uint32_t buffer_bind_count,
146*61046927SAndroid Build Coastguard Worker                       uint32_t image_opaque_bind_count,
147*61046927SAndroid Build Coastguard Worker                       uint32_t image_bind_count,
148*61046927SAndroid Build Coastguard Worker                       uint32_t bind_entry_count,
149*61046927SAndroid Build Coastguard Worker                       uint32_t image_bind_entry_count,
150*61046927SAndroid Build Coastguard Worker                       uint32_t signal_count,
151*61046927SAndroid Build Coastguard Worker                       VkSparseMemoryBind **bind_entries,
152*61046927SAndroid Build Coastguard Worker                       VkSparseImageMemoryBind **image_bind_entries)
153*61046927SAndroid Build Coastguard Worker {
154*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC(ma);
155*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC_DECL(&ma, struct vk_queue_submit, submit, 1);
156*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC_DECL(&ma, struct vk_sync_wait, waits, wait_count);
157*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC_DECL(&ma, struct vk_command_buffer *, command_buffers,
158*61046927SAndroid Build Coastguard Worker                       command_buffer_count);
159*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC_DECL(&ma, VkSparseBufferMemoryBindInfo, buffer_binds,
160*61046927SAndroid Build Coastguard Worker                       buffer_bind_count);
161*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC_DECL(&ma, VkSparseImageOpaqueMemoryBindInfo,
162*61046927SAndroid Build Coastguard Worker                       image_opaque_binds, image_opaque_bind_count);
163*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC_DECL(&ma, VkSparseImageMemoryBindInfo, image_binds,
164*61046927SAndroid Build Coastguard Worker                       image_bind_count);
165*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC_DECL(&ma, VkSparseMemoryBind,
166*61046927SAndroid Build Coastguard Worker                       bind_entries_local, bind_entry_count);
167*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC_DECL(&ma, VkSparseImageMemoryBind, image_bind_entries_local,
168*61046927SAndroid Build Coastguard Worker                       image_bind_entry_count);
169*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC_DECL(&ma, struct vk_sync_signal, signals, signal_count);
170*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC_DECL(&ma, struct vk_sync *, wait_temps, wait_count);
171*61046927SAndroid Build Coastguard Worker 
172*61046927SAndroid Build Coastguard Worker    struct vk_sync_timeline_point **wait_points = NULL, **signal_points = NULL;
173*61046927SAndroid Build Coastguard Worker    if (queue->base.device->timeline_mode == VK_DEVICE_TIMELINE_MODE_EMULATED) {
174*61046927SAndroid Build Coastguard Worker       vk_multialloc_add(&ma, &wait_points,
175*61046927SAndroid Build Coastguard Worker                         struct vk_sync_timeline_point *, wait_count);
176*61046927SAndroid Build Coastguard Worker       vk_multialloc_add(&ma, &signal_points,
177*61046927SAndroid Build Coastguard Worker                         struct vk_sync_timeline_point *, signal_count);
178*61046927SAndroid Build Coastguard Worker    }
179*61046927SAndroid Build Coastguard Worker 
180*61046927SAndroid Build Coastguard Worker    if (!vk_multialloc_zalloc(&ma, &queue->base.device->alloc,
181*61046927SAndroid Build Coastguard Worker                              VK_SYSTEM_ALLOCATION_SCOPE_DEVICE))
182*61046927SAndroid Build Coastguard Worker       return NULL;
183*61046927SAndroid Build Coastguard Worker 
184*61046927SAndroid Build Coastguard Worker    submit->wait_count            = wait_count;
185*61046927SAndroid Build Coastguard Worker    submit->command_buffer_count  = command_buffer_count;
186*61046927SAndroid Build Coastguard Worker    submit->signal_count          = signal_count;
187*61046927SAndroid Build Coastguard Worker    submit->buffer_bind_count     = buffer_bind_count;
188*61046927SAndroid Build Coastguard Worker    submit->image_opaque_bind_count = image_opaque_bind_count;
189*61046927SAndroid Build Coastguard Worker    submit->image_bind_count      = image_bind_count;
190*61046927SAndroid Build Coastguard Worker 
191*61046927SAndroid Build Coastguard Worker    submit->waits           = waits;
192*61046927SAndroid Build Coastguard Worker    submit->command_buffers = command_buffers;
193*61046927SAndroid Build Coastguard Worker    submit->signals         = signals;
194*61046927SAndroid Build Coastguard Worker    submit->buffer_binds    = buffer_binds;
195*61046927SAndroid Build Coastguard Worker    submit->image_opaque_binds = image_opaque_binds;
196*61046927SAndroid Build Coastguard Worker    submit->image_binds     = image_binds;
197*61046927SAndroid Build Coastguard Worker    submit->_wait_temps     = wait_temps;
198*61046927SAndroid Build Coastguard Worker    submit->_wait_points    = wait_points;
199*61046927SAndroid Build Coastguard Worker    submit->_signal_points  = signal_points;
200*61046927SAndroid Build Coastguard Worker 
201*61046927SAndroid Build Coastguard Worker    if (bind_entries)
202*61046927SAndroid Build Coastguard Worker       *bind_entries = bind_entries_local;
203*61046927SAndroid Build Coastguard Worker 
204*61046927SAndroid Build Coastguard Worker    if (image_bind_entries)
205*61046927SAndroid Build Coastguard Worker       *image_bind_entries = image_bind_entries_local;
206*61046927SAndroid Build Coastguard Worker 
207*61046927SAndroid Build Coastguard Worker    return submit;
208*61046927SAndroid Build Coastguard Worker }
209*61046927SAndroid Build Coastguard Worker 
210*61046927SAndroid Build Coastguard Worker static void
vk_queue_submit_cleanup(struct vk_queue * queue,struct vk_queue_submit * submit)211*61046927SAndroid Build Coastguard Worker vk_queue_submit_cleanup(struct vk_queue *queue,
212*61046927SAndroid Build Coastguard Worker                         struct vk_queue_submit *submit)
213*61046927SAndroid Build Coastguard Worker {
214*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < submit->wait_count; i++) {
215*61046927SAndroid Build Coastguard Worker       if (submit->_wait_temps[i] != NULL)
216*61046927SAndroid Build Coastguard Worker          vk_sync_destroy(queue->base.device, submit->_wait_temps[i]);
217*61046927SAndroid Build Coastguard Worker    }
218*61046927SAndroid Build Coastguard Worker 
219*61046927SAndroid Build Coastguard Worker    if (submit->_mem_signal_temp != NULL)
220*61046927SAndroid Build Coastguard Worker       vk_sync_destroy(queue->base.device, submit->_mem_signal_temp);
221*61046927SAndroid Build Coastguard Worker 
222*61046927SAndroid Build Coastguard Worker    if (submit->_wait_points != NULL) {
223*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < submit->wait_count; i++) {
224*61046927SAndroid Build Coastguard Worker          if (unlikely(submit->_wait_points[i] != NULL)) {
225*61046927SAndroid Build Coastguard Worker             vk_sync_timeline_point_release(queue->base.device,
226*61046927SAndroid Build Coastguard Worker                                            submit->_wait_points[i]);
227*61046927SAndroid Build Coastguard Worker          }
228*61046927SAndroid Build Coastguard Worker       }
229*61046927SAndroid Build Coastguard Worker    }
230*61046927SAndroid Build Coastguard Worker 
231*61046927SAndroid Build Coastguard Worker    if (submit->_signal_points != NULL) {
232*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < submit->signal_count; i++) {
233*61046927SAndroid Build Coastguard Worker          if (unlikely(submit->_signal_points[i] != NULL)) {
234*61046927SAndroid Build Coastguard Worker             vk_sync_timeline_point_free(queue->base.device,
235*61046927SAndroid Build Coastguard Worker                                         submit->_signal_points[i]);
236*61046927SAndroid Build Coastguard Worker          }
237*61046927SAndroid Build Coastguard Worker       }
238*61046927SAndroid Build Coastguard Worker    }
239*61046927SAndroid Build Coastguard Worker }
240*61046927SAndroid Build Coastguard Worker 
241*61046927SAndroid Build Coastguard Worker static void
vk_queue_submit_free(struct vk_queue * queue,struct vk_queue_submit * submit)242*61046927SAndroid Build Coastguard Worker vk_queue_submit_free(struct vk_queue *queue,
243*61046927SAndroid Build Coastguard Worker                      struct vk_queue_submit *submit)
244*61046927SAndroid Build Coastguard Worker {
245*61046927SAndroid Build Coastguard Worker    vk_free(&queue->base.device->alloc, submit);
246*61046927SAndroid Build Coastguard Worker }
247*61046927SAndroid Build Coastguard Worker 
248*61046927SAndroid Build Coastguard Worker static void
vk_queue_submit_destroy(struct vk_queue * queue,struct vk_queue_submit * submit)249*61046927SAndroid Build Coastguard Worker vk_queue_submit_destroy(struct vk_queue *queue,
250*61046927SAndroid Build Coastguard Worker                         struct vk_queue_submit *submit)
251*61046927SAndroid Build Coastguard Worker {
252*61046927SAndroid Build Coastguard Worker    vk_queue_submit_cleanup(queue, submit);
253*61046927SAndroid Build Coastguard Worker    vk_queue_submit_free(queue, submit);
254*61046927SAndroid Build Coastguard Worker }
255*61046927SAndroid Build Coastguard Worker 
256*61046927SAndroid Build Coastguard Worker static void
vk_queue_push_submit(struct vk_queue * queue,struct vk_queue_submit * submit)257*61046927SAndroid Build Coastguard Worker vk_queue_push_submit(struct vk_queue *queue,
258*61046927SAndroid Build Coastguard Worker                      struct vk_queue_submit *submit)
259*61046927SAndroid Build Coastguard Worker {
260*61046927SAndroid Build Coastguard Worker    mtx_lock(&queue->submit.mutex);
261*61046927SAndroid Build Coastguard Worker    list_addtail(&submit->link, &queue->submit.submits);
262*61046927SAndroid Build Coastguard Worker    cnd_signal(&queue->submit.push);
263*61046927SAndroid Build Coastguard Worker    mtx_unlock(&queue->submit.mutex);
264*61046927SAndroid Build Coastguard Worker }
265*61046927SAndroid Build Coastguard Worker 
266*61046927SAndroid Build Coastguard Worker static VkResult
vk_queue_drain(struct vk_queue * queue)267*61046927SAndroid Build Coastguard Worker vk_queue_drain(struct vk_queue *queue)
268*61046927SAndroid Build Coastguard Worker {
269*61046927SAndroid Build Coastguard Worker    VkResult result = VK_SUCCESS;
270*61046927SAndroid Build Coastguard Worker 
271*61046927SAndroid Build Coastguard Worker    mtx_lock(&queue->submit.mutex);
272*61046927SAndroid Build Coastguard Worker    while (!list_is_empty(&queue->submit.submits)) {
273*61046927SAndroid Build Coastguard Worker       if (vk_device_is_lost(queue->base.device)) {
274*61046927SAndroid Build Coastguard Worker          result = VK_ERROR_DEVICE_LOST;
275*61046927SAndroid Build Coastguard Worker          break;
276*61046927SAndroid Build Coastguard Worker       }
277*61046927SAndroid Build Coastguard Worker 
278*61046927SAndroid Build Coastguard Worker       int ret = cnd_wait(&queue->submit.pop, &queue->submit.mutex);
279*61046927SAndroid Build Coastguard Worker       if (ret == thrd_error) {
280*61046927SAndroid Build Coastguard Worker          result = vk_queue_set_lost(queue, "cnd_wait failed");
281*61046927SAndroid Build Coastguard Worker          break;
282*61046927SAndroid Build Coastguard Worker       }
283*61046927SAndroid Build Coastguard Worker    }
284*61046927SAndroid Build Coastguard Worker    mtx_unlock(&queue->submit.mutex);
285*61046927SAndroid Build Coastguard Worker 
286*61046927SAndroid Build Coastguard Worker    return result;
287*61046927SAndroid Build Coastguard Worker }
288*61046927SAndroid Build Coastguard Worker 
289*61046927SAndroid Build Coastguard Worker static VkResult
vk_queue_submit_final(struct vk_queue * queue,struct vk_queue_submit * submit)290*61046927SAndroid Build Coastguard Worker vk_queue_submit_final(struct vk_queue *queue,
291*61046927SAndroid Build Coastguard Worker                       struct vk_queue_submit *submit)
292*61046927SAndroid Build Coastguard Worker {
293*61046927SAndroid Build Coastguard Worker    VkResult result;
294*61046927SAndroid Build Coastguard Worker 
295*61046927SAndroid Build Coastguard Worker    /* Now that we know all our time points exist, fetch the time point syncs
296*61046927SAndroid Build Coastguard Worker     * from any vk_sync_timelines.  While we're here, also compact down the
297*61046927SAndroid Build Coastguard Worker     * list of waits to get rid of any trivial timeline waits.
298*61046927SAndroid Build Coastguard Worker     */
299*61046927SAndroid Build Coastguard Worker    uint32_t wait_count = 0;
300*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < submit->wait_count; i++) {
301*61046927SAndroid Build Coastguard Worker       /* A timeline wait on 0 is always a no-op */
302*61046927SAndroid Build Coastguard Worker       if ((submit->waits[i].sync->flags & VK_SYNC_IS_TIMELINE) &&
303*61046927SAndroid Build Coastguard Worker           submit->waits[i].wait_value == 0)
304*61046927SAndroid Build Coastguard Worker          continue;
305*61046927SAndroid Build Coastguard Worker 
306*61046927SAndroid Build Coastguard Worker       /* Waits on dummy vk_syncs are no-ops */
307*61046927SAndroid Build Coastguard Worker       if (vk_sync_type_is_dummy(submit->waits[i].sync->type)) {
308*61046927SAndroid Build Coastguard Worker          /* We are about to lose track of this wait, if it has a temporary
309*61046927SAndroid Build Coastguard Worker           * we need to destroy it now, as vk_queue_submit_cleanup will not
310*61046927SAndroid Build Coastguard Worker           * know about it */
311*61046927SAndroid Build Coastguard Worker          if (submit->_wait_temps[i] != NULL) {
312*61046927SAndroid Build Coastguard Worker             vk_sync_destroy(queue->base.device, submit->_wait_temps[i]);
313*61046927SAndroid Build Coastguard Worker             submit->waits[i].sync = NULL;
314*61046927SAndroid Build Coastguard Worker          }
315*61046927SAndroid Build Coastguard Worker          continue;
316*61046927SAndroid Build Coastguard Worker       }
317*61046927SAndroid Build Coastguard Worker 
318*61046927SAndroid Build Coastguard Worker       /* For emulated timelines, we have a binary vk_sync associated with
319*61046927SAndroid Build Coastguard Worker        * each time point and pass the binary vk_sync to the driver.
320*61046927SAndroid Build Coastguard Worker        */
321*61046927SAndroid Build Coastguard Worker       struct vk_sync_timeline *timeline =
322*61046927SAndroid Build Coastguard Worker          vk_sync_as_timeline(submit->waits[i].sync);
323*61046927SAndroid Build Coastguard Worker       if (timeline) {
324*61046927SAndroid Build Coastguard Worker          assert(queue->base.device->timeline_mode ==
325*61046927SAndroid Build Coastguard Worker                 VK_DEVICE_TIMELINE_MODE_EMULATED);
326*61046927SAndroid Build Coastguard Worker          result = vk_sync_timeline_get_point(queue->base.device, timeline,
327*61046927SAndroid Build Coastguard Worker                                              submit->waits[i].wait_value,
328*61046927SAndroid Build Coastguard Worker                                              &submit->_wait_points[i]);
329*61046927SAndroid Build Coastguard Worker          if (unlikely(result != VK_SUCCESS)) {
330*61046927SAndroid Build Coastguard Worker             result = vk_queue_set_lost(queue,
331*61046927SAndroid Build Coastguard Worker                                        "Time point >= %"PRIu64" not found",
332*61046927SAndroid Build Coastguard Worker                                        submit->waits[i].wait_value);
333*61046927SAndroid Build Coastguard Worker          }
334*61046927SAndroid Build Coastguard Worker 
335*61046927SAndroid Build Coastguard Worker          /* This can happen if the point is long past */
336*61046927SAndroid Build Coastguard Worker          if (submit->_wait_points[i] == NULL)
337*61046927SAndroid Build Coastguard Worker             continue;
338*61046927SAndroid Build Coastguard Worker 
339*61046927SAndroid Build Coastguard Worker          submit->waits[i].sync = &submit->_wait_points[i]->sync;
340*61046927SAndroid Build Coastguard Worker          submit->waits[i].wait_value = 0;
341*61046927SAndroid Build Coastguard Worker       }
342*61046927SAndroid Build Coastguard Worker 
343*61046927SAndroid Build Coastguard Worker       struct vk_sync_binary *binary =
344*61046927SAndroid Build Coastguard Worker          vk_sync_as_binary(submit->waits[i].sync);
345*61046927SAndroid Build Coastguard Worker       if (binary) {
346*61046927SAndroid Build Coastguard Worker          submit->waits[i].sync = &binary->timeline;
347*61046927SAndroid Build Coastguard Worker          submit->waits[i].wait_value = binary->next_point;
348*61046927SAndroid Build Coastguard Worker       }
349*61046927SAndroid Build Coastguard Worker 
350*61046927SAndroid Build Coastguard Worker       assert((submit->waits[i].sync->flags & VK_SYNC_IS_TIMELINE) ||
351*61046927SAndroid Build Coastguard Worker              submit->waits[i].wait_value == 0);
352*61046927SAndroid Build Coastguard Worker 
353*61046927SAndroid Build Coastguard Worker       assert(wait_count <= i);
354*61046927SAndroid Build Coastguard Worker       if (wait_count < i) {
355*61046927SAndroid Build Coastguard Worker          submit->waits[wait_count] = submit->waits[i];
356*61046927SAndroid Build Coastguard Worker          submit->_wait_temps[wait_count] = submit->_wait_temps[i];
357*61046927SAndroid Build Coastguard Worker          if (submit->_wait_points)
358*61046927SAndroid Build Coastguard Worker             submit->_wait_points[wait_count] = submit->_wait_points[i];
359*61046927SAndroid Build Coastguard Worker       }
360*61046927SAndroid Build Coastguard Worker       wait_count++;
361*61046927SAndroid Build Coastguard Worker    }
362*61046927SAndroid Build Coastguard Worker 
363*61046927SAndroid Build Coastguard Worker    assert(wait_count <= submit->wait_count);
364*61046927SAndroid Build Coastguard Worker    submit->wait_count = wait_count;
365*61046927SAndroid Build Coastguard Worker 
366*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < submit->signal_count; i++) {
367*61046927SAndroid Build Coastguard Worker       assert((submit->signals[i].sync->flags & VK_SYNC_IS_TIMELINE) ||
368*61046927SAndroid Build Coastguard Worker              submit->signals[i].signal_value == 0);
369*61046927SAndroid Build Coastguard Worker 
370*61046927SAndroid Build Coastguard Worker       struct vk_sync_binary *binary =
371*61046927SAndroid Build Coastguard Worker          vk_sync_as_binary(submit->signals[i].sync);
372*61046927SAndroid Build Coastguard Worker       if (binary) {
373*61046927SAndroid Build Coastguard Worker          submit->signals[i].sync = &binary->timeline;
374*61046927SAndroid Build Coastguard Worker          submit->signals[i].signal_value = ++binary->next_point;
375*61046927SAndroid Build Coastguard Worker       }
376*61046927SAndroid Build Coastguard Worker    }
377*61046927SAndroid Build Coastguard Worker 
378*61046927SAndroid Build Coastguard Worker    result = queue->driver_submit(queue, submit);
379*61046927SAndroid Build Coastguard Worker    if (unlikely(result != VK_SUCCESS))
380*61046927SAndroid Build Coastguard Worker       return result;
381*61046927SAndroid Build Coastguard Worker 
382*61046927SAndroid Build Coastguard Worker    if (submit->_signal_points) {
383*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < submit->signal_count; i++) {
384*61046927SAndroid Build Coastguard Worker          if (submit->_signal_points[i] == NULL)
385*61046927SAndroid Build Coastguard Worker             continue;
386*61046927SAndroid Build Coastguard Worker 
387*61046927SAndroid Build Coastguard Worker          vk_sync_timeline_point_install(queue->base.device,
388*61046927SAndroid Build Coastguard Worker                                         submit->_signal_points[i]);
389*61046927SAndroid Build Coastguard Worker          submit->_signal_points[i] = NULL;
390*61046927SAndroid Build Coastguard Worker       }
391*61046927SAndroid Build Coastguard Worker    }
392*61046927SAndroid Build Coastguard Worker 
393*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
394*61046927SAndroid Build Coastguard Worker }
395*61046927SAndroid Build Coastguard Worker 
396*61046927SAndroid Build Coastguard Worker VkResult
vk_queue_flush(struct vk_queue * queue,uint32_t * submit_count_out)397*61046927SAndroid Build Coastguard Worker vk_queue_flush(struct vk_queue *queue, uint32_t *submit_count_out)
398*61046927SAndroid Build Coastguard Worker {
399*61046927SAndroid Build Coastguard Worker    VkResult result = VK_SUCCESS;
400*61046927SAndroid Build Coastguard Worker 
401*61046927SAndroid Build Coastguard Worker    assert(queue->submit.mode == VK_QUEUE_SUBMIT_MODE_DEFERRED);
402*61046927SAndroid Build Coastguard Worker 
403*61046927SAndroid Build Coastguard Worker    mtx_lock(&queue->submit.mutex);
404*61046927SAndroid Build Coastguard Worker 
405*61046927SAndroid Build Coastguard Worker    uint32_t submit_count = 0;
406*61046927SAndroid Build Coastguard Worker    while (!list_is_empty(&queue->submit.submits)) {
407*61046927SAndroid Build Coastguard Worker       struct vk_queue_submit *submit =
408*61046927SAndroid Build Coastguard Worker          list_first_entry(&queue->submit.submits,
409*61046927SAndroid Build Coastguard Worker                           struct vk_queue_submit, link);
410*61046927SAndroid Build Coastguard Worker 
411*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < submit->wait_count; i++) {
412*61046927SAndroid Build Coastguard Worker          /* In emulated timeline mode, only emulated timelines are allowed */
413*61046927SAndroid Build Coastguard Worker          if (!vk_sync_type_is_vk_sync_timeline(submit->waits[i].sync->type)) {
414*61046927SAndroid Build Coastguard Worker             assert(!(submit->waits[i].sync->flags & VK_SYNC_IS_TIMELINE));
415*61046927SAndroid Build Coastguard Worker             continue;
416*61046927SAndroid Build Coastguard Worker          }
417*61046927SAndroid Build Coastguard Worker 
418*61046927SAndroid Build Coastguard Worker          result = vk_sync_wait(queue->base.device,
419*61046927SAndroid Build Coastguard Worker                                submit->waits[i].sync,
420*61046927SAndroid Build Coastguard Worker                                submit->waits[i].wait_value,
421*61046927SAndroid Build Coastguard Worker                                VK_SYNC_WAIT_PENDING, 0);
422*61046927SAndroid Build Coastguard Worker          if (result == VK_TIMEOUT) {
423*61046927SAndroid Build Coastguard Worker             /* This one's not ready yet */
424*61046927SAndroid Build Coastguard Worker             result = VK_SUCCESS;
425*61046927SAndroid Build Coastguard Worker             goto done;
426*61046927SAndroid Build Coastguard Worker          } else if (result != VK_SUCCESS) {
427*61046927SAndroid Build Coastguard Worker             result = vk_queue_set_lost(queue, "Wait for time points failed");
428*61046927SAndroid Build Coastguard Worker             goto done;
429*61046927SAndroid Build Coastguard Worker          }
430*61046927SAndroid Build Coastguard Worker       }
431*61046927SAndroid Build Coastguard Worker 
432*61046927SAndroid Build Coastguard Worker       result = vk_queue_submit_final(queue, submit);
433*61046927SAndroid Build Coastguard Worker       if (unlikely(result != VK_SUCCESS)) {
434*61046927SAndroid Build Coastguard Worker          result = vk_queue_set_lost(queue, "queue::driver_submit failed");
435*61046927SAndroid Build Coastguard Worker          goto done;
436*61046927SAndroid Build Coastguard Worker       }
437*61046927SAndroid Build Coastguard Worker 
438*61046927SAndroid Build Coastguard Worker       submit_count++;
439*61046927SAndroid Build Coastguard Worker 
440*61046927SAndroid Build Coastguard Worker       list_del(&submit->link);
441*61046927SAndroid Build Coastguard Worker 
442*61046927SAndroid Build Coastguard Worker       vk_queue_submit_destroy(queue, submit);
443*61046927SAndroid Build Coastguard Worker    }
444*61046927SAndroid Build Coastguard Worker 
445*61046927SAndroid Build Coastguard Worker done:
446*61046927SAndroid Build Coastguard Worker    if (submit_count)
447*61046927SAndroid Build Coastguard Worker       cnd_broadcast(&queue->submit.pop);
448*61046927SAndroid Build Coastguard Worker 
449*61046927SAndroid Build Coastguard Worker    mtx_unlock(&queue->submit.mutex);
450*61046927SAndroid Build Coastguard Worker 
451*61046927SAndroid Build Coastguard Worker    if (submit_count_out)
452*61046927SAndroid Build Coastguard Worker       *submit_count_out = submit_count;
453*61046927SAndroid Build Coastguard Worker 
454*61046927SAndroid Build Coastguard Worker    return result;
455*61046927SAndroid Build Coastguard Worker }
456*61046927SAndroid Build Coastguard Worker 
457*61046927SAndroid Build Coastguard Worker static int
vk_queue_submit_thread_func(void * _data)458*61046927SAndroid Build Coastguard Worker vk_queue_submit_thread_func(void *_data)
459*61046927SAndroid Build Coastguard Worker {
460*61046927SAndroid Build Coastguard Worker    struct vk_queue *queue = _data;
461*61046927SAndroid Build Coastguard Worker    VkResult result;
462*61046927SAndroid Build Coastguard Worker 
463*61046927SAndroid Build Coastguard Worker    mtx_lock(&queue->submit.mutex);
464*61046927SAndroid Build Coastguard Worker 
465*61046927SAndroid Build Coastguard Worker    while (queue->submit.thread_run) {
466*61046927SAndroid Build Coastguard Worker       if (list_is_empty(&queue->submit.submits)) {
467*61046927SAndroid Build Coastguard Worker          int ret = cnd_wait(&queue->submit.push, &queue->submit.mutex);
468*61046927SAndroid Build Coastguard Worker          if (ret == thrd_error) {
469*61046927SAndroid Build Coastguard Worker             mtx_unlock(&queue->submit.mutex);
470*61046927SAndroid Build Coastguard Worker             vk_queue_set_lost(queue, "cnd_wait failed");
471*61046927SAndroid Build Coastguard Worker             return 1;
472*61046927SAndroid Build Coastguard Worker          }
473*61046927SAndroid Build Coastguard Worker          continue;
474*61046927SAndroid Build Coastguard Worker       }
475*61046927SAndroid Build Coastguard Worker 
476*61046927SAndroid Build Coastguard Worker       struct vk_queue_submit *submit =
477*61046927SAndroid Build Coastguard Worker          list_first_entry(&queue->submit.submits,
478*61046927SAndroid Build Coastguard Worker                           struct vk_queue_submit, link);
479*61046927SAndroid Build Coastguard Worker 
480*61046927SAndroid Build Coastguard Worker       /* Drop the lock while we wait */
481*61046927SAndroid Build Coastguard Worker       mtx_unlock(&queue->submit.mutex);
482*61046927SAndroid Build Coastguard Worker 
483*61046927SAndroid Build Coastguard Worker       result = vk_sync_wait_many(queue->base.device,
484*61046927SAndroid Build Coastguard Worker                                  submit->wait_count, submit->waits,
485*61046927SAndroid Build Coastguard Worker                                  VK_SYNC_WAIT_PENDING, UINT64_MAX);
486*61046927SAndroid Build Coastguard Worker       if (unlikely(result != VK_SUCCESS)) {
487*61046927SAndroid Build Coastguard Worker          vk_queue_set_lost(queue, "Wait for time points failed");
488*61046927SAndroid Build Coastguard Worker          return 1;
489*61046927SAndroid Build Coastguard Worker       }
490*61046927SAndroid Build Coastguard Worker 
491*61046927SAndroid Build Coastguard Worker       result = vk_queue_submit_final(queue, submit);
492*61046927SAndroid Build Coastguard Worker       if (unlikely(result != VK_SUCCESS)) {
493*61046927SAndroid Build Coastguard Worker          vk_queue_set_lost(queue, "queue::driver_submit failed");
494*61046927SAndroid Build Coastguard Worker          return 1;
495*61046927SAndroid Build Coastguard Worker       }
496*61046927SAndroid Build Coastguard Worker 
497*61046927SAndroid Build Coastguard Worker       /* Do all our cleanup of individual fences etc. outside the lock.
498*61046927SAndroid Build Coastguard Worker        * We can't actually remove it from the list yet.  We have to do
499*61046927SAndroid Build Coastguard Worker        * that under the lock.
500*61046927SAndroid Build Coastguard Worker        */
501*61046927SAndroid Build Coastguard Worker       vk_queue_submit_cleanup(queue, submit);
502*61046927SAndroid Build Coastguard Worker 
503*61046927SAndroid Build Coastguard Worker       mtx_lock(&queue->submit.mutex);
504*61046927SAndroid Build Coastguard Worker 
505*61046927SAndroid Build Coastguard Worker       /* Only remove the submit from from the list and free it after
506*61046927SAndroid Build Coastguard Worker        * queue->submit() has completed.  This ensures that, when
507*61046927SAndroid Build Coastguard Worker        * vk_queue_drain() completes, there are no more pending jobs.
508*61046927SAndroid Build Coastguard Worker        */
509*61046927SAndroid Build Coastguard Worker       list_del(&submit->link);
510*61046927SAndroid Build Coastguard Worker       vk_queue_submit_free(queue, submit);
511*61046927SAndroid Build Coastguard Worker 
512*61046927SAndroid Build Coastguard Worker       cnd_broadcast(&queue->submit.pop);
513*61046927SAndroid Build Coastguard Worker    }
514*61046927SAndroid Build Coastguard Worker 
515*61046927SAndroid Build Coastguard Worker    mtx_unlock(&queue->submit.mutex);
516*61046927SAndroid Build Coastguard Worker    return 0;
517*61046927SAndroid Build Coastguard Worker }
518*61046927SAndroid Build Coastguard Worker 
519*61046927SAndroid Build Coastguard Worker static VkResult
vk_queue_start_submit_thread(struct vk_queue * queue)520*61046927SAndroid Build Coastguard Worker vk_queue_start_submit_thread(struct vk_queue *queue)
521*61046927SAndroid Build Coastguard Worker {
522*61046927SAndroid Build Coastguard Worker    int ret;
523*61046927SAndroid Build Coastguard Worker 
524*61046927SAndroid Build Coastguard Worker    mtx_lock(&queue->submit.mutex);
525*61046927SAndroid Build Coastguard Worker    queue->submit.thread_run = true;
526*61046927SAndroid Build Coastguard Worker    mtx_unlock(&queue->submit.mutex);
527*61046927SAndroid Build Coastguard Worker 
528*61046927SAndroid Build Coastguard Worker    ret = thrd_create(&queue->submit.thread,
529*61046927SAndroid Build Coastguard Worker                      vk_queue_submit_thread_func,
530*61046927SAndroid Build Coastguard Worker                      queue);
531*61046927SAndroid Build Coastguard Worker    if (ret == thrd_error)
532*61046927SAndroid Build Coastguard Worker       return vk_errorf(queue, VK_ERROR_UNKNOWN, "thrd_create failed");
533*61046927SAndroid Build Coastguard Worker 
534*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
535*61046927SAndroid Build Coastguard Worker }
536*61046927SAndroid Build Coastguard Worker 
537*61046927SAndroid Build Coastguard Worker static void
vk_queue_stop_submit_thread(struct vk_queue * queue)538*61046927SAndroid Build Coastguard Worker vk_queue_stop_submit_thread(struct vk_queue *queue)
539*61046927SAndroid Build Coastguard Worker {
540*61046927SAndroid Build Coastguard Worker    vk_queue_drain(queue);
541*61046927SAndroid Build Coastguard Worker 
542*61046927SAndroid Build Coastguard Worker    /* Kick the thread to disable it */
543*61046927SAndroid Build Coastguard Worker    mtx_lock(&queue->submit.mutex);
544*61046927SAndroid Build Coastguard Worker    queue->submit.thread_run = false;
545*61046927SAndroid Build Coastguard Worker    cnd_signal(&queue->submit.push);
546*61046927SAndroid Build Coastguard Worker    mtx_unlock(&queue->submit.mutex);
547*61046927SAndroid Build Coastguard Worker 
548*61046927SAndroid Build Coastguard Worker    thrd_join(queue->submit.thread, NULL);
549*61046927SAndroid Build Coastguard Worker 
550*61046927SAndroid Build Coastguard Worker    assert(list_is_empty(&queue->submit.submits));
551*61046927SAndroid Build Coastguard Worker    queue->submit.mode = VK_QUEUE_SUBMIT_MODE_IMMEDIATE;
552*61046927SAndroid Build Coastguard Worker }
553*61046927SAndroid Build Coastguard Worker 
554*61046927SAndroid Build Coastguard Worker VkResult
vk_queue_enable_submit_thread(struct vk_queue * queue)555*61046927SAndroid Build Coastguard Worker vk_queue_enable_submit_thread(struct vk_queue *queue)
556*61046927SAndroid Build Coastguard Worker {
557*61046927SAndroid Build Coastguard Worker    assert(vk_device_supports_threaded_submit(queue->base.device));
558*61046927SAndroid Build Coastguard Worker 
559*61046927SAndroid Build Coastguard Worker    if (queue->submit.mode == VK_QUEUE_SUBMIT_MODE_THREADED)
560*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
561*61046927SAndroid Build Coastguard Worker 
562*61046927SAndroid Build Coastguard Worker    VkResult result = vk_queue_start_submit_thread(queue);
563*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
564*61046927SAndroid Build Coastguard Worker       return result;
565*61046927SAndroid Build Coastguard Worker 
566*61046927SAndroid Build Coastguard Worker    queue->submit.mode = VK_QUEUE_SUBMIT_MODE_THREADED;
567*61046927SAndroid Build Coastguard Worker 
568*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
569*61046927SAndroid Build Coastguard Worker }
570*61046927SAndroid Build Coastguard Worker 
571*61046927SAndroid Build Coastguard Worker struct vulkan_submit_info {
572*61046927SAndroid Build Coastguard Worker    const void *pNext;
573*61046927SAndroid Build Coastguard Worker 
574*61046927SAndroid Build Coastguard Worker    uint32_t command_buffer_count;
575*61046927SAndroid Build Coastguard Worker    const VkCommandBufferSubmitInfo *command_buffers;
576*61046927SAndroid Build Coastguard Worker 
577*61046927SAndroid Build Coastguard Worker    uint32_t wait_count;
578*61046927SAndroid Build Coastguard Worker    const VkSemaphoreSubmitInfo *waits;
579*61046927SAndroid Build Coastguard Worker 
580*61046927SAndroid Build Coastguard Worker    uint32_t signal_count;
581*61046927SAndroid Build Coastguard Worker    const VkSemaphoreSubmitInfo *signals;
582*61046927SAndroid Build Coastguard Worker 
583*61046927SAndroid Build Coastguard Worker    uint32_t buffer_bind_count;
584*61046927SAndroid Build Coastguard Worker    const VkSparseBufferMemoryBindInfo *buffer_binds;
585*61046927SAndroid Build Coastguard Worker 
586*61046927SAndroid Build Coastguard Worker    uint32_t image_opaque_bind_count;
587*61046927SAndroid Build Coastguard Worker    const VkSparseImageOpaqueMemoryBindInfo *image_opaque_binds;
588*61046927SAndroid Build Coastguard Worker 
589*61046927SAndroid Build Coastguard Worker    uint32_t image_bind_count;
590*61046927SAndroid Build Coastguard Worker    const VkSparseImageMemoryBindInfo *image_binds;
591*61046927SAndroid Build Coastguard Worker 
592*61046927SAndroid Build Coastguard Worker    struct vk_fence *fence;
593*61046927SAndroid Build Coastguard Worker };
594*61046927SAndroid Build Coastguard Worker 
595*61046927SAndroid Build Coastguard Worker static VkResult
vk_queue_submit(struct vk_queue * queue,const struct vulkan_submit_info * info)596*61046927SAndroid Build Coastguard Worker vk_queue_submit(struct vk_queue *queue,
597*61046927SAndroid Build Coastguard Worker                 const struct vulkan_submit_info *info)
598*61046927SAndroid Build Coastguard Worker {
599*61046927SAndroid Build Coastguard Worker    struct vk_device *device = queue->base.device;
600*61046927SAndroid Build Coastguard Worker    VkResult result;
601*61046927SAndroid Build Coastguard Worker    uint32_t sparse_memory_bind_entry_count = 0;
602*61046927SAndroid Build Coastguard Worker    uint32_t sparse_memory_image_bind_entry_count = 0;
603*61046927SAndroid Build Coastguard Worker    VkSparseMemoryBind *sparse_memory_bind_entries = NULL;
604*61046927SAndroid Build Coastguard Worker    VkSparseImageMemoryBind *sparse_memory_image_bind_entries = NULL;
605*61046927SAndroid Build Coastguard Worker 
606*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < info->buffer_bind_count; ++i)
607*61046927SAndroid Build Coastguard Worker       sparse_memory_bind_entry_count += info->buffer_binds[i].bindCount;
608*61046927SAndroid Build Coastguard Worker 
609*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < info->image_opaque_bind_count; ++i)
610*61046927SAndroid Build Coastguard Worker       sparse_memory_bind_entry_count += info->image_opaque_binds[i].bindCount;
611*61046927SAndroid Build Coastguard Worker 
612*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < info->image_bind_count; ++i)
613*61046927SAndroid Build Coastguard Worker       sparse_memory_image_bind_entry_count += info->image_binds[i].bindCount;
614*61046927SAndroid Build Coastguard Worker 
615*61046927SAndroid Build Coastguard Worker    const struct wsi_memory_signal_submit_info *mem_signal =
616*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(info->pNext, WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA);
617*61046927SAndroid Build Coastguard Worker    bool signal_mem_sync = mem_signal != NULL &&
618*61046927SAndroid Build Coastguard Worker                           mem_signal->memory != VK_NULL_HANDLE &&
619*61046927SAndroid Build Coastguard Worker                           queue->base.device->create_sync_for_memory != NULL;
620*61046927SAndroid Build Coastguard Worker 
621*61046927SAndroid Build Coastguard Worker    struct vk_queue_submit *submit =
622*61046927SAndroid Build Coastguard Worker       vk_queue_submit_alloc(queue, info->wait_count,
623*61046927SAndroid Build Coastguard Worker                             info->command_buffer_count,
624*61046927SAndroid Build Coastguard Worker                             info->buffer_bind_count,
625*61046927SAndroid Build Coastguard Worker                             info->image_opaque_bind_count,
626*61046927SAndroid Build Coastguard Worker                             info->image_bind_count,
627*61046927SAndroid Build Coastguard Worker                             sparse_memory_bind_entry_count,
628*61046927SAndroid Build Coastguard Worker                             sparse_memory_image_bind_entry_count,
629*61046927SAndroid Build Coastguard Worker                             info->signal_count +
630*61046927SAndroid Build Coastguard Worker                             signal_mem_sync + (info->fence != NULL),
631*61046927SAndroid Build Coastguard Worker                             &sparse_memory_bind_entries,
632*61046927SAndroid Build Coastguard Worker                             &sparse_memory_image_bind_entries);
633*61046927SAndroid Build Coastguard Worker    if (unlikely(submit == NULL))
634*61046927SAndroid Build Coastguard Worker       return vk_error(queue, VK_ERROR_OUT_OF_HOST_MEMORY);
635*61046927SAndroid Build Coastguard Worker 
636*61046927SAndroid Build Coastguard Worker    /* From the Vulkan 1.2.194 spec:
637*61046927SAndroid Build Coastguard Worker     *
638*61046927SAndroid Build Coastguard Worker     *    "If the VkSubmitInfo::pNext chain does not include this structure,
639*61046927SAndroid Build Coastguard Worker     *    the batch defaults to use counter pass index 0."
640*61046927SAndroid Build Coastguard Worker     */
641*61046927SAndroid Build Coastguard Worker    const VkPerformanceQuerySubmitInfoKHR *perf_info =
642*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(info->pNext, PERFORMANCE_QUERY_SUBMIT_INFO_KHR);
643*61046927SAndroid Build Coastguard Worker    submit->perf_pass_index = perf_info ? perf_info->counterPassIndex : 0;
644*61046927SAndroid Build Coastguard Worker 
645*61046927SAndroid Build Coastguard Worker    bool has_binary_permanent_semaphore_wait = false;
646*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < info->wait_count; i++) {
647*61046927SAndroid Build Coastguard Worker       VK_FROM_HANDLE(vk_semaphore, semaphore,
648*61046927SAndroid Build Coastguard Worker                      info->waits[i].semaphore);
649*61046927SAndroid Build Coastguard Worker 
650*61046927SAndroid Build Coastguard Worker       /* From the Vulkan 1.2.194 spec:
651*61046927SAndroid Build Coastguard Worker        *
652*61046927SAndroid Build Coastguard Worker        *    "Applications can import a semaphore payload into an existing
653*61046927SAndroid Build Coastguard Worker        *    semaphore using an external semaphore handle. The effects of the
654*61046927SAndroid Build Coastguard Worker        *    import operation will be either temporary or permanent, as
655*61046927SAndroid Build Coastguard Worker        *    specified by the application. If the import is temporary, the
656*61046927SAndroid Build Coastguard Worker        *    implementation must restore the semaphore to its prior permanent
657*61046927SAndroid Build Coastguard Worker        *    state after submitting the next semaphore wait operation."
658*61046927SAndroid Build Coastguard Worker        *
659*61046927SAndroid Build Coastguard Worker        * and
660*61046927SAndroid Build Coastguard Worker        *
661*61046927SAndroid Build Coastguard Worker        *    VUID-VkImportSemaphoreFdInfoKHR-flags-03323
662*61046927SAndroid Build Coastguard Worker        *
663*61046927SAndroid Build Coastguard Worker        *    "If flags contains VK_SEMAPHORE_IMPORT_TEMPORARY_BIT, the
664*61046927SAndroid Build Coastguard Worker        *    VkSemaphoreTypeCreateInfo::semaphoreType field of the semaphore
665*61046927SAndroid Build Coastguard Worker        *    from which handle or name was exported must not be
666*61046927SAndroid Build Coastguard Worker        *    VK_SEMAPHORE_TYPE_TIMELINE"
667*61046927SAndroid Build Coastguard Worker        */
668*61046927SAndroid Build Coastguard Worker       struct vk_sync *sync;
669*61046927SAndroid Build Coastguard Worker       if (semaphore->temporary) {
670*61046927SAndroid Build Coastguard Worker          assert(semaphore->type == VK_SEMAPHORE_TYPE_BINARY);
671*61046927SAndroid Build Coastguard Worker          sync = submit->_wait_temps[i] = semaphore->temporary;
672*61046927SAndroid Build Coastguard Worker          semaphore->temporary = NULL;
673*61046927SAndroid Build Coastguard Worker       } else {
674*61046927SAndroid Build Coastguard Worker          if (semaphore->type == VK_SEMAPHORE_TYPE_BINARY) {
675*61046927SAndroid Build Coastguard Worker             if (vk_device_supports_threaded_submit(device))
676*61046927SAndroid Build Coastguard Worker                assert(semaphore->permanent.type->move);
677*61046927SAndroid Build Coastguard Worker             has_binary_permanent_semaphore_wait = true;
678*61046927SAndroid Build Coastguard Worker          }
679*61046927SAndroid Build Coastguard Worker 
680*61046927SAndroid Build Coastguard Worker          sync = &semaphore->permanent;
681*61046927SAndroid Build Coastguard Worker       }
682*61046927SAndroid Build Coastguard Worker 
683*61046927SAndroid Build Coastguard Worker       uint64_t wait_value = semaphore->type == VK_SEMAPHORE_TYPE_TIMELINE ?
684*61046927SAndroid Build Coastguard Worker                             info->waits[i].value : 0;
685*61046927SAndroid Build Coastguard Worker 
686*61046927SAndroid Build Coastguard Worker       submit->waits[i] = (struct vk_sync_wait) {
687*61046927SAndroid Build Coastguard Worker          .sync = sync,
688*61046927SAndroid Build Coastguard Worker          .stage_mask = info->waits[i].stageMask,
689*61046927SAndroid Build Coastguard Worker          .wait_value = wait_value,
690*61046927SAndroid Build Coastguard Worker       };
691*61046927SAndroid Build Coastguard Worker    }
692*61046927SAndroid Build Coastguard Worker 
693*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < info->command_buffer_count; i++) {
694*61046927SAndroid Build Coastguard Worker       VK_FROM_HANDLE(vk_command_buffer, cmd_buffer,
695*61046927SAndroid Build Coastguard Worker                      info->command_buffers[i].commandBuffer);
696*61046927SAndroid Build Coastguard Worker       assert(info->command_buffers[i].deviceMask == 0 ||
697*61046927SAndroid Build Coastguard Worker              info->command_buffers[i].deviceMask == 1);
698*61046927SAndroid Build Coastguard Worker       assert(cmd_buffer->pool->queue_family_index == queue->queue_family_index);
699*61046927SAndroid Build Coastguard Worker 
700*61046927SAndroid Build Coastguard Worker       /* Some drivers don't call vk_command_buffer_begin/end() yet and, for
701*61046927SAndroid Build Coastguard Worker        * those, we'll see initial layout.  However, this is enough to catch
702*61046927SAndroid Build Coastguard Worker        * command buffers which get submitted without calling EndCommandBuffer.
703*61046927SAndroid Build Coastguard Worker        */
704*61046927SAndroid Build Coastguard Worker       assert(cmd_buffer->state == MESA_VK_COMMAND_BUFFER_STATE_INITIAL ||
705*61046927SAndroid Build Coastguard Worker              cmd_buffer->state == MESA_VK_COMMAND_BUFFER_STATE_EXECUTABLE ||
706*61046927SAndroid Build Coastguard Worker              cmd_buffer->state == MESA_VK_COMMAND_BUFFER_STATE_PENDING);
707*61046927SAndroid Build Coastguard Worker       cmd_buffer->state = MESA_VK_COMMAND_BUFFER_STATE_PENDING;
708*61046927SAndroid Build Coastguard Worker 
709*61046927SAndroid Build Coastguard Worker       submit->command_buffers[i] = cmd_buffer;
710*61046927SAndroid Build Coastguard Worker    }
711*61046927SAndroid Build Coastguard Worker 
712*61046927SAndroid Build Coastguard Worker    sparse_memory_bind_entry_count = 0;
713*61046927SAndroid Build Coastguard Worker    sparse_memory_image_bind_entry_count = 0;
714*61046927SAndroid Build Coastguard Worker 
715*61046927SAndroid Build Coastguard Worker    if (info->buffer_binds)
716*61046927SAndroid Build Coastguard Worker       typed_memcpy(submit->buffer_binds, info->buffer_binds, info->buffer_bind_count);
717*61046927SAndroid Build Coastguard Worker 
718*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < info->buffer_bind_count; ++i) {
719*61046927SAndroid Build Coastguard Worker       VkSparseMemoryBind *binds = sparse_memory_bind_entries +
720*61046927SAndroid Build Coastguard Worker                                   sparse_memory_bind_entry_count;
721*61046927SAndroid Build Coastguard Worker       submit->buffer_binds[i].pBinds = binds;
722*61046927SAndroid Build Coastguard Worker       typed_memcpy(binds, info->buffer_binds[i].pBinds,
723*61046927SAndroid Build Coastguard Worker                    info->buffer_binds[i].bindCount);
724*61046927SAndroid Build Coastguard Worker 
725*61046927SAndroid Build Coastguard Worker       sparse_memory_bind_entry_count += info->buffer_binds[i].bindCount;
726*61046927SAndroid Build Coastguard Worker    }
727*61046927SAndroid Build Coastguard Worker 
728*61046927SAndroid Build Coastguard Worker    if (info->image_opaque_binds)
729*61046927SAndroid Build Coastguard Worker       typed_memcpy(submit->image_opaque_binds, info->image_opaque_binds,
730*61046927SAndroid Build Coastguard Worker                    info->image_opaque_bind_count);
731*61046927SAndroid Build Coastguard Worker 
732*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < info->image_opaque_bind_count; ++i) {
733*61046927SAndroid Build Coastguard Worker       VkSparseMemoryBind *binds = sparse_memory_bind_entries +
734*61046927SAndroid Build Coastguard Worker                                   sparse_memory_bind_entry_count;
735*61046927SAndroid Build Coastguard Worker       submit->image_opaque_binds[i].pBinds = binds;
736*61046927SAndroid Build Coastguard Worker       typed_memcpy(binds, info->image_opaque_binds[i].pBinds,
737*61046927SAndroid Build Coastguard Worker                    info->image_opaque_binds[i].bindCount);
738*61046927SAndroid Build Coastguard Worker 
739*61046927SAndroid Build Coastguard Worker       sparse_memory_bind_entry_count += info->image_opaque_binds[i].bindCount;
740*61046927SAndroid Build Coastguard Worker    }
741*61046927SAndroid Build Coastguard Worker 
742*61046927SAndroid Build Coastguard Worker    if (info->image_binds)
743*61046927SAndroid Build Coastguard Worker       typed_memcpy(submit->image_binds, info->image_binds, info->image_bind_count);
744*61046927SAndroid Build Coastguard Worker 
745*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < info->image_bind_count; ++i) {
746*61046927SAndroid Build Coastguard Worker       VkSparseImageMemoryBind *binds = sparse_memory_image_bind_entries +
747*61046927SAndroid Build Coastguard Worker                                        sparse_memory_image_bind_entry_count;
748*61046927SAndroid Build Coastguard Worker       submit->image_binds[i].pBinds = binds;
749*61046927SAndroid Build Coastguard Worker       typed_memcpy(binds, info->image_binds[i].pBinds,
750*61046927SAndroid Build Coastguard Worker                    info->image_binds[i].bindCount);
751*61046927SAndroid Build Coastguard Worker 
752*61046927SAndroid Build Coastguard Worker       sparse_memory_image_bind_entry_count += info->image_binds[i].bindCount;
753*61046927SAndroid Build Coastguard Worker    }
754*61046927SAndroid Build Coastguard Worker 
755*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < info->signal_count; i++) {
756*61046927SAndroid Build Coastguard Worker       VK_FROM_HANDLE(vk_semaphore, semaphore,
757*61046927SAndroid Build Coastguard Worker                      info->signals[i].semaphore);
758*61046927SAndroid Build Coastguard Worker 
759*61046927SAndroid Build Coastguard Worker       struct vk_sync *sync = vk_semaphore_get_active_sync(semaphore);
760*61046927SAndroid Build Coastguard Worker       uint64_t signal_value = info->signals[i].value;
761*61046927SAndroid Build Coastguard Worker       if (semaphore->type == VK_SEMAPHORE_TYPE_TIMELINE) {
762*61046927SAndroid Build Coastguard Worker          if (signal_value == 0) {
763*61046927SAndroid Build Coastguard Worker             result = vk_queue_set_lost(queue,
764*61046927SAndroid Build Coastguard Worker                "Tried to signal a timeline with value 0");
765*61046927SAndroid Build Coastguard Worker             goto fail;
766*61046927SAndroid Build Coastguard Worker          }
767*61046927SAndroid Build Coastguard Worker       } else {
768*61046927SAndroid Build Coastguard Worker          signal_value = 0;
769*61046927SAndroid Build Coastguard Worker       }
770*61046927SAndroid Build Coastguard Worker 
771*61046927SAndroid Build Coastguard Worker       /* For emulated timelines, we need to associate a binary vk_sync with
772*61046927SAndroid Build Coastguard Worker        * each time point and pass the binary vk_sync to the driver.  We could
773*61046927SAndroid Build Coastguard Worker        * do this in vk_queue_submit_final but it might require doing memory
774*61046927SAndroid Build Coastguard Worker        * allocation and we don't want to to add extra failure paths there.
775*61046927SAndroid Build Coastguard Worker        * Instead, allocate and replace the driver-visible vk_sync now and
776*61046927SAndroid Build Coastguard Worker        * we'll insert it into the timeline in vk_queue_submit_final.  The
777*61046927SAndroid Build Coastguard Worker        * insert step is guaranteed to not fail.
778*61046927SAndroid Build Coastguard Worker        */
779*61046927SAndroid Build Coastguard Worker       struct vk_sync_timeline *timeline = vk_sync_as_timeline(sync);
780*61046927SAndroid Build Coastguard Worker       if (timeline) {
781*61046927SAndroid Build Coastguard Worker          assert(queue->base.device->timeline_mode ==
782*61046927SAndroid Build Coastguard Worker                 VK_DEVICE_TIMELINE_MODE_EMULATED);
783*61046927SAndroid Build Coastguard Worker          result = vk_sync_timeline_alloc_point(queue->base.device, timeline,
784*61046927SAndroid Build Coastguard Worker                                                signal_value,
785*61046927SAndroid Build Coastguard Worker                                                &submit->_signal_points[i]);
786*61046927SAndroid Build Coastguard Worker          if (unlikely(result != VK_SUCCESS))
787*61046927SAndroid Build Coastguard Worker             goto fail;
788*61046927SAndroid Build Coastguard Worker 
789*61046927SAndroid Build Coastguard Worker          sync = &submit->_signal_points[i]->sync;
790*61046927SAndroid Build Coastguard Worker          signal_value = 0;
791*61046927SAndroid Build Coastguard Worker       }
792*61046927SAndroid Build Coastguard Worker 
793*61046927SAndroid Build Coastguard Worker       submit->signals[i] = (struct vk_sync_signal) {
794*61046927SAndroid Build Coastguard Worker          .sync = sync,
795*61046927SAndroid Build Coastguard Worker          .stage_mask = info->signals[i].stageMask,
796*61046927SAndroid Build Coastguard Worker          .signal_value = signal_value,
797*61046927SAndroid Build Coastguard Worker       };
798*61046927SAndroid Build Coastguard Worker    }
799*61046927SAndroid Build Coastguard Worker 
800*61046927SAndroid Build Coastguard Worker    uint32_t signal_count = info->signal_count;
801*61046927SAndroid Build Coastguard Worker    if (signal_mem_sync) {
802*61046927SAndroid Build Coastguard Worker       struct vk_sync *mem_sync;
803*61046927SAndroid Build Coastguard Worker       result = queue->base.device->create_sync_for_memory(queue->base.device,
804*61046927SAndroid Build Coastguard Worker                                                           mem_signal->memory,
805*61046927SAndroid Build Coastguard Worker                                                           true, &mem_sync);
806*61046927SAndroid Build Coastguard Worker       if (unlikely(result != VK_SUCCESS))
807*61046927SAndroid Build Coastguard Worker          goto fail;
808*61046927SAndroid Build Coastguard Worker 
809*61046927SAndroid Build Coastguard Worker       submit->_mem_signal_temp = mem_sync;
810*61046927SAndroid Build Coastguard Worker 
811*61046927SAndroid Build Coastguard Worker       assert(submit->signals[signal_count].sync == NULL);
812*61046927SAndroid Build Coastguard Worker       submit->signals[signal_count++] = (struct vk_sync_signal) {
813*61046927SAndroid Build Coastguard Worker          .sync = mem_sync,
814*61046927SAndroid Build Coastguard Worker          .stage_mask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
815*61046927SAndroid Build Coastguard Worker       };
816*61046927SAndroid Build Coastguard Worker    }
817*61046927SAndroid Build Coastguard Worker 
818*61046927SAndroid Build Coastguard Worker    if (info->fence != NULL) {
819*61046927SAndroid Build Coastguard Worker       assert(submit->signals[signal_count].sync == NULL);
820*61046927SAndroid Build Coastguard Worker       submit->signals[signal_count++] = (struct vk_sync_signal) {
821*61046927SAndroid Build Coastguard Worker          .sync = vk_fence_get_active_sync(info->fence),
822*61046927SAndroid Build Coastguard Worker          .stage_mask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
823*61046927SAndroid Build Coastguard Worker       };
824*61046927SAndroid Build Coastguard Worker    }
825*61046927SAndroid Build Coastguard Worker 
826*61046927SAndroid Build Coastguard Worker    assert(signal_count == submit->signal_count);
827*61046927SAndroid Build Coastguard Worker 
828*61046927SAndroid Build Coastguard Worker    /* If this device supports threaded submit, we can't rely on the client
829*61046927SAndroid Build Coastguard Worker     * ordering requirements to ensure submits happen in the right order.  Even
830*61046927SAndroid Build Coastguard Worker     * if this queue doesn't have a submit thread, another queue (possibly in a
831*61046927SAndroid Build Coastguard Worker     * different process) may and that means we our dependencies may not have
832*61046927SAndroid Build Coastguard Worker     * been submitted to the kernel yet.  Do a quick zero-timeout WAIT_PENDING
833*61046927SAndroid Build Coastguard Worker     * on all the wait semaphores to see if we need to start up our own thread.
834*61046927SAndroid Build Coastguard Worker     */
835*61046927SAndroid Build Coastguard Worker    if (device->submit_mode == VK_QUEUE_SUBMIT_MODE_THREADED_ON_DEMAND &&
836*61046927SAndroid Build Coastguard Worker        queue->submit.mode != VK_QUEUE_SUBMIT_MODE_THREADED) {
837*61046927SAndroid Build Coastguard Worker       assert(queue->submit.mode == VK_QUEUE_SUBMIT_MODE_IMMEDIATE);
838*61046927SAndroid Build Coastguard Worker 
839*61046927SAndroid Build Coastguard Worker       result = vk_sync_wait_many(queue->base.device,
840*61046927SAndroid Build Coastguard Worker                                  submit->wait_count, submit->waits,
841*61046927SAndroid Build Coastguard Worker                                  VK_SYNC_WAIT_PENDING, 0);
842*61046927SAndroid Build Coastguard Worker       if (result == VK_TIMEOUT)
843*61046927SAndroid Build Coastguard Worker          result = vk_queue_enable_submit_thread(queue);
844*61046927SAndroid Build Coastguard Worker       if (unlikely(result != VK_SUCCESS))
845*61046927SAndroid Build Coastguard Worker          goto fail;
846*61046927SAndroid Build Coastguard Worker    }
847*61046927SAndroid Build Coastguard Worker 
848*61046927SAndroid Build Coastguard Worker    switch (queue->submit.mode) {
849*61046927SAndroid Build Coastguard Worker    case VK_QUEUE_SUBMIT_MODE_IMMEDIATE:
850*61046927SAndroid Build Coastguard Worker       result = vk_queue_submit_final(queue, submit);
851*61046927SAndroid Build Coastguard Worker       if (unlikely(result != VK_SUCCESS))
852*61046927SAndroid Build Coastguard Worker          goto fail;
853*61046927SAndroid Build Coastguard Worker 
854*61046927SAndroid Build Coastguard Worker       /* If threaded submit is possible on this device, we need to ensure that
855*61046927SAndroid Build Coastguard Worker        * binary semaphore payloads get reset so that any other threads can
856*61046927SAndroid Build Coastguard Worker        * properly wait on them for dependency checking.  Because we don't
857*61046927SAndroid Build Coastguard Worker        * currently have a submit thread, we can directly reset that binary
858*61046927SAndroid Build Coastguard Worker        * semaphore payloads.
859*61046927SAndroid Build Coastguard Worker        *
860*61046927SAndroid Build Coastguard Worker        * If we the vk_sync is in our signal et, we can consider it to have
861*61046927SAndroid Build Coastguard Worker        * been both reset and signaled by queue_submit_final().  A reset in
862*61046927SAndroid Build Coastguard Worker        * this case would be wrong because it would throw away our signal
863*61046927SAndroid Build Coastguard Worker        * operation.  If we don't signal the vk_sync, then we need to reset it.
864*61046927SAndroid Build Coastguard Worker        */
865*61046927SAndroid Build Coastguard Worker       if (vk_device_supports_threaded_submit(device) &&
866*61046927SAndroid Build Coastguard Worker           has_binary_permanent_semaphore_wait) {
867*61046927SAndroid Build Coastguard Worker          for (uint32_t i = 0; i < submit->wait_count; i++) {
868*61046927SAndroid Build Coastguard Worker             if ((submit->waits[i].sync->flags & VK_SYNC_IS_TIMELINE) ||
869*61046927SAndroid Build Coastguard Worker                 submit->_wait_temps[i] != NULL)
870*61046927SAndroid Build Coastguard Worker                continue;
871*61046927SAndroid Build Coastguard Worker 
872*61046927SAndroid Build Coastguard Worker             bool was_signaled = false;
873*61046927SAndroid Build Coastguard Worker             for (uint32_t j = 0; j < submit->signal_count; j++) {
874*61046927SAndroid Build Coastguard Worker                if (submit->signals[j].sync == submit->waits[i].sync) {
875*61046927SAndroid Build Coastguard Worker                   was_signaled = true;
876*61046927SAndroid Build Coastguard Worker                   break;
877*61046927SAndroid Build Coastguard Worker                }
878*61046927SAndroid Build Coastguard Worker             }
879*61046927SAndroid Build Coastguard Worker 
880*61046927SAndroid Build Coastguard Worker             if (!was_signaled) {
881*61046927SAndroid Build Coastguard Worker                result = vk_sync_reset(queue->base.device,
882*61046927SAndroid Build Coastguard Worker                                       submit->waits[i].sync);
883*61046927SAndroid Build Coastguard Worker                if (unlikely(result != VK_SUCCESS))
884*61046927SAndroid Build Coastguard Worker                   goto fail;
885*61046927SAndroid Build Coastguard Worker             }
886*61046927SAndroid Build Coastguard Worker          }
887*61046927SAndroid Build Coastguard Worker       }
888*61046927SAndroid Build Coastguard Worker 
889*61046927SAndroid Build Coastguard Worker       vk_queue_submit_destroy(queue, submit);
890*61046927SAndroid Build Coastguard Worker       return result;
891*61046927SAndroid Build Coastguard Worker 
892*61046927SAndroid Build Coastguard Worker    case VK_QUEUE_SUBMIT_MODE_DEFERRED:
893*61046927SAndroid Build Coastguard Worker       vk_queue_push_submit(queue, submit);
894*61046927SAndroid Build Coastguard Worker       return vk_device_flush(queue->base.device);
895*61046927SAndroid Build Coastguard Worker 
896*61046927SAndroid Build Coastguard Worker    case VK_QUEUE_SUBMIT_MODE_THREADED:
897*61046927SAndroid Build Coastguard Worker       if (has_binary_permanent_semaphore_wait) {
898*61046927SAndroid Build Coastguard Worker          for (uint32_t i = 0; i < info->wait_count; i++) {
899*61046927SAndroid Build Coastguard Worker             VK_FROM_HANDLE(vk_semaphore, semaphore,
900*61046927SAndroid Build Coastguard Worker                            info->waits[i].semaphore);
901*61046927SAndroid Build Coastguard Worker 
902*61046927SAndroid Build Coastguard Worker             if (semaphore->type != VK_SEMAPHORE_TYPE_BINARY)
903*61046927SAndroid Build Coastguard Worker                continue;
904*61046927SAndroid Build Coastguard Worker 
905*61046927SAndroid Build Coastguard Worker             /* From the Vulkan 1.2.194 spec:
906*61046927SAndroid Build Coastguard Worker              *
907*61046927SAndroid Build Coastguard Worker              *    "When a batch is submitted to a queue via a queue
908*61046927SAndroid Build Coastguard Worker              *    submission, and it includes semaphores to be waited on,
909*61046927SAndroid Build Coastguard Worker              *    it defines a memory dependency between prior semaphore
910*61046927SAndroid Build Coastguard Worker              *    signal operations and the batch, and defines semaphore
911*61046927SAndroid Build Coastguard Worker              *    wait operations.
912*61046927SAndroid Build Coastguard Worker              *
913*61046927SAndroid Build Coastguard Worker              *    Such semaphore wait operations set the semaphores
914*61046927SAndroid Build Coastguard Worker              *    created with a VkSemaphoreType of
915*61046927SAndroid Build Coastguard Worker              *    VK_SEMAPHORE_TYPE_BINARY to the unsignaled state."
916*61046927SAndroid Build Coastguard Worker              *
917*61046927SAndroid Build Coastguard Worker              * For threaded submit, we depend on tracking the unsignaled
918*61046927SAndroid Build Coastguard Worker              * state of binary semaphores to determine when we can safely
919*61046927SAndroid Build Coastguard Worker              * submit.  The VK_SYNC_WAIT_PENDING check above as well as the
920*61046927SAndroid Build Coastguard Worker              * one in the sumbit thread depend on all binary semaphores
921*61046927SAndroid Build Coastguard Worker              * being reset when they're not in active use from the point
922*61046927SAndroid Build Coastguard Worker              * of view of the client's CPU timeline.  This means we need to
923*61046927SAndroid Build Coastguard Worker              * reset them inside vkQueueSubmit and cannot wait until the
924*61046927SAndroid Build Coastguard Worker              * actual submit which happens later in the thread.
925*61046927SAndroid Build Coastguard Worker              *
926*61046927SAndroid Build Coastguard Worker              * We've already stolen temporary semaphore payloads above as
927*61046927SAndroid Build Coastguard Worker              * part of basic semaphore processing.  We steal permanent
928*61046927SAndroid Build Coastguard Worker              * semaphore payloads here by way of vk_sync_move.  For shared
929*61046927SAndroid Build Coastguard Worker              * semaphores, this can be a bit expensive (sync file import
930*61046927SAndroid Build Coastguard Worker              * and export) but, for non-shared semaphores, it can be made
931*61046927SAndroid Build Coastguard Worker              * fairly cheap.  Also, we only do this semaphore swapping in
932*61046927SAndroid Build Coastguard Worker              * the case where you have real timelines AND the client is
933*61046927SAndroid Build Coastguard Worker              * using timeline semaphores with wait-before-signal (that's
934*61046927SAndroid Build Coastguard Worker              * the only way to get a submit thread) AND mixing those with
935*61046927SAndroid Build Coastguard Worker              * waits on binary semaphores AND said binary semaphore is
936*61046927SAndroid Build Coastguard Worker              * using its permanent payload.  In other words, this code
937*61046927SAndroid Build Coastguard Worker              * should basically only ever get executed in CTS tests.
938*61046927SAndroid Build Coastguard Worker              */
939*61046927SAndroid Build Coastguard Worker             if (submit->_wait_temps[i] != NULL)
940*61046927SAndroid Build Coastguard Worker                continue;
941*61046927SAndroid Build Coastguard Worker 
942*61046927SAndroid Build Coastguard Worker             assert(submit->waits[i].sync == &semaphore->permanent);
943*61046927SAndroid Build Coastguard Worker 
944*61046927SAndroid Build Coastguard Worker             /* From the Vulkan 1.2.194 spec:
945*61046927SAndroid Build Coastguard Worker              *
946*61046927SAndroid Build Coastguard Worker              *    VUID-vkQueueSubmit-pWaitSemaphores-03238
947*61046927SAndroid Build Coastguard Worker              *
948*61046927SAndroid Build Coastguard Worker              *    "All elements of the pWaitSemaphores member of all
949*61046927SAndroid Build Coastguard Worker              *    elements of pSubmits created with a VkSemaphoreType of
950*61046927SAndroid Build Coastguard Worker              *    VK_SEMAPHORE_TYPE_BINARY must reference a semaphore
951*61046927SAndroid Build Coastguard Worker              *    signal operation that has been submitted for execution
952*61046927SAndroid Build Coastguard Worker              *    and any semaphore signal operations on which it depends
953*61046927SAndroid Build Coastguard Worker              *    (if any) must have also been submitted for execution."
954*61046927SAndroid Build Coastguard Worker              *
955*61046927SAndroid Build Coastguard Worker              * Therefore, we can safely do a blocking wait here and it
956*61046927SAndroid Build Coastguard Worker              * won't actually block for long.  This ensures that the
957*61046927SAndroid Build Coastguard Worker              * vk_sync_move below will succeed.
958*61046927SAndroid Build Coastguard Worker              */
959*61046927SAndroid Build Coastguard Worker             result = vk_sync_wait(queue->base.device,
960*61046927SAndroid Build Coastguard Worker                                   submit->waits[i].sync, 0,
961*61046927SAndroid Build Coastguard Worker                                   VK_SYNC_WAIT_PENDING, UINT64_MAX);
962*61046927SAndroid Build Coastguard Worker             if (unlikely(result != VK_SUCCESS))
963*61046927SAndroid Build Coastguard Worker                goto fail;
964*61046927SAndroid Build Coastguard Worker 
965*61046927SAndroid Build Coastguard Worker             result = vk_sync_create(queue->base.device,
966*61046927SAndroid Build Coastguard Worker                                     semaphore->permanent.type,
967*61046927SAndroid Build Coastguard Worker                                     0 /* flags */,
968*61046927SAndroid Build Coastguard Worker                                     0 /* initial value */,
969*61046927SAndroid Build Coastguard Worker                                     &submit->_wait_temps[i]);
970*61046927SAndroid Build Coastguard Worker             if (unlikely(result != VK_SUCCESS))
971*61046927SAndroid Build Coastguard Worker                goto fail;
972*61046927SAndroid Build Coastguard Worker 
973*61046927SAndroid Build Coastguard Worker             result = vk_sync_move(queue->base.device,
974*61046927SAndroid Build Coastguard Worker                                   submit->_wait_temps[i],
975*61046927SAndroid Build Coastguard Worker                                   &semaphore->permanent);
976*61046927SAndroid Build Coastguard Worker             if (unlikely(result != VK_SUCCESS))
977*61046927SAndroid Build Coastguard Worker                goto fail;
978*61046927SAndroid Build Coastguard Worker 
979*61046927SAndroid Build Coastguard Worker             submit->waits[i].sync = submit->_wait_temps[i];
980*61046927SAndroid Build Coastguard Worker          }
981*61046927SAndroid Build Coastguard Worker       }
982*61046927SAndroid Build Coastguard Worker 
983*61046927SAndroid Build Coastguard Worker       vk_queue_push_submit(queue, submit);
984*61046927SAndroid Build Coastguard Worker 
985*61046927SAndroid Build Coastguard Worker       if (signal_mem_sync) {
986*61046927SAndroid Build Coastguard Worker          /* If we're signaling a memory object, we have to ensure that
987*61046927SAndroid Build Coastguard Worker           * vkQueueSubmit does not return until the kernel submission has
988*61046927SAndroid Build Coastguard Worker           * happened.  Otherwise, we may get a race between this process
989*61046927SAndroid Build Coastguard Worker           * and whatever is going to wait on the object where the other
990*61046927SAndroid Build Coastguard Worker           * process may wait before we've submitted our work.  Drain the
991*61046927SAndroid Build Coastguard Worker           * queue now to avoid this.  It's the responsibility of the caller
992*61046927SAndroid Build Coastguard Worker           * to ensure that any vkQueueSubmit which signals a memory object
993*61046927SAndroid Build Coastguard Worker           * has fully resolved dependencies.
994*61046927SAndroid Build Coastguard Worker           */
995*61046927SAndroid Build Coastguard Worker          result = vk_queue_drain(queue);
996*61046927SAndroid Build Coastguard Worker          if (unlikely(result != VK_SUCCESS))
997*61046927SAndroid Build Coastguard Worker             return result;
998*61046927SAndroid Build Coastguard Worker       }
999*61046927SAndroid Build Coastguard Worker 
1000*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
1001*61046927SAndroid Build Coastguard Worker 
1002*61046927SAndroid Build Coastguard Worker    case VK_QUEUE_SUBMIT_MODE_THREADED_ON_DEMAND:
1003*61046927SAndroid Build Coastguard Worker       unreachable("Invalid vk_queue::submit.mode");
1004*61046927SAndroid Build Coastguard Worker    }
1005*61046927SAndroid Build Coastguard Worker    unreachable("Invalid submit mode");
1006*61046927SAndroid Build Coastguard Worker 
1007*61046927SAndroid Build Coastguard Worker fail:
1008*61046927SAndroid Build Coastguard Worker    vk_queue_submit_destroy(queue, submit);
1009*61046927SAndroid Build Coastguard Worker    return result;
1010*61046927SAndroid Build Coastguard Worker }
1011*61046927SAndroid Build Coastguard Worker 
1012*61046927SAndroid Build Coastguard Worker VkResult
vk_queue_wait_before_present(struct vk_queue * queue,const VkPresentInfoKHR * pPresentInfo)1013*61046927SAndroid Build Coastguard Worker vk_queue_wait_before_present(struct vk_queue *queue,
1014*61046927SAndroid Build Coastguard Worker                              const VkPresentInfoKHR *pPresentInfo)
1015*61046927SAndroid Build Coastguard Worker {
1016*61046927SAndroid Build Coastguard Worker    if (vk_device_is_lost(queue->base.device))
1017*61046927SAndroid Build Coastguard Worker       return VK_ERROR_DEVICE_LOST;
1018*61046927SAndroid Build Coastguard Worker 
1019*61046927SAndroid Build Coastguard Worker    /* From the Vulkan 1.2.194 spec:
1020*61046927SAndroid Build Coastguard Worker     *
1021*61046927SAndroid Build Coastguard Worker     *    VUID-vkQueuePresentKHR-pWaitSemaphores-03268
1022*61046927SAndroid Build Coastguard Worker     *
1023*61046927SAndroid Build Coastguard Worker     *    "All elements of the pWaitSemaphores member of pPresentInfo must
1024*61046927SAndroid Build Coastguard Worker     *    reference a semaphore signal operation that has been submitted for
1025*61046927SAndroid Build Coastguard Worker     *    execution and any semaphore signal operations on which it depends (if
1026*61046927SAndroid Build Coastguard Worker     *    any) must have also been submitted for execution."
1027*61046927SAndroid Build Coastguard Worker     *
1028*61046927SAndroid Build Coastguard Worker     * As with vkQueueSubmit above, we need to ensure that any binary
1029*61046927SAndroid Build Coastguard Worker     * semaphores we use in this present actually exist.  If we don't have
1030*61046927SAndroid Build Coastguard Worker     * timeline semaphores, this is a non-issue.  If they're emulated, then
1031*61046927SAndroid Build Coastguard Worker     * this is ensured for us by the vk_device_flush() at the end of every
1032*61046927SAndroid Build Coastguard Worker     * vkQueueSubmit() and every vkSignalSemaphore().  For real timeline
1033*61046927SAndroid Build Coastguard Worker     * semaphores, however, we need to do a wait.  Thanks to the above bit of
1034*61046927SAndroid Build Coastguard Worker     * spec text, that wait should never block for long.
1035*61046927SAndroid Build Coastguard Worker     */
1036*61046927SAndroid Build Coastguard Worker    if (!vk_device_supports_threaded_submit(queue->base.device))
1037*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
1038*61046927SAndroid Build Coastguard Worker 
1039*61046927SAndroid Build Coastguard Worker    const uint32_t wait_count = pPresentInfo->waitSemaphoreCount;
1040*61046927SAndroid Build Coastguard Worker 
1041*61046927SAndroid Build Coastguard Worker    if (wait_count == 0)
1042*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
1043*61046927SAndroid Build Coastguard Worker 
1044*61046927SAndroid Build Coastguard Worker    STACK_ARRAY(struct vk_sync_wait, waits, wait_count);
1045*61046927SAndroid Build Coastguard Worker 
1046*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < wait_count; i++) {
1047*61046927SAndroid Build Coastguard Worker       VK_FROM_HANDLE(vk_semaphore, semaphore,
1048*61046927SAndroid Build Coastguard Worker                      pPresentInfo->pWaitSemaphores[i]);
1049*61046927SAndroid Build Coastguard Worker 
1050*61046927SAndroid Build Coastguard Worker       /* From the Vulkan 1.2.194 spec:
1051*61046927SAndroid Build Coastguard Worker        *
1052*61046927SAndroid Build Coastguard Worker        *    VUID-vkQueuePresentKHR-pWaitSemaphores-03267
1053*61046927SAndroid Build Coastguard Worker        *
1054*61046927SAndroid Build Coastguard Worker        *    "All elements of the pWaitSemaphores member of pPresentInfo must
1055*61046927SAndroid Build Coastguard Worker        *    be created with a VkSemaphoreType of VK_SEMAPHORE_TYPE_BINARY."
1056*61046927SAndroid Build Coastguard Worker        */
1057*61046927SAndroid Build Coastguard Worker       assert(semaphore->type == VK_SEMAPHORE_TYPE_BINARY);
1058*61046927SAndroid Build Coastguard Worker 
1059*61046927SAndroid Build Coastguard Worker       waits[i] = (struct vk_sync_wait) {
1060*61046927SAndroid Build Coastguard Worker          .sync = vk_semaphore_get_active_sync(semaphore),
1061*61046927SAndroid Build Coastguard Worker          .stage_mask = ~(VkPipelineStageFlags2)0,
1062*61046927SAndroid Build Coastguard Worker       };
1063*61046927SAndroid Build Coastguard Worker    }
1064*61046927SAndroid Build Coastguard Worker 
1065*61046927SAndroid Build Coastguard Worker    VkResult result = vk_sync_wait_many(queue->base.device, wait_count, waits,
1066*61046927SAndroid Build Coastguard Worker                                        VK_SYNC_WAIT_PENDING, UINT64_MAX);
1067*61046927SAndroid Build Coastguard Worker 
1068*61046927SAndroid Build Coastguard Worker    STACK_ARRAY_FINISH(waits);
1069*61046927SAndroid Build Coastguard Worker 
1070*61046927SAndroid Build Coastguard Worker    /* Check again, just in case */
1071*61046927SAndroid Build Coastguard Worker    if (vk_device_is_lost(queue->base.device))
1072*61046927SAndroid Build Coastguard Worker       return VK_ERROR_DEVICE_LOST;
1073*61046927SAndroid Build Coastguard Worker 
1074*61046927SAndroid Build Coastguard Worker    return result;
1075*61046927SAndroid Build Coastguard Worker }
1076*61046927SAndroid Build Coastguard Worker 
1077*61046927SAndroid Build Coastguard Worker static VkResult
vk_queue_signal_sync(struct vk_queue * queue,struct vk_sync * sync,uint32_t signal_value)1078*61046927SAndroid Build Coastguard Worker vk_queue_signal_sync(struct vk_queue *queue,
1079*61046927SAndroid Build Coastguard Worker                      struct vk_sync *sync,
1080*61046927SAndroid Build Coastguard Worker                      uint32_t signal_value)
1081*61046927SAndroid Build Coastguard Worker {
1082*61046927SAndroid Build Coastguard Worker    struct vk_queue_submit *submit = vk_queue_submit_alloc(queue, 0, 0, 0, 0, 0,
1083*61046927SAndroid Build Coastguard Worker                                                           0, 0, 1, NULL, NULL);
1084*61046927SAndroid Build Coastguard Worker    if (unlikely(submit == NULL))
1085*61046927SAndroid Build Coastguard Worker       return vk_error(queue, VK_ERROR_OUT_OF_HOST_MEMORY);
1086*61046927SAndroid Build Coastguard Worker 
1087*61046927SAndroid Build Coastguard Worker    submit->signals[0] = (struct vk_sync_signal) {
1088*61046927SAndroid Build Coastguard Worker       .sync = sync,
1089*61046927SAndroid Build Coastguard Worker       .stage_mask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
1090*61046927SAndroid Build Coastguard Worker       .signal_value = signal_value,
1091*61046927SAndroid Build Coastguard Worker    };
1092*61046927SAndroid Build Coastguard Worker 
1093*61046927SAndroid Build Coastguard Worker    VkResult result;
1094*61046927SAndroid Build Coastguard Worker    switch (queue->submit.mode) {
1095*61046927SAndroid Build Coastguard Worker    case VK_QUEUE_SUBMIT_MODE_IMMEDIATE:
1096*61046927SAndroid Build Coastguard Worker       result = vk_queue_submit_final(queue, submit);
1097*61046927SAndroid Build Coastguard Worker       vk_queue_submit_destroy(queue, submit);
1098*61046927SAndroid Build Coastguard Worker       return result;
1099*61046927SAndroid Build Coastguard Worker 
1100*61046927SAndroid Build Coastguard Worker    case VK_QUEUE_SUBMIT_MODE_DEFERRED:
1101*61046927SAndroid Build Coastguard Worker       vk_queue_push_submit(queue, submit);
1102*61046927SAndroid Build Coastguard Worker       return vk_device_flush(queue->base.device);
1103*61046927SAndroid Build Coastguard Worker 
1104*61046927SAndroid Build Coastguard Worker    case VK_QUEUE_SUBMIT_MODE_THREADED:
1105*61046927SAndroid Build Coastguard Worker       vk_queue_push_submit(queue, submit);
1106*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
1107*61046927SAndroid Build Coastguard Worker 
1108*61046927SAndroid Build Coastguard Worker    case VK_QUEUE_SUBMIT_MODE_THREADED_ON_DEMAND:
1109*61046927SAndroid Build Coastguard Worker       unreachable("Invalid vk_queue::submit.mode");
1110*61046927SAndroid Build Coastguard Worker    }
1111*61046927SAndroid Build Coastguard Worker    unreachable("Invalid timeline mode");
1112*61046927SAndroid Build Coastguard Worker }
1113*61046927SAndroid Build Coastguard Worker 
1114*61046927SAndroid Build Coastguard Worker void
vk_queue_finish(struct vk_queue * queue)1115*61046927SAndroid Build Coastguard Worker vk_queue_finish(struct vk_queue *queue)
1116*61046927SAndroid Build Coastguard Worker {
1117*61046927SAndroid Build Coastguard Worker    if (queue->submit.mode == VK_QUEUE_SUBMIT_MODE_THREADED)
1118*61046927SAndroid Build Coastguard Worker       vk_queue_stop_submit_thread(queue);
1119*61046927SAndroid Build Coastguard Worker 
1120*61046927SAndroid Build Coastguard Worker    while (!list_is_empty(&queue->submit.submits)) {
1121*61046927SAndroid Build Coastguard Worker       assert(vk_device_is_lost_no_report(queue->base.device));
1122*61046927SAndroid Build Coastguard Worker 
1123*61046927SAndroid Build Coastguard Worker       struct vk_queue_submit *submit =
1124*61046927SAndroid Build Coastguard Worker          list_first_entry(&queue->submit.submits,
1125*61046927SAndroid Build Coastguard Worker                           struct vk_queue_submit, link);
1126*61046927SAndroid Build Coastguard Worker 
1127*61046927SAndroid Build Coastguard Worker       list_del(&submit->link);
1128*61046927SAndroid Build Coastguard Worker       vk_queue_submit_destroy(queue, submit);
1129*61046927SAndroid Build Coastguard Worker    }
1130*61046927SAndroid Build Coastguard Worker 
1131*61046927SAndroid Build Coastguard Worker #if DETECT_OS_ANDROID
1132*61046927SAndroid Build Coastguard Worker    if (queue->anb_semaphore != VK_NULL_HANDLE) {
1133*61046927SAndroid Build Coastguard Worker       struct vk_device *device = queue->base.device;
1134*61046927SAndroid Build Coastguard Worker       device->dispatch_table.DestroySemaphore(vk_device_to_handle(device),
1135*61046927SAndroid Build Coastguard Worker                                               queue->anb_semaphore, NULL);
1136*61046927SAndroid Build Coastguard Worker    }
1137*61046927SAndroid Build Coastguard Worker #endif
1138*61046927SAndroid Build Coastguard Worker 
1139*61046927SAndroid Build Coastguard Worker    cnd_destroy(&queue->submit.pop);
1140*61046927SAndroid Build Coastguard Worker    cnd_destroy(&queue->submit.push);
1141*61046927SAndroid Build Coastguard Worker    mtx_destroy(&queue->submit.mutex);
1142*61046927SAndroid Build Coastguard Worker 
1143*61046927SAndroid Build Coastguard Worker    util_dynarray_fini(&queue->labels);
1144*61046927SAndroid Build Coastguard Worker    list_del(&queue->link);
1145*61046927SAndroid Build Coastguard Worker    vk_object_base_finish(&queue->base);
1146*61046927SAndroid Build Coastguard Worker }
1147*61046927SAndroid Build Coastguard Worker 
1148*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
vk_common_QueueSubmit2(VkQueue _queue,uint32_t submitCount,const VkSubmitInfo2 * pSubmits,VkFence _fence)1149*61046927SAndroid Build Coastguard Worker vk_common_QueueSubmit2(VkQueue _queue,
1150*61046927SAndroid Build Coastguard Worker                           uint32_t submitCount,
1151*61046927SAndroid Build Coastguard Worker                           const VkSubmitInfo2 *pSubmits,
1152*61046927SAndroid Build Coastguard Worker                           VkFence _fence)
1153*61046927SAndroid Build Coastguard Worker {
1154*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_queue, queue, _queue);
1155*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_fence, fence, _fence);
1156*61046927SAndroid Build Coastguard Worker 
1157*61046927SAndroid Build Coastguard Worker    if (vk_device_is_lost(queue->base.device))
1158*61046927SAndroid Build Coastguard Worker       return VK_ERROR_DEVICE_LOST;
1159*61046927SAndroid Build Coastguard Worker 
1160*61046927SAndroid Build Coastguard Worker    if (submitCount == 0) {
1161*61046927SAndroid Build Coastguard Worker       if (fence == NULL) {
1162*61046927SAndroid Build Coastguard Worker          return VK_SUCCESS;
1163*61046927SAndroid Build Coastguard Worker       } else {
1164*61046927SAndroid Build Coastguard Worker          return vk_queue_signal_sync(queue, vk_fence_get_active_sync(fence), 0);
1165*61046927SAndroid Build Coastguard Worker       }
1166*61046927SAndroid Build Coastguard Worker    }
1167*61046927SAndroid Build Coastguard Worker 
1168*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < submitCount; i++) {
1169*61046927SAndroid Build Coastguard Worker       struct vulkan_submit_info info = {
1170*61046927SAndroid Build Coastguard Worker          .pNext = pSubmits[i].pNext,
1171*61046927SAndroid Build Coastguard Worker          .command_buffer_count = pSubmits[i].commandBufferInfoCount,
1172*61046927SAndroid Build Coastguard Worker          .command_buffers = pSubmits[i].pCommandBufferInfos,
1173*61046927SAndroid Build Coastguard Worker          .wait_count = pSubmits[i].waitSemaphoreInfoCount,
1174*61046927SAndroid Build Coastguard Worker          .waits = pSubmits[i].pWaitSemaphoreInfos,
1175*61046927SAndroid Build Coastguard Worker          .signal_count = pSubmits[i].signalSemaphoreInfoCount,
1176*61046927SAndroid Build Coastguard Worker          .signals = pSubmits[i].pSignalSemaphoreInfos,
1177*61046927SAndroid Build Coastguard Worker          .fence = i == submitCount - 1 ? fence : NULL
1178*61046927SAndroid Build Coastguard Worker       };
1179*61046927SAndroid Build Coastguard Worker       VkResult result = vk_queue_submit(queue, &info);
1180*61046927SAndroid Build Coastguard Worker       if (unlikely(result != VK_SUCCESS))
1181*61046927SAndroid Build Coastguard Worker          return result;
1182*61046927SAndroid Build Coastguard Worker    }
1183*61046927SAndroid Build Coastguard Worker 
1184*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1185*61046927SAndroid Build Coastguard Worker }
1186*61046927SAndroid Build Coastguard Worker 
1187*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
vk_common_QueueBindSparse(VkQueue _queue,uint32_t bindInfoCount,const VkBindSparseInfo * pBindInfo,VkFence _fence)1188*61046927SAndroid Build Coastguard Worker vk_common_QueueBindSparse(VkQueue _queue,
1189*61046927SAndroid Build Coastguard Worker                           uint32_t bindInfoCount,
1190*61046927SAndroid Build Coastguard Worker                           const VkBindSparseInfo *pBindInfo,
1191*61046927SAndroid Build Coastguard Worker                           VkFence _fence)
1192*61046927SAndroid Build Coastguard Worker {
1193*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_queue, queue, _queue);
1194*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_fence, fence, _fence);
1195*61046927SAndroid Build Coastguard Worker 
1196*61046927SAndroid Build Coastguard Worker    if (vk_device_is_lost(queue->base.device))
1197*61046927SAndroid Build Coastguard Worker       return VK_ERROR_DEVICE_LOST;
1198*61046927SAndroid Build Coastguard Worker 
1199*61046927SAndroid Build Coastguard Worker    if (bindInfoCount == 0) {
1200*61046927SAndroid Build Coastguard Worker       if (fence == NULL) {
1201*61046927SAndroid Build Coastguard Worker          return VK_SUCCESS;
1202*61046927SAndroid Build Coastguard Worker       } else {
1203*61046927SAndroid Build Coastguard Worker          return vk_queue_signal_sync(queue, vk_fence_get_active_sync(fence), 0);
1204*61046927SAndroid Build Coastguard Worker       }
1205*61046927SAndroid Build Coastguard Worker    }
1206*61046927SAndroid Build Coastguard Worker 
1207*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < bindInfoCount; i++) {
1208*61046927SAndroid Build Coastguard Worker       const VkTimelineSemaphoreSubmitInfo *timeline_info =
1209*61046927SAndroid Build Coastguard Worker          vk_find_struct_const(pBindInfo[i].pNext, TIMELINE_SEMAPHORE_SUBMIT_INFO);
1210*61046927SAndroid Build Coastguard Worker       const uint64_t *wait_values = NULL;
1211*61046927SAndroid Build Coastguard Worker       const uint64_t *signal_values = NULL;
1212*61046927SAndroid Build Coastguard Worker 
1213*61046927SAndroid Build Coastguard Worker       if (timeline_info && timeline_info->waitSemaphoreValueCount) {
1214*61046927SAndroid Build Coastguard Worker          /* From the Vulkan 1.3.204 spec:
1215*61046927SAndroid Build Coastguard Worker           *
1216*61046927SAndroid Build Coastguard Worker           *    VUID-VkBindSparseInfo-pNext-03248
1217*61046927SAndroid Build Coastguard Worker           *
1218*61046927SAndroid Build Coastguard Worker           *    "If the pNext chain of this structure includes a VkTimelineSemaphoreSubmitInfo structure
1219*61046927SAndroid Build Coastguard Worker           *    and any element of pSignalSemaphores was created with a VkSemaphoreType of
1220*61046927SAndroid Build Coastguard Worker           *    VK_SEMAPHORE_TYPE_TIMELINE, then its signalSemaphoreValueCount member must equal
1221*61046927SAndroid Build Coastguard Worker           *    signalSemaphoreCount"
1222*61046927SAndroid Build Coastguard Worker           */
1223*61046927SAndroid Build Coastguard Worker          assert(timeline_info->waitSemaphoreValueCount == pBindInfo[i].waitSemaphoreCount);
1224*61046927SAndroid Build Coastguard Worker          wait_values = timeline_info->pWaitSemaphoreValues;
1225*61046927SAndroid Build Coastguard Worker       }
1226*61046927SAndroid Build Coastguard Worker 
1227*61046927SAndroid Build Coastguard Worker       if (timeline_info && timeline_info->signalSemaphoreValueCount) {
1228*61046927SAndroid Build Coastguard Worker          /* From the Vulkan 1.3.204 spec:
1229*61046927SAndroid Build Coastguard Worker           *
1230*61046927SAndroid Build Coastguard Worker           * VUID-VkBindSparseInfo-pNext-03247
1231*61046927SAndroid Build Coastguard Worker           *
1232*61046927SAndroid Build Coastguard Worker           *    "If the pNext chain of this structure includes a VkTimelineSemaphoreSubmitInfo structure
1233*61046927SAndroid Build Coastguard Worker           *    and any element of pWaitSemaphores was created with a VkSemaphoreType of
1234*61046927SAndroid Build Coastguard Worker           *    VK_SEMAPHORE_TYPE_TIMELINE, then its waitSemaphoreValueCount member must equal
1235*61046927SAndroid Build Coastguard Worker           *    waitSemaphoreCount"
1236*61046927SAndroid Build Coastguard Worker           */
1237*61046927SAndroid Build Coastguard Worker          assert(timeline_info->signalSemaphoreValueCount == pBindInfo[i].signalSemaphoreCount);
1238*61046927SAndroid Build Coastguard Worker          signal_values = timeline_info->pSignalSemaphoreValues;
1239*61046927SAndroid Build Coastguard Worker       }
1240*61046927SAndroid Build Coastguard Worker 
1241*61046927SAndroid Build Coastguard Worker       STACK_ARRAY(VkSemaphoreSubmitInfo, wait_semaphore_infos,
1242*61046927SAndroid Build Coastguard Worker                   pBindInfo[i].waitSemaphoreCount);
1243*61046927SAndroid Build Coastguard Worker       STACK_ARRAY(VkSemaphoreSubmitInfo, signal_semaphore_infos,
1244*61046927SAndroid Build Coastguard Worker                   pBindInfo[i].signalSemaphoreCount);
1245*61046927SAndroid Build Coastguard Worker 
1246*61046927SAndroid Build Coastguard Worker       if (!wait_semaphore_infos || !signal_semaphore_infos) {
1247*61046927SAndroid Build Coastguard Worker          STACK_ARRAY_FINISH(wait_semaphore_infos);
1248*61046927SAndroid Build Coastguard Worker          STACK_ARRAY_FINISH(signal_semaphore_infos);
1249*61046927SAndroid Build Coastguard Worker          return vk_error(queue, VK_ERROR_OUT_OF_HOST_MEMORY);
1250*61046927SAndroid Build Coastguard Worker       }
1251*61046927SAndroid Build Coastguard Worker 
1252*61046927SAndroid Build Coastguard Worker       for (uint32_t j = 0; j < pBindInfo[i].waitSemaphoreCount; j++) {
1253*61046927SAndroid Build Coastguard Worker          wait_semaphore_infos[j] = (VkSemaphoreSubmitInfo) {
1254*61046927SAndroid Build Coastguard Worker             .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
1255*61046927SAndroid Build Coastguard Worker             .semaphore = pBindInfo[i].pWaitSemaphores[j],
1256*61046927SAndroid Build Coastguard Worker             .value = wait_values ? wait_values[j] : 0,
1257*61046927SAndroid Build Coastguard Worker          };
1258*61046927SAndroid Build Coastguard Worker       }
1259*61046927SAndroid Build Coastguard Worker 
1260*61046927SAndroid Build Coastguard Worker       for (uint32_t j = 0; j < pBindInfo[i].signalSemaphoreCount; j++) {
1261*61046927SAndroid Build Coastguard Worker          signal_semaphore_infos[j] = (VkSemaphoreSubmitInfo) {
1262*61046927SAndroid Build Coastguard Worker             .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
1263*61046927SAndroid Build Coastguard Worker             .semaphore = pBindInfo[i].pSignalSemaphores[j],
1264*61046927SAndroid Build Coastguard Worker             .value = signal_values ? signal_values[j] : 0,
1265*61046927SAndroid Build Coastguard Worker          };
1266*61046927SAndroid Build Coastguard Worker       }
1267*61046927SAndroid Build Coastguard Worker       struct vulkan_submit_info info = {
1268*61046927SAndroid Build Coastguard Worker          .pNext = pBindInfo[i].pNext,
1269*61046927SAndroid Build Coastguard Worker          .wait_count = pBindInfo[i].waitSemaphoreCount,
1270*61046927SAndroid Build Coastguard Worker          .waits = wait_semaphore_infos,
1271*61046927SAndroid Build Coastguard Worker          .signal_count = pBindInfo[i].signalSemaphoreCount,
1272*61046927SAndroid Build Coastguard Worker          .signals = signal_semaphore_infos,
1273*61046927SAndroid Build Coastguard Worker          .buffer_bind_count = pBindInfo[i].bufferBindCount,
1274*61046927SAndroid Build Coastguard Worker          .buffer_binds = pBindInfo[i].pBufferBinds,
1275*61046927SAndroid Build Coastguard Worker          .image_opaque_bind_count = pBindInfo[i].imageOpaqueBindCount,
1276*61046927SAndroid Build Coastguard Worker          .image_opaque_binds = pBindInfo[i].pImageOpaqueBinds,
1277*61046927SAndroid Build Coastguard Worker          .image_bind_count = pBindInfo[i].imageBindCount,
1278*61046927SAndroid Build Coastguard Worker          .image_binds = pBindInfo[i].pImageBinds,
1279*61046927SAndroid Build Coastguard Worker          .fence = i == bindInfoCount - 1 ? fence : NULL
1280*61046927SAndroid Build Coastguard Worker       };
1281*61046927SAndroid Build Coastguard Worker       VkResult result = vk_queue_submit(queue, &info);
1282*61046927SAndroid Build Coastguard Worker 
1283*61046927SAndroid Build Coastguard Worker       STACK_ARRAY_FINISH(wait_semaphore_infos);
1284*61046927SAndroid Build Coastguard Worker       STACK_ARRAY_FINISH(signal_semaphore_infos);
1285*61046927SAndroid Build Coastguard Worker 
1286*61046927SAndroid Build Coastguard Worker       if (unlikely(result != VK_SUCCESS))
1287*61046927SAndroid Build Coastguard Worker          return result;
1288*61046927SAndroid Build Coastguard Worker    }
1289*61046927SAndroid Build Coastguard Worker 
1290*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1291*61046927SAndroid Build Coastguard Worker }
1292*61046927SAndroid Build Coastguard Worker 
1293*61046927SAndroid Build Coastguard Worker static const struct vk_sync_type *
get_cpu_wait_type(struct vk_physical_device * pdevice)1294*61046927SAndroid Build Coastguard Worker get_cpu_wait_type(struct vk_physical_device *pdevice)
1295*61046927SAndroid Build Coastguard Worker {
1296*61046927SAndroid Build Coastguard Worker    for (const struct vk_sync_type *const *t =
1297*61046927SAndroid Build Coastguard Worker         pdevice->supported_sync_types; *t; t++) {
1298*61046927SAndroid Build Coastguard Worker       if (((*t)->features & VK_SYNC_FEATURE_BINARY) &&
1299*61046927SAndroid Build Coastguard Worker           ((*t)->features & VK_SYNC_FEATURE_CPU_WAIT))
1300*61046927SAndroid Build Coastguard Worker          return *t;
1301*61046927SAndroid Build Coastguard Worker    }
1302*61046927SAndroid Build Coastguard Worker 
1303*61046927SAndroid Build Coastguard Worker    unreachable("You must have a non-timeline CPU wait sync type");
1304*61046927SAndroid Build Coastguard Worker }
1305*61046927SAndroid Build Coastguard Worker 
1306*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
vk_common_QueueWaitIdle(VkQueue _queue)1307*61046927SAndroid Build Coastguard Worker vk_common_QueueWaitIdle(VkQueue _queue)
1308*61046927SAndroid Build Coastguard Worker {
1309*61046927SAndroid Build Coastguard Worker    MESA_TRACE_FUNC();
1310*61046927SAndroid Build Coastguard Worker 
1311*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_queue, queue, _queue);
1312*61046927SAndroid Build Coastguard Worker    VkResult result;
1313*61046927SAndroid Build Coastguard Worker 
1314*61046927SAndroid Build Coastguard Worker    if (vk_device_is_lost(queue->base.device))
1315*61046927SAndroid Build Coastguard Worker       return VK_ERROR_DEVICE_LOST;
1316*61046927SAndroid Build Coastguard Worker 
1317*61046927SAndroid Build Coastguard Worker    const struct vk_sync_type *sync_type =
1318*61046927SAndroid Build Coastguard Worker       get_cpu_wait_type(queue->base.device->physical);
1319*61046927SAndroid Build Coastguard Worker 
1320*61046927SAndroid Build Coastguard Worker    struct vk_sync *sync;
1321*61046927SAndroid Build Coastguard Worker    result = vk_sync_create(queue->base.device, sync_type, 0, 0, &sync);
1322*61046927SAndroid Build Coastguard Worker    if (unlikely(result != VK_SUCCESS))
1323*61046927SAndroid Build Coastguard Worker       return result;
1324*61046927SAndroid Build Coastguard Worker 
1325*61046927SAndroid Build Coastguard Worker    result = vk_queue_signal_sync(queue, sync, 0);
1326*61046927SAndroid Build Coastguard Worker    if (unlikely(result != VK_SUCCESS))
1327*61046927SAndroid Build Coastguard Worker       return result;
1328*61046927SAndroid Build Coastguard Worker 
1329*61046927SAndroid Build Coastguard Worker    result = vk_sync_wait(queue->base.device, sync, 0,
1330*61046927SAndroid Build Coastguard Worker                          VK_SYNC_WAIT_COMPLETE, UINT64_MAX);
1331*61046927SAndroid Build Coastguard Worker 
1332*61046927SAndroid Build Coastguard Worker    vk_sync_destroy(queue->base.device, sync);
1333*61046927SAndroid Build Coastguard Worker 
1334*61046927SAndroid Build Coastguard Worker    VkResult device_status = vk_device_check_status(queue->base.device);
1335*61046927SAndroid Build Coastguard Worker    if (device_status != VK_SUCCESS)
1336*61046927SAndroid Build Coastguard Worker       return device_status;
1337*61046927SAndroid Build Coastguard Worker 
1338*61046927SAndroid Build Coastguard Worker    return result;
1339*61046927SAndroid Build Coastguard Worker }
1340