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