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