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