xref: /aosp_15_r20/external/mesa3d/src/virtio/vulkan/vn_queue.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright 2019 Google LLC
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  *
5*61046927SAndroid Build Coastguard Worker  * based in part on anv and radv which are:
6*61046927SAndroid Build Coastguard Worker  * Copyright © 2015 Intel Corporation
7*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Red Hat.
8*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Bas Nieuwenhuizen
9*61046927SAndroid Build Coastguard Worker  */
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker #include "vn_queue.h"
12*61046927SAndroid Build Coastguard Worker 
13*61046927SAndroid Build Coastguard Worker #include "util/libsync.h"
14*61046927SAndroid Build Coastguard Worker #include "venus-protocol/vn_protocol_driver_event.h"
15*61046927SAndroid Build Coastguard Worker #include "venus-protocol/vn_protocol_driver_fence.h"
16*61046927SAndroid Build Coastguard Worker #include "venus-protocol/vn_protocol_driver_queue.h"
17*61046927SAndroid Build Coastguard Worker #include "venus-protocol/vn_protocol_driver_semaphore.h"
18*61046927SAndroid Build Coastguard Worker #include "venus-protocol/vn_protocol_driver_transport.h"
19*61046927SAndroid Build Coastguard Worker 
20*61046927SAndroid Build Coastguard Worker #include "vn_command_buffer.h"
21*61046927SAndroid Build Coastguard Worker #include "vn_device.h"
22*61046927SAndroid Build Coastguard Worker #include "vn_device_memory.h"
23*61046927SAndroid Build Coastguard Worker #include "vn_feedback.h"
24*61046927SAndroid Build Coastguard Worker #include "vn_instance.h"
25*61046927SAndroid Build Coastguard Worker #include "vn_physical_device.h"
26*61046927SAndroid Build Coastguard Worker #include "vn_query_pool.h"
27*61046927SAndroid Build Coastguard Worker #include "vn_renderer.h"
28*61046927SAndroid Build Coastguard Worker #include "vn_wsi.h"
29*61046927SAndroid Build Coastguard Worker 
30*61046927SAndroid Build Coastguard Worker /* queue commands */
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker struct vn_submit_info_pnext_fix {
33*61046927SAndroid Build Coastguard Worker    VkDeviceGroupSubmitInfo group;
34*61046927SAndroid Build Coastguard Worker    VkProtectedSubmitInfo protected;
35*61046927SAndroid Build Coastguard Worker    VkTimelineSemaphoreSubmitInfo timeline;
36*61046927SAndroid Build Coastguard Worker };
37*61046927SAndroid Build Coastguard Worker 
38*61046927SAndroid Build Coastguard Worker struct vn_queue_submission {
39*61046927SAndroid Build Coastguard Worker    VkStructureType batch_type;
40*61046927SAndroid Build Coastguard Worker    VkQueue queue_handle;
41*61046927SAndroid Build Coastguard Worker    uint32_t batch_count;
42*61046927SAndroid Build Coastguard Worker    union {
43*61046927SAndroid Build Coastguard Worker       const void *batches;
44*61046927SAndroid Build Coastguard Worker       const VkSubmitInfo *submit_batches;
45*61046927SAndroid Build Coastguard Worker       const VkSubmitInfo2 *submit2_batches;
46*61046927SAndroid Build Coastguard Worker       const VkBindSparseInfo *sparse_batches;
47*61046927SAndroid Build Coastguard Worker    };
48*61046927SAndroid Build Coastguard Worker    VkFence fence_handle;
49*61046927SAndroid Build Coastguard Worker 
50*61046927SAndroid Build Coastguard Worker    uint32_t cmd_count;
51*61046927SAndroid Build Coastguard Worker    uint32_t feedback_types;
52*61046927SAndroid Build Coastguard Worker    uint32_t pnext_count;
53*61046927SAndroid Build Coastguard Worker    uint32_t dev_mask_count;
54*61046927SAndroid Build Coastguard Worker    bool has_zink_sync_batch;
55*61046927SAndroid Build Coastguard Worker    const struct vn_device_memory *wsi_mem;
56*61046927SAndroid Build Coastguard Worker    struct vn_sync_payload_external external_payload;
57*61046927SAndroid Build Coastguard Worker 
58*61046927SAndroid Build Coastguard Worker    /* Temporary storage allocation for submission
59*61046927SAndroid Build Coastguard Worker     *
60*61046927SAndroid Build Coastguard Worker     * A single alloc for storage is performed and the offsets inside storage
61*61046927SAndroid Build Coastguard Worker     * are set as below:
62*61046927SAndroid Build Coastguard Worker     *
63*61046927SAndroid Build Coastguard Worker     * batches
64*61046927SAndroid Build Coastguard Worker     *  - non-empty submission: copy of original batches
65*61046927SAndroid Build Coastguard Worker     *  - empty submission: a single batch for fence feedback (ffb)
66*61046927SAndroid Build Coastguard Worker     * cmds
67*61046927SAndroid Build Coastguard Worker     *  - for each batch:
68*61046927SAndroid Build Coastguard Worker     *    - copy of original batch cmds
69*61046927SAndroid Build Coastguard Worker     *    - a single cmd for query feedback (qfb)
70*61046927SAndroid Build Coastguard Worker     *    - one cmd for each signal semaphore that has feedback (sfb)
71*61046927SAndroid Build Coastguard Worker     *    - if last batch, a single cmd for ffb
72*61046927SAndroid Build Coastguard Worker     */
73*61046927SAndroid Build Coastguard Worker    struct {
74*61046927SAndroid Build Coastguard Worker       void *storage;
75*61046927SAndroid Build Coastguard Worker 
76*61046927SAndroid Build Coastguard Worker       union {
77*61046927SAndroid Build Coastguard Worker          void *batches;
78*61046927SAndroid Build Coastguard Worker          VkSubmitInfo *submit_batches;
79*61046927SAndroid Build Coastguard Worker          VkSubmitInfo2 *submit2_batches;
80*61046927SAndroid Build Coastguard Worker       };
81*61046927SAndroid Build Coastguard Worker 
82*61046927SAndroid Build Coastguard Worker       union {
83*61046927SAndroid Build Coastguard Worker          void *cmds;
84*61046927SAndroid Build Coastguard Worker          VkCommandBuffer *cmd_handles;
85*61046927SAndroid Build Coastguard Worker          VkCommandBufferSubmitInfo *cmd_infos;
86*61046927SAndroid Build Coastguard Worker       };
87*61046927SAndroid Build Coastguard Worker 
88*61046927SAndroid Build Coastguard Worker       struct vn_submit_info_pnext_fix *pnexts;
89*61046927SAndroid Build Coastguard Worker       uint32_t *dev_masks;
90*61046927SAndroid Build Coastguard Worker    } temp;
91*61046927SAndroid Build Coastguard Worker };
92*61046927SAndroid Build Coastguard Worker 
93*61046927SAndroid Build Coastguard Worker static inline uint32_t
vn_get_wait_semaphore_count(struct vn_queue_submission * submit,uint32_t batch_index)94*61046927SAndroid Build Coastguard Worker vn_get_wait_semaphore_count(struct vn_queue_submission *submit,
95*61046927SAndroid Build Coastguard Worker                             uint32_t batch_index)
96*61046927SAndroid Build Coastguard Worker {
97*61046927SAndroid Build Coastguard Worker    switch (submit->batch_type) {
98*61046927SAndroid Build Coastguard Worker    case VK_STRUCTURE_TYPE_SUBMIT_INFO:
99*61046927SAndroid Build Coastguard Worker       return submit->submit_batches[batch_index].waitSemaphoreCount;
100*61046927SAndroid Build Coastguard Worker    case VK_STRUCTURE_TYPE_SUBMIT_INFO_2:
101*61046927SAndroid Build Coastguard Worker       return submit->submit2_batches[batch_index].waitSemaphoreInfoCount;
102*61046927SAndroid Build Coastguard Worker    case VK_STRUCTURE_TYPE_BIND_SPARSE_INFO:
103*61046927SAndroid Build Coastguard Worker       return submit->sparse_batches[batch_index].waitSemaphoreCount;
104*61046927SAndroid Build Coastguard Worker    default:
105*61046927SAndroid Build Coastguard Worker       unreachable("unexpected batch type");
106*61046927SAndroid Build Coastguard Worker    }
107*61046927SAndroid Build Coastguard Worker }
108*61046927SAndroid Build Coastguard Worker 
109*61046927SAndroid Build Coastguard Worker static inline uint32_t
vn_get_signal_semaphore_count(struct vn_queue_submission * submit,uint32_t batch_index)110*61046927SAndroid Build Coastguard Worker vn_get_signal_semaphore_count(struct vn_queue_submission *submit,
111*61046927SAndroid Build Coastguard Worker                               uint32_t batch_index)
112*61046927SAndroid Build Coastguard Worker {
113*61046927SAndroid Build Coastguard Worker    switch (submit->batch_type) {
114*61046927SAndroid Build Coastguard Worker    case VK_STRUCTURE_TYPE_SUBMIT_INFO:
115*61046927SAndroid Build Coastguard Worker       return submit->submit_batches[batch_index].signalSemaphoreCount;
116*61046927SAndroid Build Coastguard Worker    case VK_STRUCTURE_TYPE_SUBMIT_INFO_2:
117*61046927SAndroid Build Coastguard Worker       return submit->submit2_batches[batch_index].signalSemaphoreInfoCount;
118*61046927SAndroid Build Coastguard Worker    case VK_STRUCTURE_TYPE_BIND_SPARSE_INFO:
119*61046927SAndroid Build Coastguard Worker       return submit->sparse_batches[batch_index].signalSemaphoreCount;
120*61046927SAndroid Build Coastguard Worker    default:
121*61046927SAndroid Build Coastguard Worker       unreachable("unexpected batch type");
122*61046927SAndroid Build Coastguard Worker    }
123*61046927SAndroid Build Coastguard Worker }
124*61046927SAndroid Build Coastguard Worker 
125*61046927SAndroid Build Coastguard Worker static inline VkSemaphore
vn_get_wait_semaphore(struct vn_queue_submission * submit,uint32_t batch_index,uint32_t semaphore_index)126*61046927SAndroid Build Coastguard Worker vn_get_wait_semaphore(struct vn_queue_submission *submit,
127*61046927SAndroid Build Coastguard Worker                       uint32_t batch_index,
128*61046927SAndroid Build Coastguard Worker                       uint32_t semaphore_index)
129*61046927SAndroid Build Coastguard Worker {
130*61046927SAndroid Build Coastguard Worker    switch (submit->batch_type) {
131*61046927SAndroid Build Coastguard Worker    case VK_STRUCTURE_TYPE_SUBMIT_INFO:
132*61046927SAndroid Build Coastguard Worker       return submit->submit_batches[batch_index]
133*61046927SAndroid Build Coastguard Worker          .pWaitSemaphores[semaphore_index];
134*61046927SAndroid Build Coastguard Worker    case VK_STRUCTURE_TYPE_SUBMIT_INFO_2:
135*61046927SAndroid Build Coastguard Worker       return submit->submit2_batches[batch_index]
136*61046927SAndroid Build Coastguard Worker          .pWaitSemaphoreInfos[semaphore_index]
137*61046927SAndroid Build Coastguard Worker          .semaphore;
138*61046927SAndroid Build Coastguard Worker    case VK_STRUCTURE_TYPE_BIND_SPARSE_INFO:
139*61046927SAndroid Build Coastguard Worker       return submit->sparse_batches[batch_index]
140*61046927SAndroid Build Coastguard Worker          .pWaitSemaphores[semaphore_index];
141*61046927SAndroid Build Coastguard Worker    default:
142*61046927SAndroid Build Coastguard Worker       unreachable("unexpected batch type");
143*61046927SAndroid Build Coastguard Worker    }
144*61046927SAndroid Build Coastguard Worker }
145*61046927SAndroid Build Coastguard Worker 
146*61046927SAndroid Build Coastguard Worker static inline VkSemaphore
vn_get_signal_semaphore(struct vn_queue_submission * submit,uint32_t batch_index,uint32_t semaphore_index)147*61046927SAndroid Build Coastguard Worker vn_get_signal_semaphore(struct vn_queue_submission *submit,
148*61046927SAndroid Build Coastguard Worker                         uint32_t batch_index,
149*61046927SAndroid Build Coastguard Worker                         uint32_t semaphore_index)
150*61046927SAndroid Build Coastguard Worker {
151*61046927SAndroid Build Coastguard Worker    switch (submit->batch_type) {
152*61046927SAndroid Build Coastguard Worker    case VK_STRUCTURE_TYPE_SUBMIT_INFO:
153*61046927SAndroid Build Coastguard Worker       return submit->submit_batches[batch_index]
154*61046927SAndroid Build Coastguard Worker          .pSignalSemaphores[semaphore_index];
155*61046927SAndroid Build Coastguard Worker    case VK_STRUCTURE_TYPE_SUBMIT_INFO_2:
156*61046927SAndroid Build Coastguard Worker       return submit->submit2_batches[batch_index]
157*61046927SAndroid Build Coastguard Worker          .pSignalSemaphoreInfos[semaphore_index]
158*61046927SAndroid Build Coastguard Worker          .semaphore;
159*61046927SAndroid Build Coastguard Worker    case VK_STRUCTURE_TYPE_BIND_SPARSE_INFO:
160*61046927SAndroid Build Coastguard Worker       return submit->sparse_batches[batch_index]
161*61046927SAndroid Build Coastguard Worker          .pSignalSemaphores[semaphore_index];
162*61046927SAndroid Build Coastguard Worker    default:
163*61046927SAndroid Build Coastguard Worker       unreachable("unexpected batch type");
164*61046927SAndroid Build Coastguard Worker    }
165*61046927SAndroid Build Coastguard Worker }
166*61046927SAndroid Build Coastguard Worker 
167*61046927SAndroid Build Coastguard Worker static inline size_t
vn_get_batch_size(struct vn_queue_submission * submit)168*61046927SAndroid Build Coastguard Worker vn_get_batch_size(struct vn_queue_submission *submit)
169*61046927SAndroid Build Coastguard Worker {
170*61046927SAndroid Build Coastguard Worker    assert((submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO) ||
171*61046927SAndroid Build Coastguard Worker           (submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO_2));
172*61046927SAndroid Build Coastguard Worker    return submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO
173*61046927SAndroid Build Coastguard Worker              ? sizeof(VkSubmitInfo)
174*61046927SAndroid Build Coastguard Worker              : sizeof(VkSubmitInfo2);
175*61046927SAndroid Build Coastguard Worker }
176*61046927SAndroid Build Coastguard Worker 
177*61046927SAndroid Build Coastguard Worker static inline size_t
vn_get_cmd_size(struct vn_queue_submission * submit)178*61046927SAndroid Build Coastguard Worker vn_get_cmd_size(struct vn_queue_submission *submit)
179*61046927SAndroid Build Coastguard Worker {
180*61046927SAndroid Build Coastguard Worker    assert((submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO) ||
181*61046927SAndroid Build Coastguard Worker           (submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO_2));
182*61046927SAndroid Build Coastguard Worker    return submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO
183*61046927SAndroid Build Coastguard Worker              ? sizeof(VkCommandBuffer)
184*61046927SAndroid Build Coastguard Worker              : sizeof(VkCommandBufferSubmitInfo);
185*61046927SAndroid Build Coastguard Worker }
186*61046927SAndroid Build Coastguard Worker 
187*61046927SAndroid Build Coastguard Worker static inline uint32_t
vn_get_cmd_count(struct vn_queue_submission * submit,uint32_t batch_index)188*61046927SAndroid Build Coastguard Worker vn_get_cmd_count(struct vn_queue_submission *submit, uint32_t batch_index)
189*61046927SAndroid Build Coastguard Worker {
190*61046927SAndroid Build Coastguard Worker    assert((submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO) ||
191*61046927SAndroid Build Coastguard Worker           (submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO_2));
192*61046927SAndroid Build Coastguard Worker    return submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO
193*61046927SAndroid Build Coastguard Worker              ? submit->submit_batches[batch_index].commandBufferCount
194*61046927SAndroid Build Coastguard Worker              : submit->submit2_batches[batch_index].commandBufferInfoCount;
195*61046927SAndroid Build Coastguard Worker }
196*61046927SAndroid Build Coastguard Worker 
197*61046927SAndroid Build Coastguard Worker static inline const void *
vn_get_cmds(struct vn_queue_submission * submit,uint32_t batch_index)198*61046927SAndroid Build Coastguard Worker vn_get_cmds(struct vn_queue_submission *submit, uint32_t batch_index)
199*61046927SAndroid Build Coastguard Worker {
200*61046927SAndroid Build Coastguard Worker    assert((submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO) ||
201*61046927SAndroid Build Coastguard Worker           (submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO_2));
202*61046927SAndroid Build Coastguard Worker    return submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO
203*61046927SAndroid Build Coastguard Worker              ? (const void *)submit->submit_batches[batch_index]
204*61046927SAndroid Build Coastguard Worker                   .pCommandBuffers
205*61046927SAndroid Build Coastguard Worker              : (const void *)submit->submit2_batches[batch_index]
206*61046927SAndroid Build Coastguard Worker                   .pCommandBufferInfos;
207*61046927SAndroid Build Coastguard Worker }
208*61046927SAndroid Build Coastguard Worker 
209*61046927SAndroid Build Coastguard Worker static inline struct vn_command_buffer *
vn_get_cmd(struct vn_queue_submission * submit,uint32_t batch_index,uint32_t cmd_index)210*61046927SAndroid Build Coastguard Worker vn_get_cmd(struct vn_queue_submission *submit,
211*61046927SAndroid Build Coastguard Worker            uint32_t batch_index,
212*61046927SAndroid Build Coastguard Worker            uint32_t cmd_index)
213*61046927SAndroid Build Coastguard Worker {
214*61046927SAndroid Build Coastguard Worker    assert((submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO) ||
215*61046927SAndroid Build Coastguard Worker           (submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO_2));
216*61046927SAndroid Build Coastguard Worker    return vn_command_buffer_from_handle(
217*61046927SAndroid Build Coastguard Worker       submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO
218*61046927SAndroid Build Coastguard Worker          ? submit->submit_batches[batch_index].pCommandBuffers[cmd_index]
219*61046927SAndroid Build Coastguard Worker          : submit->submit2_batches[batch_index]
220*61046927SAndroid Build Coastguard Worker               .pCommandBufferInfos[cmd_index]
221*61046927SAndroid Build Coastguard Worker               .commandBuffer);
222*61046927SAndroid Build Coastguard Worker }
223*61046927SAndroid Build Coastguard Worker 
224*61046927SAndroid Build Coastguard Worker static inline void
vn_set_temp_cmd(struct vn_queue_submission * submit,uint32_t cmd_index,VkCommandBuffer cmd_handle)225*61046927SAndroid Build Coastguard Worker vn_set_temp_cmd(struct vn_queue_submission *submit,
226*61046927SAndroid Build Coastguard Worker                 uint32_t cmd_index,
227*61046927SAndroid Build Coastguard Worker                 VkCommandBuffer cmd_handle)
228*61046927SAndroid Build Coastguard Worker {
229*61046927SAndroid Build Coastguard Worker    assert((submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO) ||
230*61046927SAndroid Build Coastguard Worker           (submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO_2));
231*61046927SAndroid Build Coastguard Worker    if (submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO_2) {
232*61046927SAndroid Build Coastguard Worker       submit->temp.cmd_infos[cmd_index] = (VkCommandBufferSubmitInfo){
233*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO,
234*61046927SAndroid Build Coastguard Worker          .commandBuffer = cmd_handle,
235*61046927SAndroid Build Coastguard Worker       };
236*61046927SAndroid Build Coastguard Worker    } else {
237*61046927SAndroid Build Coastguard Worker       submit->temp.cmd_handles[cmd_index] = cmd_handle;
238*61046927SAndroid Build Coastguard Worker    }
239*61046927SAndroid Build Coastguard Worker }
240*61046927SAndroid Build Coastguard Worker 
241*61046927SAndroid Build Coastguard Worker static uint64_t
vn_get_signal_semaphore_counter(struct vn_queue_submission * submit,uint32_t batch_index,uint32_t sem_index)242*61046927SAndroid Build Coastguard Worker vn_get_signal_semaphore_counter(struct vn_queue_submission *submit,
243*61046927SAndroid Build Coastguard Worker                                 uint32_t batch_index,
244*61046927SAndroid Build Coastguard Worker                                 uint32_t sem_index)
245*61046927SAndroid Build Coastguard Worker {
246*61046927SAndroid Build Coastguard Worker    switch (submit->batch_type) {
247*61046927SAndroid Build Coastguard Worker    case VK_STRUCTURE_TYPE_SUBMIT_INFO: {
248*61046927SAndroid Build Coastguard Worker       const struct VkTimelineSemaphoreSubmitInfo *timeline_sem_info =
249*61046927SAndroid Build Coastguard Worker          vk_find_struct_const(submit->submit_batches[batch_index].pNext,
250*61046927SAndroid Build Coastguard Worker                               TIMELINE_SEMAPHORE_SUBMIT_INFO);
251*61046927SAndroid Build Coastguard Worker       return timeline_sem_info->pSignalSemaphoreValues[sem_index];
252*61046927SAndroid Build Coastguard Worker    }
253*61046927SAndroid Build Coastguard Worker    case VK_STRUCTURE_TYPE_SUBMIT_INFO_2:
254*61046927SAndroid Build Coastguard Worker       return submit->submit2_batches[batch_index]
255*61046927SAndroid Build Coastguard Worker          .pSignalSemaphoreInfos[sem_index]
256*61046927SAndroid Build Coastguard Worker          .value;
257*61046927SAndroid Build Coastguard Worker    default:
258*61046927SAndroid Build Coastguard Worker       unreachable("unexpected batch type");
259*61046927SAndroid Build Coastguard Worker    }
260*61046927SAndroid Build Coastguard Worker }
261*61046927SAndroid Build Coastguard Worker 
262*61046927SAndroid Build Coastguard Worker static bool
vn_has_zink_sync_batch(struct vn_queue_submission * submit)263*61046927SAndroid Build Coastguard Worker vn_has_zink_sync_batch(struct vn_queue_submission *submit)
264*61046927SAndroid Build Coastguard Worker {
265*61046927SAndroid Build Coastguard Worker    struct vn_queue *queue = vn_queue_from_handle(submit->queue_handle);
266*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = (void *)queue->base.base.base.device;
267*61046927SAndroid Build Coastguard Worker    struct vn_instance *instance = dev->instance;
268*61046927SAndroid Build Coastguard Worker    const uint32_t last_batch_index = submit->batch_count - 1;
269*61046927SAndroid Build Coastguard Worker 
270*61046927SAndroid Build Coastguard Worker    if (!instance->engine_is_zink)
271*61046927SAndroid Build Coastguard Worker       return false;
272*61046927SAndroid Build Coastguard Worker 
273*61046927SAndroid Build Coastguard Worker    if (!submit->batch_count || !last_batch_index ||
274*61046927SAndroid Build Coastguard Worker        vn_get_cmd_count(submit, last_batch_index))
275*61046927SAndroid Build Coastguard Worker       return false;
276*61046927SAndroid Build Coastguard Worker 
277*61046927SAndroid Build Coastguard Worker    if (vn_get_wait_semaphore_count(submit, last_batch_index))
278*61046927SAndroid Build Coastguard Worker       return false;
279*61046927SAndroid Build Coastguard Worker 
280*61046927SAndroid Build Coastguard Worker    const uint32_t signal_count =
281*61046927SAndroid Build Coastguard Worker       vn_get_signal_semaphore_count(submit, last_batch_index);
282*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < signal_count; i++) {
283*61046927SAndroid Build Coastguard Worker       struct vn_semaphore *sem = vn_semaphore_from_handle(
284*61046927SAndroid Build Coastguard Worker          vn_get_signal_semaphore(submit, last_batch_index, i));
285*61046927SAndroid Build Coastguard Worker       if (sem->feedback.slot) {
286*61046927SAndroid Build Coastguard Worker          return true;
287*61046927SAndroid Build Coastguard Worker       }
288*61046927SAndroid Build Coastguard Worker    }
289*61046927SAndroid Build Coastguard Worker    return false;
290*61046927SAndroid Build Coastguard Worker }
291*61046927SAndroid Build Coastguard Worker 
292*61046927SAndroid Build Coastguard Worker static bool
vn_fix_batch_cmd_count_for_zink_sync(struct vn_queue_submission * submit,uint32_t batch_index,uint32_t new_cmd_count)293*61046927SAndroid Build Coastguard Worker vn_fix_batch_cmd_count_for_zink_sync(struct vn_queue_submission *submit,
294*61046927SAndroid Build Coastguard Worker                                      uint32_t batch_index,
295*61046927SAndroid Build Coastguard Worker                                      uint32_t new_cmd_count)
296*61046927SAndroid Build Coastguard Worker {
297*61046927SAndroid Build Coastguard Worker    /* If the last batch is a zink sync batch which is empty but contains
298*61046927SAndroid Build Coastguard Worker     * feedback, append the feedback to the previous batch instead so that
299*61046927SAndroid Build Coastguard Worker     * the last batch remains empty for perf.
300*61046927SAndroid Build Coastguard Worker     */
301*61046927SAndroid Build Coastguard Worker    if (batch_index == submit->batch_count - 1 &&
302*61046927SAndroid Build Coastguard Worker        submit->has_zink_sync_batch) {
303*61046927SAndroid Build Coastguard Worker       if (submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO_2) {
304*61046927SAndroid Build Coastguard Worker          VkSubmitInfo2 *batch =
305*61046927SAndroid Build Coastguard Worker             &submit->temp.submit2_batches[batch_index - 1];
306*61046927SAndroid Build Coastguard Worker          assert(batch->pCommandBufferInfos);
307*61046927SAndroid Build Coastguard Worker          batch->commandBufferInfoCount += new_cmd_count;
308*61046927SAndroid Build Coastguard Worker       } else {
309*61046927SAndroid Build Coastguard Worker          VkSubmitInfo *batch = &submit->temp.submit_batches[batch_index - 1];
310*61046927SAndroid Build Coastguard Worker          assert(batch->pCommandBuffers);
311*61046927SAndroid Build Coastguard Worker          batch->commandBufferCount += new_cmd_count;
312*61046927SAndroid Build Coastguard Worker       }
313*61046927SAndroid Build Coastguard Worker       return true;
314*61046927SAndroid Build Coastguard Worker    }
315*61046927SAndroid Build Coastguard Worker    return false;
316*61046927SAndroid Build Coastguard Worker }
317*61046927SAndroid Build Coastguard Worker 
318*61046927SAndroid Build Coastguard Worker static void
vn_fix_device_group_cmd_count(struct vn_queue_submission * submit,uint32_t batch_index)319*61046927SAndroid Build Coastguard Worker vn_fix_device_group_cmd_count(struct vn_queue_submission *submit,
320*61046927SAndroid Build Coastguard Worker                               uint32_t batch_index)
321*61046927SAndroid Build Coastguard Worker {
322*61046927SAndroid Build Coastguard Worker    struct vk_queue *queue_vk = vk_queue_from_handle(submit->queue_handle);
323*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = (void *)queue_vk->base.device;
324*61046927SAndroid Build Coastguard Worker    const VkSubmitInfo *src_batch = &submit->submit_batches[batch_index];
325*61046927SAndroid Build Coastguard Worker    struct vn_submit_info_pnext_fix *pnext_fix = submit->temp.pnexts;
326*61046927SAndroid Build Coastguard Worker    VkBaseOutStructure *dst =
327*61046927SAndroid Build Coastguard Worker       (void *)&submit->temp.submit_batches[batch_index];
328*61046927SAndroid Build Coastguard Worker    uint32_t new_cmd_count =
329*61046927SAndroid Build Coastguard Worker       submit->temp.submit_batches[batch_index].commandBufferCount;
330*61046927SAndroid Build Coastguard Worker 
331*61046927SAndroid Build Coastguard Worker    vk_foreach_struct_const(src, src_batch->pNext) {
332*61046927SAndroid Build Coastguard Worker       void *pnext = NULL;
333*61046927SAndroid Build Coastguard Worker       switch (src->sType) {
334*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO: {
335*61046927SAndroid Build Coastguard Worker          uint32_t orig_cmd_count = 0;
336*61046927SAndroid Build Coastguard Worker 
337*61046927SAndroid Build Coastguard Worker          memcpy(&pnext_fix->group, src, sizeof(pnext_fix->group));
338*61046927SAndroid Build Coastguard Worker 
339*61046927SAndroid Build Coastguard Worker          VkDeviceGroupSubmitInfo *src_device_group =
340*61046927SAndroid Build Coastguard Worker             (VkDeviceGroupSubmitInfo *)src;
341*61046927SAndroid Build Coastguard Worker          if (src_device_group->commandBufferCount) {
342*61046927SAndroid Build Coastguard Worker             orig_cmd_count = src_device_group->commandBufferCount;
343*61046927SAndroid Build Coastguard Worker             memcpy(submit->temp.dev_masks,
344*61046927SAndroid Build Coastguard Worker                    src_device_group->pCommandBufferDeviceMasks,
345*61046927SAndroid Build Coastguard Worker                    sizeof(uint32_t) * orig_cmd_count);
346*61046927SAndroid Build Coastguard Worker          }
347*61046927SAndroid Build Coastguard Worker 
348*61046927SAndroid Build Coastguard Worker          /* Set the group device mask. Unlike sync2, zero means skip. */
349*61046927SAndroid Build Coastguard Worker          for (uint32_t i = orig_cmd_count; i < new_cmd_count; i++) {
350*61046927SAndroid Build Coastguard Worker             submit->temp.dev_masks[i] = dev->device_mask;
351*61046927SAndroid Build Coastguard Worker          }
352*61046927SAndroid Build Coastguard Worker 
353*61046927SAndroid Build Coastguard Worker          pnext_fix->group.commandBufferCount = new_cmd_count;
354*61046927SAndroid Build Coastguard Worker          pnext_fix->group.pCommandBufferDeviceMasks = submit->temp.dev_masks;
355*61046927SAndroid Build Coastguard Worker          pnext = &pnext_fix->group;
356*61046927SAndroid Build Coastguard Worker          break;
357*61046927SAndroid Build Coastguard Worker       }
358*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO:
359*61046927SAndroid Build Coastguard Worker          memcpy(&pnext_fix->protected, src, sizeof(pnext_fix->protected));
360*61046927SAndroid Build Coastguard Worker          pnext = &pnext_fix->protected;
361*61046927SAndroid Build Coastguard Worker          break;
362*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO:
363*61046927SAndroid Build Coastguard Worker          memcpy(&pnext_fix->timeline, src, sizeof(pnext_fix->timeline));
364*61046927SAndroid Build Coastguard Worker          pnext = &pnext_fix->timeline;
365*61046927SAndroid Build Coastguard Worker          break;
366*61046927SAndroid Build Coastguard Worker       default:
367*61046927SAndroid Build Coastguard Worker          /* The following structs are not supported by venus so are not
368*61046927SAndroid Build Coastguard Worker           * handled here. VkAmigoProfilingSubmitInfoSEC,
369*61046927SAndroid Build Coastguard Worker           * VkD3D12FenceSubmitInfoKHR, VkFrameBoundaryEXT,
370*61046927SAndroid Build Coastguard Worker           * VkLatencySubmissionPresentIdNV, VkPerformanceQuerySubmitInfoKHR,
371*61046927SAndroid Build Coastguard Worker           * VkWin32KeyedMutexAcquireReleaseInfoKHR,
372*61046927SAndroid Build Coastguard Worker           * VkWin32KeyedMutexAcquireReleaseInfoNV
373*61046927SAndroid Build Coastguard Worker           */
374*61046927SAndroid Build Coastguard Worker          break;
375*61046927SAndroid Build Coastguard Worker       }
376*61046927SAndroid Build Coastguard Worker 
377*61046927SAndroid Build Coastguard Worker       if (pnext) {
378*61046927SAndroid Build Coastguard Worker          dst->pNext = pnext;
379*61046927SAndroid Build Coastguard Worker          dst = pnext;
380*61046927SAndroid Build Coastguard Worker       }
381*61046927SAndroid Build Coastguard Worker    }
382*61046927SAndroid Build Coastguard Worker    submit->temp.pnexts++;
383*61046927SAndroid Build Coastguard Worker    submit->temp.dev_masks += new_cmd_count;
384*61046927SAndroid Build Coastguard Worker }
385*61046927SAndroid Build Coastguard Worker 
386*61046927SAndroid Build Coastguard Worker static bool
387*61046927SAndroid Build Coastguard Worker vn_semaphore_wait_external(struct vn_device *dev, struct vn_semaphore *sem);
388*61046927SAndroid Build Coastguard Worker 
389*61046927SAndroid Build Coastguard Worker static VkResult
vn_queue_submission_fix_batch_semaphores(struct vn_queue_submission * submit,uint32_t batch_index)390*61046927SAndroid Build Coastguard Worker vn_queue_submission_fix_batch_semaphores(struct vn_queue_submission *submit,
391*61046927SAndroid Build Coastguard Worker                                          uint32_t batch_index)
392*61046927SAndroid Build Coastguard Worker {
393*61046927SAndroid Build Coastguard Worker    struct vk_queue *queue_vk = vk_queue_from_handle(submit->queue_handle);
394*61046927SAndroid Build Coastguard Worker    VkDevice dev_handle = vk_device_to_handle(queue_vk->base.device);
395*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(dev_handle);
396*61046927SAndroid Build Coastguard Worker 
397*61046927SAndroid Build Coastguard Worker    const uint32_t wait_count =
398*61046927SAndroid Build Coastguard Worker       vn_get_wait_semaphore_count(submit, batch_index);
399*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < wait_count; i++) {
400*61046927SAndroid Build Coastguard Worker       VkSemaphore sem_handle = vn_get_wait_semaphore(submit, batch_index, i);
401*61046927SAndroid Build Coastguard Worker       struct vn_semaphore *sem = vn_semaphore_from_handle(sem_handle);
402*61046927SAndroid Build Coastguard Worker       const struct vn_sync_payload *payload = sem->payload;
403*61046927SAndroid Build Coastguard Worker 
404*61046927SAndroid Build Coastguard Worker       if (payload->type != VN_SYNC_TYPE_IMPORTED_SYNC_FD)
405*61046927SAndroid Build Coastguard Worker          continue;
406*61046927SAndroid Build Coastguard Worker 
407*61046927SAndroid Build Coastguard Worker       if (!vn_semaphore_wait_external(dev, sem))
408*61046927SAndroid Build Coastguard Worker          return VK_ERROR_DEVICE_LOST;
409*61046927SAndroid Build Coastguard Worker 
410*61046927SAndroid Build Coastguard Worker       assert(dev->physical_device->renderer_sync_fd.semaphore_importable);
411*61046927SAndroid Build Coastguard Worker 
412*61046927SAndroid Build Coastguard Worker       const VkImportSemaphoreResourceInfoMESA res_info = {
413*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_RESOURCE_INFO_MESA,
414*61046927SAndroid Build Coastguard Worker          .semaphore = sem_handle,
415*61046927SAndroid Build Coastguard Worker          .resourceId = 0,
416*61046927SAndroid Build Coastguard Worker       };
417*61046927SAndroid Build Coastguard Worker       vn_async_vkImportSemaphoreResourceMESA(dev->primary_ring, dev_handle,
418*61046927SAndroid Build Coastguard Worker                                              &res_info);
419*61046927SAndroid Build Coastguard Worker    }
420*61046927SAndroid Build Coastguard Worker 
421*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
422*61046927SAndroid Build Coastguard Worker }
423*61046927SAndroid Build Coastguard Worker 
424*61046927SAndroid Build Coastguard Worker static void
vn_queue_submission_count_batch_feedback(struct vn_queue_submission * submit,uint32_t batch_index)425*61046927SAndroid Build Coastguard Worker vn_queue_submission_count_batch_feedback(struct vn_queue_submission *submit,
426*61046927SAndroid Build Coastguard Worker                                          uint32_t batch_index)
427*61046927SAndroid Build Coastguard Worker {
428*61046927SAndroid Build Coastguard Worker    const uint32_t signal_count =
429*61046927SAndroid Build Coastguard Worker       vn_get_signal_semaphore_count(submit, batch_index);
430*61046927SAndroid Build Coastguard Worker    uint32_t extra_cmd_count = 0;
431*61046927SAndroid Build Coastguard Worker    uint32_t feedback_types = 0;
432*61046927SAndroid Build Coastguard Worker 
433*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < signal_count; i++) {
434*61046927SAndroid Build Coastguard Worker       struct vn_semaphore *sem = vn_semaphore_from_handle(
435*61046927SAndroid Build Coastguard Worker          vn_get_signal_semaphore(submit, batch_index, i));
436*61046927SAndroid Build Coastguard Worker       if (sem->feedback.slot) {
437*61046927SAndroid Build Coastguard Worker          feedback_types |= VN_FEEDBACK_TYPE_SEMAPHORE;
438*61046927SAndroid Build Coastguard Worker          extra_cmd_count++;
439*61046927SAndroid Build Coastguard Worker       }
440*61046927SAndroid Build Coastguard Worker    }
441*61046927SAndroid Build Coastguard Worker 
442*61046927SAndroid Build Coastguard Worker    if (submit->batch_type != VK_STRUCTURE_TYPE_BIND_SPARSE_INFO) {
443*61046927SAndroid Build Coastguard Worker       const uint32_t cmd_count = vn_get_cmd_count(submit, batch_index);
444*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < cmd_count; i++) {
445*61046927SAndroid Build Coastguard Worker          struct vn_command_buffer *cmd = vn_get_cmd(submit, batch_index, i);
446*61046927SAndroid Build Coastguard Worker          if (!list_is_empty(&cmd->builder.query_records))
447*61046927SAndroid Build Coastguard Worker             feedback_types |= VN_FEEDBACK_TYPE_QUERY;
448*61046927SAndroid Build Coastguard Worker 
449*61046927SAndroid Build Coastguard Worker          /* If a cmd that was submitted previously and already has a feedback
450*61046927SAndroid Build Coastguard Worker           * cmd linked, as long as
451*61046927SAndroid Build Coastguard Worker           * VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT was not set we can
452*61046927SAndroid Build Coastguard Worker           * assume it has completed execution and is no longer in the pending
453*61046927SAndroid Build Coastguard Worker           * state so its safe to recycle the old feedback command.
454*61046927SAndroid Build Coastguard Worker           */
455*61046927SAndroid Build Coastguard Worker          if (cmd->linked_qfb_cmd) {
456*61046927SAndroid Build Coastguard Worker             assert(!cmd->builder.is_simultaneous);
457*61046927SAndroid Build Coastguard Worker 
458*61046927SAndroid Build Coastguard Worker             vn_query_feedback_cmd_free(cmd->linked_qfb_cmd);
459*61046927SAndroid Build Coastguard Worker             cmd->linked_qfb_cmd = NULL;
460*61046927SAndroid Build Coastguard Worker          }
461*61046927SAndroid Build Coastguard Worker       }
462*61046927SAndroid Build Coastguard Worker       if (feedback_types & VN_FEEDBACK_TYPE_QUERY)
463*61046927SAndroid Build Coastguard Worker          extra_cmd_count++;
464*61046927SAndroid Build Coastguard Worker 
465*61046927SAndroid Build Coastguard Worker       if (submit->feedback_types & VN_FEEDBACK_TYPE_FENCE &&
466*61046927SAndroid Build Coastguard Worker           batch_index == submit->batch_count - 1) {
467*61046927SAndroid Build Coastguard Worker          feedback_types |= VN_FEEDBACK_TYPE_FENCE;
468*61046927SAndroid Build Coastguard Worker          extra_cmd_count++;
469*61046927SAndroid Build Coastguard Worker       }
470*61046927SAndroid Build Coastguard Worker 
471*61046927SAndroid Build Coastguard Worker       /* Space to copy the original cmds to append feedback to it.
472*61046927SAndroid Build Coastguard Worker        * If the last batch is a zink sync batch which is an empty batch with
473*61046927SAndroid Build Coastguard Worker        * sem  feedback, feedback will be appended to the second to last batch
474*61046927SAndroid Build Coastguard Worker        * so also need to copy the second to last batch's original cmds even
475*61046927SAndroid Build Coastguard Worker        * if it doesn't have feedback itself.
476*61046927SAndroid Build Coastguard Worker        */
477*61046927SAndroid Build Coastguard Worker       if (feedback_types || (batch_index == submit->batch_count - 2 &&
478*61046927SAndroid Build Coastguard Worker                              submit->has_zink_sync_batch)) {
479*61046927SAndroid Build Coastguard Worker          extra_cmd_count += cmd_count;
480*61046927SAndroid Build Coastguard Worker       }
481*61046927SAndroid Build Coastguard Worker    }
482*61046927SAndroid Build Coastguard Worker 
483*61046927SAndroid Build Coastguard Worker    if (submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO &&
484*61046927SAndroid Build Coastguard Worker        extra_cmd_count) {
485*61046927SAndroid Build Coastguard Worker       const VkDeviceGroupSubmitInfo *device_group = vk_find_struct_const(
486*61046927SAndroid Build Coastguard Worker          submit->submit_batches[batch_index].pNext, DEVICE_GROUP_SUBMIT_INFO);
487*61046927SAndroid Build Coastguard Worker       if (device_group) {
488*61046927SAndroid Build Coastguard Worker          submit->pnext_count++;
489*61046927SAndroid Build Coastguard Worker          submit->dev_mask_count += extra_cmd_count;
490*61046927SAndroid Build Coastguard Worker       }
491*61046927SAndroid Build Coastguard Worker    }
492*61046927SAndroid Build Coastguard Worker 
493*61046927SAndroid Build Coastguard Worker    submit->feedback_types |= feedback_types;
494*61046927SAndroid Build Coastguard Worker    submit->cmd_count += extra_cmd_count;
495*61046927SAndroid Build Coastguard Worker }
496*61046927SAndroid Build Coastguard Worker 
497*61046927SAndroid Build Coastguard Worker static VkResult
vn_queue_submission_prepare(struct vn_queue_submission * submit)498*61046927SAndroid Build Coastguard Worker vn_queue_submission_prepare(struct vn_queue_submission *submit)
499*61046927SAndroid Build Coastguard Worker {
500*61046927SAndroid Build Coastguard Worker    struct vn_queue *queue = vn_queue_from_handle(submit->queue_handle);
501*61046927SAndroid Build Coastguard Worker    struct vn_fence *fence = vn_fence_from_handle(submit->fence_handle);
502*61046927SAndroid Build Coastguard Worker 
503*61046927SAndroid Build Coastguard Worker    assert(!fence || !fence->is_external || !fence->feedback.slot);
504*61046927SAndroid Build Coastguard Worker    if (fence && fence->feedback.slot)
505*61046927SAndroid Build Coastguard Worker       submit->feedback_types |= VN_FEEDBACK_TYPE_FENCE;
506*61046927SAndroid Build Coastguard Worker 
507*61046927SAndroid Build Coastguard Worker    if (submit->batch_type != VK_STRUCTURE_TYPE_BIND_SPARSE_INFO)
508*61046927SAndroid Build Coastguard Worker       submit->has_zink_sync_batch = vn_has_zink_sync_batch(submit);
509*61046927SAndroid Build Coastguard Worker 
510*61046927SAndroid Build Coastguard Worker    submit->external_payload.ring_idx = queue->ring_idx;
511*61046927SAndroid Build Coastguard Worker 
512*61046927SAndroid Build Coastguard Worker    submit->wsi_mem = NULL;
513*61046927SAndroid Build Coastguard Worker    if (submit->batch_count == 1 &&
514*61046927SAndroid Build Coastguard Worker        submit->batch_type != VK_STRUCTURE_TYPE_BIND_SPARSE_INFO) {
515*61046927SAndroid Build Coastguard Worker       const struct wsi_memory_signal_submit_info *info = vk_find_struct_const(
516*61046927SAndroid Build Coastguard Worker          submit->submit_batches[0].pNext, WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA);
517*61046927SAndroid Build Coastguard Worker       if (info) {
518*61046927SAndroid Build Coastguard Worker          submit->wsi_mem = vn_device_memory_from_handle(info->memory);
519*61046927SAndroid Build Coastguard Worker          assert(submit->wsi_mem->base_bo);
520*61046927SAndroid Build Coastguard Worker       }
521*61046927SAndroid Build Coastguard Worker    }
522*61046927SAndroid Build Coastguard Worker 
523*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < submit->batch_count; i++) {
524*61046927SAndroid Build Coastguard Worker       VkResult result = vn_queue_submission_fix_batch_semaphores(submit, i);
525*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
526*61046927SAndroid Build Coastguard Worker          return result;
527*61046927SAndroid Build Coastguard Worker 
528*61046927SAndroid Build Coastguard Worker       vn_queue_submission_count_batch_feedback(submit, i);
529*61046927SAndroid Build Coastguard Worker    }
530*61046927SAndroid Build Coastguard Worker 
531*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
532*61046927SAndroid Build Coastguard Worker }
533*61046927SAndroid Build Coastguard Worker 
534*61046927SAndroid Build Coastguard Worker static VkResult
vn_queue_submission_alloc_storage(struct vn_queue_submission * submit)535*61046927SAndroid Build Coastguard Worker vn_queue_submission_alloc_storage(struct vn_queue_submission *submit)
536*61046927SAndroid Build Coastguard Worker {
537*61046927SAndroid Build Coastguard Worker    struct vn_queue *queue = vn_queue_from_handle(submit->queue_handle);
538*61046927SAndroid Build Coastguard Worker 
539*61046927SAndroid Build Coastguard Worker    if (!submit->feedback_types)
540*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
541*61046927SAndroid Build Coastguard Worker 
542*61046927SAndroid Build Coastguard Worker    /* for original batches or a new batch to hold feedback fence cmd */
543*61046927SAndroid Build Coastguard Worker    const size_t total_batch_size =
544*61046927SAndroid Build Coastguard Worker       vn_get_batch_size(submit) * MAX2(submit->batch_count, 1);
545*61046927SAndroid Build Coastguard Worker    /* for fence, timeline semaphore and query feedback cmds */
546*61046927SAndroid Build Coastguard Worker    const size_t total_cmd_size =
547*61046927SAndroid Build Coastguard Worker       vn_get_cmd_size(submit) * MAX2(submit->cmd_count, 1);
548*61046927SAndroid Build Coastguard Worker    /* for fixing command buffer counts in device group info, if it exists */
549*61046927SAndroid Build Coastguard Worker    const size_t total_pnext_size =
550*61046927SAndroid Build Coastguard Worker       submit->pnext_count * sizeof(struct vn_submit_info_pnext_fix);
551*61046927SAndroid Build Coastguard Worker    const size_t total_dev_mask_size =
552*61046927SAndroid Build Coastguard Worker       submit->dev_mask_count * sizeof(uint32_t);
553*61046927SAndroid Build Coastguard Worker    submit->temp.storage = vn_cached_storage_get(
554*61046927SAndroid Build Coastguard Worker       &queue->storage, total_batch_size + total_cmd_size + total_pnext_size +
555*61046927SAndroid Build Coastguard Worker                           total_dev_mask_size);
556*61046927SAndroid Build Coastguard Worker    if (!submit->temp.storage)
557*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
558*61046927SAndroid Build Coastguard Worker 
559*61046927SAndroid Build Coastguard Worker    submit->temp.batches = submit->temp.storage;
560*61046927SAndroid Build Coastguard Worker    submit->temp.cmds = submit->temp.storage + total_batch_size;
561*61046927SAndroid Build Coastguard Worker    submit->temp.pnexts =
562*61046927SAndroid Build Coastguard Worker       submit->temp.storage + total_batch_size + total_cmd_size;
563*61046927SAndroid Build Coastguard Worker    submit->temp.dev_masks = submit->temp.storage + total_batch_size +
564*61046927SAndroid Build Coastguard Worker                             total_cmd_size + total_pnext_size;
565*61046927SAndroid Build Coastguard Worker 
566*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
567*61046927SAndroid Build Coastguard Worker }
568*61046927SAndroid Build Coastguard Worker 
569*61046927SAndroid Build Coastguard Worker static VkResult
vn_queue_submission_get_resolved_query_records(struct vn_queue_submission * submit,uint32_t batch_index,struct vn_feedback_cmd_pool * fb_cmd_pool,struct list_head * resolved_records)570*61046927SAndroid Build Coastguard Worker vn_queue_submission_get_resolved_query_records(
571*61046927SAndroid Build Coastguard Worker    struct vn_queue_submission *submit,
572*61046927SAndroid Build Coastguard Worker    uint32_t batch_index,
573*61046927SAndroid Build Coastguard Worker    struct vn_feedback_cmd_pool *fb_cmd_pool,
574*61046927SAndroid Build Coastguard Worker    struct list_head *resolved_records)
575*61046927SAndroid Build Coastguard Worker {
576*61046927SAndroid Build Coastguard Worker    struct vn_command_pool *cmd_pool =
577*61046927SAndroid Build Coastguard Worker       vn_command_pool_from_handle(fb_cmd_pool->pool_handle);
578*61046927SAndroid Build Coastguard Worker    struct list_head dropped_records;
579*61046927SAndroid Build Coastguard Worker    VkResult result = VK_SUCCESS;
580*61046927SAndroid Build Coastguard Worker 
581*61046927SAndroid Build Coastguard Worker    list_inithead(resolved_records);
582*61046927SAndroid Build Coastguard Worker    list_inithead(&dropped_records);
583*61046927SAndroid Build Coastguard Worker    const uint32_t cmd_count = vn_get_cmd_count(submit, batch_index);
584*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < cmd_count; i++) {
585*61046927SAndroid Build Coastguard Worker       struct vn_command_buffer *cmd = vn_get_cmd(submit, batch_index, i);
586*61046927SAndroid Build Coastguard Worker 
587*61046927SAndroid Build Coastguard Worker       list_for_each_entry(struct vn_cmd_query_record, record,
588*61046927SAndroid Build Coastguard Worker                           &cmd->builder.query_records, head) {
589*61046927SAndroid Build Coastguard Worker          if (!record->copy) {
590*61046927SAndroid Build Coastguard Worker             list_for_each_entry_safe(struct vn_cmd_query_record, prev,
591*61046927SAndroid Build Coastguard Worker                                      resolved_records, head) {
592*61046927SAndroid Build Coastguard Worker                /* If we previously added a query feedback that is now getting
593*61046927SAndroid Build Coastguard Worker                 * reset, remove it since it is now a no-op and the deferred
594*61046927SAndroid Build Coastguard Worker                 * feedback copy will cause a hang waiting for the reset query
595*61046927SAndroid Build Coastguard Worker                 * to become available.
596*61046927SAndroid Build Coastguard Worker                 */
597*61046927SAndroid Build Coastguard Worker                if (prev->copy && prev->query_pool == record->query_pool &&
598*61046927SAndroid Build Coastguard Worker                    prev->query >= record->query &&
599*61046927SAndroid Build Coastguard Worker                    prev->query < record->query + record->query_count)
600*61046927SAndroid Build Coastguard Worker                   list_move_to(&prev->head, &dropped_records);
601*61046927SAndroid Build Coastguard Worker             }
602*61046927SAndroid Build Coastguard Worker          }
603*61046927SAndroid Build Coastguard Worker 
604*61046927SAndroid Build Coastguard Worker          simple_mtx_lock(&fb_cmd_pool->mutex);
605*61046927SAndroid Build Coastguard Worker          struct vn_cmd_query_record *curr = vn_cmd_pool_alloc_query_record(
606*61046927SAndroid Build Coastguard Worker             cmd_pool, record->query_pool, record->query, record->query_count,
607*61046927SAndroid Build Coastguard Worker             record->copy);
608*61046927SAndroid Build Coastguard Worker          simple_mtx_unlock(&fb_cmd_pool->mutex);
609*61046927SAndroid Build Coastguard Worker 
610*61046927SAndroid Build Coastguard Worker          if (!curr) {
611*61046927SAndroid Build Coastguard Worker             list_splicetail(resolved_records, &dropped_records);
612*61046927SAndroid Build Coastguard Worker             result = VK_ERROR_OUT_OF_HOST_MEMORY;
613*61046927SAndroid Build Coastguard Worker             goto out_free_dropped_records;
614*61046927SAndroid Build Coastguard Worker          }
615*61046927SAndroid Build Coastguard Worker 
616*61046927SAndroid Build Coastguard Worker          list_addtail(&curr->head, resolved_records);
617*61046927SAndroid Build Coastguard Worker       }
618*61046927SAndroid Build Coastguard Worker    }
619*61046927SAndroid Build Coastguard Worker 
620*61046927SAndroid Build Coastguard Worker    /* further resolve to batch sequential queries */
621*61046927SAndroid Build Coastguard Worker    struct vn_cmd_query_record *curr =
622*61046927SAndroid Build Coastguard Worker       list_first_entry(resolved_records, struct vn_cmd_query_record, head);
623*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe(struct vn_cmd_query_record, next,
624*61046927SAndroid Build Coastguard Worker                             resolved_records, head) {
625*61046927SAndroid Build Coastguard Worker       if (curr->query_pool == next->query_pool && curr->copy == next->copy) {
626*61046927SAndroid Build Coastguard Worker          if (curr->query + curr->query_count == next->query) {
627*61046927SAndroid Build Coastguard Worker             curr->query_count += next->query_count;
628*61046927SAndroid Build Coastguard Worker             list_move_to(&next->head, &dropped_records);
629*61046927SAndroid Build Coastguard Worker          } else if (curr->query == next->query + next->query_count) {
630*61046927SAndroid Build Coastguard Worker             curr->query = next->query;
631*61046927SAndroid Build Coastguard Worker             curr->query_count += next->query_count;
632*61046927SAndroid Build Coastguard Worker             list_move_to(&next->head, &dropped_records);
633*61046927SAndroid Build Coastguard Worker          } else {
634*61046927SAndroid Build Coastguard Worker             curr = next;
635*61046927SAndroid Build Coastguard Worker          }
636*61046927SAndroid Build Coastguard Worker       } else {
637*61046927SAndroid Build Coastguard Worker          curr = next;
638*61046927SAndroid Build Coastguard Worker       }
639*61046927SAndroid Build Coastguard Worker    }
640*61046927SAndroid Build Coastguard Worker 
641*61046927SAndroid Build Coastguard Worker out_free_dropped_records:
642*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&fb_cmd_pool->mutex);
643*61046927SAndroid Build Coastguard Worker    vn_cmd_pool_free_query_records(cmd_pool, &dropped_records);
644*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&fb_cmd_pool->mutex);
645*61046927SAndroid Build Coastguard Worker    return result;
646*61046927SAndroid Build Coastguard Worker }
647*61046927SAndroid Build Coastguard Worker 
648*61046927SAndroid Build Coastguard Worker static VkResult
vn_queue_submission_add_query_feedback(struct vn_queue_submission * submit,uint32_t batch_index,uint32_t * new_cmd_count)649*61046927SAndroid Build Coastguard Worker vn_queue_submission_add_query_feedback(struct vn_queue_submission *submit,
650*61046927SAndroid Build Coastguard Worker                                        uint32_t batch_index,
651*61046927SAndroid Build Coastguard Worker                                        uint32_t *new_cmd_count)
652*61046927SAndroid Build Coastguard Worker {
653*61046927SAndroid Build Coastguard Worker    struct vk_queue *queue_vk = vk_queue_from_handle(submit->queue_handle);
654*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = (void *)queue_vk->base.device;
655*61046927SAndroid Build Coastguard Worker    VkResult result;
656*61046927SAndroid Build Coastguard Worker 
657*61046927SAndroid Build Coastguard Worker    struct vn_feedback_cmd_pool *fb_cmd_pool = NULL;
658*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < dev->queue_family_count; i++) {
659*61046927SAndroid Build Coastguard Worker       if (dev->queue_families[i] == queue_vk->queue_family_index) {
660*61046927SAndroid Build Coastguard Worker          fb_cmd_pool = &dev->fb_cmd_pools[i];
661*61046927SAndroid Build Coastguard Worker          break;
662*61046927SAndroid Build Coastguard Worker       }
663*61046927SAndroid Build Coastguard Worker    }
664*61046927SAndroid Build Coastguard Worker    assert(fb_cmd_pool);
665*61046927SAndroid Build Coastguard Worker 
666*61046927SAndroid Build Coastguard Worker    struct list_head resolved_records;
667*61046927SAndroid Build Coastguard Worker    result = vn_queue_submission_get_resolved_query_records(
668*61046927SAndroid Build Coastguard Worker       submit, batch_index, fb_cmd_pool, &resolved_records);
669*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
670*61046927SAndroid Build Coastguard Worker       return result;
671*61046927SAndroid Build Coastguard Worker 
672*61046927SAndroid Build Coastguard Worker    /* currently the reset query is always recorded */
673*61046927SAndroid Build Coastguard Worker    assert(!list_is_empty(&resolved_records));
674*61046927SAndroid Build Coastguard Worker    struct vn_query_feedback_cmd *qfb_cmd;
675*61046927SAndroid Build Coastguard Worker    result = vn_query_feedback_cmd_alloc(vn_device_to_handle(dev), fb_cmd_pool,
676*61046927SAndroid Build Coastguard Worker                                         &resolved_records, &qfb_cmd);
677*61046927SAndroid Build Coastguard Worker    if (result == VK_SUCCESS) {
678*61046927SAndroid Build Coastguard Worker       /* link query feedback cmd lifecycle with a cmd in the original batch so
679*61046927SAndroid Build Coastguard Worker        * that the feedback cmd can be reset and recycled when that cmd gets
680*61046927SAndroid Build Coastguard Worker        * reset/freed.
681*61046927SAndroid Build Coastguard Worker        *
682*61046927SAndroid Build Coastguard Worker        * Avoid cmd buffers with VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT
683*61046927SAndroid Build Coastguard Worker        * since we don't know if all its instances have completed execution.
684*61046927SAndroid Build Coastguard Worker        * Should be rare enough to just log and leak the feedback cmd.
685*61046927SAndroid Build Coastguard Worker        */
686*61046927SAndroid Build Coastguard Worker       bool found_companion_cmd = false;
687*61046927SAndroid Build Coastguard Worker       const uint32_t cmd_count = vn_get_cmd_count(submit, batch_index);
688*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < cmd_count; i++) {
689*61046927SAndroid Build Coastguard Worker          struct vn_command_buffer *cmd = vn_get_cmd(submit, batch_index, i);
690*61046927SAndroid Build Coastguard Worker          if (!cmd->builder.is_simultaneous) {
691*61046927SAndroid Build Coastguard Worker             cmd->linked_qfb_cmd = qfb_cmd;
692*61046927SAndroid Build Coastguard Worker             found_companion_cmd = true;
693*61046927SAndroid Build Coastguard Worker             break;
694*61046927SAndroid Build Coastguard Worker          }
695*61046927SAndroid Build Coastguard Worker       }
696*61046927SAndroid Build Coastguard Worker       if (!found_companion_cmd)
697*61046927SAndroid Build Coastguard Worker          vn_log(dev->instance, "WARN: qfb cmd has leaked!");
698*61046927SAndroid Build Coastguard Worker 
699*61046927SAndroid Build Coastguard Worker       vn_set_temp_cmd(submit, (*new_cmd_count)++, qfb_cmd->cmd_handle);
700*61046927SAndroid Build Coastguard Worker    }
701*61046927SAndroid Build Coastguard Worker 
702*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&fb_cmd_pool->mutex);
703*61046927SAndroid Build Coastguard Worker    vn_cmd_pool_free_query_records(
704*61046927SAndroid Build Coastguard Worker       vn_command_pool_from_handle(fb_cmd_pool->pool_handle),
705*61046927SAndroid Build Coastguard Worker       &resolved_records);
706*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&fb_cmd_pool->mutex);
707*61046927SAndroid Build Coastguard Worker 
708*61046927SAndroid Build Coastguard Worker    return result;
709*61046927SAndroid Build Coastguard Worker }
710*61046927SAndroid Build Coastguard Worker 
711*61046927SAndroid Build Coastguard Worker struct vn_semaphore_feedback_cmd *
712*61046927SAndroid Build Coastguard Worker vn_semaphore_get_feedback_cmd(struct vn_device *dev,
713*61046927SAndroid Build Coastguard Worker                               struct vn_semaphore *sem);
714*61046927SAndroid Build Coastguard Worker 
715*61046927SAndroid Build Coastguard Worker static VkResult
vn_queue_submission_add_semaphore_feedback(struct vn_queue_submission * submit,uint32_t batch_index,uint32_t signal_index,uint32_t * new_cmd_count)716*61046927SAndroid Build Coastguard Worker vn_queue_submission_add_semaphore_feedback(struct vn_queue_submission *submit,
717*61046927SAndroid Build Coastguard Worker                                            uint32_t batch_index,
718*61046927SAndroid Build Coastguard Worker                                            uint32_t signal_index,
719*61046927SAndroid Build Coastguard Worker                                            uint32_t *new_cmd_count)
720*61046927SAndroid Build Coastguard Worker {
721*61046927SAndroid Build Coastguard Worker    struct vn_semaphore *sem = vn_semaphore_from_handle(
722*61046927SAndroid Build Coastguard Worker       vn_get_signal_semaphore(submit, batch_index, signal_index));
723*61046927SAndroid Build Coastguard Worker    if (!sem->feedback.slot)
724*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
725*61046927SAndroid Build Coastguard Worker 
726*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_queue, queue_vk, submit->queue_handle);
727*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = (void *)queue_vk->base.device;
728*61046927SAndroid Build Coastguard Worker    struct vn_semaphore_feedback_cmd *sfb_cmd =
729*61046927SAndroid Build Coastguard Worker       vn_semaphore_get_feedback_cmd(dev, sem);
730*61046927SAndroid Build Coastguard Worker    if (!sfb_cmd)
731*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
732*61046927SAndroid Build Coastguard Worker 
733*61046927SAndroid Build Coastguard Worker    const uint64_t counter =
734*61046927SAndroid Build Coastguard Worker       vn_get_signal_semaphore_counter(submit, batch_index, signal_index);
735*61046927SAndroid Build Coastguard Worker    vn_feedback_set_counter(sfb_cmd->src_slot, counter);
736*61046927SAndroid Build Coastguard Worker 
737*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < dev->queue_family_count; i++) {
738*61046927SAndroid Build Coastguard Worker       if (dev->queue_families[i] == queue_vk->queue_family_index) {
739*61046927SAndroid Build Coastguard Worker          vn_set_temp_cmd(submit, (*new_cmd_count)++, sfb_cmd->cmd_handles[i]);
740*61046927SAndroid Build Coastguard Worker          return VK_SUCCESS;
741*61046927SAndroid Build Coastguard Worker       }
742*61046927SAndroid Build Coastguard Worker    }
743*61046927SAndroid Build Coastguard Worker 
744*61046927SAndroid Build Coastguard Worker    unreachable("bad feedback sem");
745*61046927SAndroid Build Coastguard Worker }
746*61046927SAndroid Build Coastguard Worker 
747*61046927SAndroid Build Coastguard Worker static void
vn_queue_submission_add_fence_feedback(struct vn_queue_submission * submit,uint32_t batch_index,uint32_t * new_cmd_count)748*61046927SAndroid Build Coastguard Worker vn_queue_submission_add_fence_feedback(struct vn_queue_submission *submit,
749*61046927SAndroid Build Coastguard Worker                                        uint32_t batch_index,
750*61046927SAndroid Build Coastguard Worker                                        uint32_t *new_cmd_count)
751*61046927SAndroid Build Coastguard Worker {
752*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(vk_queue, queue_vk, submit->queue_handle);
753*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = (void *)queue_vk->base.device;
754*61046927SAndroid Build Coastguard Worker    struct vn_fence *fence = vn_fence_from_handle(submit->fence_handle);
755*61046927SAndroid Build Coastguard Worker 
756*61046927SAndroid Build Coastguard Worker    VkCommandBuffer ffb_cmd_handle = VK_NULL_HANDLE;
757*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < dev->queue_family_count; i++) {
758*61046927SAndroid Build Coastguard Worker       if (dev->queue_families[i] == queue_vk->queue_family_index) {
759*61046927SAndroid Build Coastguard Worker          ffb_cmd_handle = fence->feedback.commands[i];
760*61046927SAndroid Build Coastguard Worker       }
761*61046927SAndroid Build Coastguard Worker    }
762*61046927SAndroid Build Coastguard Worker    assert(ffb_cmd_handle != VK_NULL_HANDLE);
763*61046927SAndroid Build Coastguard Worker 
764*61046927SAndroid Build Coastguard Worker    vn_set_temp_cmd(submit, (*new_cmd_count)++, ffb_cmd_handle);
765*61046927SAndroid Build Coastguard Worker }
766*61046927SAndroid Build Coastguard Worker 
767*61046927SAndroid Build Coastguard Worker static VkResult
vn_queue_submission_add_feedback_cmds(struct vn_queue_submission * submit,uint32_t batch_index,uint32_t feedback_types)768*61046927SAndroid Build Coastguard Worker vn_queue_submission_add_feedback_cmds(struct vn_queue_submission *submit,
769*61046927SAndroid Build Coastguard Worker                                       uint32_t batch_index,
770*61046927SAndroid Build Coastguard Worker                                       uint32_t feedback_types)
771*61046927SAndroid Build Coastguard Worker {
772*61046927SAndroid Build Coastguard Worker    VkResult result;
773*61046927SAndroid Build Coastguard Worker    uint32_t new_cmd_count = vn_get_cmd_count(submit, batch_index);
774*61046927SAndroid Build Coastguard Worker 
775*61046927SAndroid Build Coastguard Worker    if (feedback_types & VN_FEEDBACK_TYPE_QUERY) {
776*61046927SAndroid Build Coastguard Worker       result = vn_queue_submission_add_query_feedback(submit, batch_index,
777*61046927SAndroid Build Coastguard Worker                                                       &new_cmd_count);
778*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
779*61046927SAndroid Build Coastguard Worker          return result;
780*61046927SAndroid Build Coastguard Worker    }
781*61046927SAndroid Build Coastguard Worker 
782*61046927SAndroid Build Coastguard Worker    if (feedback_types & VN_FEEDBACK_TYPE_SEMAPHORE) {
783*61046927SAndroid Build Coastguard Worker       const uint32_t signal_count =
784*61046927SAndroid Build Coastguard Worker          vn_get_signal_semaphore_count(submit, batch_index);
785*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < signal_count; i++) {
786*61046927SAndroid Build Coastguard Worker          result = vn_queue_submission_add_semaphore_feedback(
787*61046927SAndroid Build Coastguard Worker             submit, batch_index, i, &new_cmd_count);
788*61046927SAndroid Build Coastguard Worker          if (result != VK_SUCCESS)
789*61046927SAndroid Build Coastguard Worker             return result;
790*61046927SAndroid Build Coastguard Worker       }
791*61046927SAndroid Build Coastguard Worker       if (vn_fix_batch_cmd_count_for_zink_sync(submit, batch_index,
792*61046927SAndroid Build Coastguard Worker                                                new_cmd_count))
793*61046927SAndroid Build Coastguard Worker          return VK_SUCCESS;
794*61046927SAndroid Build Coastguard Worker    }
795*61046927SAndroid Build Coastguard Worker 
796*61046927SAndroid Build Coastguard Worker    if (feedback_types & VN_FEEDBACK_TYPE_FENCE) {
797*61046927SAndroid Build Coastguard Worker       vn_queue_submission_add_fence_feedback(submit, batch_index,
798*61046927SAndroid Build Coastguard Worker                                              &new_cmd_count);
799*61046927SAndroid Build Coastguard Worker    }
800*61046927SAndroid Build Coastguard Worker 
801*61046927SAndroid Build Coastguard Worker    if (submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO_2) {
802*61046927SAndroid Build Coastguard Worker       VkSubmitInfo2 *batch = &submit->temp.submit2_batches[batch_index];
803*61046927SAndroid Build Coastguard Worker       batch->pCommandBufferInfos = submit->temp.cmd_infos;
804*61046927SAndroid Build Coastguard Worker       batch->commandBufferInfoCount = new_cmd_count;
805*61046927SAndroid Build Coastguard Worker    } else {
806*61046927SAndroid Build Coastguard Worker       VkSubmitInfo *batch = &submit->temp.submit_batches[batch_index];
807*61046927SAndroid Build Coastguard Worker       batch->pCommandBuffers = submit->temp.cmd_handles;
808*61046927SAndroid Build Coastguard Worker       batch->commandBufferCount = new_cmd_count;
809*61046927SAndroid Build Coastguard Worker 
810*61046927SAndroid Build Coastguard Worker       const VkDeviceGroupSubmitInfo *device_group = vk_find_struct_const(
811*61046927SAndroid Build Coastguard Worker          submit->submit_batches[batch_index].pNext, DEVICE_GROUP_SUBMIT_INFO);
812*61046927SAndroid Build Coastguard Worker       if (device_group)
813*61046927SAndroid Build Coastguard Worker          vn_fix_device_group_cmd_count(submit, batch_index);
814*61046927SAndroid Build Coastguard Worker    }
815*61046927SAndroid Build Coastguard Worker 
816*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
817*61046927SAndroid Build Coastguard Worker }
818*61046927SAndroid Build Coastguard Worker 
819*61046927SAndroid Build Coastguard Worker static VkResult
vn_queue_submission_setup_batch(struct vn_queue_submission * submit,uint32_t batch_index)820*61046927SAndroid Build Coastguard Worker vn_queue_submission_setup_batch(struct vn_queue_submission *submit,
821*61046927SAndroid Build Coastguard Worker                                 uint32_t batch_index)
822*61046927SAndroid Build Coastguard Worker {
823*61046927SAndroid Build Coastguard Worker    uint32_t feedback_types = 0;
824*61046927SAndroid Build Coastguard Worker    uint32_t extra_cmd_count = 0;
825*61046927SAndroid Build Coastguard Worker 
826*61046927SAndroid Build Coastguard Worker    const uint32_t signal_count =
827*61046927SAndroid Build Coastguard Worker       vn_get_signal_semaphore_count(submit, batch_index);
828*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < signal_count; i++) {
829*61046927SAndroid Build Coastguard Worker       struct vn_semaphore *sem = vn_semaphore_from_handle(
830*61046927SAndroid Build Coastguard Worker          vn_get_signal_semaphore(submit, batch_index, i));
831*61046927SAndroid Build Coastguard Worker       if (sem->feedback.slot) {
832*61046927SAndroid Build Coastguard Worker          feedback_types |= VN_FEEDBACK_TYPE_SEMAPHORE;
833*61046927SAndroid Build Coastguard Worker          extra_cmd_count++;
834*61046927SAndroid Build Coastguard Worker       }
835*61046927SAndroid Build Coastguard Worker    }
836*61046927SAndroid Build Coastguard Worker 
837*61046927SAndroid Build Coastguard Worker    const uint32_t cmd_count = vn_get_cmd_count(submit, batch_index);
838*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < cmd_count; i++) {
839*61046927SAndroid Build Coastguard Worker       struct vn_command_buffer *cmd = vn_get_cmd(submit, batch_index, i);
840*61046927SAndroid Build Coastguard Worker       if (!list_is_empty(&cmd->builder.query_records)) {
841*61046927SAndroid Build Coastguard Worker          feedback_types |= VN_FEEDBACK_TYPE_QUERY;
842*61046927SAndroid Build Coastguard Worker          extra_cmd_count++;
843*61046927SAndroid Build Coastguard Worker          break;
844*61046927SAndroid Build Coastguard Worker       }
845*61046927SAndroid Build Coastguard Worker    }
846*61046927SAndroid Build Coastguard Worker 
847*61046927SAndroid Build Coastguard Worker    if (submit->feedback_types & VN_FEEDBACK_TYPE_FENCE &&
848*61046927SAndroid Build Coastguard Worker        batch_index == submit->batch_count - 1) {
849*61046927SAndroid Build Coastguard Worker       feedback_types |= VN_FEEDBACK_TYPE_FENCE;
850*61046927SAndroid Build Coastguard Worker       extra_cmd_count++;
851*61046927SAndroid Build Coastguard Worker    }
852*61046927SAndroid Build Coastguard Worker 
853*61046927SAndroid Build Coastguard Worker    /* If the batch has qfb, sfb or ffb, copy the original commands and append
854*61046927SAndroid Build Coastguard Worker     * feedback cmds.
855*61046927SAndroid Build Coastguard Worker     * If this is the second to last batch and the last batch a zink sync batch
856*61046927SAndroid Build Coastguard Worker     * which is empty but has feedback, also copy the original commands for
857*61046927SAndroid Build Coastguard Worker     * this batch so that the last batch's feedback can be appended to it.
858*61046927SAndroid Build Coastguard Worker     */
859*61046927SAndroid Build Coastguard Worker    if (feedback_types || (batch_index == submit->batch_count - 2 &&
860*61046927SAndroid Build Coastguard Worker                           submit->has_zink_sync_batch)) {
861*61046927SAndroid Build Coastguard Worker       const size_t cmd_size = vn_get_cmd_size(submit);
862*61046927SAndroid Build Coastguard Worker       const size_t total_cmd_size = cmd_count * cmd_size;
863*61046927SAndroid Build Coastguard Worker       /* copy only needed for non-empty batches */
864*61046927SAndroid Build Coastguard Worker       if (total_cmd_size) {
865*61046927SAndroid Build Coastguard Worker          memcpy(submit->temp.cmds, vn_get_cmds(submit, batch_index),
866*61046927SAndroid Build Coastguard Worker                 total_cmd_size);
867*61046927SAndroid Build Coastguard Worker       }
868*61046927SAndroid Build Coastguard Worker 
869*61046927SAndroid Build Coastguard Worker       VkResult result = vn_queue_submission_add_feedback_cmds(
870*61046927SAndroid Build Coastguard Worker          submit, batch_index, feedback_types);
871*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
872*61046927SAndroid Build Coastguard Worker          return result;
873*61046927SAndroid Build Coastguard Worker 
874*61046927SAndroid Build Coastguard Worker       /* advance the temp cmds for working on next batch cmds */
875*61046927SAndroid Build Coastguard Worker       submit->temp.cmds += total_cmd_size + (extra_cmd_count * cmd_size);
876*61046927SAndroid Build Coastguard Worker    }
877*61046927SAndroid Build Coastguard Worker 
878*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
879*61046927SAndroid Build Coastguard Worker }
880*61046927SAndroid Build Coastguard Worker 
881*61046927SAndroid Build Coastguard Worker static VkResult
vn_queue_submission_setup_batches(struct vn_queue_submission * submit)882*61046927SAndroid Build Coastguard Worker vn_queue_submission_setup_batches(struct vn_queue_submission *submit)
883*61046927SAndroid Build Coastguard Worker {
884*61046927SAndroid Build Coastguard Worker    assert(submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO_2 ||
885*61046927SAndroid Build Coastguard Worker           submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO);
886*61046927SAndroid Build Coastguard Worker 
887*61046927SAndroid Build Coastguard Worker    if (!submit->feedback_types)
888*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
889*61046927SAndroid Build Coastguard Worker 
890*61046927SAndroid Build Coastguard Worker    /* For a submission that is:
891*61046927SAndroid Build Coastguard Worker     * - non-empty: copy batches for adding feedbacks
892*61046927SAndroid Build Coastguard Worker     * - empty: initialize a batch for fence feedback
893*61046927SAndroid Build Coastguard Worker     */
894*61046927SAndroid Build Coastguard Worker    if (submit->batch_count) {
895*61046927SAndroid Build Coastguard Worker       memcpy(submit->temp.batches, submit->batches,
896*61046927SAndroid Build Coastguard Worker              vn_get_batch_size(submit) * submit->batch_count);
897*61046927SAndroid Build Coastguard Worker    } else {
898*61046927SAndroid Build Coastguard Worker       assert(submit->feedback_types & VN_FEEDBACK_TYPE_FENCE);
899*61046927SAndroid Build Coastguard Worker       if (submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO_2) {
900*61046927SAndroid Build Coastguard Worker          submit->temp.submit2_batches[0] = (VkSubmitInfo2){
901*61046927SAndroid Build Coastguard Worker             .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2,
902*61046927SAndroid Build Coastguard Worker          };
903*61046927SAndroid Build Coastguard Worker       } else {
904*61046927SAndroid Build Coastguard Worker          submit->temp.submit_batches[0] = (VkSubmitInfo){
905*61046927SAndroid Build Coastguard Worker             .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
906*61046927SAndroid Build Coastguard Worker          };
907*61046927SAndroid Build Coastguard Worker       }
908*61046927SAndroid Build Coastguard Worker       submit->batch_count = 1;
909*61046927SAndroid Build Coastguard Worker       submit->batches = submit->temp.batches;
910*61046927SAndroid Build Coastguard Worker    }
911*61046927SAndroid Build Coastguard Worker 
912*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < submit->batch_count; i++) {
913*61046927SAndroid Build Coastguard Worker       VkResult result = vn_queue_submission_setup_batch(submit, i);
914*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
915*61046927SAndroid Build Coastguard Worker          return result;
916*61046927SAndroid Build Coastguard Worker    }
917*61046927SAndroid Build Coastguard Worker 
918*61046927SAndroid Build Coastguard Worker    submit->batches = submit->temp.batches;
919*61046927SAndroid Build Coastguard Worker 
920*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
921*61046927SAndroid Build Coastguard Worker }
922*61046927SAndroid Build Coastguard Worker 
923*61046927SAndroid Build Coastguard Worker static void
vn_queue_submission_cleanup_semaphore_feedback(struct vn_queue_submission * submit)924*61046927SAndroid Build Coastguard Worker vn_queue_submission_cleanup_semaphore_feedback(
925*61046927SAndroid Build Coastguard Worker    struct vn_queue_submission *submit)
926*61046927SAndroid Build Coastguard Worker {
927*61046927SAndroid Build Coastguard Worker    struct vk_queue *queue_vk = vk_queue_from_handle(submit->queue_handle);
928*61046927SAndroid Build Coastguard Worker    VkDevice dev_handle = vk_device_to_handle(queue_vk->base.device);
929*61046927SAndroid Build Coastguard Worker 
930*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < submit->batch_count; i++) {
931*61046927SAndroid Build Coastguard Worker       const uint32_t wait_count = vn_get_wait_semaphore_count(submit, i);
932*61046927SAndroid Build Coastguard Worker       for (uint32_t j = 0; j < wait_count; j++) {
933*61046927SAndroid Build Coastguard Worker          VkSemaphore sem_handle = vn_get_wait_semaphore(submit, i, j);
934*61046927SAndroid Build Coastguard Worker          struct vn_semaphore *sem = vn_semaphore_from_handle(sem_handle);
935*61046927SAndroid Build Coastguard Worker          if (!sem->feedback.slot)
936*61046927SAndroid Build Coastguard Worker             continue;
937*61046927SAndroid Build Coastguard Worker 
938*61046927SAndroid Build Coastguard Worker          /* sfb pending cmds are recycled when signaled counter is updated */
939*61046927SAndroid Build Coastguard Worker          uint64_t counter = 0;
940*61046927SAndroid Build Coastguard Worker          vn_GetSemaphoreCounterValue(dev_handle, sem_handle, &counter);
941*61046927SAndroid Build Coastguard Worker       }
942*61046927SAndroid Build Coastguard Worker 
943*61046927SAndroid Build Coastguard Worker       const uint32_t signal_count = vn_get_signal_semaphore_count(submit, i);
944*61046927SAndroid Build Coastguard Worker       for (uint32_t j = 0; j < signal_count; j++) {
945*61046927SAndroid Build Coastguard Worker          VkSemaphore sem_handle = vn_get_signal_semaphore(submit, i, j);
946*61046927SAndroid Build Coastguard Worker          struct vn_semaphore *sem = vn_semaphore_from_handle(sem_handle);
947*61046927SAndroid Build Coastguard Worker          if (!sem->feedback.slot)
948*61046927SAndroid Build Coastguard Worker             continue;
949*61046927SAndroid Build Coastguard Worker 
950*61046927SAndroid Build Coastguard Worker          /* sfb pending cmds are recycled when signaled counter is updated */
951*61046927SAndroid Build Coastguard Worker          uint64_t counter = 0;
952*61046927SAndroid Build Coastguard Worker          vn_GetSemaphoreCounterValue(dev_handle, sem_handle, &counter);
953*61046927SAndroid Build Coastguard Worker       }
954*61046927SAndroid Build Coastguard Worker    }
955*61046927SAndroid Build Coastguard Worker }
956*61046927SAndroid Build Coastguard Worker 
957*61046927SAndroid Build Coastguard Worker static void
vn_queue_submission_cleanup(struct vn_queue_submission * submit)958*61046927SAndroid Build Coastguard Worker vn_queue_submission_cleanup(struct vn_queue_submission *submit)
959*61046927SAndroid Build Coastguard Worker {
960*61046927SAndroid Build Coastguard Worker    /* TODO clean up pending src feedbacks on failure? */
961*61046927SAndroid Build Coastguard Worker    if (submit->feedback_types & VN_FEEDBACK_TYPE_SEMAPHORE)
962*61046927SAndroid Build Coastguard Worker       vn_queue_submission_cleanup_semaphore_feedback(submit);
963*61046927SAndroid Build Coastguard Worker }
964*61046927SAndroid Build Coastguard Worker 
965*61046927SAndroid Build Coastguard Worker static VkResult
vn_queue_submission_prepare_submit(struct vn_queue_submission * submit)966*61046927SAndroid Build Coastguard Worker vn_queue_submission_prepare_submit(struct vn_queue_submission *submit)
967*61046927SAndroid Build Coastguard Worker {
968*61046927SAndroid Build Coastguard Worker    VkResult result = vn_queue_submission_prepare(submit);
969*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
970*61046927SAndroid Build Coastguard Worker       return result;
971*61046927SAndroid Build Coastguard Worker 
972*61046927SAndroid Build Coastguard Worker    result = vn_queue_submission_alloc_storage(submit);
973*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
974*61046927SAndroid Build Coastguard Worker       return result;
975*61046927SAndroid Build Coastguard Worker 
976*61046927SAndroid Build Coastguard Worker    result = vn_queue_submission_setup_batches(submit);
977*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
978*61046927SAndroid Build Coastguard Worker       vn_queue_submission_cleanup(submit);
979*61046927SAndroid Build Coastguard Worker       return result;
980*61046927SAndroid Build Coastguard Worker    }
981*61046927SAndroid Build Coastguard Worker 
982*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
983*61046927SAndroid Build Coastguard Worker }
984*61046927SAndroid Build Coastguard Worker 
985*61046927SAndroid Build Coastguard Worker static void
vn_queue_wsi_present(struct vn_queue_submission * submit)986*61046927SAndroid Build Coastguard Worker vn_queue_wsi_present(struct vn_queue_submission *submit)
987*61046927SAndroid Build Coastguard Worker {
988*61046927SAndroid Build Coastguard Worker    struct vk_queue *queue_vk = vk_queue_from_handle(submit->queue_handle);
989*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = (void *)queue_vk->base.device;
990*61046927SAndroid Build Coastguard Worker 
991*61046927SAndroid Build Coastguard Worker    if (!submit->wsi_mem)
992*61046927SAndroid Build Coastguard Worker       return;
993*61046927SAndroid Build Coastguard Worker 
994*61046927SAndroid Build Coastguard Worker    if (dev->renderer->info.has_implicit_fencing) {
995*61046927SAndroid Build Coastguard Worker       struct vn_renderer_submit_batch batch = {
996*61046927SAndroid Build Coastguard Worker          .ring_idx = submit->external_payload.ring_idx,
997*61046927SAndroid Build Coastguard Worker       };
998*61046927SAndroid Build Coastguard Worker 
999*61046927SAndroid Build Coastguard Worker       uint32_t local_data[8];
1000*61046927SAndroid Build Coastguard Worker       struct vn_cs_encoder local_enc =
1001*61046927SAndroid Build Coastguard Worker          VN_CS_ENCODER_INITIALIZER_LOCAL(local_data, sizeof(local_data));
1002*61046927SAndroid Build Coastguard Worker       if (submit->external_payload.ring_seqno_valid) {
1003*61046927SAndroid Build Coastguard Worker          const uint64_t ring_id = vn_ring_get_id(dev->primary_ring);
1004*61046927SAndroid Build Coastguard Worker          vn_encode_vkWaitRingSeqnoMESA(&local_enc, 0, ring_id,
1005*61046927SAndroid Build Coastguard Worker                                        submit->external_payload.ring_seqno);
1006*61046927SAndroid Build Coastguard Worker          batch.cs_data = local_data;
1007*61046927SAndroid Build Coastguard Worker          batch.cs_size = vn_cs_encoder_get_len(&local_enc);
1008*61046927SAndroid Build Coastguard Worker       }
1009*61046927SAndroid Build Coastguard Worker 
1010*61046927SAndroid Build Coastguard Worker       const struct vn_renderer_submit renderer_submit = {
1011*61046927SAndroid Build Coastguard Worker          .bos = &submit->wsi_mem->base_bo,
1012*61046927SAndroid Build Coastguard Worker          .bo_count = 1,
1013*61046927SAndroid Build Coastguard Worker          .batches = &batch,
1014*61046927SAndroid Build Coastguard Worker          .batch_count = 1,
1015*61046927SAndroid Build Coastguard Worker       };
1016*61046927SAndroid Build Coastguard Worker       vn_renderer_submit(dev->renderer, &renderer_submit);
1017*61046927SAndroid Build Coastguard Worker    } else {
1018*61046927SAndroid Build Coastguard Worker       if (VN_DEBUG(WSI)) {
1019*61046927SAndroid Build Coastguard Worker          static uint32_t num_rate_limit_warning = 0;
1020*61046927SAndroid Build Coastguard Worker 
1021*61046927SAndroid Build Coastguard Worker          if (num_rate_limit_warning++ < 10)
1022*61046927SAndroid Build Coastguard Worker             vn_log(dev->instance,
1023*61046927SAndroid Build Coastguard Worker                    "forcing vkQueueWaitIdle before presenting");
1024*61046927SAndroid Build Coastguard Worker       }
1025*61046927SAndroid Build Coastguard Worker 
1026*61046927SAndroid Build Coastguard Worker       vn_QueueWaitIdle(submit->queue_handle);
1027*61046927SAndroid Build Coastguard Worker    }
1028*61046927SAndroid Build Coastguard Worker }
1029*61046927SAndroid Build Coastguard Worker 
1030*61046927SAndroid Build Coastguard Worker static VkResult
vn_queue_submit(struct vn_queue_submission * submit)1031*61046927SAndroid Build Coastguard Worker vn_queue_submit(struct vn_queue_submission *submit)
1032*61046927SAndroid Build Coastguard Worker {
1033*61046927SAndroid Build Coastguard Worker    struct vn_queue *queue = vn_queue_from_handle(submit->queue_handle);
1034*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = (void *)queue->base.base.base.device;
1035*61046927SAndroid Build Coastguard Worker    struct vn_instance *instance = dev->instance;
1036*61046927SAndroid Build Coastguard Worker    VkResult result;
1037*61046927SAndroid Build Coastguard Worker 
1038*61046927SAndroid Build Coastguard Worker    /* To ensure external components waiting on the correct fence payload,
1039*61046927SAndroid Build Coastguard Worker     * below sync primitives must be installed after the submission:
1040*61046927SAndroid Build Coastguard Worker     * - explicit fencing: sync file export
1041*61046927SAndroid Build Coastguard Worker     * - implicit fencing: dma-fence attached to the wsi bo
1042*61046927SAndroid Build Coastguard Worker     *
1043*61046927SAndroid Build Coastguard Worker     * We enforce above via an asynchronous vkQueueSubmit(2) via ring followed
1044*61046927SAndroid Build Coastguard Worker     * by an asynchronous renderer submission to wait for the ring submission:
1045*61046927SAndroid Build Coastguard Worker     * - struct wsi_memory_signal_submit_info
1046*61046927SAndroid Build Coastguard Worker     * - fence is an external fence
1047*61046927SAndroid Build Coastguard Worker     * - has an external signal semaphore
1048*61046927SAndroid Build Coastguard Worker     */
1049*61046927SAndroid Build Coastguard Worker    result = vn_queue_submission_prepare_submit(submit);
1050*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1051*61046927SAndroid Build Coastguard Worker       return vn_error(instance, result);
1052*61046927SAndroid Build Coastguard Worker 
1053*61046927SAndroid Build Coastguard Worker    /* skip no-op submit */
1054*61046927SAndroid Build Coastguard Worker    if (!submit->batch_count && submit->fence_handle == VK_NULL_HANDLE)
1055*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
1056*61046927SAndroid Build Coastguard Worker 
1057*61046927SAndroid Build Coastguard Worker    if (VN_PERF(NO_ASYNC_QUEUE_SUBMIT)) {
1058*61046927SAndroid Build Coastguard Worker       if (submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO_2) {
1059*61046927SAndroid Build Coastguard Worker          result = vn_call_vkQueueSubmit2(
1060*61046927SAndroid Build Coastguard Worker             dev->primary_ring, submit->queue_handle, submit->batch_count,
1061*61046927SAndroid Build Coastguard Worker             submit->submit2_batches, submit->fence_handle);
1062*61046927SAndroid Build Coastguard Worker       } else {
1063*61046927SAndroid Build Coastguard Worker          result = vn_call_vkQueueSubmit(
1064*61046927SAndroid Build Coastguard Worker             dev->primary_ring, submit->queue_handle, submit->batch_count,
1065*61046927SAndroid Build Coastguard Worker             submit->submit_batches, submit->fence_handle);
1066*61046927SAndroid Build Coastguard Worker       }
1067*61046927SAndroid Build Coastguard Worker 
1068*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS) {
1069*61046927SAndroid Build Coastguard Worker          vn_queue_submission_cleanup(submit);
1070*61046927SAndroid Build Coastguard Worker          return vn_error(instance, result);
1071*61046927SAndroid Build Coastguard Worker       }
1072*61046927SAndroid Build Coastguard Worker    } else {
1073*61046927SAndroid Build Coastguard Worker       struct vn_ring_submit_command ring_submit;
1074*61046927SAndroid Build Coastguard Worker       if (submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO_2) {
1075*61046927SAndroid Build Coastguard Worker          vn_submit_vkQueueSubmit2(
1076*61046927SAndroid Build Coastguard Worker             dev->primary_ring, 0, submit->queue_handle, submit->batch_count,
1077*61046927SAndroid Build Coastguard Worker             submit->submit2_batches, submit->fence_handle, &ring_submit);
1078*61046927SAndroid Build Coastguard Worker       } else {
1079*61046927SAndroid Build Coastguard Worker          vn_submit_vkQueueSubmit(dev->primary_ring, 0, submit->queue_handle,
1080*61046927SAndroid Build Coastguard Worker                                  submit->batch_count, submit->submit_batches,
1081*61046927SAndroid Build Coastguard Worker                                  submit->fence_handle, &ring_submit);
1082*61046927SAndroid Build Coastguard Worker       }
1083*61046927SAndroid Build Coastguard Worker       if (!ring_submit.ring_seqno_valid) {
1084*61046927SAndroid Build Coastguard Worker          vn_queue_submission_cleanup(submit);
1085*61046927SAndroid Build Coastguard Worker          return vn_error(instance, VK_ERROR_DEVICE_LOST);
1086*61046927SAndroid Build Coastguard Worker       }
1087*61046927SAndroid Build Coastguard Worker       submit->external_payload.ring_seqno_valid = true;
1088*61046927SAndroid Build Coastguard Worker       submit->external_payload.ring_seqno = ring_submit.ring_seqno;
1089*61046927SAndroid Build Coastguard Worker    }
1090*61046927SAndroid Build Coastguard Worker 
1091*61046927SAndroid Build Coastguard Worker    /* If external fence, track the submission's ring_idx to facilitate
1092*61046927SAndroid Build Coastguard Worker     * sync_file export.
1093*61046927SAndroid Build Coastguard Worker     *
1094*61046927SAndroid Build Coastguard Worker     * Imported syncs don't need a proxy renderer sync on subsequent export,
1095*61046927SAndroid Build Coastguard Worker     * because an fd is already available.
1096*61046927SAndroid Build Coastguard Worker     */
1097*61046927SAndroid Build Coastguard Worker    struct vn_fence *fence = vn_fence_from_handle(submit->fence_handle);
1098*61046927SAndroid Build Coastguard Worker    if (fence && fence->is_external) {
1099*61046927SAndroid Build Coastguard Worker       assert(fence->payload->type == VN_SYNC_TYPE_DEVICE_ONLY);
1100*61046927SAndroid Build Coastguard Worker       fence->external_payload = submit->external_payload;
1101*61046927SAndroid Build Coastguard Worker    }
1102*61046927SAndroid Build Coastguard Worker 
1103*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < submit->batch_count; i++) {
1104*61046927SAndroid Build Coastguard Worker       const uint32_t signal_count = vn_get_signal_semaphore_count(submit, i);
1105*61046927SAndroid Build Coastguard Worker       for (uint32_t j = 0; j < signal_count; j++) {
1106*61046927SAndroid Build Coastguard Worker          struct vn_semaphore *sem =
1107*61046927SAndroid Build Coastguard Worker             vn_semaphore_from_handle(vn_get_signal_semaphore(submit, i, j));
1108*61046927SAndroid Build Coastguard Worker          if (sem->is_external) {
1109*61046927SAndroid Build Coastguard Worker             assert(sem->payload->type == VN_SYNC_TYPE_DEVICE_ONLY);
1110*61046927SAndroid Build Coastguard Worker             sem->external_payload = submit->external_payload;
1111*61046927SAndroid Build Coastguard Worker          }
1112*61046927SAndroid Build Coastguard Worker       }
1113*61046927SAndroid Build Coastguard Worker    }
1114*61046927SAndroid Build Coastguard Worker 
1115*61046927SAndroid Build Coastguard Worker    vn_queue_wsi_present(submit);
1116*61046927SAndroid Build Coastguard Worker 
1117*61046927SAndroid Build Coastguard Worker    vn_queue_submission_cleanup(submit);
1118*61046927SAndroid Build Coastguard Worker 
1119*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1120*61046927SAndroid Build Coastguard Worker }
1121*61046927SAndroid Build Coastguard Worker 
1122*61046927SAndroid Build Coastguard Worker VkResult
vn_QueueSubmit(VkQueue queue,uint32_t submitCount,const VkSubmitInfo * pSubmits,VkFence fence)1123*61046927SAndroid Build Coastguard Worker vn_QueueSubmit(VkQueue queue,
1124*61046927SAndroid Build Coastguard Worker                uint32_t submitCount,
1125*61046927SAndroid Build Coastguard Worker                const VkSubmitInfo *pSubmits,
1126*61046927SAndroid Build Coastguard Worker                VkFence fence)
1127*61046927SAndroid Build Coastguard Worker {
1128*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
1129*61046927SAndroid Build Coastguard Worker 
1130*61046927SAndroid Build Coastguard Worker    struct vn_queue_submission submit = {
1131*61046927SAndroid Build Coastguard Worker       .batch_type = VK_STRUCTURE_TYPE_SUBMIT_INFO,
1132*61046927SAndroid Build Coastguard Worker       .queue_handle = queue,
1133*61046927SAndroid Build Coastguard Worker       .batch_count = submitCount,
1134*61046927SAndroid Build Coastguard Worker       .submit_batches = pSubmits,
1135*61046927SAndroid Build Coastguard Worker       .fence_handle = fence,
1136*61046927SAndroid Build Coastguard Worker    };
1137*61046927SAndroid Build Coastguard Worker 
1138*61046927SAndroid Build Coastguard Worker    return vn_queue_submit(&submit);
1139*61046927SAndroid Build Coastguard Worker }
1140*61046927SAndroid Build Coastguard Worker 
1141*61046927SAndroid Build Coastguard Worker VkResult
vn_QueueSubmit2(VkQueue queue,uint32_t submitCount,const VkSubmitInfo2 * pSubmits,VkFence fence)1142*61046927SAndroid Build Coastguard Worker vn_QueueSubmit2(VkQueue queue,
1143*61046927SAndroid Build Coastguard Worker                 uint32_t submitCount,
1144*61046927SAndroid Build Coastguard Worker                 const VkSubmitInfo2 *pSubmits,
1145*61046927SAndroid Build Coastguard Worker                 VkFence fence)
1146*61046927SAndroid Build Coastguard Worker {
1147*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
1148*61046927SAndroid Build Coastguard Worker 
1149*61046927SAndroid Build Coastguard Worker    struct vn_queue_submission submit = {
1150*61046927SAndroid Build Coastguard Worker       .batch_type = VK_STRUCTURE_TYPE_SUBMIT_INFO_2,
1151*61046927SAndroid Build Coastguard Worker       .queue_handle = queue,
1152*61046927SAndroid Build Coastguard Worker       .batch_count = submitCount,
1153*61046927SAndroid Build Coastguard Worker       .submit2_batches = pSubmits,
1154*61046927SAndroid Build Coastguard Worker       .fence_handle = fence,
1155*61046927SAndroid Build Coastguard Worker    };
1156*61046927SAndroid Build Coastguard Worker 
1157*61046927SAndroid Build Coastguard Worker    return vn_queue_submit(&submit);
1158*61046927SAndroid Build Coastguard Worker }
1159*61046927SAndroid Build Coastguard Worker 
1160*61046927SAndroid Build Coastguard Worker static VkResult
vn_queue_bind_sparse_submit(struct vn_queue_submission * submit)1161*61046927SAndroid Build Coastguard Worker vn_queue_bind_sparse_submit(struct vn_queue_submission *submit)
1162*61046927SAndroid Build Coastguard Worker {
1163*61046927SAndroid Build Coastguard Worker    struct vn_queue *queue = vn_queue_from_handle(submit->queue_handle);
1164*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = (void *)queue->base.base.base.device;
1165*61046927SAndroid Build Coastguard Worker    struct vn_instance *instance = dev->instance;
1166*61046927SAndroid Build Coastguard Worker    VkResult result;
1167*61046927SAndroid Build Coastguard Worker 
1168*61046927SAndroid Build Coastguard Worker    if (VN_PERF(NO_ASYNC_QUEUE_SUBMIT)) {
1169*61046927SAndroid Build Coastguard Worker       result = vn_call_vkQueueBindSparse(
1170*61046927SAndroid Build Coastguard Worker          dev->primary_ring, submit->queue_handle, submit->batch_count,
1171*61046927SAndroid Build Coastguard Worker          submit->sparse_batches, submit->fence_handle);
1172*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
1173*61046927SAndroid Build Coastguard Worker          return vn_error(instance, result);
1174*61046927SAndroid Build Coastguard Worker    } else {
1175*61046927SAndroid Build Coastguard Worker       struct vn_ring_submit_command ring_submit;
1176*61046927SAndroid Build Coastguard Worker       vn_submit_vkQueueBindSparse(dev->primary_ring, 0, submit->queue_handle,
1177*61046927SAndroid Build Coastguard Worker                                   submit->batch_count, submit->sparse_batches,
1178*61046927SAndroid Build Coastguard Worker                                   submit->fence_handle, &ring_submit);
1179*61046927SAndroid Build Coastguard Worker 
1180*61046927SAndroid Build Coastguard Worker       if (!ring_submit.ring_seqno_valid)
1181*61046927SAndroid Build Coastguard Worker          return vn_error(instance, VK_ERROR_DEVICE_LOST);
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 static VkResult
vn_queue_bind_sparse_submit_batch(struct vn_queue_submission * submit,uint32_t batch_index)1188*61046927SAndroid Build Coastguard Worker vn_queue_bind_sparse_submit_batch(struct vn_queue_submission *submit,
1189*61046927SAndroid Build Coastguard Worker                                   uint32_t batch_index)
1190*61046927SAndroid Build Coastguard Worker {
1191*61046927SAndroid Build Coastguard Worker    struct vn_queue *queue = vn_queue_from_handle(submit->queue_handle);
1192*61046927SAndroid Build Coastguard Worker    VkDevice dev_handle = vk_device_to_handle(queue->base.base.base.device);
1193*61046927SAndroid Build Coastguard Worker    const VkBindSparseInfo *sparse_info = &submit->sparse_batches[batch_index];
1194*61046927SAndroid Build Coastguard Worker    const VkSemaphore *signal_sem = sparse_info->pSignalSemaphores;
1195*61046927SAndroid Build Coastguard Worker    uint32_t signal_sem_count = sparse_info->signalSemaphoreCount;
1196*61046927SAndroid Build Coastguard Worker    VkResult result;
1197*61046927SAndroid Build Coastguard Worker 
1198*61046927SAndroid Build Coastguard Worker    struct vn_queue_submission sparse_batch = {
1199*61046927SAndroid Build Coastguard Worker       .batch_type = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,
1200*61046927SAndroid Build Coastguard Worker       .queue_handle = submit->queue_handle,
1201*61046927SAndroid Build Coastguard Worker       .batch_count = 1,
1202*61046927SAndroid Build Coastguard Worker       .fence_handle = VK_NULL_HANDLE,
1203*61046927SAndroid Build Coastguard Worker    };
1204*61046927SAndroid Build Coastguard Worker 
1205*61046927SAndroid Build Coastguard Worker    /* lazily create sparse semaphore */
1206*61046927SAndroid Build Coastguard Worker    if (queue->sparse_semaphore == VK_NULL_HANDLE) {
1207*61046927SAndroid Build Coastguard Worker       queue->sparse_semaphore_counter = 1;
1208*61046927SAndroid Build Coastguard Worker       const VkSemaphoreTypeCreateInfo sem_type_create_info = {
1209*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
1210*61046927SAndroid Build Coastguard Worker          .pNext = NULL,
1211*61046927SAndroid Build Coastguard Worker          /* This must be timeline type to adhere to mesa's requirement
1212*61046927SAndroid Build Coastguard Worker           * not to mix binary semaphores with wait-before-signal.
1213*61046927SAndroid Build Coastguard Worker           */
1214*61046927SAndroid Build Coastguard Worker          .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
1215*61046927SAndroid Build Coastguard Worker          .initialValue = 1,
1216*61046927SAndroid Build Coastguard Worker       };
1217*61046927SAndroid Build Coastguard Worker       const VkSemaphoreCreateInfo create_info = {
1218*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
1219*61046927SAndroid Build Coastguard Worker          .pNext = &sem_type_create_info,
1220*61046927SAndroid Build Coastguard Worker          .flags = 0,
1221*61046927SAndroid Build Coastguard Worker       };
1222*61046927SAndroid Build Coastguard Worker 
1223*61046927SAndroid Build Coastguard Worker       result = vn_CreateSemaphore(dev_handle, &create_info, NULL,
1224*61046927SAndroid Build Coastguard Worker                                   &queue->sparse_semaphore);
1225*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
1226*61046927SAndroid Build Coastguard Worker          return result;
1227*61046927SAndroid Build Coastguard Worker    }
1228*61046927SAndroid Build Coastguard Worker 
1229*61046927SAndroid Build Coastguard Worker    /* Setup VkTimelineSemaphoreSubmitInfo's for our queue sparse semaphore
1230*61046927SAndroid Build Coastguard Worker     * so that the vkQueueSubmit waits on the vkQueueBindSparse signal.
1231*61046927SAndroid Build Coastguard Worker     */
1232*61046927SAndroid Build Coastguard Worker    queue->sparse_semaphore_counter++;
1233*61046927SAndroid Build Coastguard Worker    struct VkTimelineSemaphoreSubmitInfo wait_timeline_sem_info = { 0 };
1234*61046927SAndroid Build Coastguard Worker    wait_timeline_sem_info.sType =
1235*61046927SAndroid Build Coastguard Worker       VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
1236*61046927SAndroid Build Coastguard Worker    wait_timeline_sem_info.signalSemaphoreValueCount = 1;
1237*61046927SAndroid Build Coastguard Worker    wait_timeline_sem_info.pSignalSemaphoreValues =
1238*61046927SAndroid Build Coastguard Worker       &queue->sparse_semaphore_counter;
1239*61046927SAndroid Build Coastguard Worker 
1240*61046927SAndroid Build Coastguard Worker    struct VkTimelineSemaphoreSubmitInfo signal_timeline_sem_info = { 0 };
1241*61046927SAndroid Build Coastguard Worker    signal_timeline_sem_info.sType =
1242*61046927SAndroid Build Coastguard Worker       VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
1243*61046927SAndroid Build Coastguard Worker    signal_timeline_sem_info.waitSemaphoreValueCount = 1;
1244*61046927SAndroid Build Coastguard Worker    signal_timeline_sem_info.pWaitSemaphoreValues =
1245*61046927SAndroid Build Coastguard Worker       &queue->sparse_semaphore_counter;
1246*61046927SAndroid Build Coastguard Worker 
1247*61046927SAndroid Build Coastguard Worker    /* Split up the original wait and signal semaphores into its respective
1248*61046927SAndroid Build Coastguard Worker     * vkTimelineSemaphoreSubmitInfo
1249*61046927SAndroid Build Coastguard Worker     */
1250*61046927SAndroid Build Coastguard Worker    const struct VkTimelineSemaphoreSubmitInfo *timeline_sem_info =
1251*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(sparse_info->pNext,
1252*61046927SAndroid Build Coastguard Worker                            TIMELINE_SEMAPHORE_SUBMIT_INFO);
1253*61046927SAndroid Build Coastguard Worker    if (timeline_sem_info) {
1254*61046927SAndroid Build Coastguard Worker       if (timeline_sem_info->waitSemaphoreValueCount) {
1255*61046927SAndroid Build Coastguard Worker          wait_timeline_sem_info.waitSemaphoreValueCount =
1256*61046927SAndroid Build Coastguard Worker             timeline_sem_info->waitSemaphoreValueCount;
1257*61046927SAndroid Build Coastguard Worker          wait_timeline_sem_info.pWaitSemaphoreValues =
1258*61046927SAndroid Build Coastguard Worker             timeline_sem_info->pWaitSemaphoreValues;
1259*61046927SAndroid Build Coastguard Worker       }
1260*61046927SAndroid Build Coastguard Worker 
1261*61046927SAndroid Build Coastguard Worker       if (timeline_sem_info->signalSemaphoreValueCount) {
1262*61046927SAndroid Build Coastguard Worker          signal_timeline_sem_info.signalSemaphoreValueCount =
1263*61046927SAndroid Build Coastguard Worker             timeline_sem_info->signalSemaphoreValueCount;
1264*61046927SAndroid Build Coastguard Worker          signal_timeline_sem_info.pSignalSemaphoreValues =
1265*61046927SAndroid Build Coastguard Worker             timeline_sem_info->pSignalSemaphoreValues;
1266*61046927SAndroid Build Coastguard Worker       }
1267*61046927SAndroid Build Coastguard Worker    }
1268*61046927SAndroid Build Coastguard Worker 
1269*61046927SAndroid Build Coastguard Worker    /* Attach the original VkDeviceGroupBindSparseInfo if it exists */
1270*61046927SAndroid Build Coastguard Worker    struct VkDeviceGroupBindSparseInfo batch_device_group_info;
1271*61046927SAndroid Build Coastguard Worker    const struct VkDeviceGroupBindSparseInfo *device_group_info =
1272*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(sparse_info->pNext, DEVICE_GROUP_BIND_SPARSE_INFO);
1273*61046927SAndroid Build Coastguard Worker    if (device_group_info) {
1274*61046927SAndroid Build Coastguard Worker       memcpy(&batch_device_group_info, device_group_info,
1275*61046927SAndroid Build Coastguard Worker              sizeof(*device_group_info));
1276*61046927SAndroid Build Coastguard Worker       batch_device_group_info.pNext = NULL;
1277*61046927SAndroid Build Coastguard Worker 
1278*61046927SAndroid Build Coastguard Worker       wait_timeline_sem_info.pNext = &batch_device_group_info;
1279*61046927SAndroid Build Coastguard Worker    }
1280*61046927SAndroid Build Coastguard Worker 
1281*61046927SAndroid Build Coastguard Worker    /* Copy the original batch VkBindSparseInfo modified to signal
1282*61046927SAndroid Build Coastguard Worker     * our sparse semaphore.
1283*61046927SAndroid Build Coastguard Worker     */
1284*61046927SAndroid Build Coastguard Worker    VkBindSparseInfo batch_sparse_info;
1285*61046927SAndroid Build Coastguard Worker    memcpy(&batch_sparse_info, sparse_info, sizeof(*sparse_info));
1286*61046927SAndroid Build Coastguard Worker 
1287*61046927SAndroid Build Coastguard Worker    batch_sparse_info.pNext = &wait_timeline_sem_info;
1288*61046927SAndroid Build Coastguard Worker    batch_sparse_info.signalSemaphoreCount = 1;
1289*61046927SAndroid Build Coastguard Worker    batch_sparse_info.pSignalSemaphores = &queue->sparse_semaphore;
1290*61046927SAndroid Build Coastguard Worker 
1291*61046927SAndroid Build Coastguard Worker    /* Set up the SubmitInfo to wait on our sparse semaphore before sending
1292*61046927SAndroid Build Coastguard Worker     * feedback and signaling the original semaphores/fence
1293*61046927SAndroid Build Coastguard Worker     *
1294*61046927SAndroid Build Coastguard Worker     * Even if this VkBindSparse batch does not have feedback semaphores,
1295*61046927SAndroid Build Coastguard Worker     * we still glue all the batches together to ensure the feedback
1296*61046927SAndroid Build Coastguard Worker     * fence occurs after.
1297*61046927SAndroid Build Coastguard Worker     */
1298*61046927SAndroid Build Coastguard Worker    VkPipelineStageFlags stage_masks = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1299*61046927SAndroid Build Coastguard Worker    VkSubmitInfo batch_submit_info = {
1300*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
1301*61046927SAndroid Build Coastguard Worker       .pNext = &signal_timeline_sem_info,
1302*61046927SAndroid Build Coastguard Worker       .waitSemaphoreCount = 1,
1303*61046927SAndroid Build Coastguard Worker       .pWaitSemaphores = &queue->sparse_semaphore,
1304*61046927SAndroid Build Coastguard Worker       .pWaitDstStageMask = &stage_masks,
1305*61046927SAndroid Build Coastguard Worker       .signalSemaphoreCount = signal_sem_count,
1306*61046927SAndroid Build Coastguard Worker       .pSignalSemaphores = signal_sem,
1307*61046927SAndroid Build Coastguard Worker    };
1308*61046927SAndroid Build Coastguard Worker 
1309*61046927SAndroid Build Coastguard Worker    /* Set the possible fence if on the last batch */
1310*61046927SAndroid Build Coastguard Worker    VkFence fence_handle = VK_NULL_HANDLE;
1311*61046927SAndroid Build Coastguard Worker    if ((submit->feedback_types & VN_FEEDBACK_TYPE_FENCE) &&
1312*61046927SAndroid Build Coastguard Worker        batch_index == (submit->batch_count - 1)) {
1313*61046927SAndroid Build Coastguard Worker       fence_handle = submit->fence_handle;
1314*61046927SAndroid Build Coastguard Worker    }
1315*61046927SAndroid Build Coastguard Worker 
1316*61046927SAndroid Build Coastguard Worker    sparse_batch.sparse_batches = &batch_sparse_info;
1317*61046927SAndroid Build Coastguard Worker    result = vn_queue_bind_sparse_submit(&sparse_batch);
1318*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1319*61046927SAndroid Build Coastguard Worker       return result;
1320*61046927SAndroid Build Coastguard Worker 
1321*61046927SAndroid Build Coastguard Worker    result = vn_QueueSubmit(submit->queue_handle, 1, &batch_submit_info,
1322*61046927SAndroid Build Coastguard Worker                            fence_handle);
1323*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1324*61046927SAndroid Build Coastguard Worker       return result;
1325*61046927SAndroid Build Coastguard Worker 
1326*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1327*61046927SAndroid Build Coastguard Worker }
1328*61046927SAndroid Build Coastguard Worker 
1329*61046927SAndroid Build Coastguard Worker VkResult
vn_QueueBindSparse(VkQueue queue,uint32_t bindInfoCount,const VkBindSparseInfo * pBindInfo,VkFence fence)1330*61046927SAndroid Build Coastguard Worker vn_QueueBindSparse(VkQueue queue,
1331*61046927SAndroid Build Coastguard Worker                    uint32_t bindInfoCount,
1332*61046927SAndroid Build Coastguard Worker                    const VkBindSparseInfo *pBindInfo,
1333*61046927SAndroid Build Coastguard Worker                    VkFence fence)
1334*61046927SAndroid Build Coastguard Worker {
1335*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
1336*61046927SAndroid Build Coastguard Worker    VkResult result;
1337*61046927SAndroid Build Coastguard Worker 
1338*61046927SAndroid Build Coastguard Worker    struct vn_queue_submission submit = {
1339*61046927SAndroid Build Coastguard Worker       .batch_type = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,
1340*61046927SAndroid Build Coastguard Worker       .queue_handle = queue,
1341*61046927SAndroid Build Coastguard Worker       .batch_count = bindInfoCount,
1342*61046927SAndroid Build Coastguard Worker       .sparse_batches = pBindInfo,
1343*61046927SAndroid Build Coastguard Worker       .fence_handle = fence,
1344*61046927SAndroid Build Coastguard Worker    };
1345*61046927SAndroid Build Coastguard Worker 
1346*61046927SAndroid Build Coastguard Worker    result = vn_queue_submission_prepare(&submit);
1347*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1348*61046927SAndroid Build Coastguard Worker       return result;
1349*61046927SAndroid Build Coastguard Worker 
1350*61046927SAndroid Build Coastguard Worker    if (!submit.batch_count) {
1351*61046927SAndroid Build Coastguard Worker       /* skip no-op submit */
1352*61046927SAndroid Build Coastguard Worker       if (submit.fence_handle == VK_NULL_HANDLE)
1353*61046927SAndroid Build Coastguard Worker          return VK_SUCCESS;
1354*61046927SAndroid Build Coastguard Worker 
1355*61046927SAndroid Build Coastguard Worker       /* if empty batch, just send a vkQueueSubmit with the fence */
1356*61046927SAndroid Build Coastguard Worker       result =
1357*61046927SAndroid Build Coastguard Worker          vn_QueueSubmit(submit.queue_handle, 0, NULL, submit.fence_handle);
1358*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
1359*61046927SAndroid Build Coastguard Worker          return result;
1360*61046927SAndroid Build Coastguard Worker    }
1361*61046927SAndroid Build Coastguard Worker 
1362*61046927SAndroid Build Coastguard Worker    /* if feedback isn't used in the batch, can directly submit */
1363*61046927SAndroid Build Coastguard Worker    if (!submit.feedback_types)
1364*61046927SAndroid Build Coastguard Worker       return vn_queue_bind_sparse_submit(&submit);
1365*61046927SAndroid Build Coastguard Worker 
1366*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < submit.batch_count; i++) {
1367*61046927SAndroid Build Coastguard Worker       result = vn_queue_bind_sparse_submit_batch(&submit, i);
1368*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
1369*61046927SAndroid Build Coastguard Worker          return result;
1370*61046927SAndroid Build Coastguard Worker    }
1371*61046927SAndroid Build Coastguard Worker 
1372*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1373*61046927SAndroid Build Coastguard Worker }
1374*61046927SAndroid Build Coastguard Worker 
1375*61046927SAndroid Build Coastguard Worker VkResult
vn_QueueWaitIdle(VkQueue _queue)1376*61046927SAndroid Build Coastguard Worker vn_QueueWaitIdle(VkQueue _queue)
1377*61046927SAndroid Build Coastguard Worker {
1378*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
1379*61046927SAndroid Build Coastguard Worker    struct vn_queue *queue = vn_queue_from_handle(_queue);
1380*61046927SAndroid Build Coastguard Worker    VkDevice dev_handle = vk_device_to_handle(queue->base.base.base.device);
1381*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(dev_handle);
1382*61046927SAndroid Build Coastguard Worker    VkResult result;
1383*61046927SAndroid Build Coastguard Worker 
1384*61046927SAndroid Build Coastguard Worker    /* lazily create queue wait fence for queue idle waiting */
1385*61046927SAndroid Build Coastguard Worker    if (queue->wait_fence == VK_NULL_HANDLE) {
1386*61046927SAndroid Build Coastguard Worker       const VkFenceCreateInfo create_info = {
1387*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1388*61046927SAndroid Build Coastguard Worker          .flags = 0,
1389*61046927SAndroid Build Coastguard Worker       };
1390*61046927SAndroid Build Coastguard Worker       result =
1391*61046927SAndroid Build Coastguard Worker          vn_CreateFence(dev_handle, &create_info, NULL, &queue->wait_fence);
1392*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
1393*61046927SAndroid Build Coastguard Worker          return result;
1394*61046927SAndroid Build Coastguard Worker    }
1395*61046927SAndroid Build Coastguard Worker 
1396*61046927SAndroid Build Coastguard Worker    result = vn_QueueSubmit(_queue, 0, NULL, queue->wait_fence);
1397*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1398*61046927SAndroid Build Coastguard Worker       return result;
1399*61046927SAndroid Build Coastguard Worker 
1400*61046927SAndroid Build Coastguard Worker    result =
1401*61046927SAndroid Build Coastguard Worker       vn_WaitForFences(dev_handle, 1, &queue->wait_fence, true, UINT64_MAX);
1402*61046927SAndroid Build Coastguard Worker    vn_ResetFences(dev_handle, 1, &queue->wait_fence);
1403*61046927SAndroid Build Coastguard Worker 
1404*61046927SAndroid Build Coastguard Worker    return vn_result(dev->instance, result);
1405*61046927SAndroid Build Coastguard Worker }
1406*61046927SAndroid Build Coastguard Worker 
1407*61046927SAndroid Build Coastguard Worker /* fence commands */
1408*61046927SAndroid Build Coastguard Worker 
1409*61046927SAndroid Build Coastguard Worker static void
vn_sync_payload_release(UNUSED struct vn_device * dev,struct vn_sync_payload * payload)1410*61046927SAndroid Build Coastguard Worker vn_sync_payload_release(UNUSED struct vn_device *dev,
1411*61046927SAndroid Build Coastguard Worker                         struct vn_sync_payload *payload)
1412*61046927SAndroid Build Coastguard Worker {
1413*61046927SAndroid Build Coastguard Worker    if (payload->type == VN_SYNC_TYPE_IMPORTED_SYNC_FD && payload->fd >= 0)
1414*61046927SAndroid Build Coastguard Worker       close(payload->fd);
1415*61046927SAndroid Build Coastguard Worker 
1416*61046927SAndroid Build Coastguard Worker    payload->type = VN_SYNC_TYPE_INVALID;
1417*61046927SAndroid Build Coastguard Worker }
1418*61046927SAndroid Build Coastguard Worker 
1419*61046927SAndroid Build Coastguard Worker static VkResult
vn_fence_init_payloads(struct vn_device * dev,struct vn_fence * fence,bool signaled,const VkAllocationCallbacks * alloc)1420*61046927SAndroid Build Coastguard Worker vn_fence_init_payloads(struct vn_device *dev,
1421*61046927SAndroid Build Coastguard Worker                        struct vn_fence *fence,
1422*61046927SAndroid Build Coastguard Worker                        bool signaled,
1423*61046927SAndroid Build Coastguard Worker                        const VkAllocationCallbacks *alloc)
1424*61046927SAndroid Build Coastguard Worker {
1425*61046927SAndroid Build Coastguard Worker    fence->permanent.type = VN_SYNC_TYPE_DEVICE_ONLY;
1426*61046927SAndroid Build Coastguard Worker    fence->temporary.type = VN_SYNC_TYPE_INVALID;
1427*61046927SAndroid Build Coastguard Worker    fence->payload = &fence->permanent;
1428*61046927SAndroid Build Coastguard Worker 
1429*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1430*61046927SAndroid Build Coastguard Worker }
1431*61046927SAndroid Build Coastguard Worker 
1432*61046927SAndroid Build Coastguard Worker void
vn_fence_signal_wsi(struct vn_device * dev,struct vn_fence * fence)1433*61046927SAndroid Build Coastguard Worker vn_fence_signal_wsi(struct vn_device *dev, struct vn_fence *fence)
1434*61046927SAndroid Build Coastguard Worker {
1435*61046927SAndroid Build Coastguard Worker    struct vn_sync_payload *temp = &fence->temporary;
1436*61046927SAndroid Build Coastguard Worker 
1437*61046927SAndroid Build Coastguard Worker    vn_sync_payload_release(dev, temp);
1438*61046927SAndroid Build Coastguard Worker    temp->type = VN_SYNC_TYPE_IMPORTED_SYNC_FD;
1439*61046927SAndroid Build Coastguard Worker    temp->fd = -1;
1440*61046927SAndroid Build Coastguard Worker    fence->payload = temp;
1441*61046927SAndroid Build Coastguard Worker }
1442*61046927SAndroid Build Coastguard Worker 
1443*61046927SAndroid Build Coastguard Worker static VkResult
vn_fence_feedback_init(struct vn_device * dev,struct vn_fence * fence,bool signaled,const VkAllocationCallbacks * alloc)1444*61046927SAndroid Build Coastguard Worker vn_fence_feedback_init(struct vn_device *dev,
1445*61046927SAndroid Build Coastguard Worker                        struct vn_fence *fence,
1446*61046927SAndroid Build Coastguard Worker                        bool signaled,
1447*61046927SAndroid Build Coastguard Worker                        const VkAllocationCallbacks *alloc)
1448*61046927SAndroid Build Coastguard Worker {
1449*61046927SAndroid Build Coastguard Worker    VkDevice dev_handle = vn_device_to_handle(dev);
1450*61046927SAndroid Build Coastguard Worker    struct vn_feedback_slot *slot;
1451*61046927SAndroid Build Coastguard Worker    VkCommandBuffer *cmd_handles;
1452*61046927SAndroid Build Coastguard Worker    VkResult result;
1453*61046927SAndroid Build Coastguard Worker 
1454*61046927SAndroid Build Coastguard Worker    if (fence->is_external)
1455*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
1456*61046927SAndroid Build Coastguard Worker 
1457*61046927SAndroid Build Coastguard Worker    if (VN_PERF(NO_FENCE_FEEDBACK))
1458*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
1459*61046927SAndroid Build Coastguard Worker 
1460*61046927SAndroid Build Coastguard Worker    slot = vn_feedback_pool_alloc(&dev->feedback_pool, VN_FEEDBACK_TYPE_FENCE);
1461*61046927SAndroid Build Coastguard Worker    if (!slot)
1462*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
1463*61046927SAndroid Build Coastguard Worker 
1464*61046927SAndroid Build Coastguard Worker    vn_feedback_set_status(slot, signaled ? VK_SUCCESS : VK_NOT_READY);
1465*61046927SAndroid Build Coastguard Worker 
1466*61046927SAndroid Build Coastguard Worker    cmd_handles =
1467*61046927SAndroid Build Coastguard Worker       vk_zalloc(alloc, sizeof(*cmd_handles) * dev->queue_family_count,
1468*61046927SAndroid Build Coastguard Worker                 VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1469*61046927SAndroid Build Coastguard Worker    if (!cmd_handles) {
1470*61046927SAndroid Build Coastguard Worker       vn_feedback_pool_free(&dev->feedback_pool, slot);
1471*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
1472*61046927SAndroid Build Coastguard Worker    }
1473*61046927SAndroid Build Coastguard Worker 
1474*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < dev->queue_family_count; i++) {
1475*61046927SAndroid Build Coastguard Worker       result = vn_feedback_cmd_alloc(dev_handle, &dev->fb_cmd_pools[i], slot,
1476*61046927SAndroid Build Coastguard Worker                                      NULL, &cmd_handles[i]);
1477*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS) {
1478*61046927SAndroid Build Coastguard Worker          for (uint32_t j = 0; j < i; j++) {
1479*61046927SAndroid Build Coastguard Worker             vn_feedback_cmd_free(dev_handle, &dev->fb_cmd_pools[j],
1480*61046927SAndroid Build Coastguard Worker                                  cmd_handles[j]);
1481*61046927SAndroid Build Coastguard Worker          }
1482*61046927SAndroid Build Coastguard Worker          break;
1483*61046927SAndroid Build Coastguard Worker       }
1484*61046927SAndroid Build Coastguard Worker    }
1485*61046927SAndroid Build Coastguard Worker 
1486*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
1487*61046927SAndroid Build Coastguard Worker       vk_free(alloc, cmd_handles);
1488*61046927SAndroid Build Coastguard Worker       vn_feedback_pool_free(&dev->feedback_pool, slot);
1489*61046927SAndroid Build Coastguard Worker       return result;
1490*61046927SAndroid Build Coastguard Worker    }
1491*61046927SAndroid Build Coastguard Worker 
1492*61046927SAndroid Build Coastguard Worker    fence->feedback.slot = slot;
1493*61046927SAndroid Build Coastguard Worker    fence->feedback.commands = cmd_handles;
1494*61046927SAndroid Build Coastguard Worker 
1495*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1496*61046927SAndroid Build Coastguard Worker }
1497*61046927SAndroid Build Coastguard Worker 
1498*61046927SAndroid Build Coastguard Worker static void
vn_fence_feedback_fini(struct vn_device * dev,struct vn_fence * fence,const VkAllocationCallbacks * alloc)1499*61046927SAndroid Build Coastguard Worker vn_fence_feedback_fini(struct vn_device *dev,
1500*61046927SAndroid Build Coastguard Worker                        struct vn_fence *fence,
1501*61046927SAndroid Build Coastguard Worker                        const VkAllocationCallbacks *alloc)
1502*61046927SAndroid Build Coastguard Worker {
1503*61046927SAndroid Build Coastguard Worker    VkDevice dev_handle = vn_device_to_handle(dev);
1504*61046927SAndroid Build Coastguard Worker 
1505*61046927SAndroid Build Coastguard Worker    if (!fence->feedback.slot)
1506*61046927SAndroid Build Coastguard Worker       return;
1507*61046927SAndroid Build Coastguard Worker 
1508*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < dev->queue_family_count; i++) {
1509*61046927SAndroid Build Coastguard Worker       vn_feedback_cmd_free(dev_handle, &dev->fb_cmd_pools[i],
1510*61046927SAndroid Build Coastguard Worker                            fence->feedback.commands[i]);
1511*61046927SAndroid Build Coastguard Worker    }
1512*61046927SAndroid Build Coastguard Worker 
1513*61046927SAndroid Build Coastguard Worker    vn_feedback_pool_free(&dev->feedback_pool, fence->feedback.slot);
1514*61046927SAndroid Build Coastguard Worker 
1515*61046927SAndroid Build Coastguard Worker    vk_free(alloc, fence->feedback.commands);
1516*61046927SAndroid Build Coastguard Worker }
1517*61046927SAndroid Build Coastguard Worker 
1518*61046927SAndroid Build Coastguard Worker VkResult
vn_CreateFence(VkDevice device,const VkFenceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkFence * pFence)1519*61046927SAndroid Build Coastguard Worker vn_CreateFence(VkDevice device,
1520*61046927SAndroid Build Coastguard Worker                const VkFenceCreateInfo *pCreateInfo,
1521*61046927SAndroid Build Coastguard Worker                const VkAllocationCallbacks *pAllocator,
1522*61046927SAndroid Build Coastguard Worker                VkFence *pFence)
1523*61046927SAndroid Build Coastguard Worker {
1524*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
1525*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
1526*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc =
1527*61046927SAndroid Build Coastguard Worker       pAllocator ? pAllocator : &dev->base.base.alloc;
1528*61046927SAndroid Build Coastguard Worker    const bool signaled = pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT;
1529*61046927SAndroid Build Coastguard Worker    VkResult result;
1530*61046927SAndroid Build Coastguard Worker 
1531*61046927SAndroid Build Coastguard Worker    struct vn_fence *fence = vk_zalloc(alloc, sizeof(*fence), VN_DEFAULT_ALIGN,
1532*61046927SAndroid Build Coastguard Worker                                       VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1533*61046927SAndroid Build Coastguard Worker    if (!fence)
1534*61046927SAndroid Build Coastguard Worker       return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1535*61046927SAndroid Build Coastguard Worker 
1536*61046927SAndroid Build Coastguard Worker    vn_object_base_init(&fence->base, VK_OBJECT_TYPE_FENCE, &dev->base);
1537*61046927SAndroid Build Coastguard Worker 
1538*61046927SAndroid Build Coastguard Worker    const struct VkExportFenceCreateInfo *export_info =
1539*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(pCreateInfo->pNext, EXPORT_FENCE_CREATE_INFO);
1540*61046927SAndroid Build Coastguard Worker    fence->is_external = export_info && export_info->handleTypes;
1541*61046927SAndroid Build Coastguard Worker 
1542*61046927SAndroid Build Coastguard Worker    result = vn_fence_init_payloads(dev, fence, signaled, alloc);
1543*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1544*61046927SAndroid Build Coastguard Worker       goto out_object_base_fini;
1545*61046927SAndroid Build Coastguard Worker 
1546*61046927SAndroid Build Coastguard Worker    result = vn_fence_feedback_init(dev, fence, signaled, alloc);
1547*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1548*61046927SAndroid Build Coastguard Worker       goto out_payloads_fini;
1549*61046927SAndroid Build Coastguard Worker 
1550*61046927SAndroid Build Coastguard Worker    *pFence = vn_fence_to_handle(fence);
1551*61046927SAndroid Build Coastguard Worker    vn_async_vkCreateFence(dev->primary_ring, device, pCreateInfo, NULL,
1552*61046927SAndroid Build Coastguard Worker                           pFence);
1553*61046927SAndroid Build Coastguard Worker 
1554*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1555*61046927SAndroid Build Coastguard Worker 
1556*61046927SAndroid Build Coastguard Worker out_payloads_fini:
1557*61046927SAndroid Build Coastguard Worker    vn_sync_payload_release(dev, &fence->permanent);
1558*61046927SAndroid Build Coastguard Worker    vn_sync_payload_release(dev, &fence->temporary);
1559*61046927SAndroid Build Coastguard Worker 
1560*61046927SAndroid Build Coastguard Worker out_object_base_fini:
1561*61046927SAndroid Build Coastguard Worker    vn_object_base_fini(&fence->base);
1562*61046927SAndroid Build Coastguard Worker    vk_free(alloc, fence);
1563*61046927SAndroid Build Coastguard Worker    return vn_error(dev->instance, result);
1564*61046927SAndroid Build Coastguard Worker }
1565*61046927SAndroid Build Coastguard Worker 
1566*61046927SAndroid Build Coastguard Worker void
vn_DestroyFence(VkDevice device,VkFence _fence,const VkAllocationCallbacks * pAllocator)1567*61046927SAndroid Build Coastguard Worker vn_DestroyFence(VkDevice device,
1568*61046927SAndroid Build Coastguard Worker                 VkFence _fence,
1569*61046927SAndroid Build Coastguard Worker                 const VkAllocationCallbacks *pAllocator)
1570*61046927SAndroid Build Coastguard Worker {
1571*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
1572*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
1573*61046927SAndroid Build Coastguard Worker    struct vn_fence *fence = vn_fence_from_handle(_fence);
1574*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc =
1575*61046927SAndroid Build Coastguard Worker       pAllocator ? pAllocator : &dev->base.base.alloc;
1576*61046927SAndroid Build Coastguard Worker 
1577*61046927SAndroid Build Coastguard Worker    if (!fence)
1578*61046927SAndroid Build Coastguard Worker       return;
1579*61046927SAndroid Build Coastguard Worker 
1580*61046927SAndroid Build Coastguard Worker    vn_async_vkDestroyFence(dev->primary_ring, device, _fence, NULL);
1581*61046927SAndroid Build Coastguard Worker 
1582*61046927SAndroid Build Coastguard Worker    vn_fence_feedback_fini(dev, fence, alloc);
1583*61046927SAndroid Build Coastguard Worker 
1584*61046927SAndroid Build Coastguard Worker    vn_sync_payload_release(dev, &fence->permanent);
1585*61046927SAndroid Build Coastguard Worker    vn_sync_payload_release(dev, &fence->temporary);
1586*61046927SAndroid Build Coastguard Worker 
1587*61046927SAndroid Build Coastguard Worker    vn_object_base_fini(&fence->base);
1588*61046927SAndroid Build Coastguard Worker    vk_free(alloc, fence);
1589*61046927SAndroid Build Coastguard Worker }
1590*61046927SAndroid Build Coastguard Worker 
1591*61046927SAndroid Build Coastguard Worker VkResult
vn_ResetFences(VkDevice device,uint32_t fenceCount,const VkFence * pFences)1592*61046927SAndroid Build Coastguard Worker vn_ResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences)
1593*61046927SAndroid Build Coastguard Worker {
1594*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
1595*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
1596*61046927SAndroid Build Coastguard Worker 
1597*61046927SAndroid Build Coastguard Worker    vn_async_vkResetFences(dev->primary_ring, device, fenceCount, pFences);
1598*61046927SAndroid Build Coastguard Worker 
1599*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < fenceCount; i++) {
1600*61046927SAndroid Build Coastguard Worker       struct vn_fence *fence = vn_fence_from_handle(pFences[i]);
1601*61046927SAndroid Build Coastguard Worker       struct vn_sync_payload *perm = &fence->permanent;
1602*61046927SAndroid Build Coastguard Worker 
1603*61046927SAndroid Build Coastguard Worker       vn_sync_payload_release(dev, &fence->temporary);
1604*61046927SAndroid Build Coastguard Worker 
1605*61046927SAndroid Build Coastguard Worker       assert(perm->type == VN_SYNC_TYPE_DEVICE_ONLY);
1606*61046927SAndroid Build Coastguard Worker       fence->payload = perm;
1607*61046927SAndroid Build Coastguard Worker 
1608*61046927SAndroid Build Coastguard Worker       if (fence->feedback.slot)
1609*61046927SAndroid Build Coastguard Worker          vn_feedback_reset_status(fence->feedback.slot);
1610*61046927SAndroid Build Coastguard Worker    }
1611*61046927SAndroid Build Coastguard Worker 
1612*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1613*61046927SAndroid Build Coastguard Worker }
1614*61046927SAndroid Build Coastguard Worker 
1615*61046927SAndroid Build Coastguard Worker VkResult
vn_GetFenceStatus(VkDevice device,VkFence _fence)1616*61046927SAndroid Build Coastguard Worker vn_GetFenceStatus(VkDevice device, VkFence _fence)
1617*61046927SAndroid Build Coastguard Worker {
1618*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
1619*61046927SAndroid Build Coastguard Worker    struct vn_fence *fence = vn_fence_from_handle(_fence);
1620*61046927SAndroid Build Coastguard Worker    struct vn_sync_payload *payload = fence->payload;
1621*61046927SAndroid Build Coastguard Worker 
1622*61046927SAndroid Build Coastguard Worker    VkResult result;
1623*61046927SAndroid Build Coastguard Worker    switch (payload->type) {
1624*61046927SAndroid Build Coastguard Worker    case VN_SYNC_TYPE_DEVICE_ONLY:
1625*61046927SAndroid Build Coastguard Worker       if (fence->feedback.slot) {
1626*61046927SAndroid Build Coastguard Worker          result = vn_feedback_get_status(fence->feedback.slot);
1627*61046927SAndroid Build Coastguard Worker          if (result == VK_SUCCESS) {
1628*61046927SAndroid Build Coastguard Worker             /* When fence feedback slot gets signaled, the real fence
1629*61046927SAndroid Build Coastguard Worker              * signal operation follows after but the signaling isr can be
1630*61046927SAndroid Build Coastguard Worker              * deferred or preempted. To avoid racing, we let the
1631*61046927SAndroid Build Coastguard Worker              * renderer wait for the fence. This also helps resolve
1632*61046927SAndroid Build Coastguard Worker              * synchronization validation errors, because the layer no
1633*61046927SAndroid Build Coastguard Worker              * longer sees any fence status checks and falsely believes the
1634*61046927SAndroid Build Coastguard Worker              * caller does not sync.
1635*61046927SAndroid Build Coastguard Worker              */
1636*61046927SAndroid Build Coastguard Worker             vn_async_vkWaitForFences(dev->primary_ring, device, 1, &_fence,
1637*61046927SAndroid Build Coastguard Worker                                      VK_TRUE, UINT64_MAX);
1638*61046927SAndroid Build Coastguard Worker          }
1639*61046927SAndroid Build Coastguard Worker       } else {
1640*61046927SAndroid Build Coastguard Worker          result = vn_call_vkGetFenceStatus(dev->primary_ring, device, _fence);
1641*61046927SAndroid Build Coastguard Worker       }
1642*61046927SAndroid Build Coastguard Worker       break;
1643*61046927SAndroid Build Coastguard Worker    case VN_SYNC_TYPE_IMPORTED_SYNC_FD:
1644*61046927SAndroid Build Coastguard Worker       if (payload->fd < 0 || sync_wait(payload->fd, 0) == 0)
1645*61046927SAndroid Build Coastguard Worker          result = VK_SUCCESS;
1646*61046927SAndroid Build Coastguard Worker       else
1647*61046927SAndroid Build Coastguard Worker          result = errno == ETIME ? VK_NOT_READY : VK_ERROR_DEVICE_LOST;
1648*61046927SAndroid Build Coastguard Worker       break;
1649*61046927SAndroid Build Coastguard Worker    default:
1650*61046927SAndroid Build Coastguard Worker       unreachable("unexpected fence payload type");
1651*61046927SAndroid Build Coastguard Worker       break;
1652*61046927SAndroid Build Coastguard Worker    }
1653*61046927SAndroid Build Coastguard Worker 
1654*61046927SAndroid Build Coastguard Worker    return vn_result(dev->instance, result);
1655*61046927SAndroid Build Coastguard Worker }
1656*61046927SAndroid Build Coastguard Worker 
1657*61046927SAndroid Build Coastguard Worker static VkResult
vn_find_first_signaled_fence(VkDevice device,const VkFence * fences,uint32_t count)1658*61046927SAndroid Build Coastguard Worker vn_find_first_signaled_fence(VkDevice device,
1659*61046927SAndroid Build Coastguard Worker                              const VkFence *fences,
1660*61046927SAndroid Build Coastguard Worker                              uint32_t count)
1661*61046927SAndroid Build Coastguard Worker {
1662*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < count; i++) {
1663*61046927SAndroid Build Coastguard Worker       VkResult result = vn_GetFenceStatus(device, fences[i]);
1664*61046927SAndroid Build Coastguard Worker       if (result == VK_SUCCESS || result < 0)
1665*61046927SAndroid Build Coastguard Worker          return result;
1666*61046927SAndroid Build Coastguard Worker    }
1667*61046927SAndroid Build Coastguard Worker    return VK_NOT_READY;
1668*61046927SAndroid Build Coastguard Worker }
1669*61046927SAndroid Build Coastguard Worker 
1670*61046927SAndroid Build Coastguard Worker static VkResult
vn_remove_signaled_fences(VkDevice device,VkFence * fences,uint32_t * count)1671*61046927SAndroid Build Coastguard Worker vn_remove_signaled_fences(VkDevice device, VkFence *fences, uint32_t *count)
1672*61046927SAndroid Build Coastguard Worker {
1673*61046927SAndroid Build Coastguard Worker    uint32_t cur = 0;
1674*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < *count; i++) {
1675*61046927SAndroid Build Coastguard Worker       VkResult result = vn_GetFenceStatus(device, fences[i]);
1676*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS) {
1677*61046927SAndroid Build Coastguard Worker          if (result < 0)
1678*61046927SAndroid Build Coastguard Worker             return result;
1679*61046927SAndroid Build Coastguard Worker          fences[cur++] = fences[i];
1680*61046927SAndroid Build Coastguard Worker       }
1681*61046927SAndroid Build Coastguard Worker    }
1682*61046927SAndroid Build Coastguard Worker 
1683*61046927SAndroid Build Coastguard Worker    *count = cur;
1684*61046927SAndroid Build Coastguard Worker    return cur ? VK_NOT_READY : VK_SUCCESS;
1685*61046927SAndroid Build Coastguard Worker }
1686*61046927SAndroid Build Coastguard Worker 
1687*61046927SAndroid Build Coastguard Worker static VkResult
vn_update_sync_result(struct vn_device * dev,VkResult result,int64_t abs_timeout,struct vn_relax_state * relax_state)1688*61046927SAndroid Build Coastguard Worker vn_update_sync_result(struct vn_device *dev,
1689*61046927SAndroid Build Coastguard Worker                       VkResult result,
1690*61046927SAndroid Build Coastguard Worker                       int64_t abs_timeout,
1691*61046927SAndroid Build Coastguard Worker                       struct vn_relax_state *relax_state)
1692*61046927SAndroid Build Coastguard Worker {
1693*61046927SAndroid Build Coastguard Worker    switch (result) {
1694*61046927SAndroid Build Coastguard Worker    case VK_NOT_READY:
1695*61046927SAndroid Build Coastguard Worker       if (abs_timeout != OS_TIMEOUT_INFINITE &&
1696*61046927SAndroid Build Coastguard Worker           os_time_get_nano() >= abs_timeout)
1697*61046927SAndroid Build Coastguard Worker          result = VK_TIMEOUT;
1698*61046927SAndroid Build Coastguard Worker       else
1699*61046927SAndroid Build Coastguard Worker          vn_relax(relax_state);
1700*61046927SAndroid Build Coastguard Worker       break;
1701*61046927SAndroid Build Coastguard Worker    default:
1702*61046927SAndroid Build Coastguard Worker       assert(result == VK_SUCCESS || result < 0);
1703*61046927SAndroid Build Coastguard Worker       break;
1704*61046927SAndroid Build Coastguard Worker    }
1705*61046927SAndroid Build Coastguard Worker 
1706*61046927SAndroid Build Coastguard Worker    return result;
1707*61046927SAndroid Build Coastguard Worker }
1708*61046927SAndroid Build Coastguard Worker 
1709*61046927SAndroid Build Coastguard Worker VkResult
vn_WaitForFences(VkDevice device,uint32_t fenceCount,const VkFence * pFences,VkBool32 waitAll,uint64_t timeout)1710*61046927SAndroid Build Coastguard Worker vn_WaitForFences(VkDevice device,
1711*61046927SAndroid Build Coastguard Worker                  uint32_t fenceCount,
1712*61046927SAndroid Build Coastguard Worker                  const VkFence *pFences,
1713*61046927SAndroid Build Coastguard Worker                  VkBool32 waitAll,
1714*61046927SAndroid Build Coastguard Worker                  uint64_t timeout)
1715*61046927SAndroid Build Coastguard Worker {
1716*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
1717*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
1718*61046927SAndroid Build Coastguard Worker 
1719*61046927SAndroid Build Coastguard Worker    const int64_t abs_timeout = os_time_get_absolute_timeout(timeout);
1720*61046927SAndroid Build Coastguard Worker    VkResult result = VK_NOT_READY;
1721*61046927SAndroid Build Coastguard Worker    if (fenceCount > 1 && waitAll) {
1722*61046927SAndroid Build Coastguard Worker       STACK_ARRAY(VkFence, fences, fenceCount);
1723*61046927SAndroid Build Coastguard Worker       typed_memcpy(fences, pFences, fenceCount);
1724*61046927SAndroid Build Coastguard Worker 
1725*61046927SAndroid Build Coastguard Worker       struct vn_relax_state relax_state =
1726*61046927SAndroid Build Coastguard Worker          vn_relax_init(dev->instance, VN_RELAX_REASON_FENCE);
1727*61046927SAndroid Build Coastguard Worker       while (result == VK_NOT_READY) {
1728*61046927SAndroid Build Coastguard Worker          result = vn_remove_signaled_fences(device, fences, &fenceCount);
1729*61046927SAndroid Build Coastguard Worker          result =
1730*61046927SAndroid Build Coastguard Worker             vn_update_sync_result(dev, result, abs_timeout, &relax_state);
1731*61046927SAndroid Build Coastguard Worker       }
1732*61046927SAndroid Build Coastguard Worker       vn_relax_fini(&relax_state);
1733*61046927SAndroid Build Coastguard Worker 
1734*61046927SAndroid Build Coastguard Worker       STACK_ARRAY_FINISH(fences);
1735*61046927SAndroid Build Coastguard Worker    } else {
1736*61046927SAndroid Build Coastguard Worker       struct vn_relax_state relax_state =
1737*61046927SAndroid Build Coastguard Worker          vn_relax_init(dev->instance, VN_RELAX_REASON_FENCE);
1738*61046927SAndroid Build Coastguard Worker       while (result == VK_NOT_READY) {
1739*61046927SAndroid Build Coastguard Worker          result = vn_find_first_signaled_fence(device, pFences, fenceCount);
1740*61046927SAndroid Build Coastguard Worker          result =
1741*61046927SAndroid Build Coastguard Worker             vn_update_sync_result(dev, result, abs_timeout, &relax_state);
1742*61046927SAndroid Build Coastguard Worker       }
1743*61046927SAndroid Build Coastguard Worker       vn_relax_fini(&relax_state);
1744*61046927SAndroid Build Coastguard Worker    }
1745*61046927SAndroid Build Coastguard Worker 
1746*61046927SAndroid Build Coastguard Worker    return vn_result(dev->instance, result);
1747*61046927SAndroid Build Coastguard Worker }
1748*61046927SAndroid Build Coastguard Worker 
1749*61046927SAndroid Build Coastguard Worker static VkResult
vn_create_sync_file(struct vn_device * dev,struct vn_sync_payload_external * external_payload,int * out_fd)1750*61046927SAndroid Build Coastguard Worker vn_create_sync_file(struct vn_device *dev,
1751*61046927SAndroid Build Coastguard Worker                     struct vn_sync_payload_external *external_payload,
1752*61046927SAndroid Build Coastguard Worker                     int *out_fd)
1753*61046927SAndroid Build Coastguard Worker {
1754*61046927SAndroid Build Coastguard Worker    struct vn_renderer_sync *sync;
1755*61046927SAndroid Build Coastguard Worker    VkResult result = vn_renderer_sync_create(dev->renderer, 0,
1756*61046927SAndroid Build Coastguard Worker                                              VN_RENDERER_SYNC_BINARY, &sync);
1757*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1758*61046927SAndroid Build Coastguard Worker       return vn_error(dev->instance, result);
1759*61046927SAndroid Build Coastguard Worker 
1760*61046927SAndroid Build Coastguard Worker    struct vn_renderer_submit_batch batch = {
1761*61046927SAndroid Build Coastguard Worker       .syncs = &sync,
1762*61046927SAndroid Build Coastguard Worker       .sync_values = &(const uint64_t){ 1 },
1763*61046927SAndroid Build Coastguard Worker       .sync_count = 1,
1764*61046927SAndroid Build Coastguard Worker       .ring_idx = external_payload->ring_idx,
1765*61046927SAndroid Build Coastguard Worker    };
1766*61046927SAndroid Build Coastguard Worker 
1767*61046927SAndroid Build Coastguard Worker    uint32_t local_data[8];
1768*61046927SAndroid Build Coastguard Worker    struct vn_cs_encoder local_enc =
1769*61046927SAndroid Build Coastguard Worker       VN_CS_ENCODER_INITIALIZER_LOCAL(local_data, sizeof(local_data));
1770*61046927SAndroid Build Coastguard Worker    if (external_payload->ring_seqno_valid) {
1771*61046927SAndroid Build Coastguard Worker       const uint64_t ring_id = vn_ring_get_id(dev->primary_ring);
1772*61046927SAndroid Build Coastguard Worker       vn_encode_vkWaitRingSeqnoMESA(&local_enc, 0, ring_id,
1773*61046927SAndroid Build Coastguard Worker                                     external_payload->ring_seqno);
1774*61046927SAndroid Build Coastguard Worker       batch.cs_data = local_data;
1775*61046927SAndroid Build Coastguard Worker       batch.cs_size = vn_cs_encoder_get_len(&local_enc);
1776*61046927SAndroid Build Coastguard Worker    }
1777*61046927SAndroid Build Coastguard Worker 
1778*61046927SAndroid Build Coastguard Worker    const struct vn_renderer_submit submit = {
1779*61046927SAndroid Build Coastguard Worker       .batches = &batch,
1780*61046927SAndroid Build Coastguard Worker       .batch_count = 1,
1781*61046927SAndroid Build Coastguard Worker    };
1782*61046927SAndroid Build Coastguard Worker    result = vn_renderer_submit(dev->renderer, &submit);
1783*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
1784*61046927SAndroid Build Coastguard Worker       vn_renderer_sync_destroy(dev->renderer, sync);
1785*61046927SAndroid Build Coastguard Worker       return vn_error(dev->instance, result);
1786*61046927SAndroid Build Coastguard Worker    }
1787*61046927SAndroid Build Coastguard Worker 
1788*61046927SAndroid Build Coastguard Worker    *out_fd = vn_renderer_sync_export_syncobj(dev->renderer, sync, true);
1789*61046927SAndroid Build Coastguard Worker    vn_renderer_sync_destroy(dev->renderer, sync);
1790*61046927SAndroid Build Coastguard Worker 
1791*61046927SAndroid Build Coastguard Worker    return *out_fd >= 0 ? VK_SUCCESS : VK_ERROR_TOO_MANY_OBJECTS;
1792*61046927SAndroid Build Coastguard Worker }
1793*61046927SAndroid Build Coastguard Worker 
1794*61046927SAndroid Build Coastguard Worker static inline bool
vn_sync_valid_fd(int fd)1795*61046927SAndroid Build Coastguard Worker vn_sync_valid_fd(int fd)
1796*61046927SAndroid Build Coastguard Worker {
1797*61046927SAndroid Build Coastguard Worker    /* the special value -1 for fd is treated like a valid sync file descriptor
1798*61046927SAndroid Build Coastguard Worker     * referring to an object that has already signaled
1799*61046927SAndroid Build Coastguard Worker     */
1800*61046927SAndroid Build Coastguard Worker    return (fd >= 0 && sync_valid_fd(fd)) || fd == -1;
1801*61046927SAndroid Build Coastguard Worker }
1802*61046927SAndroid Build Coastguard Worker 
1803*61046927SAndroid Build Coastguard Worker VkResult
vn_ImportFenceFdKHR(VkDevice device,const VkImportFenceFdInfoKHR * pImportFenceFdInfo)1804*61046927SAndroid Build Coastguard Worker vn_ImportFenceFdKHR(VkDevice device,
1805*61046927SAndroid Build Coastguard Worker                     const VkImportFenceFdInfoKHR *pImportFenceFdInfo)
1806*61046927SAndroid Build Coastguard Worker {
1807*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
1808*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
1809*61046927SAndroid Build Coastguard Worker    struct vn_fence *fence = vn_fence_from_handle(pImportFenceFdInfo->fence);
1810*61046927SAndroid Build Coastguard Worker    ASSERTED const bool sync_file = pImportFenceFdInfo->handleType ==
1811*61046927SAndroid Build Coastguard Worker                                    VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
1812*61046927SAndroid Build Coastguard Worker    const int fd = pImportFenceFdInfo->fd;
1813*61046927SAndroid Build Coastguard Worker 
1814*61046927SAndroid Build Coastguard Worker    assert(sync_file);
1815*61046927SAndroid Build Coastguard Worker 
1816*61046927SAndroid Build Coastguard Worker    if (!vn_sync_valid_fd(fd))
1817*61046927SAndroid Build Coastguard Worker       return vn_error(dev->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
1818*61046927SAndroid Build Coastguard Worker 
1819*61046927SAndroid Build Coastguard Worker    struct vn_sync_payload *temp = &fence->temporary;
1820*61046927SAndroid Build Coastguard Worker    vn_sync_payload_release(dev, temp);
1821*61046927SAndroid Build Coastguard Worker    temp->type = VN_SYNC_TYPE_IMPORTED_SYNC_FD;
1822*61046927SAndroid Build Coastguard Worker    temp->fd = fd;
1823*61046927SAndroid Build Coastguard Worker    fence->payload = temp;
1824*61046927SAndroid Build Coastguard Worker 
1825*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1826*61046927SAndroid Build Coastguard Worker }
1827*61046927SAndroid Build Coastguard Worker 
1828*61046927SAndroid Build Coastguard Worker VkResult
vn_GetFenceFdKHR(VkDevice device,const VkFenceGetFdInfoKHR * pGetFdInfo,int * pFd)1829*61046927SAndroid Build Coastguard Worker vn_GetFenceFdKHR(VkDevice device,
1830*61046927SAndroid Build Coastguard Worker                  const VkFenceGetFdInfoKHR *pGetFdInfo,
1831*61046927SAndroid Build Coastguard Worker                  int *pFd)
1832*61046927SAndroid Build Coastguard Worker {
1833*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
1834*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
1835*61046927SAndroid Build Coastguard Worker    struct vn_fence *fence = vn_fence_from_handle(pGetFdInfo->fence);
1836*61046927SAndroid Build Coastguard Worker    const bool sync_file =
1837*61046927SAndroid Build Coastguard Worker       pGetFdInfo->handleType == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
1838*61046927SAndroid Build Coastguard Worker    struct vn_sync_payload *payload = fence->payload;
1839*61046927SAndroid Build Coastguard Worker    VkResult result;
1840*61046927SAndroid Build Coastguard Worker 
1841*61046927SAndroid Build Coastguard Worker    assert(sync_file);
1842*61046927SAndroid Build Coastguard Worker    assert(dev->physical_device->renderer_sync_fd.fence_exportable);
1843*61046927SAndroid Build Coastguard Worker 
1844*61046927SAndroid Build Coastguard Worker    int fd = -1;
1845*61046927SAndroid Build Coastguard Worker    if (payload->type == VN_SYNC_TYPE_DEVICE_ONLY) {
1846*61046927SAndroid Build Coastguard Worker       result = vn_create_sync_file(dev, &fence->external_payload, &fd);
1847*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
1848*61046927SAndroid Build Coastguard Worker          return vn_error(dev->instance, result);
1849*61046927SAndroid Build Coastguard Worker 
1850*61046927SAndroid Build Coastguard Worker       vn_async_vkResetFenceResourceMESA(dev->primary_ring, device,
1851*61046927SAndroid Build Coastguard Worker                                         pGetFdInfo->fence);
1852*61046927SAndroid Build Coastguard Worker 
1853*61046927SAndroid Build Coastguard Worker       vn_sync_payload_release(dev, &fence->temporary);
1854*61046927SAndroid Build Coastguard Worker       fence->payload = &fence->permanent;
1855*61046927SAndroid Build Coastguard Worker 
1856*61046927SAndroid Build Coastguard Worker #ifdef VN_USE_WSI_PLATFORM
1857*61046927SAndroid Build Coastguard Worker       if (!dev->renderer->info.has_implicit_fencing)
1858*61046927SAndroid Build Coastguard Worker          sync_wait(fd, -1);
1859*61046927SAndroid Build Coastguard Worker #endif
1860*61046927SAndroid Build Coastguard Worker    } else {
1861*61046927SAndroid Build Coastguard Worker       assert(payload->type == VN_SYNC_TYPE_IMPORTED_SYNC_FD);
1862*61046927SAndroid Build Coastguard Worker 
1863*61046927SAndroid Build Coastguard Worker       /* transfer ownership of imported sync fd to save a dup */
1864*61046927SAndroid Build Coastguard Worker       fd = payload->fd;
1865*61046927SAndroid Build Coastguard Worker       payload->fd = -1;
1866*61046927SAndroid Build Coastguard Worker 
1867*61046927SAndroid Build Coastguard Worker       /* reset host fence in case in signaled state before import */
1868*61046927SAndroid Build Coastguard Worker       result = vn_ResetFences(device, 1, &pGetFdInfo->fence);
1869*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS) {
1870*61046927SAndroid Build Coastguard Worker          /* transfer sync fd ownership back on error */
1871*61046927SAndroid Build Coastguard Worker          payload->fd = fd;
1872*61046927SAndroid Build Coastguard Worker          return result;
1873*61046927SAndroid Build Coastguard Worker       }
1874*61046927SAndroid Build Coastguard Worker    }
1875*61046927SAndroid Build Coastguard Worker 
1876*61046927SAndroid Build Coastguard Worker    *pFd = fd;
1877*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1878*61046927SAndroid Build Coastguard Worker }
1879*61046927SAndroid Build Coastguard Worker 
1880*61046927SAndroid Build Coastguard Worker /* semaphore commands */
1881*61046927SAndroid Build Coastguard Worker 
1882*61046927SAndroid Build Coastguard Worker static VkResult
vn_semaphore_init_payloads(struct vn_device * dev,struct vn_semaphore * sem,uint64_t initial_val,const VkAllocationCallbacks * alloc)1883*61046927SAndroid Build Coastguard Worker vn_semaphore_init_payloads(struct vn_device *dev,
1884*61046927SAndroid Build Coastguard Worker                            struct vn_semaphore *sem,
1885*61046927SAndroid Build Coastguard Worker                            uint64_t initial_val,
1886*61046927SAndroid Build Coastguard Worker                            const VkAllocationCallbacks *alloc)
1887*61046927SAndroid Build Coastguard Worker {
1888*61046927SAndroid Build Coastguard Worker    sem->permanent.type = VN_SYNC_TYPE_DEVICE_ONLY;
1889*61046927SAndroid Build Coastguard Worker    sem->temporary.type = VN_SYNC_TYPE_INVALID;
1890*61046927SAndroid Build Coastguard Worker    sem->payload = &sem->permanent;
1891*61046927SAndroid Build Coastguard Worker 
1892*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1893*61046927SAndroid Build Coastguard Worker }
1894*61046927SAndroid Build Coastguard Worker 
1895*61046927SAndroid Build Coastguard Worker static bool
vn_semaphore_wait_external(struct vn_device * dev,struct vn_semaphore * sem)1896*61046927SAndroid Build Coastguard Worker vn_semaphore_wait_external(struct vn_device *dev, struct vn_semaphore *sem)
1897*61046927SAndroid Build Coastguard Worker {
1898*61046927SAndroid Build Coastguard Worker    struct vn_sync_payload *temp = &sem->temporary;
1899*61046927SAndroid Build Coastguard Worker 
1900*61046927SAndroid Build Coastguard Worker    assert(temp->type == VN_SYNC_TYPE_IMPORTED_SYNC_FD);
1901*61046927SAndroid Build Coastguard Worker 
1902*61046927SAndroid Build Coastguard Worker    if (temp->fd >= 0) {
1903*61046927SAndroid Build Coastguard Worker       if (sync_wait(temp->fd, -1))
1904*61046927SAndroid Build Coastguard Worker          return false;
1905*61046927SAndroid Build Coastguard Worker    }
1906*61046927SAndroid Build Coastguard Worker 
1907*61046927SAndroid Build Coastguard Worker    vn_sync_payload_release(dev, &sem->temporary);
1908*61046927SAndroid Build Coastguard Worker    sem->payload = &sem->permanent;
1909*61046927SAndroid Build Coastguard Worker 
1910*61046927SAndroid Build Coastguard Worker    return true;
1911*61046927SAndroid Build Coastguard Worker }
1912*61046927SAndroid Build Coastguard Worker 
1913*61046927SAndroid Build Coastguard Worker void
vn_semaphore_signal_wsi(struct vn_device * dev,struct vn_semaphore * sem)1914*61046927SAndroid Build Coastguard Worker vn_semaphore_signal_wsi(struct vn_device *dev, struct vn_semaphore *sem)
1915*61046927SAndroid Build Coastguard Worker {
1916*61046927SAndroid Build Coastguard Worker    struct vn_sync_payload *temp = &sem->temporary;
1917*61046927SAndroid Build Coastguard Worker 
1918*61046927SAndroid Build Coastguard Worker    vn_sync_payload_release(dev, temp);
1919*61046927SAndroid Build Coastguard Worker    temp->type = VN_SYNC_TYPE_IMPORTED_SYNC_FD;
1920*61046927SAndroid Build Coastguard Worker    temp->fd = -1;
1921*61046927SAndroid Build Coastguard Worker    sem->payload = temp;
1922*61046927SAndroid Build Coastguard Worker }
1923*61046927SAndroid Build Coastguard Worker 
1924*61046927SAndroid Build Coastguard Worker struct vn_semaphore_feedback_cmd *
vn_semaphore_get_feedback_cmd(struct vn_device * dev,struct vn_semaphore * sem)1925*61046927SAndroid Build Coastguard Worker vn_semaphore_get_feedback_cmd(struct vn_device *dev, struct vn_semaphore *sem)
1926*61046927SAndroid Build Coastguard Worker {
1927*61046927SAndroid Build Coastguard Worker    struct vn_semaphore_feedback_cmd *sfb_cmd = NULL;
1928*61046927SAndroid Build Coastguard Worker 
1929*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&sem->feedback.cmd_mtx);
1930*61046927SAndroid Build Coastguard Worker    if (!list_is_empty(&sem->feedback.free_cmds)) {
1931*61046927SAndroid Build Coastguard Worker       sfb_cmd = list_first_entry(&sem->feedback.free_cmds,
1932*61046927SAndroid Build Coastguard Worker                                  struct vn_semaphore_feedback_cmd, head);
1933*61046927SAndroid Build Coastguard Worker       list_move_to(&sfb_cmd->head, &sem->feedback.pending_cmds);
1934*61046927SAndroid Build Coastguard Worker       sem->feedback.free_cmd_count--;
1935*61046927SAndroid Build Coastguard Worker    }
1936*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&sem->feedback.cmd_mtx);
1937*61046927SAndroid Build Coastguard Worker 
1938*61046927SAndroid Build Coastguard Worker    if (!sfb_cmd) {
1939*61046927SAndroid Build Coastguard Worker       sfb_cmd = vn_semaphore_feedback_cmd_alloc(dev, sem->feedback.slot);
1940*61046927SAndroid Build Coastguard Worker 
1941*61046927SAndroid Build Coastguard Worker       simple_mtx_lock(&sem->feedback.cmd_mtx);
1942*61046927SAndroid Build Coastguard Worker       list_add(&sfb_cmd->head, &sem->feedback.pending_cmds);
1943*61046927SAndroid Build Coastguard Worker       simple_mtx_unlock(&sem->feedback.cmd_mtx);
1944*61046927SAndroid Build Coastguard Worker    }
1945*61046927SAndroid Build Coastguard Worker 
1946*61046927SAndroid Build Coastguard Worker    return sfb_cmd;
1947*61046927SAndroid Build Coastguard Worker }
1948*61046927SAndroid Build Coastguard Worker 
1949*61046927SAndroid Build Coastguard Worker static VkResult
vn_semaphore_feedback_init(struct vn_device * dev,struct vn_semaphore * sem,uint64_t initial_value,const VkAllocationCallbacks * alloc)1950*61046927SAndroid Build Coastguard Worker vn_semaphore_feedback_init(struct vn_device *dev,
1951*61046927SAndroid Build Coastguard Worker                            struct vn_semaphore *sem,
1952*61046927SAndroid Build Coastguard Worker                            uint64_t initial_value,
1953*61046927SAndroid Build Coastguard Worker                            const VkAllocationCallbacks *alloc)
1954*61046927SAndroid Build Coastguard Worker {
1955*61046927SAndroid Build Coastguard Worker    struct vn_feedback_slot *slot;
1956*61046927SAndroid Build Coastguard Worker 
1957*61046927SAndroid Build Coastguard Worker    assert(sem->type == VK_SEMAPHORE_TYPE_TIMELINE);
1958*61046927SAndroid Build Coastguard Worker 
1959*61046927SAndroid Build Coastguard Worker    if (sem->is_external)
1960*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
1961*61046927SAndroid Build Coastguard Worker 
1962*61046927SAndroid Build Coastguard Worker    if (VN_PERF(NO_SEMAPHORE_FEEDBACK))
1963*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
1964*61046927SAndroid Build Coastguard Worker 
1965*61046927SAndroid Build Coastguard Worker    slot =
1966*61046927SAndroid Build Coastguard Worker       vn_feedback_pool_alloc(&dev->feedback_pool, VN_FEEDBACK_TYPE_SEMAPHORE);
1967*61046927SAndroid Build Coastguard Worker    if (!slot)
1968*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
1969*61046927SAndroid Build Coastguard Worker 
1970*61046927SAndroid Build Coastguard Worker    list_inithead(&sem->feedback.pending_cmds);
1971*61046927SAndroid Build Coastguard Worker    list_inithead(&sem->feedback.free_cmds);
1972*61046927SAndroid Build Coastguard Worker 
1973*61046927SAndroid Build Coastguard Worker    vn_feedback_set_counter(slot, initial_value);
1974*61046927SAndroid Build Coastguard Worker 
1975*61046927SAndroid Build Coastguard Worker    simple_mtx_init(&sem->feedback.cmd_mtx, mtx_plain);
1976*61046927SAndroid Build Coastguard Worker    simple_mtx_init(&sem->feedback.async_wait_mtx, mtx_plain);
1977*61046927SAndroid Build Coastguard Worker 
1978*61046927SAndroid Build Coastguard Worker    sem->feedback.signaled_counter = initial_value;
1979*61046927SAndroid Build Coastguard Worker    sem->feedback.slot = slot;
1980*61046927SAndroid Build Coastguard Worker 
1981*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1982*61046927SAndroid Build Coastguard Worker }
1983*61046927SAndroid Build Coastguard Worker 
1984*61046927SAndroid Build Coastguard Worker static void
vn_semaphore_feedback_fini(struct vn_device * dev,struct vn_semaphore * sem)1985*61046927SAndroid Build Coastguard Worker vn_semaphore_feedback_fini(struct vn_device *dev, struct vn_semaphore *sem)
1986*61046927SAndroid Build Coastguard Worker {
1987*61046927SAndroid Build Coastguard Worker    if (!sem->feedback.slot)
1988*61046927SAndroid Build Coastguard Worker       return;
1989*61046927SAndroid Build Coastguard Worker 
1990*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe(struct vn_semaphore_feedback_cmd, sfb_cmd,
1991*61046927SAndroid Build Coastguard Worker                             &sem->feedback.free_cmds, head)
1992*61046927SAndroid Build Coastguard Worker       vn_semaphore_feedback_cmd_free(dev, sfb_cmd);
1993*61046927SAndroid Build Coastguard Worker 
1994*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe(struct vn_semaphore_feedback_cmd, sfb_cmd,
1995*61046927SAndroid Build Coastguard Worker                             &sem->feedback.pending_cmds, head)
1996*61046927SAndroid Build Coastguard Worker       vn_semaphore_feedback_cmd_free(dev, sfb_cmd);
1997*61046927SAndroid Build Coastguard Worker 
1998*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&sem->feedback.cmd_mtx);
1999*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&sem->feedback.async_wait_mtx);
2000*61046927SAndroid Build Coastguard Worker 
2001*61046927SAndroid Build Coastguard Worker    vn_feedback_pool_free(&dev->feedback_pool, sem->feedback.slot);
2002*61046927SAndroid Build Coastguard Worker }
2003*61046927SAndroid Build Coastguard Worker 
2004*61046927SAndroid Build Coastguard Worker VkResult
vn_CreateSemaphore(VkDevice device,const VkSemaphoreCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSemaphore * pSemaphore)2005*61046927SAndroid Build Coastguard Worker vn_CreateSemaphore(VkDevice device,
2006*61046927SAndroid Build Coastguard Worker                    const VkSemaphoreCreateInfo *pCreateInfo,
2007*61046927SAndroid Build Coastguard Worker                    const VkAllocationCallbacks *pAllocator,
2008*61046927SAndroid Build Coastguard Worker                    VkSemaphore *pSemaphore)
2009*61046927SAndroid Build Coastguard Worker {
2010*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
2011*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
2012*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc =
2013*61046927SAndroid Build Coastguard Worker       pAllocator ? pAllocator : &dev->base.base.alloc;
2014*61046927SAndroid Build Coastguard Worker 
2015*61046927SAndroid Build Coastguard Worker    struct vn_semaphore *sem = vk_zalloc(alloc, sizeof(*sem), VN_DEFAULT_ALIGN,
2016*61046927SAndroid Build Coastguard Worker                                         VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2017*61046927SAndroid Build Coastguard Worker    if (!sem)
2018*61046927SAndroid Build Coastguard Worker       return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
2019*61046927SAndroid Build Coastguard Worker 
2020*61046927SAndroid Build Coastguard Worker    vn_object_base_init(&sem->base, VK_OBJECT_TYPE_SEMAPHORE, &dev->base);
2021*61046927SAndroid Build Coastguard Worker 
2022*61046927SAndroid Build Coastguard Worker    const VkSemaphoreTypeCreateInfo *type_info =
2023*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(pCreateInfo->pNext, SEMAPHORE_TYPE_CREATE_INFO);
2024*61046927SAndroid Build Coastguard Worker    uint64_t initial_val = 0;
2025*61046927SAndroid Build Coastguard Worker    if (type_info && type_info->semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE) {
2026*61046927SAndroid Build Coastguard Worker       sem->type = VK_SEMAPHORE_TYPE_TIMELINE;
2027*61046927SAndroid Build Coastguard Worker       initial_val = type_info->initialValue;
2028*61046927SAndroid Build Coastguard Worker    } else {
2029*61046927SAndroid Build Coastguard Worker       sem->type = VK_SEMAPHORE_TYPE_BINARY;
2030*61046927SAndroid Build Coastguard Worker    }
2031*61046927SAndroid Build Coastguard Worker 
2032*61046927SAndroid Build Coastguard Worker    const struct VkExportSemaphoreCreateInfo *export_info =
2033*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(pCreateInfo->pNext, EXPORT_SEMAPHORE_CREATE_INFO);
2034*61046927SAndroid Build Coastguard Worker    sem->is_external = export_info && export_info->handleTypes;
2035*61046927SAndroid Build Coastguard Worker 
2036*61046927SAndroid Build Coastguard Worker    VkResult result = vn_semaphore_init_payloads(dev, sem, initial_val, alloc);
2037*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
2038*61046927SAndroid Build Coastguard Worker       goto out_object_base_fini;
2039*61046927SAndroid Build Coastguard Worker 
2040*61046927SAndroid Build Coastguard Worker    if (sem->type == VK_SEMAPHORE_TYPE_TIMELINE) {
2041*61046927SAndroid Build Coastguard Worker       result = vn_semaphore_feedback_init(dev, sem, initial_val, alloc);
2042*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
2043*61046927SAndroid Build Coastguard Worker          goto out_payloads_fini;
2044*61046927SAndroid Build Coastguard Worker    }
2045*61046927SAndroid Build Coastguard Worker 
2046*61046927SAndroid Build Coastguard Worker    VkSemaphore sem_handle = vn_semaphore_to_handle(sem);
2047*61046927SAndroid Build Coastguard Worker    vn_async_vkCreateSemaphore(dev->primary_ring, device, pCreateInfo, NULL,
2048*61046927SAndroid Build Coastguard Worker                               &sem_handle);
2049*61046927SAndroid Build Coastguard Worker 
2050*61046927SAndroid Build Coastguard Worker    *pSemaphore = sem_handle;
2051*61046927SAndroid Build Coastguard Worker 
2052*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2053*61046927SAndroid Build Coastguard Worker 
2054*61046927SAndroid Build Coastguard Worker out_payloads_fini:
2055*61046927SAndroid Build Coastguard Worker    vn_sync_payload_release(dev, &sem->permanent);
2056*61046927SAndroid Build Coastguard Worker    vn_sync_payload_release(dev, &sem->temporary);
2057*61046927SAndroid Build Coastguard Worker 
2058*61046927SAndroid Build Coastguard Worker out_object_base_fini:
2059*61046927SAndroid Build Coastguard Worker    vn_object_base_fini(&sem->base);
2060*61046927SAndroid Build Coastguard Worker    vk_free(alloc, sem);
2061*61046927SAndroid Build Coastguard Worker    return vn_error(dev->instance, result);
2062*61046927SAndroid Build Coastguard Worker }
2063*61046927SAndroid Build Coastguard Worker 
2064*61046927SAndroid Build Coastguard Worker void
vn_DestroySemaphore(VkDevice device,VkSemaphore semaphore,const VkAllocationCallbacks * pAllocator)2065*61046927SAndroid Build Coastguard Worker vn_DestroySemaphore(VkDevice device,
2066*61046927SAndroid Build Coastguard Worker                     VkSemaphore semaphore,
2067*61046927SAndroid Build Coastguard Worker                     const VkAllocationCallbacks *pAllocator)
2068*61046927SAndroid Build Coastguard Worker {
2069*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
2070*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
2071*61046927SAndroid Build Coastguard Worker    struct vn_semaphore *sem = vn_semaphore_from_handle(semaphore);
2072*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc =
2073*61046927SAndroid Build Coastguard Worker       pAllocator ? pAllocator : &dev->base.base.alloc;
2074*61046927SAndroid Build Coastguard Worker 
2075*61046927SAndroid Build Coastguard Worker    if (!sem)
2076*61046927SAndroid Build Coastguard Worker       return;
2077*61046927SAndroid Build Coastguard Worker 
2078*61046927SAndroid Build Coastguard Worker    vn_async_vkDestroySemaphore(dev->primary_ring, device, semaphore, NULL);
2079*61046927SAndroid Build Coastguard Worker 
2080*61046927SAndroid Build Coastguard Worker    if (sem->type == VK_SEMAPHORE_TYPE_TIMELINE)
2081*61046927SAndroid Build Coastguard Worker       vn_semaphore_feedback_fini(dev, sem);
2082*61046927SAndroid Build Coastguard Worker 
2083*61046927SAndroid Build Coastguard Worker    vn_sync_payload_release(dev, &sem->permanent);
2084*61046927SAndroid Build Coastguard Worker    vn_sync_payload_release(dev, &sem->temporary);
2085*61046927SAndroid Build Coastguard Worker 
2086*61046927SAndroid Build Coastguard Worker    vn_object_base_fini(&sem->base);
2087*61046927SAndroid Build Coastguard Worker    vk_free(alloc, sem);
2088*61046927SAndroid Build Coastguard Worker }
2089*61046927SAndroid Build Coastguard Worker 
2090*61046927SAndroid Build Coastguard Worker VkResult
vn_GetSemaphoreCounterValue(VkDevice device,VkSemaphore semaphore,uint64_t * pValue)2091*61046927SAndroid Build Coastguard Worker vn_GetSemaphoreCounterValue(VkDevice device,
2092*61046927SAndroid Build Coastguard Worker                             VkSemaphore semaphore,
2093*61046927SAndroid Build Coastguard Worker                             uint64_t *pValue)
2094*61046927SAndroid Build Coastguard Worker {
2095*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
2096*61046927SAndroid Build Coastguard Worker    struct vn_semaphore *sem = vn_semaphore_from_handle(semaphore);
2097*61046927SAndroid Build Coastguard Worker    ASSERTED struct vn_sync_payload *payload = sem->payload;
2098*61046927SAndroid Build Coastguard Worker 
2099*61046927SAndroid Build Coastguard Worker    assert(payload->type == VN_SYNC_TYPE_DEVICE_ONLY);
2100*61046927SAndroid Build Coastguard Worker 
2101*61046927SAndroid Build Coastguard Worker    if (sem->feedback.slot) {
2102*61046927SAndroid Build Coastguard Worker       simple_mtx_lock(&sem->feedback.async_wait_mtx);
2103*61046927SAndroid Build Coastguard Worker       const uint64_t counter = vn_feedback_get_counter(sem->feedback.slot);
2104*61046927SAndroid Build Coastguard Worker       if (sem->feedback.signaled_counter < counter) {
2105*61046927SAndroid Build Coastguard Worker          /* When the timeline semaphore feedback slot gets signaled, the real
2106*61046927SAndroid Build Coastguard Worker           * semaphore signal operation follows after but the signaling isr can
2107*61046927SAndroid Build Coastguard Worker           * be deferred or preempted. To avoid racing, we let the renderer
2108*61046927SAndroid Build Coastguard Worker           * wait for the semaphore by sending an asynchronous wait call for
2109*61046927SAndroid Build Coastguard Worker           * the feedback value.
2110*61046927SAndroid Build Coastguard Worker           * We also cache the counter value to only send the async call once
2111*61046927SAndroid Build Coastguard Worker           * per counter value to prevent spamming redundant async wait calls.
2112*61046927SAndroid Build Coastguard Worker           * The cached counter value requires a lock to ensure multiple
2113*61046927SAndroid Build Coastguard Worker           * threads querying for the same value are guaranteed to encode after
2114*61046927SAndroid Build Coastguard Worker           * the async wait call.
2115*61046927SAndroid Build Coastguard Worker           *
2116*61046927SAndroid Build Coastguard Worker           * This also helps resolve synchronization validation errors, because
2117*61046927SAndroid Build Coastguard Worker           * the layer no longer sees any semaphore status checks and falsely
2118*61046927SAndroid Build Coastguard Worker           * believes the caller does not sync.
2119*61046927SAndroid Build Coastguard Worker           */
2120*61046927SAndroid Build Coastguard Worker          VkSemaphoreWaitInfo wait_info = {
2121*61046927SAndroid Build Coastguard Worker             .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
2122*61046927SAndroid Build Coastguard Worker             .pNext = NULL,
2123*61046927SAndroid Build Coastguard Worker             .flags = 0,
2124*61046927SAndroid Build Coastguard Worker             .semaphoreCount = 1,
2125*61046927SAndroid Build Coastguard Worker             .pSemaphores = &semaphore,
2126*61046927SAndroid Build Coastguard Worker             .pValues = &counter,
2127*61046927SAndroid Build Coastguard Worker          };
2128*61046927SAndroid Build Coastguard Worker 
2129*61046927SAndroid Build Coastguard Worker          vn_async_vkWaitSemaphores(dev->primary_ring, device, &wait_info,
2130*61046927SAndroid Build Coastguard Worker                                    UINT64_MAX);
2131*61046927SAndroid Build Coastguard Worker 
2132*61046927SAndroid Build Coastguard Worker          /* search pending cmds for already signaled values */
2133*61046927SAndroid Build Coastguard Worker          simple_mtx_lock(&sem->feedback.cmd_mtx);
2134*61046927SAndroid Build Coastguard Worker          list_for_each_entry_safe(struct vn_semaphore_feedback_cmd, sfb_cmd,
2135*61046927SAndroid Build Coastguard Worker                                   &sem->feedback.pending_cmds, head) {
2136*61046927SAndroid Build Coastguard Worker             if (counter >= vn_feedback_get_counter(sfb_cmd->src_slot)) {
2137*61046927SAndroid Build Coastguard Worker                /* avoid over-caching more than normal runtime usage */
2138*61046927SAndroid Build Coastguard Worker                if (sem->feedback.free_cmd_count > 5) {
2139*61046927SAndroid Build Coastguard Worker                   list_del(&sfb_cmd->head);
2140*61046927SAndroid Build Coastguard Worker                   vn_semaphore_feedback_cmd_free(dev, sfb_cmd);
2141*61046927SAndroid Build Coastguard Worker                } else {
2142*61046927SAndroid Build Coastguard Worker                   list_move_to(&sfb_cmd->head, &sem->feedback.free_cmds);
2143*61046927SAndroid Build Coastguard Worker                   sem->feedback.free_cmd_count++;
2144*61046927SAndroid Build Coastguard Worker                }
2145*61046927SAndroid Build Coastguard Worker             }
2146*61046927SAndroid Build Coastguard Worker          }
2147*61046927SAndroid Build Coastguard Worker          simple_mtx_unlock(&sem->feedback.cmd_mtx);
2148*61046927SAndroid Build Coastguard Worker 
2149*61046927SAndroid Build Coastguard Worker          sem->feedback.signaled_counter = counter;
2150*61046927SAndroid Build Coastguard Worker       }
2151*61046927SAndroid Build Coastguard Worker       simple_mtx_unlock(&sem->feedback.async_wait_mtx);
2152*61046927SAndroid Build Coastguard Worker 
2153*61046927SAndroid Build Coastguard Worker       *pValue = counter;
2154*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
2155*61046927SAndroid Build Coastguard Worker    } else {
2156*61046927SAndroid Build Coastguard Worker       return vn_call_vkGetSemaphoreCounterValue(dev->primary_ring, device,
2157*61046927SAndroid Build Coastguard Worker                                                 semaphore, pValue);
2158*61046927SAndroid Build Coastguard Worker    }
2159*61046927SAndroid Build Coastguard Worker }
2160*61046927SAndroid Build Coastguard Worker 
2161*61046927SAndroid Build Coastguard Worker VkResult
vn_SignalSemaphore(VkDevice device,const VkSemaphoreSignalInfo * pSignalInfo)2162*61046927SAndroid Build Coastguard Worker vn_SignalSemaphore(VkDevice device, const VkSemaphoreSignalInfo *pSignalInfo)
2163*61046927SAndroid Build Coastguard Worker {
2164*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
2165*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
2166*61046927SAndroid Build Coastguard Worker    struct vn_semaphore *sem =
2167*61046927SAndroid Build Coastguard Worker       vn_semaphore_from_handle(pSignalInfo->semaphore);
2168*61046927SAndroid Build Coastguard Worker 
2169*61046927SAndroid Build Coastguard Worker    vn_async_vkSignalSemaphore(dev->primary_ring, device, pSignalInfo);
2170*61046927SAndroid Build Coastguard Worker 
2171*61046927SAndroid Build Coastguard Worker    if (sem->feedback.slot) {
2172*61046927SAndroid Build Coastguard Worker       simple_mtx_lock(&sem->feedback.async_wait_mtx);
2173*61046927SAndroid Build Coastguard Worker 
2174*61046927SAndroid Build Coastguard Worker       vn_feedback_set_counter(sem->feedback.slot, pSignalInfo->value);
2175*61046927SAndroid Build Coastguard Worker       /* Update async counters. Since we're signaling, we're aligned with
2176*61046927SAndroid Build Coastguard Worker        * the renderer.
2177*61046927SAndroid Build Coastguard Worker        */
2178*61046927SAndroid Build Coastguard Worker       sem->feedback.signaled_counter = pSignalInfo->value;
2179*61046927SAndroid Build Coastguard Worker 
2180*61046927SAndroid Build Coastguard Worker       simple_mtx_unlock(&sem->feedback.async_wait_mtx);
2181*61046927SAndroid Build Coastguard Worker    }
2182*61046927SAndroid Build Coastguard Worker 
2183*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2184*61046927SAndroid Build Coastguard Worker }
2185*61046927SAndroid Build Coastguard Worker 
2186*61046927SAndroid Build Coastguard Worker static VkResult
vn_find_first_signaled_semaphore(VkDevice device,const VkSemaphore * semaphores,const uint64_t * values,uint32_t count)2187*61046927SAndroid Build Coastguard Worker vn_find_first_signaled_semaphore(VkDevice device,
2188*61046927SAndroid Build Coastguard Worker                                  const VkSemaphore *semaphores,
2189*61046927SAndroid Build Coastguard Worker                                  const uint64_t *values,
2190*61046927SAndroid Build Coastguard Worker                                  uint32_t count)
2191*61046927SAndroid Build Coastguard Worker {
2192*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < count; i++) {
2193*61046927SAndroid Build Coastguard Worker       uint64_t val = 0;
2194*61046927SAndroid Build Coastguard Worker       VkResult result =
2195*61046927SAndroid Build Coastguard Worker          vn_GetSemaphoreCounterValue(device, semaphores[i], &val);
2196*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS || val >= values[i])
2197*61046927SAndroid Build Coastguard Worker          return result;
2198*61046927SAndroid Build Coastguard Worker    }
2199*61046927SAndroid Build Coastguard Worker    return VK_NOT_READY;
2200*61046927SAndroid Build Coastguard Worker }
2201*61046927SAndroid Build Coastguard Worker 
2202*61046927SAndroid Build Coastguard Worker static VkResult
vn_remove_signaled_semaphores(VkDevice device,VkSemaphore * semaphores,uint64_t * values,uint32_t * count)2203*61046927SAndroid Build Coastguard Worker vn_remove_signaled_semaphores(VkDevice device,
2204*61046927SAndroid Build Coastguard Worker                               VkSemaphore *semaphores,
2205*61046927SAndroid Build Coastguard Worker                               uint64_t *values,
2206*61046927SAndroid Build Coastguard Worker                               uint32_t *count)
2207*61046927SAndroid Build Coastguard Worker {
2208*61046927SAndroid Build Coastguard Worker    uint32_t cur = 0;
2209*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < *count; i++) {
2210*61046927SAndroid Build Coastguard Worker       uint64_t val = 0;
2211*61046927SAndroid Build Coastguard Worker       VkResult result =
2212*61046927SAndroid Build Coastguard Worker          vn_GetSemaphoreCounterValue(device, semaphores[i], &val);
2213*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
2214*61046927SAndroid Build Coastguard Worker          return result;
2215*61046927SAndroid Build Coastguard Worker       if (val < values[i])
2216*61046927SAndroid Build Coastguard Worker          semaphores[cur++] = semaphores[i];
2217*61046927SAndroid Build Coastguard Worker    }
2218*61046927SAndroid Build Coastguard Worker 
2219*61046927SAndroid Build Coastguard Worker    *count = cur;
2220*61046927SAndroid Build Coastguard Worker    return cur ? VK_NOT_READY : VK_SUCCESS;
2221*61046927SAndroid Build Coastguard Worker }
2222*61046927SAndroid Build Coastguard Worker 
2223*61046927SAndroid Build Coastguard Worker VkResult
vn_WaitSemaphores(VkDevice device,const VkSemaphoreWaitInfo * pWaitInfo,uint64_t timeout)2224*61046927SAndroid Build Coastguard Worker vn_WaitSemaphores(VkDevice device,
2225*61046927SAndroid Build Coastguard Worker                   const VkSemaphoreWaitInfo *pWaitInfo,
2226*61046927SAndroid Build Coastguard Worker                   uint64_t timeout)
2227*61046927SAndroid Build Coastguard Worker {
2228*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
2229*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
2230*61046927SAndroid Build Coastguard Worker 
2231*61046927SAndroid Build Coastguard Worker    const int64_t abs_timeout = os_time_get_absolute_timeout(timeout);
2232*61046927SAndroid Build Coastguard Worker    VkResult result = VK_NOT_READY;
2233*61046927SAndroid Build Coastguard Worker    if (pWaitInfo->semaphoreCount > 1 &&
2234*61046927SAndroid Build Coastguard Worker        !(pWaitInfo->flags & VK_SEMAPHORE_WAIT_ANY_BIT)) {
2235*61046927SAndroid Build Coastguard Worker       uint32_t semaphore_count = pWaitInfo->semaphoreCount;
2236*61046927SAndroid Build Coastguard Worker       STACK_ARRAY(VkSemaphore, semaphores, semaphore_count);
2237*61046927SAndroid Build Coastguard Worker       STACK_ARRAY(uint64_t, values, semaphore_count);
2238*61046927SAndroid Build Coastguard Worker       typed_memcpy(semaphores, pWaitInfo->pSemaphores, semaphore_count);
2239*61046927SAndroid Build Coastguard Worker       typed_memcpy(values, pWaitInfo->pValues, semaphore_count);
2240*61046927SAndroid Build Coastguard Worker 
2241*61046927SAndroid Build Coastguard Worker       struct vn_relax_state relax_state =
2242*61046927SAndroid Build Coastguard Worker          vn_relax_init(dev->instance, VN_RELAX_REASON_SEMAPHORE);
2243*61046927SAndroid Build Coastguard Worker       while (result == VK_NOT_READY) {
2244*61046927SAndroid Build Coastguard Worker          result = vn_remove_signaled_semaphores(device, semaphores, values,
2245*61046927SAndroid Build Coastguard Worker                                                 &semaphore_count);
2246*61046927SAndroid Build Coastguard Worker          result =
2247*61046927SAndroid Build Coastguard Worker             vn_update_sync_result(dev, result, abs_timeout, &relax_state);
2248*61046927SAndroid Build Coastguard Worker       }
2249*61046927SAndroid Build Coastguard Worker       vn_relax_fini(&relax_state);
2250*61046927SAndroid Build Coastguard Worker 
2251*61046927SAndroid Build Coastguard Worker       STACK_ARRAY_FINISH(semaphores);
2252*61046927SAndroid Build Coastguard Worker       STACK_ARRAY_FINISH(values);
2253*61046927SAndroid Build Coastguard Worker    } else {
2254*61046927SAndroid Build Coastguard Worker       struct vn_relax_state relax_state =
2255*61046927SAndroid Build Coastguard Worker          vn_relax_init(dev->instance, VN_RELAX_REASON_SEMAPHORE);
2256*61046927SAndroid Build Coastguard Worker       while (result == VK_NOT_READY) {
2257*61046927SAndroid Build Coastguard Worker          result = vn_find_first_signaled_semaphore(
2258*61046927SAndroid Build Coastguard Worker             device, pWaitInfo->pSemaphores, pWaitInfo->pValues,
2259*61046927SAndroid Build Coastguard Worker             pWaitInfo->semaphoreCount);
2260*61046927SAndroid Build Coastguard Worker          result =
2261*61046927SAndroid Build Coastguard Worker             vn_update_sync_result(dev, result, abs_timeout, &relax_state);
2262*61046927SAndroid Build Coastguard Worker       }
2263*61046927SAndroid Build Coastguard Worker       vn_relax_fini(&relax_state);
2264*61046927SAndroid Build Coastguard Worker    }
2265*61046927SAndroid Build Coastguard Worker 
2266*61046927SAndroid Build Coastguard Worker    return vn_result(dev->instance, result);
2267*61046927SAndroid Build Coastguard Worker }
2268*61046927SAndroid Build Coastguard Worker 
2269*61046927SAndroid Build Coastguard Worker VkResult
vn_ImportSemaphoreFdKHR(VkDevice device,const VkImportSemaphoreFdInfoKHR * pImportSemaphoreFdInfo)2270*61046927SAndroid Build Coastguard Worker vn_ImportSemaphoreFdKHR(
2271*61046927SAndroid Build Coastguard Worker    VkDevice device, const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo)
2272*61046927SAndroid Build Coastguard Worker {
2273*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
2274*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
2275*61046927SAndroid Build Coastguard Worker    struct vn_semaphore *sem =
2276*61046927SAndroid Build Coastguard Worker       vn_semaphore_from_handle(pImportSemaphoreFdInfo->semaphore);
2277*61046927SAndroid Build Coastguard Worker    ASSERTED const bool sync_file =
2278*61046927SAndroid Build Coastguard Worker       pImportSemaphoreFdInfo->handleType ==
2279*61046927SAndroid Build Coastguard Worker       VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
2280*61046927SAndroid Build Coastguard Worker    const int fd = pImportSemaphoreFdInfo->fd;
2281*61046927SAndroid Build Coastguard Worker 
2282*61046927SAndroid Build Coastguard Worker    assert(sync_file);
2283*61046927SAndroid Build Coastguard Worker 
2284*61046927SAndroid Build Coastguard Worker    if (!vn_sync_valid_fd(fd))
2285*61046927SAndroid Build Coastguard Worker       return vn_error(dev->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
2286*61046927SAndroid Build Coastguard Worker 
2287*61046927SAndroid Build Coastguard Worker    struct vn_sync_payload *temp = &sem->temporary;
2288*61046927SAndroid Build Coastguard Worker    vn_sync_payload_release(dev, temp);
2289*61046927SAndroid Build Coastguard Worker    temp->type = VN_SYNC_TYPE_IMPORTED_SYNC_FD;
2290*61046927SAndroid Build Coastguard Worker    temp->fd = fd;
2291*61046927SAndroid Build Coastguard Worker    sem->payload = temp;
2292*61046927SAndroid Build Coastguard Worker 
2293*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2294*61046927SAndroid Build Coastguard Worker }
2295*61046927SAndroid Build Coastguard Worker 
2296*61046927SAndroid Build Coastguard Worker VkResult
vn_GetSemaphoreFdKHR(VkDevice device,const VkSemaphoreGetFdInfoKHR * pGetFdInfo,int * pFd)2297*61046927SAndroid Build Coastguard Worker vn_GetSemaphoreFdKHR(VkDevice device,
2298*61046927SAndroid Build Coastguard Worker                      const VkSemaphoreGetFdInfoKHR *pGetFdInfo,
2299*61046927SAndroid Build Coastguard Worker                      int *pFd)
2300*61046927SAndroid Build Coastguard Worker {
2301*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
2302*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
2303*61046927SAndroid Build Coastguard Worker    struct vn_semaphore *sem = vn_semaphore_from_handle(pGetFdInfo->semaphore);
2304*61046927SAndroid Build Coastguard Worker    const bool sync_file =
2305*61046927SAndroid Build Coastguard Worker       pGetFdInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
2306*61046927SAndroid Build Coastguard Worker    struct vn_sync_payload *payload = sem->payload;
2307*61046927SAndroid Build Coastguard Worker 
2308*61046927SAndroid Build Coastguard Worker    assert(sync_file);
2309*61046927SAndroid Build Coastguard Worker    assert(dev->physical_device->renderer_sync_fd.semaphore_exportable);
2310*61046927SAndroid Build Coastguard Worker    assert(dev->physical_device->renderer_sync_fd.semaphore_importable);
2311*61046927SAndroid Build Coastguard Worker 
2312*61046927SAndroid Build Coastguard Worker    int fd = -1;
2313*61046927SAndroid Build Coastguard Worker    if (payload->type == VN_SYNC_TYPE_DEVICE_ONLY) {
2314*61046927SAndroid Build Coastguard Worker       VkResult result = vn_create_sync_file(dev, &sem->external_payload, &fd);
2315*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
2316*61046927SAndroid Build Coastguard Worker          return vn_error(dev->instance, result);
2317*61046927SAndroid Build Coastguard Worker 
2318*61046927SAndroid Build Coastguard Worker #ifdef VN_USE_WSI_PLATFORM
2319*61046927SAndroid Build Coastguard Worker       if (!dev->renderer->info.has_implicit_fencing)
2320*61046927SAndroid Build Coastguard Worker          sync_wait(fd, -1);
2321*61046927SAndroid Build Coastguard Worker #endif
2322*61046927SAndroid Build Coastguard Worker    } else {
2323*61046927SAndroid Build Coastguard Worker       assert(payload->type == VN_SYNC_TYPE_IMPORTED_SYNC_FD);
2324*61046927SAndroid Build Coastguard Worker 
2325*61046927SAndroid Build Coastguard Worker       /* transfer ownership of imported sync fd to save a dup */
2326*61046927SAndroid Build Coastguard Worker       fd = payload->fd;
2327*61046927SAndroid Build Coastguard Worker       payload->fd = -1;
2328*61046927SAndroid Build Coastguard Worker    }
2329*61046927SAndroid Build Coastguard Worker 
2330*61046927SAndroid Build Coastguard Worker    /* When payload->type is VN_SYNC_TYPE_IMPORTED_SYNC_FD, the current
2331*61046927SAndroid Build Coastguard Worker     * payload is from a prior temporary sync_fd import. The permanent
2332*61046927SAndroid Build Coastguard Worker     * payload of the sempahore might be in signaled state. So we do an
2333*61046927SAndroid Build Coastguard Worker     * import here to ensure later wait operation is legit. With resourceId
2334*61046927SAndroid Build Coastguard Worker     * 0, renderer does a signaled sync_fd -1 payload import on the host
2335*61046927SAndroid Build Coastguard Worker     * semaphore.
2336*61046927SAndroid Build Coastguard Worker     */
2337*61046927SAndroid Build Coastguard Worker    if (payload->type == VN_SYNC_TYPE_IMPORTED_SYNC_FD) {
2338*61046927SAndroid Build Coastguard Worker       const VkImportSemaphoreResourceInfoMESA res_info = {
2339*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_RESOURCE_INFO_MESA,
2340*61046927SAndroid Build Coastguard Worker          .semaphore = pGetFdInfo->semaphore,
2341*61046927SAndroid Build Coastguard Worker          .resourceId = 0,
2342*61046927SAndroid Build Coastguard Worker       };
2343*61046927SAndroid Build Coastguard Worker       vn_async_vkImportSemaphoreResourceMESA(dev->primary_ring, device,
2344*61046927SAndroid Build Coastguard Worker                                              &res_info);
2345*61046927SAndroid Build Coastguard Worker    }
2346*61046927SAndroid Build Coastguard Worker 
2347*61046927SAndroid Build Coastguard Worker    /* perform wait operation on the host semaphore */
2348*61046927SAndroid Build Coastguard Worker    vn_async_vkWaitSemaphoreResourceMESA(dev->primary_ring, device,
2349*61046927SAndroid Build Coastguard Worker                                         pGetFdInfo->semaphore);
2350*61046927SAndroid Build Coastguard Worker 
2351*61046927SAndroid Build Coastguard Worker    vn_sync_payload_release(dev, &sem->temporary);
2352*61046927SAndroid Build Coastguard Worker    sem->payload = &sem->permanent;
2353*61046927SAndroid Build Coastguard Worker 
2354*61046927SAndroid Build Coastguard Worker    *pFd = fd;
2355*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2356*61046927SAndroid Build Coastguard Worker }
2357*61046927SAndroid Build Coastguard Worker 
2358*61046927SAndroid Build Coastguard Worker /* event commands */
2359*61046927SAndroid Build Coastguard Worker 
2360*61046927SAndroid Build Coastguard Worker static VkResult
vn_event_feedback_init(struct vn_device * dev,struct vn_event * ev)2361*61046927SAndroid Build Coastguard Worker vn_event_feedback_init(struct vn_device *dev, struct vn_event *ev)
2362*61046927SAndroid Build Coastguard Worker {
2363*61046927SAndroid Build Coastguard Worker    struct vn_feedback_slot *slot;
2364*61046927SAndroid Build Coastguard Worker 
2365*61046927SAndroid Build Coastguard Worker    if (VN_PERF(NO_EVENT_FEEDBACK))
2366*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
2367*61046927SAndroid Build Coastguard Worker 
2368*61046927SAndroid Build Coastguard Worker    slot = vn_feedback_pool_alloc(&dev->feedback_pool, VN_FEEDBACK_TYPE_EVENT);
2369*61046927SAndroid Build Coastguard Worker    if (!slot)
2370*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
2371*61046927SAndroid Build Coastguard Worker 
2372*61046927SAndroid Build Coastguard Worker    /* newly created event object is in the unsignaled state */
2373*61046927SAndroid Build Coastguard Worker    vn_feedback_set_status(slot, VK_EVENT_RESET);
2374*61046927SAndroid Build Coastguard Worker 
2375*61046927SAndroid Build Coastguard Worker    ev->feedback_slot = slot;
2376*61046927SAndroid Build Coastguard Worker 
2377*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2378*61046927SAndroid Build Coastguard Worker }
2379*61046927SAndroid Build Coastguard Worker 
2380*61046927SAndroid Build Coastguard Worker static inline void
vn_event_feedback_fini(struct vn_device * dev,struct vn_event * ev)2381*61046927SAndroid Build Coastguard Worker vn_event_feedback_fini(struct vn_device *dev, struct vn_event *ev)
2382*61046927SAndroid Build Coastguard Worker {
2383*61046927SAndroid Build Coastguard Worker    if (ev->feedback_slot)
2384*61046927SAndroid Build Coastguard Worker       vn_feedback_pool_free(&dev->feedback_pool, ev->feedback_slot);
2385*61046927SAndroid Build Coastguard Worker }
2386*61046927SAndroid Build Coastguard Worker 
2387*61046927SAndroid Build Coastguard Worker VkResult
vn_CreateEvent(VkDevice device,const VkEventCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkEvent * pEvent)2388*61046927SAndroid Build Coastguard Worker vn_CreateEvent(VkDevice device,
2389*61046927SAndroid Build Coastguard Worker                const VkEventCreateInfo *pCreateInfo,
2390*61046927SAndroid Build Coastguard Worker                const VkAllocationCallbacks *pAllocator,
2391*61046927SAndroid Build Coastguard Worker                VkEvent *pEvent)
2392*61046927SAndroid Build Coastguard Worker {
2393*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
2394*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
2395*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc =
2396*61046927SAndroid Build Coastguard Worker       pAllocator ? pAllocator : &dev->base.base.alloc;
2397*61046927SAndroid Build Coastguard Worker 
2398*61046927SAndroid Build Coastguard Worker    struct vn_event *ev = vk_zalloc(alloc, sizeof(*ev), VN_DEFAULT_ALIGN,
2399*61046927SAndroid Build Coastguard Worker                                    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2400*61046927SAndroid Build Coastguard Worker    if (!ev)
2401*61046927SAndroid Build Coastguard Worker       return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
2402*61046927SAndroid Build Coastguard Worker 
2403*61046927SAndroid Build Coastguard Worker    vn_object_base_init(&ev->base, VK_OBJECT_TYPE_EVENT, &dev->base);
2404*61046927SAndroid Build Coastguard Worker 
2405*61046927SAndroid Build Coastguard Worker    /* feedback is only needed to speed up host operations */
2406*61046927SAndroid Build Coastguard Worker    if (!(pCreateInfo->flags & VK_EVENT_CREATE_DEVICE_ONLY_BIT)) {
2407*61046927SAndroid Build Coastguard Worker       VkResult result = vn_event_feedback_init(dev, ev);
2408*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
2409*61046927SAndroid Build Coastguard Worker          return vn_error(dev->instance, result);
2410*61046927SAndroid Build Coastguard Worker    }
2411*61046927SAndroid Build Coastguard Worker 
2412*61046927SAndroid Build Coastguard Worker    VkEvent ev_handle = vn_event_to_handle(ev);
2413*61046927SAndroid Build Coastguard Worker    vn_async_vkCreateEvent(dev->primary_ring, device, pCreateInfo, NULL,
2414*61046927SAndroid Build Coastguard Worker                           &ev_handle);
2415*61046927SAndroid Build Coastguard Worker 
2416*61046927SAndroid Build Coastguard Worker    *pEvent = ev_handle;
2417*61046927SAndroid Build Coastguard Worker 
2418*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2419*61046927SAndroid Build Coastguard Worker }
2420*61046927SAndroid Build Coastguard Worker 
2421*61046927SAndroid Build Coastguard Worker void
vn_DestroyEvent(VkDevice device,VkEvent event,const VkAllocationCallbacks * pAllocator)2422*61046927SAndroid Build Coastguard Worker vn_DestroyEvent(VkDevice device,
2423*61046927SAndroid Build Coastguard Worker                 VkEvent event,
2424*61046927SAndroid Build Coastguard Worker                 const VkAllocationCallbacks *pAllocator)
2425*61046927SAndroid Build Coastguard Worker {
2426*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
2427*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
2428*61046927SAndroid Build Coastguard Worker    struct vn_event *ev = vn_event_from_handle(event);
2429*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc =
2430*61046927SAndroid Build Coastguard Worker       pAllocator ? pAllocator : &dev->base.base.alloc;
2431*61046927SAndroid Build Coastguard Worker 
2432*61046927SAndroid Build Coastguard Worker    if (!ev)
2433*61046927SAndroid Build Coastguard Worker       return;
2434*61046927SAndroid Build Coastguard Worker 
2435*61046927SAndroid Build Coastguard Worker    vn_async_vkDestroyEvent(dev->primary_ring, device, event, NULL);
2436*61046927SAndroid Build Coastguard Worker 
2437*61046927SAndroid Build Coastguard Worker    vn_event_feedback_fini(dev, ev);
2438*61046927SAndroid Build Coastguard Worker 
2439*61046927SAndroid Build Coastguard Worker    vn_object_base_fini(&ev->base);
2440*61046927SAndroid Build Coastguard Worker    vk_free(alloc, ev);
2441*61046927SAndroid Build Coastguard Worker }
2442*61046927SAndroid Build Coastguard Worker 
2443*61046927SAndroid Build Coastguard Worker VkResult
vn_GetEventStatus(VkDevice device,VkEvent event)2444*61046927SAndroid Build Coastguard Worker vn_GetEventStatus(VkDevice device, VkEvent event)
2445*61046927SAndroid Build Coastguard Worker {
2446*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
2447*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
2448*61046927SAndroid Build Coastguard Worker    struct vn_event *ev = vn_event_from_handle(event);
2449*61046927SAndroid Build Coastguard Worker    VkResult result;
2450*61046927SAndroid Build Coastguard Worker 
2451*61046927SAndroid Build Coastguard Worker    if (ev->feedback_slot)
2452*61046927SAndroid Build Coastguard Worker       result = vn_feedback_get_status(ev->feedback_slot);
2453*61046927SAndroid Build Coastguard Worker    else
2454*61046927SAndroid Build Coastguard Worker       result = vn_call_vkGetEventStatus(dev->primary_ring, device, event);
2455*61046927SAndroid Build Coastguard Worker 
2456*61046927SAndroid Build Coastguard Worker    return vn_result(dev->instance, result);
2457*61046927SAndroid Build Coastguard Worker }
2458*61046927SAndroid Build Coastguard Worker 
2459*61046927SAndroid Build Coastguard Worker VkResult
vn_SetEvent(VkDevice device,VkEvent event)2460*61046927SAndroid Build Coastguard Worker vn_SetEvent(VkDevice device, VkEvent event)
2461*61046927SAndroid Build Coastguard Worker {
2462*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
2463*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
2464*61046927SAndroid Build Coastguard Worker    struct vn_event *ev = vn_event_from_handle(event);
2465*61046927SAndroid Build Coastguard Worker 
2466*61046927SAndroid Build Coastguard Worker    if (ev->feedback_slot) {
2467*61046927SAndroid Build Coastguard Worker       vn_feedback_set_status(ev->feedback_slot, VK_EVENT_SET);
2468*61046927SAndroid Build Coastguard Worker       vn_async_vkSetEvent(dev->primary_ring, device, event);
2469*61046927SAndroid Build Coastguard Worker    } else {
2470*61046927SAndroid Build Coastguard Worker       VkResult result = vn_call_vkSetEvent(dev->primary_ring, device, event);
2471*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
2472*61046927SAndroid Build Coastguard Worker          return vn_error(dev->instance, result);
2473*61046927SAndroid Build Coastguard Worker    }
2474*61046927SAndroid Build Coastguard Worker 
2475*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2476*61046927SAndroid Build Coastguard Worker }
2477*61046927SAndroid Build Coastguard Worker 
2478*61046927SAndroid Build Coastguard Worker VkResult
vn_ResetEvent(VkDevice device,VkEvent event)2479*61046927SAndroid Build Coastguard Worker vn_ResetEvent(VkDevice device, VkEvent event)
2480*61046927SAndroid Build Coastguard Worker {
2481*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
2482*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
2483*61046927SAndroid Build Coastguard Worker    struct vn_event *ev = vn_event_from_handle(event);
2484*61046927SAndroid Build Coastguard Worker 
2485*61046927SAndroid Build Coastguard Worker    if (ev->feedback_slot) {
2486*61046927SAndroid Build Coastguard Worker       vn_feedback_reset_status(ev->feedback_slot);
2487*61046927SAndroid Build Coastguard Worker       vn_async_vkResetEvent(dev->primary_ring, device, event);
2488*61046927SAndroid Build Coastguard Worker    } else {
2489*61046927SAndroid Build Coastguard Worker       VkResult result =
2490*61046927SAndroid Build Coastguard Worker          vn_call_vkResetEvent(dev->primary_ring, device, event);
2491*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
2492*61046927SAndroid Build Coastguard Worker          return vn_error(dev->instance, result);
2493*61046927SAndroid Build Coastguard Worker    }
2494*61046927SAndroid Build Coastguard Worker 
2495*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2496*61046927SAndroid Build Coastguard Worker }
2497