1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2021 Intel Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21bf215546Sopenharmony_ci * IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#include "vk_alloc.h"
25bf215546Sopenharmony_ci#include "vk_command_buffer.h"
26bf215546Sopenharmony_ci#include "vk_common_entrypoints.h"
27bf215546Sopenharmony_ci#include "vk_device.h"
28bf215546Sopenharmony_ci#include "vk_queue.h"
29bf215546Sopenharmony_ci#include "vk_util.h"
30bf215546Sopenharmony_ci#include "../wsi/wsi_common.h"
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL
33bf215546Sopenharmony_civk_common_CmdWriteTimestamp(
34bf215546Sopenharmony_ci   VkCommandBuffer                             commandBuffer,
35bf215546Sopenharmony_ci   VkPipelineStageFlagBits                     pipelineStage,
36bf215546Sopenharmony_ci   VkQueryPool                                 queryPool,
37bf215546Sopenharmony_ci   uint32_t                                    query)
38bf215546Sopenharmony_ci{
39bf215546Sopenharmony_ci   VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer);
40bf215546Sopenharmony_ci   struct vk_device *device = cmd_buffer->base.device;
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci   device->dispatch_table.CmdWriteTimestamp2KHR(commandBuffer,
43bf215546Sopenharmony_ci                                                (VkPipelineStageFlags2) pipelineStage,
44bf215546Sopenharmony_ci                                                queryPool,
45bf215546Sopenharmony_ci                                                query);
46bf215546Sopenharmony_ci}
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_cistatic VkMemoryBarrier2
49bf215546Sopenharmony_ciupgrade_memory_barrier(const VkMemoryBarrier *barrier,
50bf215546Sopenharmony_ci                       VkPipelineStageFlags2 src_stage_mask2,
51bf215546Sopenharmony_ci                       VkPipelineStageFlags2 dst_stage_mask2)
52bf215546Sopenharmony_ci{
53bf215546Sopenharmony_ci   return (VkMemoryBarrier2) {
54bf215546Sopenharmony_ci      .sType         = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
55bf215546Sopenharmony_ci      .srcStageMask  = src_stage_mask2,
56bf215546Sopenharmony_ci      .srcAccessMask = (VkAccessFlags2) barrier->srcAccessMask,
57bf215546Sopenharmony_ci      .dstStageMask  = dst_stage_mask2,
58bf215546Sopenharmony_ci      .dstAccessMask = (VkAccessFlags2) barrier->dstAccessMask,
59bf215546Sopenharmony_ci   };
60bf215546Sopenharmony_ci}
61bf215546Sopenharmony_ci
62bf215546Sopenharmony_cistatic VkBufferMemoryBarrier2
63bf215546Sopenharmony_ciupgrade_buffer_memory_barrier(const VkBufferMemoryBarrier *barrier,
64bf215546Sopenharmony_ci                              VkPipelineStageFlags2 src_stage_mask2,
65bf215546Sopenharmony_ci                              VkPipelineStageFlags2 dst_stage_mask2)
66bf215546Sopenharmony_ci{
67bf215546Sopenharmony_ci   return (VkBufferMemoryBarrier2) {
68bf215546Sopenharmony_ci      .sType                = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
69bf215546Sopenharmony_ci      .srcStageMask         = src_stage_mask2,
70bf215546Sopenharmony_ci      .srcAccessMask        = (VkAccessFlags2) barrier->srcAccessMask,
71bf215546Sopenharmony_ci      .dstStageMask         = dst_stage_mask2,
72bf215546Sopenharmony_ci      .dstAccessMask        = (VkAccessFlags2) barrier->dstAccessMask,
73bf215546Sopenharmony_ci      .srcQueueFamilyIndex  = barrier->srcQueueFamilyIndex,
74bf215546Sopenharmony_ci      .dstQueueFamilyIndex  = barrier->dstQueueFamilyIndex,
75bf215546Sopenharmony_ci      .buffer               = barrier->buffer,
76bf215546Sopenharmony_ci      .offset               = barrier->offset,
77bf215546Sopenharmony_ci      .size                 = barrier->size,
78bf215546Sopenharmony_ci   };
79bf215546Sopenharmony_ci}
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_cistatic VkImageMemoryBarrier2
82bf215546Sopenharmony_ciupgrade_image_memory_barrier(const VkImageMemoryBarrier *barrier,
83bf215546Sopenharmony_ci                             VkPipelineStageFlags2 src_stage_mask2,
84bf215546Sopenharmony_ci                             VkPipelineStageFlags2 dst_stage_mask2)
85bf215546Sopenharmony_ci{
86bf215546Sopenharmony_ci   return (VkImageMemoryBarrier2) {
87bf215546Sopenharmony_ci      .sType                = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
88bf215546Sopenharmony_ci      .srcStageMask         = src_stage_mask2,
89bf215546Sopenharmony_ci      .srcAccessMask        = (VkAccessFlags2) barrier->srcAccessMask,
90bf215546Sopenharmony_ci      .dstStageMask         = dst_stage_mask2,
91bf215546Sopenharmony_ci      .dstAccessMask        = (VkAccessFlags2) barrier->dstAccessMask,
92bf215546Sopenharmony_ci      .oldLayout            = barrier->oldLayout,
93bf215546Sopenharmony_ci      .newLayout            = barrier->newLayout,
94bf215546Sopenharmony_ci      .srcQueueFamilyIndex  = barrier->srcQueueFamilyIndex,
95bf215546Sopenharmony_ci      .dstQueueFamilyIndex  = barrier->dstQueueFamilyIndex,
96bf215546Sopenharmony_ci      .image                = barrier->image,
97bf215546Sopenharmony_ci      .subresourceRange     = barrier->subresourceRange,
98bf215546Sopenharmony_ci   };
99bf215546Sopenharmony_ci}
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL
102bf215546Sopenharmony_civk_common_CmdPipelineBarrier(
103bf215546Sopenharmony_ci    VkCommandBuffer                             commandBuffer,
104bf215546Sopenharmony_ci    VkPipelineStageFlags                        srcStageMask,
105bf215546Sopenharmony_ci    VkPipelineStageFlags                        dstStageMask,
106bf215546Sopenharmony_ci    VkDependencyFlags                           dependencyFlags,
107bf215546Sopenharmony_ci    uint32_t                                    memoryBarrierCount,
108bf215546Sopenharmony_ci    const VkMemoryBarrier*                      pMemoryBarriers,
109bf215546Sopenharmony_ci    uint32_t                                    bufferMemoryBarrierCount,
110bf215546Sopenharmony_ci    const VkBufferMemoryBarrier*                pBufferMemoryBarriers,
111bf215546Sopenharmony_ci    uint32_t                                    imageMemoryBarrierCount,
112bf215546Sopenharmony_ci    const VkImageMemoryBarrier*                 pImageMemoryBarriers)
113bf215546Sopenharmony_ci{
114bf215546Sopenharmony_ci   VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer);
115bf215546Sopenharmony_ci   struct vk_device *device = cmd_buffer->base.device;
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_ci   STACK_ARRAY(VkMemoryBarrier2, memory_barriers, memoryBarrierCount);
118bf215546Sopenharmony_ci   STACK_ARRAY(VkBufferMemoryBarrier2, buffer_barriers, bufferMemoryBarrierCount);
119bf215546Sopenharmony_ci   STACK_ARRAY(VkImageMemoryBarrier2, image_barriers, imageMemoryBarrierCount);
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_ci   VkPipelineStageFlags2 src_stage_mask2 = (VkPipelineStageFlags2) srcStageMask;
122bf215546Sopenharmony_ci   VkPipelineStageFlags2 dst_stage_mask2 = (VkPipelineStageFlags2) dstStageMask;
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_ci   for (uint32_t i = 0; i < memoryBarrierCount; i++) {
125bf215546Sopenharmony_ci      memory_barriers[i] = upgrade_memory_barrier(&pMemoryBarriers[i],
126bf215546Sopenharmony_ci                                                  src_stage_mask2,
127bf215546Sopenharmony_ci                                                  dst_stage_mask2);
128bf215546Sopenharmony_ci   }
129bf215546Sopenharmony_ci   for (uint32_t i = 0; i < bufferMemoryBarrierCount; i++) {
130bf215546Sopenharmony_ci      buffer_barriers[i] = upgrade_buffer_memory_barrier(&pBufferMemoryBarriers[i],
131bf215546Sopenharmony_ci                                                         src_stage_mask2,
132bf215546Sopenharmony_ci                                                         dst_stage_mask2);
133bf215546Sopenharmony_ci   }
134bf215546Sopenharmony_ci   for (uint32_t i = 0; i < imageMemoryBarrierCount; i++) {
135bf215546Sopenharmony_ci      image_barriers[i] = upgrade_image_memory_barrier(&pImageMemoryBarriers[i],
136bf215546Sopenharmony_ci                                                       src_stage_mask2,
137bf215546Sopenharmony_ci                                                       dst_stage_mask2);
138bf215546Sopenharmony_ci   }
139bf215546Sopenharmony_ci
140bf215546Sopenharmony_ci   VkDependencyInfo dep_info = {
141bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
142bf215546Sopenharmony_ci      .memoryBarrierCount = memoryBarrierCount,
143bf215546Sopenharmony_ci      .pMemoryBarriers = memory_barriers,
144bf215546Sopenharmony_ci      .bufferMemoryBarrierCount = bufferMemoryBarrierCount,
145bf215546Sopenharmony_ci      .pBufferMemoryBarriers = buffer_barriers,
146bf215546Sopenharmony_ci      .imageMemoryBarrierCount = imageMemoryBarrierCount,
147bf215546Sopenharmony_ci      .pImageMemoryBarriers = image_barriers,
148bf215546Sopenharmony_ci   };
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ci   device->dispatch_table.CmdPipelineBarrier2KHR(commandBuffer, &dep_info);
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci   STACK_ARRAY_FINISH(memory_barriers);
153bf215546Sopenharmony_ci   STACK_ARRAY_FINISH(buffer_barriers);
154bf215546Sopenharmony_ci   STACK_ARRAY_FINISH(image_barriers);
155bf215546Sopenharmony_ci}
156bf215546Sopenharmony_ci
157bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL
158bf215546Sopenharmony_civk_common_CmdSetEvent(
159bf215546Sopenharmony_ci    VkCommandBuffer                             commandBuffer,
160bf215546Sopenharmony_ci    VkEvent                                     event,
161bf215546Sopenharmony_ci    VkPipelineStageFlags                        stageMask)
162bf215546Sopenharmony_ci{
163bf215546Sopenharmony_ci   VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer);
164bf215546Sopenharmony_ci   struct vk_device *device = cmd_buffer->base.device;
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_ci   VkMemoryBarrier2 mem_barrier = {
167bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
168bf215546Sopenharmony_ci      .srcStageMask = (VkPipelineStageFlags2) stageMask,
169bf215546Sopenharmony_ci      .dstStageMask = (VkPipelineStageFlags2) stageMask,
170bf215546Sopenharmony_ci   };
171bf215546Sopenharmony_ci   VkDependencyInfo dep_info = {
172bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
173bf215546Sopenharmony_ci      .memoryBarrierCount = 1,
174bf215546Sopenharmony_ci      .pMemoryBarriers = &mem_barrier,
175bf215546Sopenharmony_ci   };
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_ci   device->dispatch_table.CmdSetEvent2KHR(commandBuffer, event, &dep_info);
178bf215546Sopenharmony_ci}
179bf215546Sopenharmony_ci
180bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL
181bf215546Sopenharmony_civk_common_CmdResetEvent(
182bf215546Sopenharmony_ci    VkCommandBuffer                             commandBuffer,
183bf215546Sopenharmony_ci    VkEvent                                     event,
184bf215546Sopenharmony_ci    VkPipelineStageFlags                        stageMask)
185bf215546Sopenharmony_ci{
186bf215546Sopenharmony_ci   VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer);
187bf215546Sopenharmony_ci   struct vk_device *device = cmd_buffer->base.device;
188bf215546Sopenharmony_ci
189bf215546Sopenharmony_ci   device->dispatch_table.CmdResetEvent2KHR(commandBuffer,
190bf215546Sopenharmony_ci                                            event,
191bf215546Sopenharmony_ci                                            (VkPipelineStageFlags2) stageMask);
192bf215546Sopenharmony_ci}
193bf215546Sopenharmony_ci
194bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL
195bf215546Sopenharmony_civk_common_CmdWaitEvents(
196bf215546Sopenharmony_ci    VkCommandBuffer                             commandBuffer,
197bf215546Sopenharmony_ci    uint32_t                                    eventCount,
198bf215546Sopenharmony_ci    const VkEvent*                              pEvents,
199bf215546Sopenharmony_ci    VkPipelineStageFlags                        srcStageMask,
200bf215546Sopenharmony_ci    VkPipelineStageFlags                        destStageMask,
201bf215546Sopenharmony_ci    uint32_t                                    memoryBarrierCount,
202bf215546Sopenharmony_ci    const VkMemoryBarrier*                      pMemoryBarriers,
203bf215546Sopenharmony_ci    uint32_t                                    bufferMemoryBarrierCount,
204bf215546Sopenharmony_ci    const VkBufferMemoryBarrier*                pBufferMemoryBarriers,
205bf215546Sopenharmony_ci    uint32_t                                    imageMemoryBarrierCount,
206bf215546Sopenharmony_ci    const VkImageMemoryBarrier*                 pImageMemoryBarriers)
207bf215546Sopenharmony_ci{
208bf215546Sopenharmony_ci   VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer);
209bf215546Sopenharmony_ci   struct vk_device *device = cmd_buffer->base.device;
210bf215546Sopenharmony_ci
211bf215546Sopenharmony_ci   STACK_ARRAY(VkDependencyInfo, deps, eventCount);
212bf215546Sopenharmony_ci
213bf215546Sopenharmony_ci   /* Note that dstStageMask and srcStageMask in the CmdWaitEvent2() call
214bf215546Sopenharmony_ci    * are the same.  This is to match the CmdSetEvent2() call from
215bf215546Sopenharmony_ci    * vk_common_CmdSetEvent().  The actual src->dst stage barrier will
216bf215546Sopenharmony_ci    * happen as part of the CmdPipelineBarrier() call below.
217bf215546Sopenharmony_ci    */
218bf215546Sopenharmony_ci   VkMemoryBarrier2 stage_barrier = {
219bf215546Sopenharmony_ci      .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
220bf215546Sopenharmony_ci      .srcStageMask = srcStageMask,
221bf215546Sopenharmony_ci      .dstStageMask = srcStageMask,
222bf215546Sopenharmony_ci   };
223bf215546Sopenharmony_ci
224bf215546Sopenharmony_ci   for (uint32_t i = 0; i < eventCount; i++) {
225bf215546Sopenharmony_ci      deps[i] = (VkDependencyInfo) {
226bf215546Sopenharmony_ci         .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
227bf215546Sopenharmony_ci         .memoryBarrierCount = 1,
228bf215546Sopenharmony_ci         .pMemoryBarriers = &stage_barrier,
229bf215546Sopenharmony_ci      };
230bf215546Sopenharmony_ci   }
231bf215546Sopenharmony_ci   device->dispatch_table.CmdWaitEvents2KHR(commandBuffer, eventCount, pEvents, deps);
232bf215546Sopenharmony_ci
233bf215546Sopenharmony_ci   STACK_ARRAY_FINISH(deps);
234bf215546Sopenharmony_ci
235bf215546Sopenharmony_ci   /* Setting dependency to 0 because :
236bf215546Sopenharmony_ci    *
237bf215546Sopenharmony_ci    *    - For BY_REGION_BIT and VIEW_LOCAL_BIT, events are not allowed inside a
238bf215546Sopenharmony_ci    *      render pass so these don't apply.
239bf215546Sopenharmony_ci    *
240bf215546Sopenharmony_ci    *    - For DEVICE_GROUP_BIT, we have the following bit of spec text:
241bf215546Sopenharmony_ci    *
242bf215546Sopenharmony_ci    *        "Semaphore and event dependencies are device-local and only
243bf215546Sopenharmony_ci    *         execute on the one physical device that performs the
244bf215546Sopenharmony_ci    *         dependency."
245bf215546Sopenharmony_ci    */
246bf215546Sopenharmony_ci   const VkDependencyFlags dep_flags = 0;
247bf215546Sopenharmony_ci
248bf215546Sopenharmony_ci   device->dispatch_table.CmdPipelineBarrier(commandBuffer,
249bf215546Sopenharmony_ci                                             srcStageMask, destStageMask,
250bf215546Sopenharmony_ci                                             dep_flags,
251bf215546Sopenharmony_ci                                             memoryBarrierCount, pMemoryBarriers,
252bf215546Sopenharmony_ci                                             bufferMemoryBarrierCount, pBufferMemoryBarriers,
253bf215546Sopenharmony_ci                                             imageMemoryBarrierCount, pImageMemoryBarriers);
254bf215546Sopenharmony_ci}
255bf215546Sopenharmony_ci
256bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL
257bf215546Sopenharmony_civk_common_CmdWriteBufferMarkerAMD(
258bf215546Sopenharmony_ci    VkCommandBuffer                             commandBuffer,
259bf215546Sopenharmony_ci    VkPipelineStageFlagBits                     pipelineStage,
260bf215546Sopenharmony_ci    VkBuffer                                    dstBuffer,
261bf215546Sopenharmony_ci    VkDeviceSize                                dstOffset,
262bf215546Sopenharmony_ci    uint32_t                                    marker)
263bf215546Sopenharmony_ci{
264bf215546Sopenharmony_ci   VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer);
265bf215546Sopenharmony_ci   struct vk_device *device = cmd_buffer->base.device;
266bf215546Sopenharmony_ci
267bf215546Sopenharmony_ci   device->dispatch_table.CmdWriteBufferMarker2AMD(commandBuffer,
268bf215546Sopenharmony_ci                                                   (VkPipelineStageFlags2) pipelineStage,
269bf215546Sopenharmony_ci                                                   dstBuffer,
270bf215546Sopenharmony_ci                                                   dstOffset,
271bf215546Sopenharmony_ci                                                   marker);
272bf215546Sopenharmony_ci}
273bf215546Sopenharmony_ci
274bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL
275bf215546Sopenharmony_civk_common_GetQueueCheckpointDataNV(
276bf215546Sopenharmony_ci    VkQueue                                     queue,
277bf215546Sopenharmony_ci    uint32_t*                                   pCheckpointDataCount,
278bf215546Sopenharmony_ci    VkCheckpointDataNV*                         pCheckpointData)
279bf215546Sopenharmony_ci{
280bf215546Sopenharmony_ci   unreachable("Entrypoint not implemented");
281bf215546Sopenharmony_ci}
282bf215546Sopenharmony_ci
283bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL
284bf215546Sopenharmony_civk_common_QueueSubmit(
285bf215546Sopenharmony_ci    VkQueue                                     _queue,
286bf215546Sopenharmony_ci    uint32_t                                    submitCount,
287bf215546Sopenharmony_ci    const VkSubmitInfo*                         pSubmits,
288bf215546Sopenharmony_ci    VkFence                                     fence)
289bf215546Sopenharmony_ci{
290bf215546Sopenharmony_ci   VK_FROM_HANDLE(vk_queue, queue, _queue);
291bf215546Sopenharmony_ci   struct vk_device *device = queue->base.device;
292bf215546Sopenharmony_ci
293bf215546Sopenharmony_ci   STACK_ARRAY(VkSubmitInfo2, submit_info_2, submitCount);
294bf215546Sopenharmony_ci   STACK_ARRAY(VkPerformanceQuerySubmitInfoKHR, perf_query_submit_info, submitCount);
295bf215546Sopenharmony_ci   STACK_ARRAY(struct wsi_memory_signal_submit_info, wsi_mem_submit_info, submitCount);
296bf215546Sopenharmony_ci
297bf215546Sopenharmony_ci   uint32_t n_wait_semaphores = 0;
298bf215546Sopenharmony_ci   uint32_t n_command_buffers = 0;
299bf215546Sopenharmony_ci   uint32_t n_signal_semaphores = 0;
300bf215546Sopenharmony_ci   for (uint32_t s = 0; s < submitCount; s++) {
301bf215546Sopenharmony_ci      n_wait_semaphores += pSubmits[s].waitSemaphoreCount;
302bf215546Sopenharmony_ci      n_command_buffers += pSubmits[s].commandBufferCount;
303bf215546Sopenharmony_ci      n_signal_semaphores += pSubmits[s].signalSemaphoreCount;
304bf215546Sopenharmony_ci   }
305bf215546Sopenharmony_ci
306bf215546Sopenharmony_ci   STACK_ARRAY(VkSemaphoreSubmitInfo, wait_semaphores, n_wait_semaphores);
307bf215546Sopenharmony_ci   STACK_ARRAY(VkCommandBufferSubmitInfo, command_buffers, n_command_buffers);
308bf215546Sopenharmony_ci   STACK_ARRAY(VkSemaphoreSubmitInfo, signal_semaphores, n_signal_semaphores);
309bf215546Sopenharmony_ci
310bf215546Sopenharmony_ci   n_wait_semaphores = 0;
311bf215546Sopenharmony_ci   n_command_buffers = 0;
312bf215546Sopenharmony_ci   n_signal_semaphores = 0;
313bf215546Sopenharmony_ci
314bf215546Sopenharmony_ci   for (uint32_t s = 0; s < submitCount; s++) {
315bf215546Sopenharmony_ci      const VkTimelineSemaphoreSubmitInfo *timeline_info =
316bf215546Sopenharmony_ci         vk_find_struct_const(pSubmits[s].pNext,
317bf215546Sopenharmony_ci                              TIMELINE_SEMAPHORE_SUBMIT_INFO);
318bf215546Sopenharmony_ci      const uint64_t *wait_values = NULL;
319bf215546Sopenharmony_ci      const uint64_t *signal_values = NULL;
320bf215546Sopenharmony_ci
321bf215546Sopenharmony_ci      if (timeline_info && timeline_info->waitSemaphoreValueCount) {
322bf215546Sopenharmony_ci         /* From the Vulkan 1.3.204 spec:
323bf215546Sopenharmony_ci          *
324bf215546Sopenharmony_ci          *    VUID-VkSubmitInfo-pNext-03240
325bf215546Sopenharmony_ci          *
326bf215546Sopenharmony_ci          *    "If the pNext chain of this structure includes a VkTimelineSemaphoreSubmitInfo structure
327bf215546Sopenharmony_ci          *    and any element of pSignalSemaphores was created with a VkSemaphoreType of
328bf215546Sopenharmony_ci          *    VK_SEMAPHORE_TYPE_TIMELINE, then its signalSemaphoreValueCount member must equal
329bf215546Sopenharmony_ci          *    signalSemaphoreCount"
330bf215546Sopenharmony_ci          */
331bf215546Sopenharmony_ci         assert(timeline_info->waitSemaphoreValueCount == pSubmits[s].waitSemaphoreCount);
332bf215546Sopenharmony_ci         wait_values = timeline_info->pWaitSemaphoreValues;
333bf215546Sopenharmony_ci      }
334bf215546Sopenharmony_ci
335bf215546Sopenharmony_ci      if (timeline_info && timeline_info->signalSemaphoreValueCount) {
336bf215546Sopenharmony_ci         /* From the Vulkan 1.3.204 spec:
337bf215546Sopenharmony_ci          *
338bf215546Sopenharmony_ci          *    VUID-VkSubmitInfo-pNext-03241
339bf215546Sopenharmony_ci          *
340bf215546Sopenharmony_ci          *    "If the pNext chain of this structure includes a VkTimelineSemaphoreSubmitInfo structure
341bf215546Sopenharmony_ci          *    and any element of pWaitSemaphores was created with a VkSemaphoreType of
342bf215546Sopenharmony_ci          *    VK_SEMAPHORE_TYPE_TIMELINE, then its waitSemaphoreValueCount member must equal
343bf215546Sopenharmony_ci          *    waitSemaphoreCount"
344bf215546Sopenharmony_ci          */
345bf215546Sopenharmony_ci         assert(timeline_info->signalSemaphoreValueCount == pSubmits[s].signalSemaphoreCount);
346bf215546Sopenharmony_ci         signal_values = timeline_info->pSignalSemaphoreValues;
347bf215546Sopenharmony_ci      }
348bf215546Sopenharmony_ci
349bf215546Sopenharmony_ci      const VkDeviceGroupSubmitInfo *group_info =
350bf215546Sopenharmony_ci         vk_find_struct_const(pSubmits[s].pNext, DEVICE_GROUP_SUBMIT_INFO);
351bf215546Sopenharmony_ci
352bf215546Sopenharmony_ci      for (uint32_t i = 0; i < pSubmits[s].waitSemaphoreCount; i++) {
353bf215546Sopenharmony_ci         wait_semaphores[n_wait_semaphores + i] = (VkSemaphoreSubmitInfo) {
354bf215546Sopenharmony_ci            .sType       = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
355bf215546Sopenharmony_ci            .semaphore   = pSubmits[s].pWaitSemaphores[i],
356bf215546Sopenharmony_ci            .value       = wait_values ? wait_values[i] : 0,
357bf215546Sopenharmony_ci            .stageMask   = pSubmits[s].pWaitDstStageMask[i],
358bf215546Sopenharmony_ci            .deviceIndex = group_info ? group_info->pWaitSemaphoreDeviceIndices[i] : 0,
359bf215546Sopenharmony_ci         };
360bf215546Sopenharmony_ci      }
361bf215546Sopenharmony_ci      for (uint32_t i = 0; i < pSubmits[s].commandBufferCount; i++) {
362bf215546Sopenharmony_ci         command_buffers[n_command_buffers + i] = (VkCommandBufferSubmitInfo) {
363bf215546Sopenharmony_ci            .sType         = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO,
364bf215546Sopenharmony_ci            .commandBuffer = pSubmits[s].pCommandBuffers[i],
365bf215546Sopenharmony_ci            .deviceMask    = group_info ? group_info->pCommandBufferDeviceMasks[i] : 0,
366bf215546Sopenharmony_ci         };
367bf215546Sopenharmony_ci      }
368bf215546Sopenharmony_ci      for (uint32_t i = 0; i < pSubmits[s].signalSemaphoreCount; i++) {
369bf215546Sopenharmony_ci         signal_semaphores[n_signal_semaphores + i] = (VkSemaphoreSubmitInfo) {
370bf215546Sopenharmony_ci            .sType     = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
371bf215546Sopenharmony_ci            .semaphore = pSubmits[s].pSignalSemaphores[i],
372bf215546Sopenharmony_ci            .value     = signal_values ? signal_values[i] : 0,
373bf215546Sopenharmony_ci            .stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
374bf215546Sopenharmony_ci            .deviceIndex = group_info ? group_info->pSignalSemaphoreDeviceIndices[i] : 0,
375bf215546Sopenharmony_ci         };
376bf215546Sopenharmony_ci      }
377bf215546Sopenharmony_ci
378bf215546Sopenharmony_ci      const VkProtectedSubmitInfo *protected_info =
379bf215546Sopenharmony_ci         vk_find_struct_const(pSubmits[s].pNext, PROTECTED_SUBMIT_INFO);
380bf215546Sopenharmony_ci
381bf215546Sopenharmony_ci      submit_info_2[s] = (VkSubmitInfo2) {
382bf215546Sopenharmony_ci         .sType                    = VK_STRUCTURE_TYPE_SUBMIT_INFO_2,
383bf215546Sopenharmony_ci         .flags                    = ((protected_info && protected_info->protectedSubmit) ?
384bf215546Sopenharmony_ci                                      VK_SUBMIT_PROTECTED_BIT : 0),
385bf215546Sopenharmony_ci         .waitSemaphoreInfoCount   = pSubmits[s].waitSemaphoreCount,
386bf215546Sopenharmony_ci         .pWaitSemaphoreInfos      = &wait_semaphores[n_wait_semaphores],
387bf215546Sopenharmony_ci         .commandBufferInfoCount   = pSubmits[s].commandBufferCount,
388bf215546Sopenharmony_ci         .pCommandBufferInfos      = &command_buffers[n_command_buffers],
389bf215546Sopenharmony_ci         .signalSemaphoreInfoCount = pSubmits[s].signalSemaphoreCount,
390bf215546Sopenharmony_ci         .pSignalSemaphoreInfos    = &signal_semaphores[n_signal_semaphores],
391bf215546Sopenharmony_ci      };
392bf215546Sopenharmony_ci
393bf215546Sopenharmony_ci      const VkPerformanceQuerySubmitInfoKHR *query_info =
394bf215546Sopenharmony_ci         vk_find_struct_const(pSubmits[s].pNext,
395bf215546Sopenharmony_ci                              PERFORMANCE_QUERY_SUBMIT_INFO_KHR);
396bf215546Sopenharmony_ci      if (query_info) {
397bf215546Sopenharmony_ci         perf_query_submit_info[s] = *query_info;
398bf215546Sopenharmony_ci         perf_query_submit_info[s].pNext = NULL;
399bf215546Sopenharmony_ci         __vk_append_struct(&submit_info_2[s], &perf_query_submit_info[s]);
400bf215546Sopenharmony_ci      }
401bf215546Sopenharmony_ci
402bf215546Sopenharmony_ci      const struct wsi_memory_signal_submit_info *mem_signal_info =
403bf215546Sopenharmony_ci         vk_find_struct_const(pSubmits[s].pNext,
404bf215546Sopenharmony_ci                              WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA);
405bf215546Sopenharmony_ci      if (mem_signal_info) {
406bf215546Sopenharmony_ci         wsi_mem_submit_info[s] = *mem_signal_info;
407bf215546Sopenharmony_ci         wsi_mem_submit_info[s].pNext = NULL;
408bf215546Sopenharmony_ci         __vk_append_struct(&submit_info_2[s], &wsi_mem_submit_info[s]);
409bf215546Sopenharmony_ci      }
410bf215546Sopenharmony_ci
411bf215546Sopenharmony_ci      n_wait_semaphores += pSubmits[s].waitSemaphoreCount;
412bf215546Sopenharmony_ci      n_command_buffers += pSubmits[s].commandBufferCount;
413bf215546Sopenharmony_ci      n_signal_semaphores += pSubmits[s].signalSemaphoreCount;
414bf215546Sopenharmony_ci   }
415bf215546Sopenharmony_ci
416bf215546Sopenharmony_ci   VkResult result = device->dispatch_table.QueueSubmit2KHR(_queue,
417bf215546Sopenharmony_ci                                                            submitCount,
418bf215546Sopenharmony_ci                                                            submit_info_2,
419bf215546Sopenharmony_ci                                                            fence);
420bf215546Sopenharmony_ci
421bf215546Sopenharmony_ci   STACK_ARRAY_FINISH(wait_semaphores);
422bf215546Sopenharmony_ci   STACK_ARRAY_FINISH(command_buffers);
423bf215546Sopenharmony_ci   STACK_ARRAY_FINISH(signal_semaphores);
424bf215546Sopenharmony_ci   STACK_ARRAY_FINISH(submit_info_2);
425bf215546Sopenharmony_ci   STACK_ARRAY_FINISH(perf_query_submit_info);
426bf215546Sopenharmony_ci   STACK_ARRAY_FINISH(wsi_mem_submit_info);
427bf215546Sopenharmony_ci
428bf215546Sopenharmony_ci   return result;
429bf215546Sopenharmony_ci}
430