1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2022 Imagination Technologies Ltd.
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * based in part on radv driver which is:
5*61046927SAndroid Build Coastguard Worker * Copyright © 2016 Red Hat.
6*61046927SAndroid Build Coastguard Worker * Copyright © 2016 Bas Nieuwenhuizen
7*61046927SAndroid Build Coastguard Worker *
8*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a copy
9*61046927SAndroid Build Coastguard Worker * of this software and associated documentation files (the "Software"), to deal
10*61046927SAndroid Build Coastguard Worker * in the Software without restriction, including without limitation the rights
11*61046927SAndroid Build Coastguard Worker * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12*61046927SAndroid Build Coastguard Worker * copies of the Software, and to permit persons to whom the Software is
13*61046927SAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions:
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
16*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
17*61046927SAndroid Build Coastguard Worker * Software.
18*61046927SAndroid Build Coastguard Worker *
19*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22*61046927SAndroid Build Coastguard Worker * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24*61046927SAndroid Build Coastguard Worker * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25*61046927SAndroid Build Coastguard Worker * SOFTWARE.
26*61046927SAndroid Build Coastguard Worker */
27*61046927SAndroid Build Coastguard Worker
28*61046927SAndroid Build Coastguard Worker /**
29*61046927SAndroid Build Coastguard Worker * This file implements VkQueue, VkFence, and VkSemaphore
30*61046927SAndroid Build Coastguard Worker */
31*61046927SAndroid Build Coastguard Worker
32*61046927SAndroid Build Coastguard Worker #include <assert.h>
33*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
34*61046927SAndroid Build Coastguard Worker #include <stddef.h>
35*61046927SAndroid Build Coastguard Worker #include <stdint.h>
36*61046927SAndroid Build Coastguard Worker #include <unistd.h>
37*61046927SAndroid Build Coastguard Worker #include <vulkan/vulkan.h>
38*61046927SAndroid Build Coastguard Worker
39*61046927SAndroid Build Coastguard Worker #include "pvr_job_compute.h"
40*61046927SAndroid Build Coastguard Worker #include "pvr_job_context.h"
41*61046927SAndroid Build Coastguard Worker #include "pvr_job_render.h"
42*61046927SAndroid Build Coastguard Worker #include "pvr_job_transfer.h"
43*61046927SAndroid Build Coastguard Worker #include "pvr_limits.h"
44*61046927SAndroid Build Coastguard Worker #include "pvr_private.h"
45*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
46*61046927SAndroid Build Coastguard Worker #include "util/u_atomic.h"
47*61046927SAndroid Build Coastguard Worker #include "vk_alloc.h"
48*61046927SAndroid Build Coastguard Worker #include "vk_fence.h"
49*61046927SAndroid Build Coastguard Worker #include "vk_log.h"
50*61046927SAndroid Build Coastguard Worker #include "vk_object.h"
51*61046927SAndroid Build Coastguard Worker #include "vk_queue.h"
52*61046927SAndroid Build Coastguard Worker #include "vk_semaphore.h"
53*61046927SAndroid Build Coastguard Worker #include "vk_sync.h"
54*61046927SAndroid Build Coastguard Worker #include "vk_sync_dummy.h"
55*61046927SAndroid Build Coastguard Worker #include "vk_util.h"
56*61046927SAndroid Build Coastguard Worker
57*61046927SAndroid Build Coastguard Worker static VkResult pvr_driver_queue_submit(struct vk_queue *queue,
58*61046927SAndroid Build Coastguard Worker struct vk_queue_submit *submit);
59*61046927SAndroid Build Coastguard Worker
pvr_queue_init(struct pvr_device * device,struct pvr_queue * queue,const VkDeviceQueueCreateInfo * pCreateInfo,uint32_t index_in_family)60*61046927SAndroid Build Coastguard Worker static VkResult pvr_queue_init(struct pvr_device *device,
61*61046927SAndroid Build Coastguard Worker struct pvr_queue *queue,
62*61046927SAndroid Build Coastguard Worker const VkDeviceQueueCreateInfo *pCreateInfo,
63*61046927SAndroid Build Coastguard Worker uint32_t index_in_family)
64*61046927SAndroid Build Coastguard Worker {
65*61046927SAndroid Build Coastguard Worker struct pvr_transfer_ctx *transfer_ctx;
66*61046927SAndroid Build Coastguard Worker struct pvr_compute_ctx *compute_ctx;
67*61046927SAndroid Build Coastguard Worker struct pvr_compute_ctx *query_ctx;
68*61046927SAndroid Build Coastguard Worker struct pvr_render_ctx *gfx_ctx;
69*61046927SAndroid Build Coastguard Worker VkResult result;
70*61046927SAndroid Build Coastguard Worker
71*61046927SAndroid Build Coastguard Worker *queue = (struct pvr_queue){ 0 };
72*61046927SAndroid Build Coastguard Worker
73*61046927SAndroid Build Coastguard Worker result =
74*61046927SAndroid Build Coastguard Worker vk_queue_init(&queue->vk, &device->vk, pCreateInfo, index_in_family);
75*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
76*61046927SAndroid Build Coastguard Worker return result;
77*61046927SAndroid Build Coastguard Worker
78*61046927SAndroid Build Coastguard Worker if (device->ws->features.supports_threaded_submit) {
79*61046927SAndroid Build Coastguard Worker result = vk_queue_enable_submit_thread(&queue->vk);
80*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
81*61046927SAndroid Build Coastguard Worker goto err_vk_queue_finish;
82*61046927SAndroid Build Coastguard Worker }
83*61046927SAndroid Build Coastguard Worker
84*61046927SAndroid Build Coastguard Worker result = pvr_transfer_ctx_create(device,
85*61046927SAndroid Build Coastguard Worker PVR_WINSYS_CTX_PRIORITY_MEDIUM,
86*61046927SAndroid Build Coastguard Worker &transfer_ctx);
87*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
88*61046927SAndroid Build Coastguard Worker goto err_vk_queue_finish;
89*61046927SAndroid Build Coastguard Worker
90*61046927SAndroid Build Coastguard Worker result = pvr_compute_ctx_create(device,
91*61046927SAndroid Build Coastguard Worker PVR_WINSYS_CTX_PRIORITY_MEDIUM,
92*61046927SAndroid Build Coastguard Worker &compute_ctx);
93*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
94*61046927SAndroid Build Coastguard Worker goto err_transfer_ctx_destroy;
95*61046927SAndroid Build Coastguard Worker
96*61046927SAndroid Build Coastguard Worker result = pvr_compute_ctx_create(device,
97*61046927SAndroid Build Coastguard Worker PVR_WINSYS_CTX_PRIORITY_MEDIUM,
98*61046927SAndroid Build Coastguard Worker &query_ctx);
99*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
100*61046927SAndroid Build Coastguard Worker goto err_compute_ctx_destroy;
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Worker result =
103*61046927SAndroid Build Coastguard Worker pvr_render_ctx_create(device, PVR_WINSYS_CTX_PRIORITY_MEDIUM, &gfx_ctx);
104*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
105*61046927SAndroid Build Coastguard Worker goto err_query_ctx_destroy;
106*61046927SAndroid Build Coastguard Worker
107*61046927SAndroid Build Coastguard Worker queue->device = device;
108*61046927SAndroid Build Coastguard Worker queue->gfx_ctx = gfx_ctx;
109*61046927SAndroid Build Coastguard Worker queue->compute_ctx = compute_ctx;
110*61046927SAndroid Build Coastguard Worker queue->query_ctx = query_ctx;
111*61046927SAndroid Build Coastguard Worker queue->transfer_ctx = transfer_ctx;
112*61046927SAndroid Build Coastguard Worker
113*61046927SAndroid Build Coastguard Worker queue->vk.driver_submit = pvr_driver_queue_submit;
114*61046927SAndroid Build Coastguard Worker
115*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
116*61046927SAndroid Build Coastguard Worker
117*61046927SAndroid Build Coastguard Worker err_query_ctx_destroy:
118*61046927SAndroid Build Coastguard Worker pvr_compute_ctx_destroy(query_ctx);
119*61046927SAndroid Build Coastguard Worker
120*61046927SAndroid Build Coastguard Worker err_compute_ctx_destroy:
121*61046927SAndroid Build Coastguard Worker pvr_compute_ctx_destroy(compute_ctx);
122*61046927SAndroid Build Coastguard Worker
123*61046927SAndroid Build Coastguard Worker err_transfer_ctx_destroy:
124*61046927SAndroid Build Coastguard Worker pvr_transfer_ctx_destroy(transfer_ctx);
125*61046927SAndroid Build Coastguard Worker
126*61046927SAndroid Build Coastguard Worker err_vk_queue_finish:
127*61046927SAndroid Build Coastguard Worker vk_queue_finish(&queue->vk);
128*61046927SAndroid Build Coastguard Worker
129*61046927SAndroid Build Coastguard Worker return result;
130*61046927SAndroid Build Coastguard Worker }
131*61046927SAndroid Build Coastguard Worker
pvr_queues_create(struct pvr_device * device,const VkDeviceCreateInfo * pCreateInfo)132*61046927SAndroid Build Coastguard Worker VkResult pvr_queues_create(struct pvr_device *device,
133*61046927SAndroid Build Coastguard Worker const VkDeviceCreateInfo *pCreateInfo)
134*61046927SAndroid Build Coastguard Worker {
135*61046927SAndroid Build Coastguard Worker VkResult result;
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Worker /* Check requested queue families and queues */
138*61046927SAndroid Build Coastguard Worker assert(pCreateInfo->queueCreateInfoCount == 1);
139*61046927SAndroid Build Coastguard Worker assert(pCreateInfo->pQueueCreateInfos[0].queueFamilyIndex == 0);
140*61046927SAndroid Build Coastguard Worker assert(pCreateInfo->pQueueCreateInfos[0].queueCount <= PVR_MAX_QUEUES);
141*61046927SAndroid Build Coastguard Worker
142*61046927SAndroid Build Coastguard Worker const VkDeviceQueueCreateInfo *queue_create =
143*61046927SAndroid Build Coastguard Worker &pCreateInfo->pQueueCreateInfos[0];
144*61046927SAndroid Build Coastguard Worker
145*61046927SAndroid Build Coastguard Worker device->queues = vk_alloc(&device->vk.alloc,
146*61046927SAndroid Build Coastguard Worker queue_create->queueCount * sizeof(*device->queues),
147*61046927SAndroid Build Coastguard Worker 8,
148*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
149*61046927SAndroid Build Coastguard Worker if (!device->queues)
150*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
151*61046927SAndroid Build Coastguard Worker
152*61046927SAndroid Build Coastguard Worker device->queue_count = 0;
153*61046927SAndroid Build Coastguard Worker
154*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < queue_create->queueCount; i++) {
155*61046927SAndroid Build Coastguard Worker result = pvr_queue_init(device, &device->queues[i], queue_create, i);
156*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
157*61046927SAndroid Build Coastguard Worker goto err_queues_finish;
158*61046927SAndroid Build Coastguard Worker
159*61046927SAndroid Build Coastguard Worker device->queue_count++;
160*61046927SAndroid Build Coastguard Worker }
161*61046927SAndroid Build Coastguard Worker
162*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
163*61046927SAndroid Build Coastguard Worker
164*61046927SAndroid Build Coastguard Worker err_queues_finish:
165*61046927SAndroid Build Coastguard Worker pvr_queues_destroy(device);
166*61046927SAndroid Build Coastguard Worker return result;
167*61046927SAndroid Build Coastguard Worker }
168*61046927SAndroid Build Coastguard Worker
pvr_queue_finish(struct pvr_queue * queue)169*61046927SAndroid Build Coastguard Worker static void pvr_queue_finish(struct pvr_queue *queue)
170*61046927SAndroid Build Coastguard Worker {
171*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < ARRAY_SIZE(queue->next_job_wait_sync); i++) {
172*61046927SAndroid Build Coastguard Worker if (queue->next_job_wait_sync[i])
173*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&queue->device->vk, queue->next_job_wait_sync[i]);
174*61046927SAndroid Build Coastguard Worker }
175*61046927SAndroid Build Coastguard Worker
176*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < ARRAY_SIZE(queue->last_job_signal_sync); i++) {
177*61046927SAndroid Build Coastguard Worker if (queue->last_job_signal_sync[i])
178*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&queue->device->vk, queue->last_job_signal_sync[i]);
179*61046927SAndroid Build Coastguard Worker }
180*61046927SAndroid Build Coastguard Worker
181*61046927SAndroid Build Coastguard Worker pvr_render_ctx_destroy(queue->gfx_ctx);
182*61046927SAndroid Build Coastguard Worker pvr_compute_ctx_destroy(queue->query_ctx);
183*61046927SAndroid Build Coastguard Worker pvr_compute_ctx_destroy(queue->compute_ctx);
184*61046927SAndroid Build Coastguard Worker pvr_transfer_ctx_destroy(queue->transfer_ctx);
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker vk_queue_finish(&queue->vk);
187*61046927SAndroid Build Coastguard Worker }
188*61046927SAndroid Build Coastguard Worker
pvr_queues_destroy(struct pvr_device * device)189*61046927SAndroid Build Coastguard Worker void pvr_queues_destroy(struct pvr_device *device)
190*61046927SAndroid Build Coastguard Worker {
191*61046927SAndroid Build Coastguard Worker for (uint32_t q_idx = 0; q_idx < device->queue_count; q_idx++)
192*61046927SAndroid Build Coastguard Worker pvr_queue_finish(&device->queues[q_idx]);
193*61046927SAndroid Build Coastguard Worker
194*61046927SAndroid Build Coastguard Worker vk_free(&device->vk.alloc, device->queues);
195*61046927SAndroid Build Coastguard Worker }
196*61046927SAndroid Build Coastguard Worker
pvr_update_job_syncs(struct pvr_device * device,struct pvr_queue * queue,struct vk_sync * new_signal_sync,enum pvr_job_type submitted_job_type)197*61046927SAndroid Build Coastguard Worker static void pvr_update_job_syncs(struct pvr_device *device,
198*61046927SAndroid Build Coastguard Worker struct pvr_queue *queue,
199*61046927SAndroid Build Coastguard Worker struct vk_sync *new_signal_sync,
200*61046927SAndroid Build Coastguard Worker enum pvr_job_type submitted_job_type)
201*61046927SAndroid Build Coastguard Worker {
202*61046927SAndroid Build Coastguard Worker if (queue->next_job_wait_sync[submitted_job_type]) {
203*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&device->vk,
204*61046927SAndroid Build Coastguard Worker queue->next_job_wait_sync[submitted_job_type]);
205*61046927SAndroid Build Coastguard Worker queue->next_job_wait_sync[submitted_job_type] = NULL;
206*61046927SAndroid Build Coastguard Worker }
207*61046927SAndroid Build Coastguard Worker
208*61046927SAndroid Build Coastguard Worker if (queue->last_job_signal_sync[submitted_job_type]) {
209*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&device->vk,
210*61046927SAndroid Build Coastguard Worker queue->last_job_signal_sync[submitted_job_type]);
211*61046927SAndroid Build Coastguard Worker }
212*61046927SAndroid Build Coastguard Worker
213*61046927SAndroid Build Coastguard Worker queue->last_job_signal_sync[submitted_job_type] = new_signal_sync;
214*61046927SAndroid Build Coastguard Worker }
215*61046927SAndroid Build Coastguard Worker
pvr_process_graphics_cmd(struct pvr_device * device,struct pvr_queue * queue,struct pvr_cmd_buffer * cmd_buffer,struct pvr_sub_cmd_gfx * sub_cmd)216*61046927SAndroid Build Coastguard Worker static VkResult pvr_process_graphics_cmd(struct pvr_device *device,
217*61046927SAndroid Build Coastguard Worker struct pvr_queue *queue,
218*61046927SAndroid Build Coastguard Worker struct pvr_cmd_buffer *cmd_buffer,
219*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_gfx *sub_cmd)
220*61046927SAndroid Build Coastguard Worker {
221*61046927SAndroid Build Coastguard Worker pvr_dev_addr_t original_ctrl_stream_addr = { 0 };
222*61046927SAndroid Build Coastguard Worker struct vk_sync *geom_signal_sync;
223*61046927SAndroid Build Coastguard Worker struct vk_sync *frag_signal_sync = NULL;
224*61046927SAndroid Build Coastguard Worker VkResult result;
225*61046927SAndroid Build Coastguard Worker
226*61046927SAndroid Build Coastguard Worker result = vk_sync_create(&device->vk,
227*61046927SAndroid Build Coastguard Worker &device->pdevice->ws->syncobj_type,
228*61046927SAndroid Build Coastguard Worker 0U,
229*61046927SAndroid Build Coastguard Worker 0UL,
230*61046927SAndroid Build Coastguard Worker &geom_signal_sync);
231*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
232*61046927SAndroid Build Coastguard Worker return result;
233*61046927SAndroid Build Coastguard Worker
234*61046927SAndroid Build Coastguard Worker if (sub_cmd->job.run_frag) {
235*61046927SAndroid Build Coastguard Worker result = vk_sync_create(&device->vk,
236*61046927SAndroid Build Coastguard Worker &device->pdevice->ws->syncobj_type,
237*61046927SAndroid Build Coastguard Worker 0U,
238*61046927SAndroid Build Coastguard Worker 0UL,
239*61046927SAndroid Build Coastguard Worker &frag_signal_sync);
240*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
241*61046927SAndroid Build Coastguard Worker goto err_destroy_geom_sync;
242*61046927SAndroid Build Coastguard Worker }
243*61046927SAndroid Build Coastguard Worker
244*61046927SAndroid Build Coastguard Worker /* FIXME: DoShadowLoadOrStore() */
245*61046927SAndroid Build Coastguard Worker
246*61046927SAndroid Build Coastguard Worker /* Perform two render submits when using multiple framebuffer layers. The
247*61046927SAndroid Build Coastguard Worker * first submit contains just geometry, while the second only terminates
248*61046927SAndroid Build Coastguard Worker * (and triggers the fragment render if originally specified). This is needed
249*61046927SAndroid Build Coastguard Worker * because the render target cache gets cleared on terminating submits, which
250*61046927SAndroid Build Coastguard Worker * could result in missing primitives.
251*61046927SAndroid Build Coastguard Worker */
252*61046927SAndroid Build Coastguard Worker if (pvr_sub_cmd_gfx_requires_split_submit(sub_cmd)) {
253*61046927SAndroid Build Coastguard Worker /* If fragment work shouldn't be run there's no need for a split,
254*61046927SAndroid Build Coastguard Worker * and if geometry_terminate is false this kick can't have a fragment
255*61046927SAndroid Build Coastguard Worker * stage without another terminating geometry kick.
256*61046927SAndroid Build Coastguard Worker */
257*61046927SAndroid Build Coastguard Worker assert(sub_cmd->job.geometry_terminate && sub_cmd->job.run_frag);
258*61046927SAndroid Build Coastguard Worker
259*61046927SAndroid Build Coastguard Worker /* First submit must not touch fragment work. */
260*61046927SAndroid Build Coastguard Worker sub_cmd->job.geometry_terminate = false;
261*61046927SAndroid Build Coastguard Worker sub_cmd->job.run_frag = false;
262*61046927SAndroid Build Coastguard Worker
263*61046927SAndroid Build Coastguard Worker result =
264*61046927SAndroid Build Coastguard Worker pvr_render_job_submit(queue->gfx_ctx,
265*61046927SAndroid Build Coastguard Worker &sub_cmd->job,
266*61046927SAndroid Build Coastguard Worker queue->next_job_wait_sync[PVR_JOB_TYPE_GEOM],
267*61046927SAndroid Build Coastguard Worker NULL,
268*61046927SAndroid Build Coastguard Worker NULL,
269*61046927SAndroid Build Coastguard Worker NULL);
270*61046927SAndroid Build Coastguard Worker
271*61046927SAndroid Build Coastguard Worker sub_cmd->job.geometry_terminate = true;
272*61046927SAndroid Build Coastguard Worker sub_cmd->job.run_frag = true;
273*61046927SAndroid Build Coastguard Worker
274*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
275*61046927SAndroid Build Coastguard Worker goto err_destroy_frag_sync;
276*61046927SAndroid Build Coastguard Worker
277*61046927SAndroid Build Coastguard Worker original_ctrl_stream_addr = sub_cmd->job.ctrl_stream_addr;
278*61046927SAndroid Build Coastguard Worker
279*61046927SAndroid Build Coastguard Worker /* Second submit contains only a trivial control stream to terminate the
280*61046927SAndroid Build Coastguard Worker * geometry work.
281*61046927SAndroid Build Coastguard Worker */
282*61046927SAndroid Build Coastguard Worker assert(sub_cmd->terminate_ctrl_stream);
283*61046927SAndroid Build Coastguard Worker sub_cmd->job.ctrl_stream_addr =
284*61046927SAndroid Build Coastguard Worker sub_cmd->terminate_ctrl_stream->vma->dev_addr;
285*61046927SAndroid Build Coastguard Worker }
286*61046927SAndroid Build Coastguard Worker
287*61046927SAndroid Build Coastguard Worker result = pvr_render_job_submit(queue->gfx_ctx,
288*61046927SAndroid Build Coastguard Worker &sub_cmd->job,
289*61046927SAndroid Build Coastguard Worker queue->next_job_wait_sync[PVR_JOB_TYPE_GEOM],
290*61046927SAndroid Build Coastguard Worker queue->next_job_wait_sync[PVR_JOB_TYPE_FRAG],
291*61046927SAndroid Build Coastguard Worker geom_signal_sync,
292*61046927SAndroid Build Coastguard Worker frag_signal_sync);
293*61046927SAndroid Build Coastguard Worker
294*61046927SAndroid Build Coastguard Worker if (original_ctrl_stream_addr.addr > 0)
295*61046927SAndroid Build Coastguard Worker sub_cmd->job.ctrl_stream_addr = original_ctrl_stream_addr;
296*61046927SAndroid Build Coastguard Worker
297*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
298*61046927SAndroid Build Coastguard Worker goto err_destroy_frag_sync;
299*61046927SAndroid Build Coastguard Worker
300*61046927SAndroid Build Coastguard Worker pvr_update_job_syncs(device, queue, geom_signal_sync, PVR_JOB_TYPE_GEOM);
301*61046927SAndroid Build Coastguard Worker
302*61046927SAndroid Build Coastguard Worker if (sub_cmd->job.run_frag)
303*61046927SAndroid Build Coastguard Worker pvr_update_job_syncs(device, queue, frag_signal_sync, PVR_JOB_TYPE_FRAG);
304*61046927SAndroid Build Coastguard Worker
305*61046927SAndroid Build Coastguard Worker /* FIXME: DoShadowLoadOrStore() */
306*61046927SAndroid Build Coastguard Worker
307*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
308*61046927SAndroid Build Coastguard Worker
309*61046927SAndroid Build Coastguard Worker err_destroy_frag_sync:
310*61046927SAndroid Build Coastguard Worker if (frag_signal_sync)
311*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&device->vk, frag_signal_sync);
312*61046927SAndroid Build Coastguard Worker err_destroy_geom_sync:
313*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&device->vk, geom_signal_sync);
314*61046927SAndroid Build Coastguard Worker
315*61046927SAndroid Build Coastguard Worker return result;
316*61046927SAndroid Build Coastguard Worker }
317*61046927SAndroid Build Coastguard Worker
pvr_process_compute_cmd(struct pvr_device * device,struct pvr_queue * queue,struct pvr_sub_cmd_compute * sub_cmd)318*61046927SAndroid Build Coastguard Worker static VkResult pvr_process_compute_cmd(struct pvr_device *device,
319*61046927SAndroid Build Coastguard Worker struct pvr_queue *queue,
320*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_compute *sub_cmd)
321*61046927SAndroid Build Coastguard Worker {
322*61046927SAndroid Build Coastguard Worker struct vk_sync *sync;
323*61046927SAndroid Build Coastguard Worker VkResult result;
324*61046927SAndroid Build Coastguard Worker
325*61046927SAndroid Build Coastguard Worker result = vk_sync_create(&device->vk,
326*61046927SAndroid Build Coastguard Worker &device->pdevice->ws->syncobj_type,
327*61046927SAndroid Build Coastguard Worker 0U,
328*61046927SAndroid Build Coastguard Worker 0UL,
329*61046927SAndroid Build Coastguard Worker &sync);
330*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
331*61046927SAndroid Build Coastguard Worker return result;
332*61046927SAndroid Build Coastguard Worker
333*61046927SAndroid Build Coastguard Worker result =
334*61046927SAndroid Build Coastguard Worker pvr_compute_job_submit(queue->compute_ctx,
335*61046927SAndroid Build Coastguard Worker sub_cmd,
336*61046927SAndroid Build Coastguard Worker queue->next_job_wait_sync[PVR_JOB_TYPE_COMPUTE],
337*61046927SAndroid Build Coastguard Worker sync);
338*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
339*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&device->vk, sync);
340*61046927SAndroid Build Coastguard Worker return result;
341*61046927SAndroid Build Coastguard Worker }
342*61046927SAndroid Build Coastguard Worker
343*61046927SAndroid Build Coastguard Worker pvr_update_job_syncs(device, queue, sync, PVR_JOB_TYPE_COMPUTE);
344*61046927SAndroid Build Coastguard Worker
345*61046927SAndroid Build Coastguard Worker return result;
346*61046927SAndroid Build Coastguard Worker }
347*61046927SAndroid Build Coastguard Worker
pvr_process_transfer_cmds(struct pvr_device * device,struct pvr_queue * queue,struct pvr_sub_cmd_transfer * sub_cmd)348*61046927SAndroid Build Coastguard Worker static VkResult pvr_process_transfer_cmds(struct pvr_device *device,
349*61046927SAndroid Build Coastguard Worker struct pvr_queue *queue,
350*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_transfer *sub_cmd)
351*61046927SAndroid Build Coastguard Worker {
352*61046927SAndroid Build Coastguard Worker struct vk_sync *sync;
353*61046927SAndroid Build Coastguard Worker VkResult result;
354*61046927SAndroid Build Coastguard Worker
355*61046927SAndroid Build Coastguard Worker result = vk_sync_create(&device->vk,
356*61046927SAndroid Build Coastguard Worker &device->pdevice->ws->syncobj_type,
357*61046927SAndroid Build Coastguard Worker 0U,
358*61046927SAndroid Build Coastguard Worker 0UL,
359*61046927SAndroid Build Coastguard Worker &sync);
360*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
361*61046927SAndroid Build Coastguard Worker return result;
362*61046927SAndroid Build Coastguard Worker
363*61046927SAndroid Build Coastguard Worker result =
364*61046927SAndroid Build Coastguard Worker pvr_transfer_job_submit(queue->transfer_ctx,
365*61046927SAndroid Build Coastguard Worker sub_cmd,
366*61046927SAndroid Build Coastguard Worker queue->next_job_wait_sync[PVR_JOB_TYPE_TRANSFER],
367*61046927SAndroid Build Coastguard Worker sync);
368*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
369*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&device->vk, sync);
370*61046927SAndroid Build Coastguard Worker return result;
371*61046927SAndroid Build Coastguard Worker }
372*61046927SAndroid Build Coastguard Worker
373*61046927SAndroid Build Coastguard Worker pvr_update_job_syncs(device, queue, sync, PVR_JOB_TYPE_TRANSFER);
374*61046927SAndroid Build Coastguard Worker
375*61046927SAndroid Build Coastguard Worker return result;
376*61046927SAndroid Build Coastguard Worker }
377*61046927SAndroid Build Coastguard Worker
378*61046927SAndroid Build Coastguard Worker static VkResult
pvr_process_occlusion_query_cmd(struct pvr_device * device,struct pvr_queue * queue,struct pvr_sub_cmd_compute * sub_cmd)379*61046927SAndroid Build Coastguard Worker pvr_process_occlusion_query_cmd(struct pvr_device *device,
380*61046927SAndroid Build Coastguard Worker struct pvr_queue *queue,
381*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_compute *sub_cmd)
382*61046927SAndroid Build Coastguard Worker {
383*61046927SAndroid Build Coastguard Worker struct vk_sync *sync;
384*61046927SAndroid Build Coastguard Worker VkResult result;
385*61046927SAndroid Build Coastguard Worker
386*61046927SAndroid Build Coastguard Worker /* TODO: Currently we add barrier event sub commands to handle the sync
387*61046927SAndroid Build Coastguard Worker * necessary for the different occlusion query types. Would we get any speed
388*61046927SAndroid Build Coastguard Worker * up in processing the queue by doing that sync here without using event sub
389*61046927SAndroid Build Coastguard Worker * commands?
390*61046927SAndroid Build Coastguard Worker */
391*61046927SAndroid Build Coastguard Worker
392*61046927SAndroid Build Coastguard Worker result = vk_sync_create(&device->vk,
393*61046927SAndroid Build Coastguard Worker &device->pdevice->ws->syncobj_type,
394*61046927SAndroid Build Coastguard Worker 0U,
395*61046927SAndroid Build Coastguard Worker 0UL,
396*61046927SAndroid Build Coastguard Worker &sync);
397*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
398*61046927SAndroid Build Coastguard Worker return result;
399*61046927SAndroid Build Coastguard Worker
400*61046927SAndroid Build Coastguard Worker result = pvr_compute_job_submit(
401*61046927SAndroid Build Coastguard Worker queue->query_ctx,
402*61046927SAndroid Build Coastguard Worker sub_cmd,
403*61046927SAndroid Build Coastguard Worker queue->next_job_wait_sync[PVR_JOB_TYPE_OCCLUSION_QUERY],
404*61046927SAndroid Build Coastguard Worker sync);
405*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
406*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&device->vk, sync);
407*61046927SAndroid Build Coastguard Worker return result;
408*61046927SAndroid Build Coastguard Worker }
409*61046927SAndroid Build Coastguard Worker
410*61046927SAndroid Build Coastguard Worker pvr_update_job_syncs(device, queue, sync, PVR_JOB_TYPE_OCCLUSION_QUERY);
411*61046927SAndroid Build Coastguard Worker
412*61046927SAndroid Build Coastguard Worker return result;
413*61046927SAndroid Build Coastguard Worker }
414*61046927SAndroid Build Coastguard Worker
415*61046927SAndroid Build Coastguard Worker static VkResult
pvr_process_event_cmd_barrier(struct pvr_device * device,struct pvr_queue * queue,struct pvr_sub_cmd_event_barrier * sub_cmd)416*61046927SAndroid Build Coastguard Worker pvr_process_event_cmd_barrier(struct pvr_device *device,
417*61046927SAndroid Build Coastguard Worker struct pvr_queue *queue,
418*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_event_barrier *sub_cmd)
419*61046927SAndroid Build Coastguard Worker {
420*61046927SAndroid Build Coastguard Worker const uint32_t src_mask = sub_cmd->wait_for_stage_mask;
421*61046927SAndroid Build Coastguard Worker const uint32_t dst_mask = sub_cmd->wait_at_stage_mask;
422*61046927SAndroid Build Coastguard Worker struct vk_sync_wait wait_syncs[PVR_JOB_TYPE_MAX + 1];
423*61046927SAndroid Build Coastguard Worker uint32_t src_wait_count = 0;
424*61046927SAndroid Build Coastguard Worker VkResult result;
425*61046927SAndroid Build Coastguard Worker
426*61046927SAndroid Build Coastguard Worker assert(!(src_mask & ~(PVR_PIPELINE_STAGE_ALL_BITS |
427*61046927SAndroid Build Coastguard Worker PVR_PIPELINE_STAGE_OCCLUSION_QUERY_BIT)));
428*61046927SAndroid Build Coastguard Worker assert(!(dst_mask & ~(PVR_PIPELINE_STAGE_ALL_BITS |
429*61046927SAndroid Build Coastguard Worker PVR_PIPELINE_STAGE_OCCLUSION_QUERY_BIT)));
430*61046927SAndroid Build Coastguard Worker
431*61046927SAndroid Build Coastguard Worker u_foreach_bit (stage, src_mask) {
432*61046927SAndroid Build Coastguard Worker if (queue->last_job_signal_sync[stage]) {
433*61046927SAndroid Build Coastguard Worker wait_syncs[src_wait_count++] = (struct vk_sync_wait){
434*61046927SAndroid Build Coastguard Worker .sync = queue->last_job_signal_sync[stage],
435*61046927SAndroid Build Coastguard Worker .stage_mask = ~(VkPipelineStageFlags2)0,
436*61046927SAndroid Build Coastguard Worker .wait_value = 0,
437*61046927SAndroid Build Coastguard Worker };
438*61046927SAndroid Build Coastguard Worker }
439*61046927SAndroid Build Coastguard Worker }
440*61046927SAndroid Build Coastguard Worker
441*61046927SAndroid Build Coastguard Worker /* No previous src jobs that need finishing so no need for a barrier. */
442*61046927SAndroid Build Coastguard Worker if (src_wait_count == 0)
443*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
444*61046927SAndroid Build Coastguard Worker
445*61046927SAndroid Build Coastguard Worker u_foreach_bit (stage, dst_mask) {
446*61046927SAndroid Build Coastguard Worker uint32_t wait_count = src_wait_count;
447*61046927SAndroid Build Coastguard Worker struct vk_sync_signal signal;
448*61046927SAndroid Build Coastguard Worker struct vk_sync *signal_sync;
449*61046927SAndroid Build Coastguard Worker
450*61046927SAndroid Build Coastguard Worker result = vk_sync_create(&device->vk,
451*61046927SAndroid Build Coastguard Worker &device->pdevice->ws->syncobj_type,
452*61046927SAndroid Build Coastguard Worker 0U,
453*61046927SAndroid Build Coastguard Worker 0UL,
454*61046927SAndroid Build Coastguard Worker &signal_sync);
455*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
456*61046927SAndroid Build Coastguard Worker return result;
457*61046927SAndroid Build Coastguard Worker
458*61046927SAndroid Build Coastguard Worker signal = (struct vk_sync_signal){
459*61046927SAndroid Build Coastguard Worker .sync = signal_sync,
460*61046927SAndroid Build Coastguard Worker .stage_mask = ~(VkPipelineStageFlags2)0,
461*61046927SAndroid Build Coastguard Worker .signal_value = 0,
462*61046927SAndroid Build Coastguard Worker };
463*61046927SAndroid Build Coastguard Worker
464*61046927SAndroid Build Coastguard Worker if (queue->next_job_wait_sync[stage]) {
465*61046927SAndroid Build Coastguard Worker wait_syncs[wait_count++] = (struct vk_sync_wait){
466*61046927SAndroid Build Coastguard Worker .sync = queue->next_job_wait_sync[stage],
467*61046927SAndroid Build Coastguard Worker .stage_mask = ~(VkPipelineStageFlags2)0,
468*61046927SAndroid Build Coastguard Worker .wait_value = 0,
469*61046927SAndroid Build Coastguard Worker };
470*61046927SAndroid Build Coastguard Worker }
471*61046927SAndroid Build Coastguard Worker
472*61046927SAndroid Build Coastguard Worker result = device->ws->ops->null_job_submit(device->ws,
473*61046927SAndroid Build Coastguard Worker wait_syncs,
474*61046927SAndroid Build Coastguard Worker wait_count,
475*61046927SAndroid Build Coastguard Worker &signal);
476*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
477*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&device->vk, signal_sync);
478*61046927SAndroid Build Coastguard Worker return result;
479*61046927SAndroid Build Coastguard Worker }
480*61046927SAndroid Build Coastguard Worker
481*61046927SAndroid Build Coastguard Worker if (queue->next_job_wait_sync[stage])
482*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&device->vk, queue->next_job_wait_sync[stage]);
483*61046927SAndroid Build Coastguard Worker
484*61046927SAndroid Build Coastguard Worker queue->next_job_wait_sync[stage] = signal_sync;
485*61046927SAndroid Build Coastguard Worker }
486*61046927SAndroid Build Coastguard Worker
487*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
488*61046927SAndroid Build Coastguard Worker }
489*61046927SAndroid Build Coastguard Worker
490*61046927SAndroid Build Coastguard Worker static VkResult
pvr_process_event_cmd_set_or_reset(struct pvr_device * device,struct pvr_queue * queue,struct pvr_sub_cmd_event_set_reset * sub_cmd,const enum pvr_event_state new_event_state)491*61046927SAndroid Build Coastguard Worker pvr_process_event_cmd_set_or_reset(struct pvr_device *device,
492*61046927SAndroid Build Coastguard Worker struct pvr_queue *queue,
493*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_event_set_reset *sub_cmd,
494*61046927SAndroid Build Coastguard Worker const enum pvr_event_state new_event_state)
495*61046927SAndroid Build Coastguard Worker {
496*61046927SAndroid Build Coastguard Worker /* Not PVR_JOB_TYPE_MAX since that also includes
497*61046927SAndroid Build Coastguard Worker * PVR_JOB_TYPE_OCCLUSION_QUERY so no stage in the src mask.
498*61046927SAndroid Build Coastguard Worker */
499*61046927SAndroid Build Coastguard Worker struct vk_sync_wait waits[PVR_NUM_SYNC_PIPELINE_STAGES];
500*61046927SAndroid Build Coastguard Worker struct vk_sync_signal signal;
501*61046927SAndroid Build Coastguard Worker struct vk_sync *signal_sync;
502*61046927SAndroid Build Coastguard Worker
503*61046927SAndroid Build Coastguard Worker uint32_t wait_count = 0;
504*61046927SAndroid Build Coastguard Worker VkResult result;
505*61046927SAndroid Build Coastguard Worker
506*61046927SAndroid Build Coastguard Worker assert(!(sub_cmd->wait_for_stage_mask & ~PVR_PIPELINE_STAGE_ALL_BITS));
507*61046927SAndroid Build Coastguard Worker
508*61046927SAndroid Build Coastguard Worker u_foreach_bit (stage, sub_cmd->wait_for_stage_mask) {
509*61046927SAndroid Build Coastguard Worker if (!queue->last_job_signal_sync[stage])
510*61046927SAndroid Build Coastguard Worker continue;
511*61046927SAndroid Build Coastguard Worker
512*61046927SAndroid Build Coastguard Worker waits[wait_count++] = (struct vk_sync_wait){
513*61046927SAndroid Build Coastguard Worker .sync = queue->last_job_signal_sync[stage],
514*61046927SAndroid Build Coastguard Worker .stage_mask = ~(VkPipelineStageFlags2)0,
515*61046927SAndroid Build Coastguard Worker .wait_value = 0,
516*61046927SAndroid Build Coastguard Worker };
517*61046927SAndroid Build Coastguard Worker }
518*61046927SAndroid Build Coastguard Worker
519*61046927SAndroid Build Coastguard Worker result = vk_sync_create(&device->vk,
520*61046927SAndroid Build Coastguard Worker &device->pdevice->ws->syncobj_type,
521*61046927SAndroid Build Coastguard Worker 0U,
522*61046927SAndroid Build Coastguard Worker 0UL,
523*61046927SAndroid Build Coastguard Worker &signal_sync);
524*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
525*61046927SAndroid Build Coastguard Worker return result;
526*61046927SAndroid Build Coastguard Worker
527*61046927SAndroid Build Coastguard Worker signal = (struct vk_sync_signal){
528*61046927SAndroid Build Coastguard Worker .sync = signal_sync,
529*61046927SAndroid Build Coastguard Worker .stage_mask = ~(VkPipelineStageFlags2)0,
530*61046927SAndroid Build Coastguard Worker .signal_value = 0,
531*61046927SAndroid Build Coastguard Worker };
532*61046927SAndroid Build Coastguard Worker
533*61046927SAndroid Build Coastguard Worker result =
534*61046927SAndroid Build Coastguard Worker device->ws->ops->null_job_submit(device->ws, waits, wait_count, &signal);
535*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
536*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&device->vk, signal_sync);
537*61046927SAndroid Build Coastguard Worker return result;
538*61046927SAndroid Build Coastguard Worker }
539*61046927SAndroid Build Coastguard Worker
540*61046927SAndroid Build Coastguard Worker if (sub_cmd->event->sync)
541*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&device->vk, sub_cmd->event->sync);
542*61046927SAndroid Build Coastguard Worker
543*61046927SAndroid Build Coastguard Worker sub_cmd->event->sync = signal_sync;
544*61046927SAndroid Build Coastguard Worker sub_cmd->event->state = new_event_state;
545*61046927SAndroid Build Coastguard Worker
546*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
547*61046927SAndroid Build Coastguard Worker }
548*61046927SAndroid Build Coastguard Worker
549*61046927SAndroid Build Coastguard Worker static inline VkResult
pvr_process_event_cmd_set(struct pvr_device * device,struct pvr_queue * queue,struct pvr_sub_cmd_event_set_reset * sub_cmd)550*61046927SAndroid Build Coastguard Worker pvr_process_event_cmd_set(struct pvr_device *device,
551*61046927SAndroid Build Coastguard Worker struct pvr_queue *queue,
552*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_event_set_reset *sub_cmd)
553*61046927SAndroid Build Coastguard Worker {
554*61046927SAndroid Build Coastguard Worker return pvr_process_event_cmd_set_or_reset(device,
555*61046927SAndroid Build Coastguard Worker queue,
556*61046927SAndroid Build Coastguard Worker sub_cmd,
557*61046927SAndroid Build Coastguard Worker PVR_EVENT_STATE_SET_BY_DEVICE);
558*61046927SAndroid Build Coastguard Worker }
559*61046927SAndroid Build Coastguard Worker
560*61046927SAndroid Build Coastguard Worker static inline VkResult
pvr_process_event_cmd_reset(struct pvr_device * device,struct pvr_queue * queue,struct pvr_sub_cmd_event_set_reset * sub_cmd)561*61046927SAndroid Build Coastguard Worker pvr_process_event_cmd_reset(struct pvr_device *device,
562*61046927SAndroid Build Coastguard Worker struct pvr_queue *queue,
563*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_event_set_reset *sub_cmd)
564*61046927SAndroid Build Coastguard Worker {
565*61046927SAndroid Build Coastguard Worker return pvr_process_event_cmd_set_or_reset(device,
566*61046927SAndroid Build Coastguard Worker queue,
567*61046927SAndroid Build Coastguard Worker sub_cmd,
568*61046927SAndroid Build Coastguard Worker PVR_EVENT_STATE_RESET_BY_DEVICE);
569*61046927SAndroid Build Coastguard Worker }
570*61046927SAndroid Build Coastguard Worker
571*61046927SAndroid Build Coastguard Worker /**
572*61046927SAndroid Build Coastguard Worker * \brief Process an event sub command of wait type.
573*61046927SAndroid Build Coastguard Worker *
574*61046927SAndroid Build Coastguard Worker * This sets up barrier syncobjs to create a dependency from the event syncobjs
575*61046927SAndroid Build Coastguard Worker * onto the next job submissions.
576*61046927SAndroid Build Coastguard Worker *
577*61046927SAndroid Build Coastguard Worker * The barriers are setup by taking into consideration each event's dst stage
578*61046927SAndroid Build Coastguard Worker * mask so this is in line with vkCmdWaitEvents2().
579*61046927SAndroid Build Coastguard Worker *
580*61046927SAndroid Build Coastguard Worker * \param[in] device Device to create the syncobjs on.
581*61046927SAndroid Build Coastguard Worker * \param[in] sub_cmd Sub command to process.
582*61046927SAndroid Build Coastguard Worker * \param[in,out] barriers Current barriers as input. Barriers
583*61046927SAndroid Build Coastguard Worker * for the next jobs as output.
584*61046927SAndroid Build Coastguard Worker * \parma[in,out] per_cmd_buffer_syncobjs Completion syncobjs for the command
585*61046927SAndroid Build Coastguard Worker * buffer being processed.
586*61046927SAndroid Build Coastguard Worker */
587*61046927SAndroid Build Coastguard Worker static VkResult
pvr_process_event_cmd_wait(struct pvr_device * device,struct pvr_queue * queue,struct pvr_sub_cmd_event_wait * sub_cmd)588*61046927SAndroid Build Coastguard Worker pvr_process_event_cmd_wait(struct pvr_device *device,
589*61046927SAndroid Build Coastguard Worker struct pvr_queue *queue,
590*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_event_wait *sub_cmd)
591*61046927SAndroid Build Coastguard Worker {
592*61046927SAndroid Build Coastguard Worker uint32_t dst_mask = 0;
593*61046927SAndroid Build Coastguard Worker VkResult result;
594*61046927SAndroid Build Coastguard Worker
595*61046927SAndroid Build Coastguard Worker STACK_ARRAY(struct vk_sync_wait, waits, sub_cmd->count + 1);
596*61046927SAndroid Build Coastguard Worker if (!waits)
597*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
598*61046927SAndroid Build Coastguard Worker
599*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < sub_cmd->count; i++)
600*61046927SAndroid Build Coastguard Worker dst_mask |= sub_cmd->wait_at_stage_masks[i];
601*61046927SAndroid Build Coastguard Worker
602*61046927SAndroid Build Coastguard Worker u_foreach_bit (stage, dst_mask) {
603*61046927SAndroid Build Coastguard Worker struct vk_sync_signal signal;
604*61046927SAndroid Build Coastguard Worker struct vk_sync *signal_sync;
605*61046927SAndroid Build Coastguard Worker uint32_t wait_count = 0;
606*61046927SAndroid Build Coastguard Worker
607*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < sub_cmd->count; i++) {
608*61046927SAndroid Build Coastguard Worker if (sub_cmd->wait_at_stage_masks[i] & stage) {
609*61046927SAndroid Build Coastguard Worker waits[wait_count++] = (struct vk_sync_wait){
610*61046927SAndroid Build Coastguard Worker .sync = sub_cmd->events[i]->sync,
611*61046927SAndroid Build Coastguard Worker .stage_mask = ~(VkPipelineStageFlags2)0,
612*61046927SAndroid Build Coastguard Worker .wait_value = 0,
613*61046927SAndroid Build Coastguard Worker };
614*61046927SAndroid Build Coastguard Worker }
615*61046927SAndroid Build Coastguard Worker }
616*61046927SAndroid Build Coastguard Worker
617*61046927SAndroid Build Coastguard Worker if (!wait_count)
618*61046927SAndroid Build Coastguard Worker continue;
619*61046927SAndroid Build Coastguard Worker
620*61046927SAndroid Build Coastguard Worker if (queue->next_job_wait_sync[stage]) {
621*61046927SAndroid Build Coastguard Worker waits[wait_count++] = (struct vk_sync_wait){
622*61046927SAndroid Build Coastguard Worker .sync = queue->next_job_wait_sync[stage],
623*61046927SAndroid Build Coastguard Worker .stage_mask = ~(VkPipelineStageFlags2)0,
624*61046927SAndroid Build Coastguard Worker .wait_value = 0,
625*61046927SAndroid Build Coastguard Worker };
626*61046927SAndroid Build Coastguard Worker }
627*61046927SAndroid Build Coastguard Worker
628*61046927SAndroid Build Coastguard Worker assert(wait_count <= (sub_cmd->count + 1));
629*61046927SAndroid Build Coastguard Worker
630*61046927SAndroid Build Coastguard Worker result = vk_sync_create(&device->vk,
631*61046927SAndroid Build Coastguard Worker &device->pdevice->ws->syncobj_type,
632*61046927SAndroid Build Coastguard Worker 0U,
633*61046927SAndroid Build Coastguard Worker 0UL,
634*61046927SAndroid Build Coastguard Worker &signal_sync);
635*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
636*61046927SAndroid Build Coastguard Worker goto err_free_waits;
637*61046927SAndroid Build Coastguard Worker
638*61046927SAndroid Build Coastguard Worker signal = (struct vk_sync_signal){
639*61046927SAndroid Build Coastguard Worker .sync = signal_sync,
640*61046927SAndroid Build Coastguard Worker .stage_mask = ~(VkPipelineStageFlags2)0,
641*61046927SAndroid Build Coastguard Worker .signal_value = 0,
642*61046927SAndroid Build Coastguard Worker };
643*61046927SAndroid Build Coastguard Worker
644*61046927SAndroid Build Coastguard Worker result = device->ws->ops->null_job_submit(device->ws,
645*61046927SAndroid Build Coastguard Worker waits,
646*61046927SAndroid Build Coastguard Worker wait_count,
647*61046927SAndroid Build Coastguard Worker &signal);
648*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
649*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&device->vk, signal.sync);
650*61046927SAndroid Build Coastguard Worker goto err_free_waits;
651*61046927SAndroid Build Coastguard Worker }
652*61046927SAndroid Build Coastguard Worker
653*61046927SAndroid Build Coastguard Worker if (queue->next_job_wait_sync[stage])
654*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&device->vk, queue->next_job_wait_sync[stage]);
655*61046927SAndroid Build Coastguard Worker
656*61046927SAndroid Build Coastguard Worker queue->next_job_wait_sync[stage] = signal.sync;
657*61046927SAndroid Build Coastguard Worker }
658*61046927SAndroid Build Coastguard Worker
659*61046927SAndroid Build Coastguard Worker STACK_ARRAY_FINISH(waits);
660*61046927SAndroid Build Coastguard Worker
661*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
662*61046927SAndroid Build Coastguard Worker
663*61046927SAndroid Build Coastguard Worker err_free_waits:
664*61046927SAndroid Build Coastguard Worker STACK_ARRAY_FINISH(waits);
665*61046927SAndroid Build Coastguard Worker
666*61046927SAndroid Build Coastguard Worker return result;
667*61046927SAndroid Build Coastguard Worker }
668*61046927SAndroid Build Coastguard Worker
pvr_process_event_cmd(struct pvr_device * device,struct pvr_queue * queue,struct pvr_sub_cmd_event * sub_cmd)669*61046927SAndroid Build Coastguard Worker static VkResult pvr_process_event_cmd(struct pvr_device *device,
670*61046927SAndroid Build Coastguard Worker struct pvr_queue *queue,
671*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_event *sub_cmd)
672*61046927SAndroid Build Coastguard Worker {
673*61046927SAndroid Build Coastguard Worker switch (sub_cmd->type) {
674*61046927SAndroid Build Coastguard Worker case PVR_EVENT_TYPE_SET:
675*61046927SAndroid Build Coastguard Worker return pvr_process_event_cmd_set(device, queue, &sub_cmd->set_reset);
676*61046927SAndroid Build Coastguard Worker case PVR_EVENT_TYPE_RESET:
677*61046927SAndroid Build Coastguard Worker return pvr_process_event_cmd_reset(device, queue, &sub_cmd->set_reset);
678*61046927SAndroid Build Coastguard Worker case PVR_EVENT_TYPE_WAIT:
679*61046927SAndroid Build Coastguard Worker return pvr_process_event_cmd_wait(device, queue, &sub_cmd->wait);
680*61046927SAndroid Build Coastguard Worker case PVR_EVENT_TYPE_BARRIER:
681*61046927SAndroid Build Coastguard Worker return pvr_process_event_cmd_barrier(device, queue, &sub_cmd->barrier);
682*61046927SAndroid Build Coastguard Worker default:
683*61046927SAndroid Build Coastguard Worker unreachable("Invalid event sub-command type.");
684*61046927SAndroid Build Coastguard Worker };
685*61046927SAndroid Build Coastguard Worker }
686*61046927SAndroid Build Coastguard Worker
pvr_process_cmd_buffer(struct pvr_device * device,struct pvr_queue * queue,struct pvr_cmd_buffer * cmd_buffer)687*61046927SAndroid Build Coastguard Worker static VkResult pvr_process_cmd_buffer(struct pvr_device *device,
688*61046927SAndroid Build Coastguard Worker struct pvr_queue *queue,
689*61046927SAndroid Build Coastguard Worker struct pvr_cmd_buffer *cmd_buffer)
690*61046927SAndroid Build Coastguard Worker {
691*61046927SAndroid Build Coastguard Worker VkResult result;
692*61046927SAndroid Build Coastguard Worker
693*61046927SAndroid Build Coastguard Worker list_for_each_entry_safe (struct pvr_sub_cmd,
694*61046927SAndroid Build Coastguard Worker sub_cmd,
695*61046927SAndroid Build Coastguard Worker &cmd_buffer->sub_cmds,
696*61046927SAndroid Build Coastguard Worker link) {
697*61046927SAndroid Build Coastguard Worker switch (sub_cmd->type) {
698*61046927SAndroid Build Coastguard Worker case PVR_SUB_CMD_TYPE_GRAPHICS: {
699*61046927SAndroid Build Coastguard Worker /* If the fragment job utilizes occlusion queries, for data integrity
700*61046927SAndroid Build Coastguard Worker * it needs to wait for the occlusion query to be processed.
701*61046927SAndroid Build Coastguard Worker */
702*61046927SAndroid Build Coastguard Worker if (sub_cmd->gfx.has_occlusion_query) {
703*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_event_barrier barrier = {
704*61046927SAndroid Build Coastguard Worker .wait_for_stage_mask = PVR_PIPELINE_STAGE_OCCLUSION_QUERY_BIT,
705*61046927SAndroid Build Coastguard Worker .wait_at_stage_mask = PVR_PIPELINE_STAGE_FRAG_BIT,
706*61046927SAndroid Build Coastguard Worker };
707*61046927SAndroid Build Coastguard Worker
708*61046927SAndroid Build Coastguard Worker result = pvr_process_event_cmd_barrier(device, queue, &barrier);
709*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
710*61046927SAndroid Build Coastguard Worker break;
711*61046927SAndroid Build Coastguard Worker }
712*61046927SAndroid Build Coastguard Worker
713*61046927SAndroid Build Coastguard Worker if (sub_cmd->gfx.wait_on_previous_transfer) {
714*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_event_barrier barrier = {
715*61046927SAndroid Build Coastguard Worker .wait_for_stage_mask = PVR_PIPELINE_STAGE_TRANSFER_BIT,
716*61046927SAndroid Build Coastguard Worker .wait_at_stage_mask = PVR_PIPELINE_STAGE_FRAG_BIT,
717*61046927SAndroid Build Coastguard Worker };
718*61046927SAndroid Build Coastguard Worker
719*61046927SAndroid Build Coastguard Worker result = pvr_process_event_cmd_barrier(device, queue, &barrier);
720*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
721*61046927SAndroid Build Coastguard Worker break;
722*61046927SAndroid Build Coastguard Worker }
723*61046927SAndroid Build Coastguard Worker
724*61046927SAndroid Build Coastguard Worker result =
725*61046927SAndroid Build Coastguard Worker pvr_process_graphics_cmd(device, queue, cmd_buffer, &sub_cmd->gfx);
726*61046927SAndroid Build Coastguard Worker break;
727*61046927SAndroid Build Coastguard Worker }
728*61046927SAndroid Build Coastguard Worker
729*61046927SAndroid Build Coastguard Worker case PVR_SUB_CMD_TYPE_COMPUTE:
730*61046927SAndroid Build Coastguard Worker result = pvr_process_compute_cmd(device, queue, &sub_cmd->compute);
731*61046927SAndroid Build Coastguard Worker break;
732*61046927SAndroid Build Coastguard Worker
733*61046927SAndroid Build Coastguard Worker case PVR_SUB_CMD_TYPE_TRANSFER: {
734*61046927SAndroid Build Coastguard Worker const bool serialize_with_frag = sub_cmd->transfer.serialize_with_frag;
735*61046927SAndroid Build Coastguard Worker
736*61046927SAndroid Build Coastguard Worker if (serialize_with_frag) {
737*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_event_barrier barrier = {
738*61046927SAndroid Build Coastguard Worker .wait_for_stage_mask = PVR_PIPELINE_STAGE_FRAG_BIT,
739*61046927SAndroid Build Coastguard Worker .wait_at_stage_mask = PVR_PIPELINE_STAGE_TRANSFER_BIT,
740*61046927SAndroid Build Coastguard Worker };
741*61046927SAndroid Build Coastguard Worker
742*61046927SAndroid Build Coastguard Worker result = pvr_process_event_cmd_barrier(device, queue, &barrier);
743*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
744*61046927SAndroid Build Coastguard Worker break;
745*61046927SAndroid Build Coastguard Worker }
746*61046927SAndroid Build Coastguard Worker
747*61046927SAndroid Build Coastguard Worker result = pvr_process_transfer_cmds(device, queue, &sub_cmd->transfer);
748*61046927SAndroid Build Coastguard Worker
749*61046927SAndroid Build Coastguard Worker if (serialize_with_frag) {
750*61046927SAndroid Build Coastguard Worker struct pvr_sub_cmd_event_barrier barrier = {
751*61046927SAndroid Build Coastguard Worker .wait_for_stage_mask = PVR_PIPELINE_STAGE_TRANSFER_BIT,
752*61046927SAndroid Build Coastguard Worker .wait_at_stage_mask = PVR_PIPELINE_STAGE_FRAG_BIT,
753*61046927SAndroid Build Coastguard Worker };
754*61046927SAndroid Build Coastguard Worker
755*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
756*61046927SAndroid Build Coastguard Worker break;
757*61046927SAndroid Build Coastguard Worker
758*61046927SAndroid Build Coastguard Worker result = pvr_process_event_cmd_barrier(device, queue, &barrier);
759*61046927SAndroid Build Coastguard Worker }
760*61046927SAndroid Build Coastguard Worker
761*61046927SAndroid Build Coastguard Worker break;
762*61046927SAndroid Build Coastguard Worker }
763*61046927SAndroid Build Coastguard Worker
764*61046927SAndroid Build Coastguard Worker case PVR_SUB_CMD_TYPE_OCCLUSION_QUERY:
765*61046927SAndroid Build Coastguard Worker result =
766*61046927SAndroid Build Coastguard Worker pvr_process_occlusion_query_cmd(device, queue, &sub_cmd->compute);
767*61046927SAndroid Build Coastguard Worker break;
768*61046927SAndroid Build Coastguard Worker
769*61046927SAndroid Build Coastguard Worker case PVR_SUB_CMD_TYPE_EVENT:
770*61046927SAndroid Build Coastguard Worker result = pvr_process_event_cmd(device, queue, &sub_cmd->event);
771*61046927SAndroid Build Coastguard Worker break;
772*61046927SAndroid Build Coastguard Worker
773*61046927SAndroid Build Coastguard Worker default:
774*61046927SAndroid Build Coastguard Worker mesa_loge("Unsupported sub-command type %d", sub_cmd->type);
775*61046927SAndroid Build Coastguard Worker result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
776*61046927SAndroid Build Coastguard Worker }
777*61046927SAndroid Build Coastguard Worker
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 p_atomic_inc(&device->global_cmd_buffer_submit_count);
782*61046927SAndroid Build Coastguard Worker }
783*61046927SAndroid Build Coastguard Worker
784*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
785*61046927SAndroid Build Coastguard Worker }
786*61046927SAndroid Build Coastguard Worker
pvr_clear_last_submits_syncs(struct pvr_queue * queue)787*61046927SAndroid Build Coastguard Worker static VkResult pvr_clear_last_submits_syncs(struct pvr_queue *queue)
788*61046927SAndroid Build Coastguard Worker {
789*61046927SAndroid Build Coastguard Worker struct vk_sync_wait waits[PVR_JOB_TYPE_MAX * 2];
790*61046927SAndroid Build Coastguard Worker uint32_t wait_count = 0;
791*61046927SAndroid Build Coastguard Worker VkResult result;
792*61046927SAndroid Build Coastguard Worker
793*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < PVR_JOB_TYPE_MAX; i++) {
794*61046927SAndroid Build Coastguard Worker if (queue->next_job_wait_sync[i]) {
795*61046927SAndroid Build Coastguard Worker waits[wait_count++] = (struct vk_sync_wait){
796*61046927SAndroid Build Coastguard Worker .sync = queue->next_job_wait_sync[i],
797*61046927SAndroid Build Coastguard Worker .stage_mask = ~(VkPipelineStageFlags2)0,
798*61046927SAndroid Build Coastguard Worker .wait_value = 0,
799*61046927SAndroid Build Coastguard Worker };
800*61046927SAndroid Build Coastguard Worker }
801*61046927SAndroid Build Coastguard Worker
802*61046927SAndroid Build Coastguard Worker if (queue->last_job_signal_sync[i]) {
803*61046927SAndroid Build Coastguard Worker waits[wait_count++] = (struct vk_sync_wait){
804*61046927SAndroid Build Coastguard Worker .sync = queue->last_job_signal_sync[i],
805*61046927SAndroid Build Coastguard Worker .stage_mask = ~(VkPipelineStageFlags2)0,
806*61046927SAndroid Build Coastguard Worker .wait_value = 0,
807*61046927SAndroid Build Coastguard Worker };
808*61046927SAndroid Build Coastguard Worker }
809*61046927SAndroid Build Coastguard Worker }
810*61046927SAndroid Build Coastguard Worker
811*61046927SAndroid Build Coastguard Worker result = vk_sync_wait_many(&queue->device->vk,
812*61046927SAndroid Build Coastguard Worker wait_count,
813*61046927SAndroid Build Coastguard Worker waits,
814*61046927SAndroid Build Coastguard Worker VK_SYNC_WAIT_COMPLETE,
815*61046927SAndroid Build Coastguard Worker UINT64_MAX);
816*61046927SAndroid Build Coastguard Worker
817*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
818*61046927SAndroid Build Coastguard Worker return vk_error(queue, result);
819*61046927SAndroid Build Coastguard Worker
820*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < PVR_JOB_TYPE_MAX; i++) {
821*61046927SAndroid Build Coastguard Worker if (queue->next_job_wait_sync[i]) {
822*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&queue->device->vk, queue->next_job_wait_sync[i]);
823*61046927SAndroid Build Coastguard Worker queue->next_job_wait_sync[i] = NULL;
824*61046927SAndroid Build Coastguard Worker }
825*61046927SAndroid Build Coastguard Worker
826*61046927SAndroid Build Coastguard Worker if (queue->last_job_signal_sync[i]) {
827*61046927SAndroid Build Coastguard Worker vk_sync_destroy(&queue->device->vk, queue->last_job_signal_sync[i]);
828*61046927SAndroid Build Coastguard Worker queue->last_job_signal_sync[i] = NULL;
829*61046927SAndroid Build Coastguard Worker }
830*61046927SAndroid Build Coastguard Worker }
831*61046927SAndroid Build Coastguard Worker
832*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
833*61046927SAndroid Build Coastguard Worker }
834*61046927SAndroid Build Coastguard Worker
pvr_process_queue_signals(struct pvr_queue * queue,struct vk_sync_signal * signals,uint32_t signal_count)835*61046927SAndroid Build Coastguard Worker static VkResult pvr_process_queue_signals(struct pvr_queue *queue,
836*61046927SAndroid Build Coastguard Worker struct vk_sync_signal *signals,
837*61046927SAndroid Build Coastguard Worker uint32_t signal_count)
838*61046927SAndroid Build Coastguard Worker {
839*61046927SAndroid Build Coastguard Worker struct vk_sync_wait signal_waits[PVR_JOB_TYPE_MAX];
840*61046927SAndroid Build Coastguard Worker struct pvr_device *device = queue->device;
841*61046927SAndroid Build Coastguard Worker VkResult result;
842*61046927SAndroid Build Coastguard Worker
843*61046927SAndroid Build Coastguard Worker for (uint32_t signal_idx = 0; signal_idx < signal_count; signal_idx++) {
844*61046927SAndroid Build Coastguard Worker struct vk_sync_signal *signal = &signals[signal_idx];
845*61046927SAndroid Build Coastguard Worker const enum pvr_pipeline_stage_bits signal_stage_src =
846*61046927SAndroid Build Coastguard Worker pvr_stage_mask_src(signal->stage_mask);
847*61046927SAndroid Build Coastguard Worker uint32_t wait_count = 0;
848*61046927SAndroid Build Coastguard Worker
849*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < PVR_JOB_TYPE_MAX; i++) {
850*61046927SAndroid Build Coastguard Worker /* Exception for occlusion query jobs since that's something internal,
851*61046927SAndroid Build Coastguard Worker * so the user provided syncs won't ever have it as a source stage.
852*61046927SAndroid Build Coastguard Worker */
853*61046927SAndroid Build Coastguard Worker if (!(signal_stage_src & BITFIELD_BIT(i)) &&
854*61046927SAndroid Build Coastguard Worker i != PVR_JOB_TYPE_OCCLUSION_QUERY)
855*61046927SAndroid Build Coastguard Worker continue;
856*61046927SAndroid Build Coastguard Worker
857*61046927SAndroid Build Coastguard Worker if (!queue->last_job_signal_sync[i])
858*61046927SAndroid Build Coastguard Worker continue;
859*61046927SAndroid Build Coastguard Worker
860*61046927SAndroid Build Coastguard Worker signal_waits[wait_count++] = (struct vk_sync_wait){
861*61046927SAndroid Build Coastguard Worker .sync = queue->last_job_signal_sync[i],
862*61046927SAndroid Build Coastguard Worker .stage_mask = ~(VkPipelineStageFlags2)0,
863*61046927SAndroid Build Coastguard Worker .wait_value = 0,
864*61046927SAndroid Build Coastguard Worker };
865*61046927SAndroid Build Coastguard Worker }
866*61046927SAndroid Build Coastguard Worker
867*61046927SAndroid Build Coastguard Worker result = device->ws->ops->null_job_submit(device->ws,
868*61046927SAndroid Build Coastguard Worker signal_waits,
869*61046927SAndroid Build Coastguard Worker wait_count,
870*61046927SAndroid Build Coastguard Worker signal);
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
875*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
876*61046927SAndroid Build Coastguard Worker }
877*61046927SAndroid Build Coastguard Worker
pvr_process_queue_waits(struct pvr_queue * queue,struct vk_sync_wait * waits,uint32_t wait_count)878*61046927SAndroid Build Coastguard Worker static VkResult pvr_process_queue_waits(struct pvr_queue *queue,
879*61046927SAndroid Build Coastguard Worker struct vk_sync_wait *waits,
880*61046927SAndroid Build Coastguard Worker uint32_t wait_count)
881*61046927SAndroid Build Coastguard Worker {
882*61046927SAndroid Build Coastguard Worker struct pvr_device *device = queue->device;
883*61046927SAndroid Build Coastguard Worker VkResult result;
884*61046927SAndroid Build Coastguard Worker
885*61046927SAndroid Build Coastguard Worker STACK_ARRAY(struct vk_sync_wait, stage_waits, wait_count);
886*61046927SAndroid Build Coastguard Worker if (!stage_waits)
887*61046927SAndroid Build Coastguard Worker return vk_error(queue, VK_ERROR_OUT_OF_HOST_MEMORY);
888*61046927SAndroid Build Coastguard Worker
889*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < PVR_JOB_TYPE_MAX; i++) {
890*61046927SAndroid Build Coastguard Worker struct vk_sync_signal next_job_wait_signal_sync;
891*61046927SAndroid Build Coastguard Worker uint32_t stage_wait_count = 0;
892*61046927SAndroid Build Coastguard Worker
893*61046927SAndroid Build Coastguard Worker for (uint32_t wait_idx = 0; wait_idx < wait_count; wait_idx++) {
894*61046927SAndroid Build Coastguard Worker if (!(pvr_stage_mask(waits[wait_idx].stage_mask) & BITFIELD_BIT(i)))
895*61046927SAndroid Build Coastguard Worker continue;
896*61046927SAndroid Build Coastguard Worker
897*61046927SAndroid Build Coastguard Worker stage_waits[stage_wait_count++] = (struct vk_sync_wait){
898*61046927SAndroid Build Coastguard Worker .sync = waits[wait_idx].sync,
899*61046927SAndroid Build Coastguard Worker .stage_mask = ~(VkPipelineStageFlags2)0,
900*61046927SAndroid Build Coastguard Worker .wait_value = waits[wait_idx].wait_value,
901*61046927SAndroid Build Coastguard Worker };
902*61046927SAndroid Build Coastguard Worker }
903*61046927SAndroid Build Coastguard Worker
904*61046927SAndroid Build Coastguard Worker result = vk_sync_create(&device->vk,
905*61046927SAndroid Build Coastguard Worker &device->pdevice->ws->syncobj_type,
906*61046927SAndroid Build Coastguard Worker 0U,
907*61046927SAndroid Build Coastguard Worker 0UL,
908*61046927SAndroid Build Coastguard Worker &queue->next_job_wait_sync[i]);
909*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
910*61046927SAndroid Build Coastguard Worker goto err_free_waits;
911*61046927SAndroid Build Coastguard Worker
912*61046927SAndroid Build Coastguard Worker next_job_wait_signal_sync = (struct vk_sync_signal){
913*61046927SAndroid Build Coastguard Worker .sync = queue->next_job_wait_sync[i],
914*61046927SAndroid Build Coastguard Worker .stage_mask = ~(VkPipelineStageFlags2)0,
915*61046927SAndroid Build Coastguard Worker .signal_value = 0,
916*61046927SAndroid Build Coastguard Worker };
917*61046927SAndroid Build Coastguard Worker
918*61046927SAndroid Build Coastguard Worker result = device->ws->ops->null_job_submit(device->ws,
919*61046927SAndroid Build Coastguard Worker stage_waits,
920*61046927SAndroid Build Coastguard Worker stage_wait_count,
921*61046927SAndroid Build Coastguard Worker &next_job_wait_signal_sync);
922*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
923*61046927SAndroid Build Coastguard Worker goto err_free_waits;
924*61046927SAndroid Build Coastguard Worker }
925*61046927SAndroid Build Coastguard Worker
926*61046927SAndroid Build Coastguard Worker STACK_ARRAY_FINISH(stage_waits);
927*61046927SAndroid Build Coastguard Worker
928*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
929*61046927SAndroid Build Coastguard Worker
930*61046927SAndroid Build Coastguard Worker err_free_waits:
931*61046927SAndroid Build Coastguard Worker STACK_ARRAY_FINISH(stage_waits);
932*61046927SAndroid Build Coastguard Worker
933*61046927SAndroid Build Coastguard Worker return result;
934*61046927SAndroid Build Coastguard Worker }
935*61046927SAndroid Build Coastguard Worker
pvr_driver_queue_submit(struct vk_queue * queue,struct vk_queue_submit * submit)936*61046927SAndroid Build Coastguard Worker static VkResult pvr_driver_queue_submit(struct vk_queue *queue,
937*61046927SAndroid Build Coastguard Worker struct vk_queue_submit *submit)
938*61046927SAndroid Build Coastguard Worker {
939*61046927SAndroid Build Coastguard Worker struct pvr_queue *driver_queue = container_of(queue, struct pvr_queue, vk);
940*61046927SAndroid Build Coastguard Worker struct pvr_device *device = driver_queue->device;
941*61046927SAndroid Build Coastguard Worker VkResult result;
942*61046927SAndroid Build Coastguard Worker
943*61046927SAndroid Build Coastguard Worker result = pvr_clear_last_submits_syncs(driver_queue);
944*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
945*61046927SAndroid Build Coastguard Worker return result;
946*61046927SAndroid Build Coastguard Worker
947*61046927SAndroid Build Coastguard Worker result =
948*61046927SAndroid Build Coastguard Worker pvr_process_queue_waits(driver_queue, submit->waits, submit->wait_count);
949*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
950*61046927SAndroid Build Coastguard Worker return result;
951*61046927SAndroid Build Coastguard Worker
952*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0U; i < submit->command_buffer_count; i++) {
953*61046927SAndroid Build Coastguard Worker result = pvr_process_cmd_buffer(
954*61046927SAndroid Build Coastguard Worker device,
955*61046927SAndroid Build Coastguard Worker driver_queue,
956*61046927SAndroid Build Coastguard Worker container_of(submit->command_buffers[i], struct pvr_cmd_buffer, vk));
957*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
958*61046927SAndroid Build Coastguard Worker return result;
959*61046927SAndroid Build Coastguard Worker }
960*61046927SAndroid Build Coastguard Worker
961*61046927SAndroid Build Coastguard Worker result = pvr_process_queue_signals(driver_queue,
962*61046927SAndroid Build Coastguard Worker submit->signals,
963*61046927SAndroid Build Coastguard Worker submit->signal_count);
964*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
965*61046927SAndroid Build Coastguard Worker return result;
966*61046927SAndroid Build Coastguard Worker
967*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
968*61046927SAndroid Build Coastguard Worker }
969