1 /*
2 * Copyright 2019 Google LLC
3 * SPDX-License-Identifier: MIT
4 *
5 * based in part on anv and radv which are:
6 * Copyright © 2015 Intel Corporation
7 * Copyright © 2016 Red Hat.
8 * Copyright © 2016 Bas Nieuwenhuizen
9 */
10
11 #include "vn_command_buffer.h"
12
13 #include "venus-protocol/vn_protocol_driver_command_buffer.h"
14 #include "venus-protocol/vn_protocol_driver_command_pool.h"
15
16 #include "vn_device.h"
17 #include "vn_image.h"
18 #include "vn_render_pass.h"
19
20 static bool
vn_image_memory_barrier_has_present_src(const VkImageMemoryBarrier * img_barriers,uint32_t count)21 vn_image_memory_barrier_has_present_src(
22 const VkImageMemoryBarrier *img_barriers, uint32_t count)
23 {
24 for (uint32_t i = 0; i < count; i++) {
25 if (img_barriers[i].oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ||
26 img_barriers[i].newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
27 return true;
28 }
29 return false;
30 }
31
32 static VkImageMemoryBarrier *
vn_cmd_get_image_memory_barriers(struct vn_command_buffer * cmd,uint32_t count)33 vn_cmd_get_image_memory_barriers(struct vn_command_buffer *cmd,
34 uint32_t count)
35 {
36 /* avoid shrinking in case of non efficient reallocation implementation */
37 if (count > cmd->builder.image_barrier_count) {
38 size_t size = sizeof(VkImageMemoryBarrier) * count;
39 VkImageMemoryBarrier *img_barriers =
40 vk_realloc(&cmd->allocator, cmd->builder.image_barriers, size,
41 VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
42 if (!img_barriers)
43 return NULL;
44
45 /* update upon successful reallocation */
46 cmd->builder.image_barrier_count = count;
47 cmd->builder.image_barriers = img_barriers;
48 }
49
50 return cmd->builder.image_barriers;
51 }
52
53 /* About VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, the spec says
54 *
55 * VK_IMAGE_LAYOUT_PRESENT_SRC_KHR must only be used for presenting a
56 * presentable image for display. A swapchain's image must be transitioned
57 * to this layout before calling vkQueuePresentKHR, and must be
58 * transitioned away from this layout after calling vkAcquireNextImageKHR.
59 *
60 * That allows us to treat the layout internally as
61 *
62 * - VK_IMAGE_LAYOUT_GENERAL
63 * - VK_QUEUE_FAMILY_FOREIGN_EXT has the ownership, if the image is not a
64 * prime blit source
65 *
66 * while staying performant.
67 *
68 * About queue family ownerships, the spec says
69 *
70 * A queue family can take ownership of an image subresource or buffer
71 * range of a resource created with VK_SHARING_MODE_EXCLUSIVE, without an
72 * ownership transfer, in the same way as for a resource that was just
73 * created; however, taking ownership in this way has the effect that the
74 * contents of the image subresource or buffer range are undefined.
75 *
76 * It is unclear if that is applicable to external resources, which supposedly
77 * have the same semantics
78 *
79 * Binding a resource to a memory object shared between multiple Vulkan
80 * instances or other APIs does not change the ownership of the underlying
81 * memory. The first entity to access the resource implicitly acquires
82 * ownership. Accessing a resource backed by memory that is owned by a
83 * particular instance or API has the same semantics as accessing a
84 * VK_SHARING_MODE_EXCLUSIVE resource[...]
85 *
86 * We should get the spec clarified, or get rid of this completely broken code
87 * (TODO).
88 *
89 * Assuming a queue family can acquire the ownership implicitly when the
90 * contents are not needed, we do not need to worry about
91 * VK_IMAGE_LAYOUT_UNDEFINED. We can use VK_IMAGE_LAYOUT_PRESENT_SRC_KHR as
92 * the sole signal to trigger queue family ownership transfers.
93 *
94 * When the image has VK_SHARING_MODE_CONCURRENT, we can, and are required to,
95 * use VK_QUEUE_FAMILY_IGNORED as the other queue family whether we are
96 * transitioning to or from VK_IMAGE_LAYOUT_PRESENT_SRC_KHR.
97 *
98 * When the image has VK_SHARING_MODE_EXCLUSIVE, we have to work out who the
99 * other queue family is. It is easier when the barrier does not also define
100 * a queue family ownership transfer (i.e., srcQueueFamilyIndex equals to
101 * dstQueueFamilyIndex). The other queue family must be the queue family the
102 * command buffer was allocated for.
103 *
104 * When the barrier also defines a queue family ownership transfer, it is
105 * submitted both to the source queue family to release the ownership and to
106 * the destination queue family to acquire the ownership. Depending on
107 * whether the barrier transitions to or from VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
108 * we are only interested in the ownership release or acquire respectively and
109 * should be careful to avoid double releases/acquires.
110 *
111 * I haven't followed all transition paths mentally to verify the correctness.
112 * I likely also violate some VUs or miss some cases below. They are
113 * hopefully fixable and are left as TODOs.
114 */
115 static void
vn_cmd_fix_image_memory_barrier(const struct vn_command_buffer * cmd,const VkImageMemoryBarrier * src_barrier,VkImageMemoryBarrier * out_barrier)116 vn_cmd_fix_image_memory_barrier(const struct vn_command_buffer *cmd,
117 const VkImageMemoryBarrier *src_barrier,
118 VkImageMemoryBarrier *out_barrier)
119 {
120 const struct vn_image *img = vn_image_from_handle(src_barrier->image);
121
122 *out_barrier = *src_barrier;
123
124 /* no fix needed */
125 if (out_barrier->oldLayout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR &&
126 out_barrier->newLayout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
127 return;
128
129 assert(img->is_wsi);
130
131 if (VN_PRESENT_SRC_INTERNAL_LAYOUT == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
132 return;
133
134 /* prime blit src or no layout transition */
135 if (img->is_prime_blit_src ||
136 out_barrier->oldLayout == out_barrier->newLayout) {
137 if (out_barrier->oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
138 out_barrier->oldLayout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
139 if (out_barrier->newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
140 out_barrier->newLayout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
141 return;
142 }
143
144 if (out_barrier->oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
145 out_barrier->oldLayout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
146
147 /* no availability operation needed */
148 out_barrier->srcAccessMask = 0;
149
150 const uint32_t dst_qfi = out_barrier->dstQueueFamilyIndex;
151 if (img->sharing_mode == VK_SHARING_MODE_CONCURRENT) {
152 out_barrier->srcQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT;
153 out_barrier->dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
154 } else if (dst_qfi == out_barrier->srcQueueFamilyIndex ||
155 dst_qfi == cmd->queue_family_index) {
156 out_barrier->srcQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT;
157 out_barrier->dstQueueFamilyIndex = cmd->queue_family_index;
158 } else {
159 /* The barrier also defines a queue family ownership transfer, and
160 * this is the one that gets submitted to the source queue family to
161 * release the ownership. Skip both the transfer and the transition.
162 */
163 out_barrier->srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
164 out_barrier->dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
165 out_barrier->newLayout = out_barrier->oldLayout;
166 }
167 } else {
168 out_barrier->newLayout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
169
170 /* no visibility operation needed */
171 out_barrier->dstAccessMask = 0;
172
173 const uint32_t src_qfi = out_barrier->srcQueueFamilyIndex;
174 if (img->sharing_mode == VK_SHARING_MODE_CONCURRENT) {
175 out_barrier->srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
176 out_barrier->dstQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT;
177 } else if (src_qfi == out_barrier->dstQueueFamilyIndex ||
178 src_qfi == cmd->queue_family_index) {
179 out_barrier->srcQueueFamilyIndex = cmd->queue_family_index;
180 out_barrier->dstQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT;
181 } else {
182 /* The barrier also defines a queue family ownership transfer, and
183 * this is the one that gets submitted to the destination queue
184 * family to acquire the ownership. Skip both the transfer and the
185 * transition.
186 */
187 out_barrier->srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
188 out_barrier->dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
189 out_barrier->oldLayout = out_barrier->newLayout;
190 }
191 }
192 }
193
194 static const VkImageMemoryBarrier *
vn_cmd_wait_events_fix_image_memory_barriers(struct vn_command_buffer * cmd,const VkImageMemoryBarrier * src_barriers,uint32_t count,uint32_t * out_transfer_count)195 vn_cmd_wait_events_fix_image_memory_barriers(
196 struct vn_command_buffer *cmd,
197 const VkImageMemoryBarrier *src_barriers,
198 uint32_t count,
199 uint32_t *out_transfer_count)
200 {
201 *out_transfer_count = 0;
202
203 if (cmd->builder.render_pass ||
204 !vn_image_memory_barrier_has_present_src(src_barriers, count))
205 return src_barriers;
206
207 VkImageMemoryBarrier *img_barriers =
208 vn_cmd_get_image_memory_barriers(cmd, count * 2);
209 if (!img_barriers) {
210 cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
211 return src_barriers;
212 }
213
214 /* vkCmdWaitEvents cannot be used for queue family ownership transfers.
215 * Nothing appears to be said about the submission order of image memory
216 * barriers in the same array. We take the liberty to move queue family
217 * ownership transfers to the tail.
218 */
219 VkImageMemoryBarrier *transfer_barriers = img_barriers + count;
220 uint32_t transfer_count = 0;
221 uint32_t valid_count = 0;
222 for (uint32_t i = 0; i < count; i++) {
223 VkImageMemoryBarrier *img_barrier = &img_barriers[valid_count];
224 vn_cmd_fix_image_memory_barrier(cmd, &src_barriers[i], img_barrier);
225
226 if (VN_PRESENT_SRC_INTERNAL_LAYOUT == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
227 valid_count++;
228 continue;
229 }
230
231 if (img_barrier->srcQueueFamilyIndex ==
232 img_barrier->dstQueueFamilyIndex) {
233 valid_count++;
234 } else {
235 transfer_barriers[transfer_count++] = *img_barrier;
236 }
237 }
238
239 assert(valid_count + transfer_count == count);
240 if (transfer_count) {
241 /* copy back to the tail */
242 memcpy(&img_barriers[valid_count], transfer_barriers,
243 sizeof(*transfer_barriers) * transfer_count);
244 *out_transfer_count = transfer_count;
245 }
246
247 return img_barriers;
248 }
249
250 static const VkImageMemoryBarrier *
vn_cmd_pipeline_barrier_fix_image_memory_barriers(struct vn_command_buffer * cmd,const VkImageMemoryBarrier * src_barriers,uint32_t count)251 vn_cmd_pipeline_barrier_fix_image_memory_barriers(
252 struct vn_command_buffer *cmd,
253 const VkImageMemoryBarrier *src_barriers,
254 uint32_t count)
255 {
256 if (cmd->builder.render_pass ||
257 !vn_image_memory_barrier_has_present_src(src_barriers, count))
258 return src_barriers;
259
260 VkImageMemoryBarrier *img_barriers =
261 vn_cmd_get_image_memory_barriers(cmd, count);
262 if (!img_barriers) {
263 cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
264 return src_barriers;
265 }
266
267 for (uint32_t i = 0; i < count; i++) {
268 vn_cmd_fix_image_memory_barrier(cmd, &src_barriers[i],
269 &img_barriers[i]);
270 }
271
272 return img_barriers;
273 }
274
275 static void
vn_cmd_encode_memory_barriers(struct vn_command_buffer * cmd,VkPipelineStageFlags src_stage_mask,VkPipelineStageFlags dst_stage_mask,uint32_t buf_barrier_count,const VkBufferMemoryBarrier * buf_barriers,uint32_t img_barrier_count,const VkImageMemoryBarrier * img_barriers)276 vn_cmd_encode_memory_barriers(struct vn_command_buffer *cmd,
277 VkPipelineStageFlags src_stage_mask,
278 VkPipelineStageFlags dst_stage_mask,
279 uint32_t buf_barrier_count,
280 const VkBufferMemoryBarrier *buf_barriers,
281 uint32_t img_barrier_count,
282 const VkImageMemoryBarrier *img_barriers)
283 {
284 const VkCommandBuffer cmd_handle = vn_command_buffer_to_handle(cmd);
285
286 const size_t cmd_size = vn_sizeof_vkCmdPipelineBarrier(
287 cmd_handle, src_stage_mask, dst_stage_mask, 0, 0, NULL,
288 buf_barrier_count, buf_barriers, img_barrier_count, img_barriers);
289 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) {
290 cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
291 return;
292 }
293
294 vn_encode_vkCmdPipelineBarrier(
295 &cmd->cs, 0, cmd_handle, src_stage_mask, dst_stage_mask, 0, 0, NULL,
296 buf_barrier_count, buf_barriers, img_barrier_count, img_barriers);
297 }
298
299 static void
vn_present_src_attachment_to_image_memory_barrier(const struct vn_image * img,const struct vn_present_src_attachment * att,VkImageMemoryBarrier * img_barrier)300 vn_present_src_attachment_to_image_memory_barrier(
301 const struct vn_image *img,
302 const struct vn_present_src_attachment *att,
303 VkImageMemoryBarrier *img_barrier)
304 {
305 *img_barrier = (VkImageMemoryBarrier)
306 {
307 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
308 .srcAccessMask = att->src_access_mask,
309 .dstAccessMask = att->dst_access_mask,
310 .oldLayout = att->acquire ? VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
311 : VN_PRESENT_SRC_INTERNAL_LAYOUT,
312 .newLayout = att->acquire ? VN_PRESENT_SRC_INTERNAL_LAYOUT
313 : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
314 .image = vn_image_to_handle((struct vn_image *)img),
315 .subresourceRange = {
316 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
317 .levelCount = 1,
318 .layerCount = 1,
319 },
320 };
321 }
322
323 static void
vn_cmd_transfer_present_src_images(struct vn_command_buffer * cmd,const struct vn_image * const * images,const struct vn_present_src_attachment * atts,uint32_t count)324 vn_cmd_transfer_present_src_images(
325 struct vn_command_buffer *cmd,
326 const struct vn_image *const *images,
327 const struct vn_present_src_attachment *atts,
328 uint32_t count)
329 {
330 VkImageMemoryBarrier *img_barriers =
331 vn_cmd_get_image_memory_barriers(cmd, count);
332 if (!img_barriers) {
333 cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
334 return;
335 }
336
337 VkPipelineStageFlags src_stage_mask = 0;
338 VkPipelineStageFlags dst_stage_mask = 0;
339 for (uint32_t i = 0; i < count; i++) {
340 src_stage_mask |= atts[i].src_stage_mask;
341 dst_stage_mask |= atts[i].dst_stage_mask;
342
343 vn_present_src_attachment_to_image_memory_barrier(images[i], &atts[i],
344 &img_barriers[i]);
345 vn_cmd_fix_image_memory_barrier(cmd, &img_barriers[i],
346 &img_barriers[i]);
347 }
348
349 if (VN_PRESENT_SRC_INTERNAL_LAYOUT == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
350 return;
351
352 vn_cmd_encode_memory_barriers(cmd, src_stage_mask, dst_stage_mask, 0, NULL,
353 count, img_barriers);
354 }
355
356 static void
vn_cmd_begin_render_pass(struct vn_command_buffer * cmd,const struct vn_render_pass * pass,const struct vn_framebuffer * fb,const VkRenderPassBeginInfo * begin_info)357 vn_cmd_begin_render_pass(struct vn_command_buffer *cmd,
358 const struct vn_render_pass *pass,
359 const struct vn_framebuffer *fb,
360 const VkRenderPassBeginInfo *begin_info)
361 {
362 cmd->builder.render_pass = pass;
363 cmd->builder.framebuffer = fb;
364
365 if (!pass->present_src_count ||
366 cmd->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY)
367 return;
368
369 /* find fb attachments */
370 const VkImageView *views;
371 ASSERTED uint32_t view_count;
372 if (fb->image_view_count) {
373 views = fb->image_views;
374 view_count = fb->image_view_count;
375 } else {
376 const VkRenderPassAttachmentBeginInfo *imageless_info =
377 vk_find_struct_const(begin_info->pNext,
378 RENDER_PASS_ATTACHMENT_BEGIN_INFO);
379 assert(imageless_info);
380 views = imageless_info->pAttachments;
381 view_count = imageless_info->attachmentCount;
382 }
383
384 const struct vn_image **images =
385 vk_alloc(&cmd->allocator, sizeof(*images) * pass->present_src_count,
386 VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
387 if (!images) {
388 cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
389 return;
390 }
391
392 for (uint32_t i = 0; i < pass->present_src_count; i++) {
393 const uint32_t index = pass->present_src_attachments[i].index;
394 assert(index < view_count);
395 images[i] = vn_image_view_from_handle(views[index])->image;
396 }
397
398 if (pass->acquire_count) {
399 vn_cmd_transfer_present_src_images(
400 cmd, images, pass->present_src_attachments, pass->acquire_count);
401 }
402
403 cmd->builder.present_src_images = images;
404 }
405
406 static void
vn_cmd_end_render_pass(struct vn_command_buffer * cmd)407 vn_cmd_end_render_pass(struct vn_command_buffer *cmd)
408 {
409 const struct vn_render_pass *pass = cmd->builder.render_pass;
410
411 cmd->builder.render_pass = NULL;
412 cmd->builder.framebuffer = NULL;
413
414 if (!pass->present_src_count || !cmd->builder.present_src_images)
415 return;
416
417 const struct vn_image **images = cmd->builder.present_src_images;
418 cmd->builder.present_src_images = NULL;
419
420 if (pass->release_count) {
421 vn_cmd_transfer_present_src_images(
422 cmd, images + pass->acquire_count,
423 pass->present_src_attachments + pass->acquire_count,
424 pass->release_count);
425 }
426
427 vk_free(&cmd->allocator, images);
428 }
429
430 /* command pool commands */
431
432 VkResult
vn_CreateCommandPool(VkDevice device,const VkCommandPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkCommandPool * pCommandPool)433 vn_CreateCommandPool(VkDevice device,
434 const VkCommandPoolCreateInfo *pCreateInfo,
435 const VkAllocationCallbacks *pAllocator,
436 VkCommandPool *pCommandPool)
437 {
438 struct vn_device *dev = vn_device_from_handle(device);
439 const VkAllocationCallbacks *alloc =
440 pAllocator ? pAllocator : &dev->base.base.alloc;
441
442 struct vn_command_pool *pool =
443 vk_zalloc(alloc, sizeof(*pool), VN_DEFAULT_ALIGN,
444 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
445 if (!pool)
446 return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
447
448 vn_object_base_init(&pool->base, VK_OBJECT_TYPE_COMMAND_POOL, &dev->base);
449
450 pool->allocator = *alloc;
451 pool->queue_family_index = pCreateInfo->queueFamilyIndex;
452 list_inithead(&pool->command_buffers);
453
454 VkCommandPool pool_handle = vn_command_pool_to_handle(pool);
455 vn_async_vkCreateCommandPool(dev->instance, device, pCreateInfo, NULL,
456 &pool_handle);
457
458 *pCommandPool = pool_handle;
459
460 return VK_SUCCESS;
461 }
462
463 void
vn_DestroyCommandPool(VkDevice device,VkCommandPool commandPool,const VkAllocationCallbacks * pAllocator)464 vn_DestroyCommandPool(VkDevice device,
465 VkCommandPool commandPool,
466 const VkAllocationCallbacks *pAllocator)
467 {
468 struct vn_device *dev = vn_device_from_handle(device);
469 struct vn_command_pool *pool = vn_command_pool_from_handle(commandPool);
470 const VkAllocationCallbacks *alloc;
471
472 if (!pool)
473 return;
474
475 alloc = pAllocator ? pAllocator : &pool->allocator;
476
477 /* We must emit vkDestroyCommandPool before freeing the command buffers in
478 * pool->command_buffers. Otherwise, another thread might reuse their
479 * object ids while they still refer to the command buffers in the
480 * renderer.
481 */
482 vn_async_vkDestroyCommandPool(dev->instance, device, commandPool, NULL);
483
484 list_for_each_entry_safe(struct vn_command_buffer, cmd,
485 &pool->command_buffers, head) {
486 vn_cs_encoder_fini(&cmd->cs);
487 vn_object_base_fini(&cmd->base);
488 vk_free(alloc, cmd);
489 }
490
491 vn_object_base_fini(&pool->base);
492 vk_free(alloc, pool);
493 }
494
495 VkResult
vn_ResetCommandPool(VkDevice device,VkCommandPool commandPool,VkCommandPoolResetFlags flags)496 vn_ResetCommandPool(VkDevice device,
497 VkCommandPool commandPool,
498 VkCommandPoolResetFlags flags)
499 {
500 struct vn_device *dev = vn_device_from_handle(device);
501 struct vn_command_pool *pool = vn_command_pool_from_handle(commandPool);
502
503 list_for_each_entry_safe(struct vn_command_buffer, cmd,
504 &pool->command_buffers, head) {
505 vn_cs_encoder_reset(&cmd->cs);
506 cmd->state = VN_COMMAND_BUFFER_STATE_INITIAL;
507 }
508
509 vn_async_vkResetCommandPool(dev->instance, device, commandPool, flags);
510
511 return VK_SUCCESS;
512 }
513
514 void
vn_TrimCommandPool(VkDevice device,VkCommandPool commandPool,VkCommandPoolTrimFlags flags)515 vn_TrimCommandPool(VkDevice device,
516 VkCommandPool commandPool,
517 VkCommandPoolTrimFlags flags)
518 {
519 struct vn_device *dev = vn_device_from_handle(device);
520
521 vn_async_vkTrimCommandPool(dev->instance, device, commandPool, flags);
522 }
523
524 /* command buffer commands */
525
526 VkResult
vn_AllocateCommandBuffers(VkDevice device,const VkCommandBufferAllocateInfo * pAllocateInfo,VkCommandBuffer * pCommandBuffers)527 vn_AllocateCommandBuffers(VkDevice device,
528 const VkCommandBufferAllocateInfo *pAllocateInfo,
529 VkCommandBuffer *pCommandBuffers)
530 {
531 struct vn_device *dev = vn_device_from_handle(device);
532 struct vn_command_pool *pool =
533 vn_command_pool_from_handle(pAllocateInfo->commandPool);
534 const VkAllocationCallbacks *alloc = &pool->allocator;
535
536 for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
537 struct vn_command_buffer *cmd =
538 vk_zalloc(alloc, sizeof(*cmd), VN_DEFAULT_ALIGN,
539 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
540 if (!cmd) {
541 for (uint32_t j = 0; j < i; j++) {
542 cmd = vn_command_buffer_from_handle(pCommandBuffers[j]);
543 vn_cs_encoder_fini(&cmd->cs);
544 list_del(&cmd->head);
545 vn_object_base_fini(&cmd->base);
546 vk_free(alloc, cmd);
547 }
548 memset(pCommandBuffers, 0,
549 sizeof(*pCommandBuffers) * pAllocateInfo->commandBufferCount);
550 return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
551 }
552
553 vn_object_base_init(&cmd->base, VK_OBJECT_TYPE_COMMAND_BUFFER,
554 &dev->base);
555 cmd->device = dev;
556 cmd->allocator = pool->allocator;
557 cmd->level = pAllocateInfo->level;
558 cmd->queue_family_index = pool->queue_family_index;
559
560 list_addtail(&cmd->head, &pool->command_buffers);
561
562 cmd->state = VN_COMMAND_BUFFER_STATE_INITIAL;
563 vn_cs_encoder_init_indirect(&cmd->cs, dev->instance, 16 * 1024);
564
565 VkCommandBuffer cmd_handle = vn_command_buffer_to_handle(cmd);
566 pCommandBuffers[i] = cmd_handle;
567 }
568
569 vn_async_vkAllocateCommandBuffers(dev->instance, device, pAllocateInfo,
570 pCommandBuffers);
571
572 return VK_SUCCESS;
573 }
574
575 void
vn_FreeCommandBuffers(VkDevice device,VkCommandPool commandPool,uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)576 vn_FreeCommandBuffers(VkDevice device,
577 VkCommandPool commandPool,
578 uint32_t commandBufferCount,
579 const VkCommandBuffer *pCommandBuffers)
580 {
581 struct vn_device *dev = vn_device_from_handle(device);
582 struct vn_command_pool *pool = vn_command_pool_from_handle(commandPool);
583 const VkAllocationCallbacks *alloc = &pool->allocator;
584
585 vn_async_vkFreeCommandBuffers(dev->instance, device, commandPool,
586 commandBufferCount, pCommandBuffers);
587
588 for (uint32_t i = 0; i < commandBufferCount; i++) {
589 struct vn_command_buffer *cmd =
590 vn_command_buffer_from_handle(pCommandBuffers[i]);
591
592 if (!cmd)
593 continue;
594
595 if (cmd->builder.image_barriers)
596 vk_free(alloc, cmd->builder.image_barriers);
597
598 vn_cs_encoder_fini(&cmd->cs);
599 list_del(&cmd->head);
600
601 vn_object_base_fini(&cmd->base);
602 vk_free(alloc, cmd);
603 }
604 }
605
606 VkResult
vn_ResetCommandBuffer(VkCommandBuffer commandBuffer,VkCommandBufferResetFlags flags)607 vn_ResetCommandBuffer(VkCommandBuffer commandBuffer,
608 VkCommandBufferResetFlags flags)
609 {
610 struct vn_command_buffer *cmd =
611 vn_command_buffer_from_handle(commandBuffer);
612
613 vn_cs_encoder_reset(&cmd->cs);
614 cmd->state = VN_COMMAND_BUFFER_STATE_INITIAL;
615
616 vn_async_vkResetCommandBuffer(cmd->device->instance, commandBuffer, flags);
617
618 return VK_SUCCESS;
619 }
620
621 VkResult
vn_BeginCommandBuffer(VkCommandBuffer commandBuffer,const VkCommandBufferBeginInfo * pBeginInfo)622 vn_BeginCommandBuffer(VkCommandBuffer commandBuffer,
623 const VkCommandBufferBeginInfo *pBeginInfo)
624 {
625 struct vn_command_buffer *cmd =
626 vn_command_buffer_from_handle(commandBuffer);
627 struct vn_instance *instance = cmd->device->instance;
628 size_t cmd_size;
629
630 vn_cs_encoder_reset(&cmd->cs);
631
632 VkCommandBufferBeginInfo local_begin_info;
633 if (pBeginInfo->pInheritanceInfo &&
634 cmd->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
635 local_begin_info = *pBeginInfo;
636 local_begin_info.pInheritanceInfo = NULL;
637 pBeginInfo = &local_begin_info;
638 }
639
640 cmd_size = vn_sizeof_vkBeginCommandBuffer(commandBuffer, pBeginInfo);
641 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) {
642 cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
643 return vn_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
644 }
645
646 vn_encode_vkBeginCommandBuffer(&cmd->cs, 0, commandBuffer, pBeginInfo);
647
648 cmd->state = VN_COMMAND_BUFFER_STATE_RECORDING;
649
650 if (cmd->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY &&
651 (pBeginInfo->flags &
652 VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
653 const VkCommandBufferInheritanceInfo *inheritance_info =
654 pBeginInfo->pInheritanceInfo;
655 vn_cmd_begin_render_pass(
656 cmd, vn_render_pass_from_handle(inheritance_info->renderPass),
657 vn_framebuffer_from_handle(inheritance_info->framebuffer), NULL);
658 }
659
660 return VK_SUCCESS;
661 }
662
663 static VkResult
vn_cmd_submit(struct vn_command_buffer * cmd)664 vn_cmd_submit(struct vn_command_buffer *cmd)
665 {
666 struct vn_instance *instance = cmd->device->instance;
667
668 if (cmd->state != VN_COMMAND_BUFFER_STATE_RECORDING)
669 return VK_ERROR_OUT_OF_HOST_MEMORY;
670
671 vn_cs_encoder_commit(&cmd->cs);
672 if (vn_cs_encoder_get_fatal(&cmd->cs)) {
673 cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
674 vn_cs_encoder_reset(&cmd->cs);
675 return VK_ERROR_OUT_OF_HOST_MEMORY;
676 }
677
678 vn_instance_wait_roundtrip(instance, cmd->cs.current_buffer_roundtrip);
679 VkResult result = vn_instance_ring_submit(instance, &cmd->cs);
680 if (result != VK_SUCCESS) {
681 cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
682 return result;
683 }
684
685 vn_cs_encoder_reset(&cmd->cs);
686
687 return VK_SUCCESS;
688 }
689
690 VkResult
vn_EndCommandBuffer(VkCommandBuffer commandBuffer)691 vn_EndCommandBuffer(VkCommandBuffer commandBuffer)
692 {
693 struct vn_command_buffer *cmd =
694 vn_command_buffer_from_handle(commandBuffer);
695 struct vn_instance *instance = cmd->device->instance;
696 size_t cmd_size;
697
698 cmd_size = vn_sizeof_vkEndCommandBuffer(commandBuffer);
699 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) {
700 cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
701 return vn_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
702 }
703
704 vn_encode_vkEndCommandBuffer(&cmd->cs, 0, commandBuffer);
705
706 VkResult result = vn_cmd_submit(cmd);
707 if (result != VK_SUCCESS) {
708 cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
709 return vn_error(instance, result);
710 }
711
712 cmd->state = VN_COMMAND_BUFFER_STATE_EXECUTABLE;
713
714 return VK_SUCCESS;
715 }
716
717 void
vn_CmdBindPipeline(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipeline pipeline)718 vn_CmdBindPipeline(VkCommandBuffer commandBuffer,
719 VkPipelineBindPoint pipelineBindPoint,
720 VkPipeline pipeline)
721 {
722 struct vn_command_buffer *cmd =
723 vn_command_buffer_from_handle(commandBuffer);
724 size_t cmd_size;
725
726 cmd_size =
727 vn_sizeof_vkCmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline);
728 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
729 return;
730
731 vn_encode_vkCmdBindPipeline(&cmd->cs, 0, commandBuffer, pipelineBindPoint,
732 pipeline);
733 }
734
735 void
vn_CmdSetViewport(VkCommandBuffer commandBuffer,uint32_t firstViewport,uint32_t viewportCount,const VkViewport * pViewports)736 vn_CmdSetViewport(VkCommandBuffer commandBuffer,
737 uint32_t firstViewport,
738 uint32_t viewportCount,
739 const VkViewport *pViewports)
740 {
741 struct vn_command_buffer *cmd =
742 vn_command_buffer_from_handle(commandBuffer);
743 size_t cmd_size;
744
745 cmd_size = vn_sizeof_vkCmdSetViewport(commandBuffer, firstViewport,
746 viewportCount, pViewports);
747 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
748 return;
749
750 vn_encode_vkCmdSetViewport(&cmd->cs, 0, commandBuffer, firstViewport,
751 viewportCount, pViewports);
752 }
753
754 void
vn_CmdSetScissor(VkCommandBuffer commandBuffer,uint32_t firstScissor,uint32_t scissorCount,const VkRect2D * pScissors)755 vn_CmdSetScissor(VkCommandBuffer commandBuffer,
756 uint32_t firstScissor,
757 uint32_t scissorCount,
758 const VkRect2D *pScissors)
759 {
760 struct vn_command_buffer *cmd =
761 vn_command_buffer_from_handle(commandBuffer);
762 size_t cmd_size;
763
764 cmd_size = vn_sizeof_vkCmdSetScissor(commandBuffer, firstScissor,
765 scissorCount, pScissors);
766 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
767 return;
768
769 vn_encode_vkCmdSetScissor(&cmd->cs, 0, commandBuffer, firstScissor,
770 scissorCount, pScissors);
771 }
772
773 void
vn_CmdSetLineWidth(VkCommandBuffer commandBuffer,float lineWidth)774 vn_CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth)
775 {
776 struct vn_command_buffer *cmd =
777 vn_command_buffer_from_handle(commandBuffer);
778 size_t cmd_size;
779
780 cmd_size = vn_sizeof_vkCmdSetLineWidth(commandBuffer, lineWidth);
781 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
782 return;
783
784 vn_encode_vkCmdSetLineWidth(&cmd->cs, 0, commandBuffer, lineWidth);
785 }
786
787 void
vn_CmdSetDepthBias(VkCommandBuffer commandBuffer,float depthBiasConstantFactor,float depthBiasClamp,float depthBiasSlopeFactor)788 vn_CmdSetDepthBias(VkCommandBuffer commandBuffer,
789 float depthBiasConstantFactor,
790 float depthBiasClamp,
791 float depthBiasSlopeFactor)
792 {
793 struct vn_command_buffer *cmd =
794 vn_command_buffer_from_handle(commandBuffer);
795 size_t cmd_size;
796
797 cmd_size =
798 vn_sizeof_vkCmdSetDepthBias(commandBuffer, depthBiasConstantFactor,
799 depthBiasClamp, depthBiasSlopeFactor);
800 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
801 return;
802
803 vn_encode_vkCmdSetDepthBias(&cmd->cs, 0, commandBuffer,
804 depthBiasConstantFactor, depthBiasClamp,
805 depthBiasSlopeFactor);
806 }
807
808 void
vn_CmdSetBlendConstants(VkCommandBuffer commandBuffer,const float blendConstants[4])809 vn_CmdSetBlendConstants(VkCommandBuffer commandBuffer,
810 const float blendConstants[4])
811 {
812 struct vn_command_buffer *cmd =
813 vn_command_buffer_from_handle(commandBuffer);
814 size_t cmd_size;
815
816 cmd_size = vn_sizeof_vkCmdSetBlendConstants(commandBuffer, blendConstants);
817 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
818 return;
819
820 vn_encode_vkCmdSetBlendConstants(&cmd->cs, 0, commandBuffer,
821 blendConstants);
822 }
823
824 void
vn_CmdSetDepthBounds(VkCommandBuffer commandBuffer,float minDepthBounds,float maxDepthBounds)825 vn_CmdSetDepthBounds(VkCommandBuffer commandBuffer,
826 float minDepthBounds,
827 float maxDepthBounds)
828 {
829 struct vn_command_buffer *cmd =
830 vn_command_buffer_from_handle(commandBuffer);
831 size_t cmd_size;
832
833 cmd_size = vn_sizeof_vkCmdSetDepthBounds(commandBuffer, minDepthBounds,
834 maxDepthBounds);
835 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
836 return;
837
838 vn_encode_vkCmdSetDepthBounds(&cmd->cs, 0, commandBuffer, minDepthBounds,
839 maxDepthBounds);
840 }
841
842 void
vn_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,uint32_t compareMask)843 vn_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,
844 VkStencilFaceFlags faceMask,
845 uint32_t compareMask)
846 {
847 struct vn_command_buffer *cmd =
848 vn_command_buffer_from_handle(commandBuffer);
849 size_t cmd_size;
850
851 cmd_size = vn_sizeof_vkCmdSetStencilCompareMask(commandBuffer, faceMask,
852 compareMask);
853 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
854 return;
855
856 vn_encode_vkCmdSetStencilCompareMask(&cmd->cs, 0, commandBuffer, faceMask,
857 compareMask);
858 }
859
860 void
vn_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,uint32_t writeMask)861 vn_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,
862 VkStencilFaceFlags faceMask,
863 uint32_t writeMask)
864 {
865 struct vn_command_buffer *cmd =
866 vn_command_buffer_from_handle(commandBuffer);
867 size_t cmd_size;
868
869 cmd_size =
870 vn_sizeof_vkCmdSetStencilWriteMask(commandBuffer, faceMask, writeMask);
871 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
872 return;
873
874 vn_encode_vkCmdSetStencilWriteMask(&cmd->cs, 0, commandBuffer, faceMask,
875 writeMask);
876 }
877
878 void
vn_CmdSetStencilReference(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,uint32_t reference)879 vn_CmdSetStencilReference(VkCommandBuffer commandBuffer,
880 VkStencilFaceFlags faceMask,
881 uint32_t reference)
882 {
883 struct vn_command_buffer *cmd =
884 vn_command_buffer_from_handle(commandBuffer);
885 size_t cmd_size;
886
887 cmd_size =
888 vn_sizeof_vkCmdSetStencilReference(commandBuffer, faceMask, reference);
889 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
890 return;
891
892 vn_encode_vkCmdSetStencilReference(&cmd->cs, 0, commandBuffer, faceMask,
893 reference);
894 }
895
896 void
vn_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipelineLayout layout,uint32_t firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets,uint32_t dynamicOffsetCount,const uint32_t * pDynamicOffsets)897 vn_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,
898 VkPipelineBindPoint pipelineBindPoint,
899 VkPipelineLayout layout,
900 uint32_t firstSet,
901 uint32_t descriptorSetCount,
902 const VkDescriptorSet *pDescriptorSets,
903 uint32_t dynamicOffsetCount,
904 const uint32_t *pDynamicOffsets)
905 {
906 struct vn_command_buffer *cmd =
907 vn_command_buffer_from_handle(commandBuffer);
908 size_t cmd_size;
909
910 cmd_size = vn_sizeof_vkCmdBindDescriptorSets(
911 commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount,
912 pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
913 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
914 return;
915
916 vn_encode_vkCmdBindDescriptorSets(&cmd->cs, 0, commandBuffer,
917 pipelineBindPoint, layout, firstSet,
918 descriptorSetCount, pDescriptorSets,
919 dynamicOffsetCount, pDynamicOffsets);
920 }
921
922 void
vn_CmdBindIndexBuffer(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset,VkIndexType indexType)923 vn_CmdBindIndexBuffer(VkCommandBuffer commandBuffer,
924 VkBuffer buffer,
925 VkDeviceSize offset,
926 VkIndexType indexType)
927 {
928 struct vn_command_buffer *cmd =
929 vn_command_buffer_from_handle(commandBuffer);
930 size_t cmd_size;
931
932 cmd_size = vn_sizeof_vkCmdBindIndexBuffer(commandBuffer, buffer, offset,
933 indexType);
934 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
935 return;
936
937 vn_encode_vkCmdBindIndexBuffer(&cmd->cs, 0, commandBuffer, buffer, offset,
938 indexType);
939 }
940
941 void
vn_CmdBindVertexBuffers(VkCommandBuffer commandBuffer,uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * pBuffers,const VkDeviceSize * pOffsets)942 vn_CmdBindVertexBuffers(VkCommandBuffer commandBuffer,
943 uint32_t firstBinding,
944 uint32_t bindingCount,
945 const VkBuffer *pBuffers,
946 const VkDeviceSize *pOffsets)
947 {
948 struct vn_command_buffer *cmd =
949 vn_command_buffer_from_handle(commandBuffer);
950 size_t cmd_size;
951
952 cmd_size = vn_sizeof_vkCmdBindVertexBuffers(
953 commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
954 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
955 return;
956
957 vn_encode_vkCmdBindVertexBuffers(&cmd->cs, 0, commandBuffer, firstBinding,
958 bindingCount, pBuffers, pOffsets);
959 }
960
961 void
vn_CmdDraw(VkCommandBuffer commandBuffer,uint32_t vertexCount,uint32_t instanceCount,uint32_t firstVertex,uint32_t firstInstance)962 vn_CmdDraw(VkCommandBuffer commandBuffer,
963 uint32_t vertexCount,
964 uint32_t instanceCount,
965 uint32_t firstVertex,
966 uint32_t firstInstance)
967 {
968 struct vn_command_buffer *cmd =
969 vn_command_buffer_from_handle(commandBuffer);
970 size_t cmd_size;
971
972 cmd_size = vn_sizeof_vkCmdDraw(commandBuffer, vertexCount, instanceCount,
973 firstVertex, firstInstance);
974 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
975 return;
976
977 vn_encode_vkCmdDraw(&cmd->cs, 0, commandBuffer, vertexCount, instanceCount,
978 firstVertex, firstInstance);
979 }
980
981 void
vn_CmdDrawIndexed(VkCommandBuffer commandBuffer,uint32_t indexCount,uint32_t instanceCount,uint32_t firstIndex,int32_t vertexOffset,uint32_t firstInstance)982 vn_CmdDrawIndexed(VkCommandBuffer commandBuffer,
983 uint32_t indexCount,
984 uint32_t instanceCount,
985 uint32_t firstIndex,
986 int32_t vertexOffset,
987 uint32_t firstInstance)
988 {
989 struct vn_command_buffer *cmd =
990 vn_command_buffer_from_handle(commandBuffer);
991 size_t cmd_size;
992
993 cmd_size =
994 vn_sizeof_vkCmdDrawIndexed(commandBuffer, indexCount, instanceCount,
995 firstIndex, vertexOffset, firstInstance);
996 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
997 return;
998
999 vn_encode_vkCmdDrawIndexed(&cmd->cs, 0, commandBuffer, indexCount,
1000 instanceCount, firstIndex, vertexOffset,
1001 firstInstance);
1002 }
1003
1004 void
vn_CmdDrawIndirect(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset,uint32_t drawCount,uint32_t stride)1005 vn_CmdDrawIndirect(VkCommandBuffer commandBuffer,
1006 VkBuffer buffer,
1007 VkDeviceSize offset,
1008 uint32_t drawCount,
1009 uint32_t stride)
1010 {
1011 struct vn_command_buffer *cmd =
1012 vn_command_buffer_from_handle(commandBuffer);
1013 size_t cmd_size;
1014
1015 cmd_size = vn_sizeof_vkCmdDrawIndirect(commandBuffer, buffer, offset,
1016 drawCount, stride);
1017 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1018 return;
1019
1020 vn_encode_vkCmdDrawIndirect(&cmd->cs, 0, commandBuffer, buffer, offset,
1021 drawCount, stride);
1022 }
1023
1024 void
vn_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset,uint32_t drawCount,uint32_t stride)1025 vn_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer,
1026 VkBuffer buffer,
1027 VkDeviceSize offset,
1028 uint32_t drawCount,
1029 uint32_t stride)
1030 {
1031 struct vn_command_buffer *cmd =
1032 vn_command_buffer_from_handle(commandBuffer);
1033 size_t cmd_size;
1034
1035 cmd_size = vn_sizeof_vkCmdDrawIndexedIndirect(commandBuffer, buffer,
1036 offset, drawCount, stride);
1037 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1038 return;
1039
1040 vn_encode_vkCmdDrawIndexedIndirect(&cmd->cs, 0, commandBuffer, buffer,
1041 offset, drawCount, stride);
1042 }
1043
1044 void
vn_CmdDrawIndirectCount(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset,VkBuffer countBuffer,VkDeviceSize countBufferOffset,uint32_t maxDrawCount,uint32_t stride)1045 vn_CmdDrawIndirectCount(VkCommandBuffer commandBuffer,
1046 VkBuffer buffer,
1047 VkDeviceSize offset,
1048 VkBuffer countBuffer,
1049 VkDeviceSize countBufferOffset,
1050 uint32_t maxDrawCount,
1051 uint32_t stride)
1052 {
1053 struct vn_command_buffer *cmd =
1054 vn_command_buffer_from_handle(commandBuffer);
1055 size_t cmd_size;
1056
1057 cmd_size = vn_sizeof_vkCmdDrawIndirectCount(commandBuffer, buffer, offset,
1058 countBuffer, countBufferOffset,
1059 maxDrawCount, stride);
1060 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1061 return;
1062
1063 vn_encode_vkCmdDrawIndirectCount(&cmd->cs, 0, commandBuffer, buffer,
1064 offset, countBuffer, countBufferOffset,
1065 maxDrawCount, stride);
1066 }
1067
1068 void
vn_CmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset,VkBuffer countBuffer,VkDeviceSize countBufferOffset,uint32_t maxDrawCount,uint32_t stride)1069 vn_CmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer,
1070 VkBuffer buffer,
1071 VkDeviceSize offset,
1072 VkBuffer countBuffer,
1073 VkDeviceSize countBufferOffset,
1074 uint32_t maxDrawCount,
1075 uint32_t stride)
1076 {
1077 struct vn_command_buffer *cmd =
1078 vn_command_buffer_from_handle(commandBuffer);
1079 size_t cmd_size;
1080
1081 cmd_size = vn_sizeof_vkCmdDrawIndexedIndirectCount(
1082 commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1083 maxDrawCount, stride);
1084 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1085 return;
1086
1087 vn_encode_vkCmdDrawIndexedIndirectCount(
1088 &cmd->cs, 0, commandBuffer, buffer, offset, countBuffer,
1089 countBufferOffset, maxDrawCount, stride);
1090 }
1091
1092 void
vn_CmdDispatch(VkCommandBuffer commandBuffer,uint32_t groupCountX,uint32_t groupCountY,uint32_t groupCountZ)1093 vn_CmdDispatch(VkCommandBuffer commandBuffer,
1094 uint32_t groupCountX,
1095 uint32_t groupCountY,
1096 uint32_t groupCountZ)
1097 {
1098 struct vn_command_buffer *cmd =
1099 vn_command_buffer_from_handle(commandBuffer);
1100 size_t cmd_size;
1101
1102 cmd_size = vn_sizeof_vkCmdDispatch(commandBuffer, groupCountX, groupCountY,
1103 groupCountZ);
1104 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1105 return;
1106
1107 vn_encode_vkCmdDispatch(&cmd->cs, 0, commandBuffer, groupCountX,
1108 groupCountY, groupCountZ);
1109 }
1110
1111 void
vn_CmdDispatchIndirect(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset)1112 vn_CmdDispatchIndirect(VkCommandBuffer commandBuffer,
1113 VkBuffer buffer,
1114 VkDeviceSize offset)
1115 {
1116 struct vn_command_buffer *cmd =
1117 vn_command_buffer_from_handle(commandBuffer);
1118 size_t cmd_size;
1119
1120 cmd_size = vn_sizeof_vkCmdDispatchIndirect(commandBuffer, buffer, offset);
1121 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1122 return;
1123
1124 vn_encode_vkCmdDispatchIndirect(&cmd->cs, 0, commandBuffer, buffer,
1125 offset);
1126 }
1127
1128 void
vn_CmdCopyBuffer(VkCommandBuffer commandBuffer,VkBuffer srcBuffer,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferCopy * pRegions)1129 vn_CmdCopyBuffer(VkCommandBuffer commandBuffer,
1130 VkBuffer srcBuffer,
1131 VkBuffer dstBuffer,
1132 uint32_t regionCount,
1133 const VkBufferCopy *pRegions)
1134 {
1135 struct vn_command_buffer *cmd =
1136 vn_command_buffer_from_handle(commandBuffer);
1137 size_t cmd_size;
1138
1139 cmd_size = vn_sizeof_vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer,
1140 regionCount, pRegions);
1141 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1142 return;
1143
1144 vn_encode_vkCmdCopyBuffer(&cmd->cs, 0, commandBuffer, srcBuffer, dstBuffer,
1145 regionCount, pRegions);
1146 }
1147
1148 void
vn_CmdCopyImage(VkCommandBuffer commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageCopy * pRegions)1149 vn_CmdCopyImage(VkCommandBuffer commandBuffer,
1150 VkImage srcImage,
1151 VkImageLayout srcImageLayout,
1152 VkImage dstImage,
1153 VkImageLayout dstImageLayout,
1154 uint32_t regionCount,
1155 const VkImageCopy *pRegions)
1156 {
1157 struct vn_command_buffer *cmd =
1158 vn_command_buffer_from_handle(commandBuffer);
1159 size_t cmd_size;
1160
1161 cmd_size = vn_sizeof_vkCmdCopyImage(commandBuffer, srcImage,
1162 srcImageLayout, dstImage,
1163 dstImageLayout, regionCount, pRegions);
1164 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1165 return;
1166
1167 vn_encode_vkCmdCopyImage(&cmd->cs, 0, commandBuffer, srcImage,
1168 srcImageLayout, dstImage, dstImageLayout,
1169 regionCount, pRegions);
1170 }
1171
1172 void
vn_CmdBlitImage(VkCommandBuffer commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageBlit * pRegions,VkFilter filter)1173 vn_CmdBlitImage(VkCommandBuffer commandBuffer,
1174 VkImage srcImage,
1175 VkImageLayout srcImageLayout,
1176 VkImage dstImage,
1177 VkImageLayout dstImageLayout,
1178 uint32_t regionCount,
1179 const VkImageBlit *pRegions,
1180 VkFilter filter)
1181 {
1182 struct vn_command_buffer *cmd =
1183 vn_command_buffer_from_handle(commandBuffer);
1184 size_t cmd_size;
1185
1186 cmd_size = vn_sizeof_vkCmdBlitImage(
1187 commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
1188 regionCount, pRegions, filter);
1189 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1190 return;
1191
1192 vn_encode_vkCmdBlitImage(&cmd->cs, 0, commandBuffer, srcImage,
1193 srcImageLayout, dstImage, dstImageLayout,
1194 regionCount, pRegions, filter);
1195 }
1196
1197 void
vn_CmdCopyBufferToImage(VkCommandBuffer commandBuffer,VkBuffer srcBuffer,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkBufferImageCopy * pRegions)1198 vn_CmdCopyBufferToImage(VkCommandBuffer commandBuffer,
1199 VkBuffer srcBuffer,
1200 VkImage dstImage,
1201 VkImageLayout dstImageLayout,
1202 uint32_t regionCount,
1203 const VkBufferImageCopy *pRegions)
1204 {
1205 struct vn_command_buffer *cmd =
1206 vn_command_buffer_from_handle(commandBuffer);
1207 size_t cmd_size;
1208
1209 cmd_size =
1210 vn_sizeof_vkCmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage,
1211 dstImageLayout, regionCount, pRegions);
1212 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1213 return;
1214
1215 vn_encode_vkCmdCopyBufferToImage(&cmd->cs, 0, commandBuffer, srcBuffer,
1216 dstImage, dstImageLayout, regionCount,
1217 pRegions);
1218 }
1219
1220 void
vn_CmdCopyImageToBuffer(VkCommandBuffer commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferImageCopy * pRegions)1221 vn_CmdCopyImageToBuffer(VkCommandBuffer commandBuffer,
1222 VkImage srcImage,
1223 VkImageLayout srcImageLayout,
1224 VkBuffer dstBuffer,
1225 uint32_t regionCount,
1226 const VkBufferImageCopy *pRegions)
1227 {
1228 struct vn_command_buffer *cmd =
1229 vn_command_buffer_from_handle(commandBuffer);
1230 size_t cmd_size;
1231
1232 bool prime_blit = false;
1233 if (srcImageLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR &&
1234 VN_PRESENT_SRC_INTERNAL_LAYOUT != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
1235 srcImageLayout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
1236
1237 /* sanity check */
1238 const struct vn_image *img = vn_image_from_handle(srcImage);
1239 prime_blit = img->is_wsi && img->is_prime_blit_src;
1240 assert(prime_blit);
1241 }
1242
1243 cmd_size = vn_sizeof_vkCmdCopyImageToBuffer(commandBuffer, srcImage,
1244 srcImageLayout, dstBuffer,
1245 regionCount, pRegions);
1246 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1247 return;
1248
1249 vn_encode_vkCmdCopyImageToBuffer(&cmd->cs, 0, commandBuffer, srcImage,
1250 srcImageLayout, dstBuffer, regionCount,
1251 pRegions);
1252
1253 if (prime_blit) {
1254 const VkBufferMemoryBarrier buf_barrier = {
1255 .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1256 .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
1257 .srcQueueFamilyIndex = cmd->queue_family_index,
1258 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT,
1259 .buffer = dstBuffer,
1260 .size = VK_WHOLE_SIZE,
1261 };
1262 vn_cmd_encode_memory_barriers(cmd, VK_PIPELINE_STAGE_TRANSFER_BIT,
1263 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 1,
1264 &buf_barrier, 0, NULL);
1265 }
1266 }
1267
1268 void
vn_CmdUpdateBuffer(VkCommandBuffer commandBuffer,VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize dataSize,const void * pData)1269 vn_CmdUpdateBuffer(VkCommandBuffer commandBuffer,
1270 VkBuffer dstBuffer,
1271 VkDeviceSize dstOffset,
1272 VkDeviceSize dataSize,
1273 const void *pData)
1274 {
1275 struct vn_command_buffer *cmd =
1276 vn_command_buffer_from_handle(commandBuffer);
1277 size_t cmd_size;
1278
1279 cmd_size = vn_sizeof_vkCmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset,
1280 dataSize, pData);
1281 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1282 return;
1283
1284 vn_encode_vkCmdUpdateBuffer(&cmd->cs, 0, commandBuffer, dstBuffer,
1285 dstOffset, dataSize, pData);
1286 }
1287
1288 void
vn_CmdFillBuffer(VkCommandBuffer commandBuffer,VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize size,uint32_t data)1289 vn_CmdFillBuffer(VkCommandBuffer commandBuffer,
1290 VkBuffer dstBuffer,
1291 VkDeviceSize dstOffset,
1292 VkDeviceSize size,
1293 uint32_t data)
1294 {
1295 struct vn_command_buffer *cmd =
1296 vn_command_buffer_from_handle(commandBuffer);
1297 size_t cmd_size;
1298
1299 cmd_size = vn_sizeof_vkCmdFillBuffer(commandBuffer, dstBuffer, dstOffset,
1300 size, data);
1301 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1302 return;
1303
1304 vn_encode_vkCmdFillBuffer(&cmd->cs, 0, commandBuffer, dstBuffer, dstOffset,
1305 size, data);
1306 }
1307
1308 void
vn_CmdClearColorImage(VkCommandBuffer commandBuffer,VkImage image,VkImageLayout imageLayout,const VkClearColorValue * pColor,uint32_t rangeCount,const VkImageSubresourceRange * pRanges)1309 vn_CmdClearColorImage(VkCommandBuffer commandBuffer,
1310 VkImage image,
1311 VkImageLayout imageLayout,
1312 const VkClearColorValue *pColor,
1313 uint32_t rangeCount,
1314 const VkImageSubresourceRange *pRanges)
1315 {
1316 struct vn_command_buffer *cmd =
1317 vn_command_buffer_from_handle(commandBuffer);
1318 size_t cmd_size;
1319
1320 cmd_size = vn_sizeof_vkCmdClearColorImage(
1321 commandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
1322 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1323 return;
1324
1325 vn_encode_vkCmdClearColorImage(&cmd->cs, 0, commandBuffer, image,
1326 imageLayout, pColor, rangeCount, pRanges);
1327 }
1328
1329 void
vn_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer,VkImage image,VkImageLayout imageLayout,const VkClearDepthStencilValue * pDepthStencil,uint32_t rangeCount,const VkImageSubresourceRange * pRanges)1330 vn_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer,
1331 VkImage image,
1332 VkImageLayout imageLayout,
1333 const VkClearDepthStencilValue *pDepthStencil,
1334 uint32_t rangeCount,
1335 const VkImageSubresourceRange *pRanges)
1336 {
1337 struct vn_command_buffer *cmd =
1338 vn_command_buffer_from_handle(commandBuffer);
1339 size_t cmd_size;
1340
1341 cmd_size = vn_sizeof_vkCmdClearDepthStencilImage(
1342 commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
1343 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1344 return;
1345
1346 vn_encode_vkCmdClearDepthStencilImage(&cmd->cs, 0, commandBuffer, image,
1347 imageLayout, pDepthStencil,
1348 rangeCount, pRanges);
1349 }
1350
1351 void
vn_CmdClearAttachments(VkCommandBuffer commandBuffer,uint32_t attachmentCount,const VkClearAttachment * pAttachments,uint32_t rectCount,const VkClearRect * pRects)1352 vn_CmdClearAttachments(VkCommandBuffer commandBuffer,
1353 uint32_t attachmentCount,
1354 const VkClearAttachment *pAttachments,
1355 uint32_t rectCount,
1356 const VkClearRect *pRects)
1357 {
1358 struct vn_command_buffer *cmd =
1359 vn_command_buffer_from_handle(commandBuffer);
1360 size_t cmd_size;
1361
1362 cmd_size = vn_sizeof_vkCmdClearAttachments(
1363 commandBuffer, attachmentCount, pAttachments, rectCount, pRects);
1364 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1365 return;
1366
1367 vn_encode_vkCmdClearAttachments(&cmd->cs, 0, commandBuffer,
1368 attachmentCount, pAttachments, rectCount,
1369 pRects);
1370 }
1371
1372 void
vn_CmdResolveImage(VkCommandBuffer commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageResolve * pRegions)1373 vn_CmdResolveImage(VkCommandBuffer commandBuffer,
1374 VkImage srcImage,
1375 VkImageLayout srcImageLayout,
1376 VkImage dstImage,
1377 VkImageLayout dstImageLayout,
1378 uint32_t regionCount,
1379 const VkImageResolve *pRegions)
1380 {
1381 struct vn_command_buffer *cmd =
1382 vn_command_buffer_from_handle(commandBuffer);
1383 size_t cmd_size;
1384
1385 cmd_size = vn_sizeof_vkCmdResolveImage(
1386 commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
1387 regionCount, pRegions);
1388 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1389 return;
1390
1391 vn_encode_vkCmdResolveImage(&cmd->cs, 0, commandBuffer, srcImage,
1392 srcImageLayout, dstImage, dstImageLayout,
1393 regionCount, pRegions);
1394 }
1395
1396 void
vn_CmdSetEvent(VkCommandBuffer commandBuffer,VkEvent event,VkPipelineStageFlags stageMask)1397 vn_CmdSetEvent(VkCommandBuffer commandBuffer,
1398 VkEvent event,
1399 VkPipelineStageFlags stageMask)
1400 {
1401 struct vn_command_buffer *cmd =
1402 vn_command_buffer_from_handle(commandBuffer);
1403 size_t cmd_size;
1404
1405 cmd_size = vn_sizeof_vkCmdSetEvent(commandBuffer, event, stageMask);
1406 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1407 return;
1408
1409 vn_encode_vkCmdSetEvent(&cmd->cs, 0, commandBuffer, event, stageMask);
1410 }
1411
1412 void
vn_CmdResetEvent(VkCommandBuffer commandBuffer,VkEvent event,VkPipelineStageFlags stageMask)1413 vn_CmdResetEvent(VkCommandBuffer commandBuffer,
1414 VkEvent event,
1415 VkPipelineStageFlags stageMask)
1416 {
1417 struct vn_command_buffer *cmd =
1418 vn_command_buffer_from_handle(commandBuffer);
1419 size_t cmd_size;
1420
1421 cmd_size = vn_sizeof_vkCmdResetEvent(commandBuffer, event, stageMask);
1422 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1423 return;
1424
1425 vn_encode_vkCmdResetEvent(&cmd->cs, 0, commandBuffer, event, stageMask);
1426 }
1427
1428 void
vn_CmdWaitEvents(VkCommandBuffer commandBuffer,uint32_t eventCount,const VkEvent * pEvents,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,uint32_t memoryBarrierCount,const VkMemoryBarrier * pMemoryBarriers,uint32_t bufferMemoryBarrierCount,const VkBufferMemoryBarrier * pBufferMemoryBarriers,uint32_t imageMemoryBarrierCount,const VkImageMemoryBarrier * pImageMemoryBarriers)1429 vn_CmdWaitEvents(VkCommandBuffer commandBuffer,
1430 uint32_t eventCount,
1431 const VkEvent *pEvents,
1432 VkPipelineStageFlags srcStageMask,
1433 VkPipelineStageFlags dstStageMask,
1434 uint32_t memoryBarrierCount,
1435 const VkMemoryBarrier *pMemoryBarriers,
1436 uint32_t bufferMemoryBarrierCount,
1437 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
1438 uint32_t imageMemoryBarrierCount,
1439 const VkImageMemoryBarrier *pImageMemoryBarriers)
1440 {
1441 struct vn_command_buffer *cmd =
1442 vn_command_buffer_from_handle(commandBuffer);
1443 size_t cmd_size;
1444
1445 uint32_t transfer_count;
1446 pImageMemoryBarriers = vn_cmd_wait_events_fix_image_memory_barriers(
1447 cmd, pImageMemoryBarriers, imageMemoryBarrierCount, &transfer_count);
1448 imageMemoryBarrierCount -= transfer_count;
1449
1450 cmd_size = vn_sizeof_vkCmdWaitEvents(
1451 commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask,
1452 memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
1453 pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
1454 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1455 return;
1456
1457 vn_encode_vkCmdWaitEvents(&cmd->cs, 0, commandBuffer, eventCount, pEvents,
1458 srcStageMask, dstStageMask, memoryBarrierCount,
1459 pMemoryBarriers, bufferMemoryBarrierCount,
1460 pBufferMemoryBarriers, imageMemoryBarrierCount,
1461 pImageMemoryBarriers);
1462
1463 if (transfer_count) {
1464 pImageMemoryBarriers += imageMemoryBarrierCount;
1465 vn_cmd_encode_memory_barriers(cmd, srcStageMask, dstStageMask, 0, NULL,
1466 transfer_count, pImageMemoryBarriers);
1467 }
1468 }
1469
1470 void
vn_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)1471 vn_CmdPipelineBarrier(VkCommandBuffer commandBuffer,
1472 VkPipelineStageFlags srcStageMask,
1473 VkPipelineStageFlags dstStageMask,
1474 VkDependencyFlags dependencyFlags,
1475 uint32_t memoryBarrierCount,
1476 const VkMemoryBarrier *pMemoryBarriers,
1477 uint32_t bufferMemoryBarrierCount,
1478 const VkBufferMemoryBarrier *pBufferMemoryBarriers,
1479 uint32_t imageMemoryBarrierCount,
1480 const VkImageMemoryBarrier *pImageMemoryBarriers)
1481 {
1482 struct vn_command_buffer *cmd =
1483 vn_command_buffer_from_handle(commandBuffer);
1484 size_t cmd_size;
1485
1486 pImageMemoryBarriers = vn_cmd_pipeline_barrier_fix_image_memory_barriers(
1487 cmd, pImageMemoryBarriers, imageMemoryBarrierCount);
1488
1489 cmd_size = vn_sizeof_vkCmdPipelineBarrier(
1490 commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
1491 memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
1492 pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
1493 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1494 return;
1495
1496 vn_encode_vkCmdPipelineBarrier(
1497 &cmd->cs, 0, commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
1498 memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
1499 pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
1500 }
1501
1502 void
vn_CmdBeginQuery(VkCommandBuffer commandBuffer,VkQueryPool queryPool,uint32_t query,VkQueryControlFlags flags)1503 vn_CmdBeginQuery(VkCommandBuffer commandBuffer,
1504 VkQueryPool queryPool,
1505 uint32_t query,
1506 VkQueryControlFlags flags)
1507 {
1508 struct vn_command_buffer *cmd =
1509 vn_command_buffer_from_handle(commandBuffer);
1510 size_t cmd_size;
1511
1512 cmd_size =
1513 vn_sizeof_vkCmdBeginQuery(commandBuffer, queryPool, query, flags);
1514 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1515 return;
1516
1517 vn_encode_vkCmdBeginQuery(&cmd->cs, 0, commandBuffer, queryPool, query,
1518 flags);
1519 }
1520
1521 void
vn_CmdEndQuery(VkCommandBuffer commandBuffer,VkQueryPool queryPool,uint32_t query)1522 vn_CmdEndQuery(VkCommandBuffer commandBuffer,
1523 VkQueryPool queryPool,
1524 uint32_t query)
1525 {
1526 struct vn_command_buffer *cmd =
1527 vn_command_buffer_from_handle(commandBuffer);
1528 size_t cmd_size;
1529
1530 cmd_size = vn_sizeof_vkCmdEndQuery(commandBuffer, queryPool, query);
1531 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1532 return;
1533
1534 vn_encode_vkCmdEndQuery(&cmd->cs, 0, commandBuffer, queryPool, query);
1535 }
1536
1537 void
vn_CmdResetQueryPool(VkCommandBuffer commandBuffer,VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount)1538 vn_CmdResetQueryPool(VkCommandBuffer commandBuffer,
1539 VkQueryPool queryPool,
1540 uint32_t firstQuery,
1541 uint32_t queryCount)
1542 {
1543 struct vn_command_buffer *cmd =
1544 vn_command_buffer_from_handle(commandBuffer);
1545 size_t cmd_size;
1546
1547 cmd_size = vn_sizeof_vkCmdResetQueryPool(commandBuffer, queryPool,
1548 firstQuery, queryCount);
1549 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1550 return;
1551
1552 vn_encode_vkCmdResetQueryPool(&cmd->cs, 0, commandBuffer, queryPool,
1553 firstQuery, queryCount);
1554 }
1555
1556 void
vn_CmdWriteTimestamp(VkCommandBuffer commandBuffer,VkPipelineStageFlagBits pipelineStage,VkQueryPool queryPool,uint32_t query)1557 vn_CmdWriteTimestamp(VkCommandBuffer commandBuffer,
1558 VkPipelineStageFlagBits pipelineStage,
1559 VkQueryPool queryPool,
1560 uint32_t query)
1561 {
1562 struct vn_command_buffer *cmd =
1563 vn_command_buffer_from_handle(commandBuffer);
1564 size_t cmd_size;
1565
1566 cmd_size = vn_sizeof_vkCmdWriteTimestamp(commandBuffer, pipelineStage,
1567 queryPool, query);
1568 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1569 return;
1570
1571 vn_encode_vkCmdWriteTimestamp(&cmd->cs, 0, commandBuffer, pipelineStage,
1572 queryPool, query);
1573 }
1574
1575 void
vn_CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer,VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount,VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize stride,VkQueryResultFlags flags)1576 vn_CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer,
1577 VkQueryPool queryPool,
1578 uint32_t firstQuery,
1579 uint32_t queryCount,
1580 VkBuffer dstBuffer,
1581 VkDeviceSize dstOffset,
1582 VkDeviceSize stride,
1583 VkQueryResultFlags flags)
1584 {
1585 struct vn_command_buffer *cmd =
1586 vn_command_buffer_from_handle(commandBuffer);
1587 size_t cmd_size;
1588
1589 cmd_size = vn_sizeof_vkCmdCopyQueryPoolResults(
1590 commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset,
1591 stride, flags);
1592 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1593 return;
1594
1595 vn_encode_vkCmdCopyQueryPoolResults(&cmd->cs, 0, commandBuffer, queryPool,
1596 firstQuery, queryCount, dstBuffer,
1597 dstOffset, stride, flags);
1598 }
1599
1600 void
vn_CmdPushConstants(VkCommandBuffer commandBuffer,VkPipelineLayout layout,VkShaderStageFlags stageFlags,uint32_t offset,uint32_t size,const void * pValues)1601 vn_CmdPushConstants(VkCommandBuffer commandBuffer,
1602 VkPipelineLayout layout,
1603 VkShaderStageFlags stageFlags,
1604 uint32_t offset,
1605 uint32_t size,
1606 const void *pValues)
1607 {
1608 struct vn_command_buffer *cmd =
1609 vn_command_buffer_from_handle(commandBuffer);
1610 size_t cmd_size;
1611
1612 cmd_size = vn_sizeof_vkCmdPushConstants(commandBuffer, layout, stageFlags,
1613 offset, size, pValues);
1614 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1615 return;
1616
1617 vn_encode_vkCmdPushConstants(&cmd->cs, 0, commandBuffer, layout,
1618 stageFlags, offset, size, pValues);
1619 }
1620
1621 void
vn_CmdBeginRenderPass(VkCommandBuffer commandBuffer,const VkRenderPassBeginInfo * pRenderPassBegin,VkSubpassContents contents)1622 vn_CmdBeginRenderPass(VkCommandBuffer commandBuffer,
1623 const VkRenderPassBeginInfo *pRenderPassBegin,
1624 VkSubpassContents contents)
1625 {
1626 struct vn_command_buffer *cmd =
1627 vn_command_buffer_from_handle(commandBuffer);
1628 size_t cmd_size;
1629
1630 vn_cmd_begin_render_pass(
1631 cmd, vn_render_pass_from_handle(pRenderPassBegin->renderPass),
1632 vn_framebuffer_from_handle(pRenderPassBegin->framebuffer),
1633 pRenderPassBegin);
1634
1635 cmd_size = vn_sizeof_vkCmdBeginRenderPass(commandBuffer, pRenderPassBegin,
1636 contents);
1637 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1638 return;
1639
1640 vn_encode_vkCmdBeginRenderPass(&cmd->cs, 0, commandBuffer,
1641 pRenderPassBegin, contents);
1642 }
1643
1644 void
vn_CmdNextSubpass(VkCommandBuffer commandBuffer,VkSubpassContents contents)1645 vn_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
1646 {
1647 struct vn_command_buffer *cmd =
1648 vn_command_buffer_from_handle(commandBuffer);
1649 size_t cmd_size;
1650
1651 cmd_size = vn_sizeof_vkCmdNextSubpass(commandBuffer, contents);
1652 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1653 return;
1654
1655 vn_encode_vkCmdNextSubpass(&cmd->cs, 0, commandBuffer, contents);
1656 }
1657
1658 void
vn_CmdEndRenderPass(VkCommandBuffer commandBuffer)1659 vn_CmdEndRenderPass(VkCommandBuffer commandBuffer)
1660 {
1661 struct vn_command_buffer *cmd =
1662 vn_command_buffer_from_handle(commandBuffer);
1663 size_t cmd_size;
1664
1665 cmd_size = vn_sizeof_vkCmdEndRenderPass(commandBuffer);
1666 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1667 return;
1668
1669 vn_encode_vkCmdEndRenderPass(&cmd->cs, 0, commandBuffer);
1670
1671 vn_cmd_end_render_pass(cmd);
1672 }
1673
1674 void
vn_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,const VkRenderPassBeginInfo * pRenderPassBegin,const VkSubpassBeginInfo * pSubpassBeginInfo)1675 vn_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,
1676 const VkRenderPassBeginInfo *pRenderPassBegin,
1677 const VkSubpassBeginInfo *pSubpassBeginInfo)
1678 {
1679 struct vn_command_buffer *cmd =
1680 vn_command_buffer_from_handle(commandBuffer);
1681 size_t cmd_size;
1682
1683 vn_cmd_begin_render_pass(
1684 cmd, vn_render_pass_from_handle(pRenderPassBegin->renderPass),
1685 vn_framebuffer_from_handle(pRenderPassBegin->framebuffer),
1686 pRenderPassBegin);
1687
1688 cmd_size = vn_sizeof_vkCmdBeginRenderPass2(commandBuffer, pRenderPassBegin,
1689 pSubpassBeginInfo);
1690 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1691 return;
1692
1693 vn_encode_vkCmdBeginRenderPass2(&cmd->cs, 0, commandBuffer,
1694 pRenderPassBegin, pSubpassBeginInfo);
1695 }
1696
1697 void
vn_CmdNextSubpass2(VkCommandBuffer commandBuffer,const VkSubpassBeginInfo * pSubpassBeginInfo,const VkSubpassEndInfo * pSubpassEndInfo)1698 vn_CmdNextSubpass2(VkCommandBuffer commandBuffer,
1699 const VkSubpassBeginInfo *pSubpassBeginInfo,
1700 const VkSubpassEndInfo *pSubpassEndInfo)
1701 {
1702 struct vn_command_buffer *cmd =
1703 vn_command_buffer_from_handle(commandBuffer);
1704 size_t cmd_size;
1705
1706 cmd_size = vn_sizeof_vkCmdNextSubpass2(commandBuffer, pSubpassBeginInfo,
1707 pSubpassEndInfo);
1708 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1709 return;
1710
1711 vn_encode_vkCmdNextSubpass2(&cmd->cs, 0, commandBuffer, pSubpassBeginInfo,
1712 pSubpassEndInfo);
1713 }
1714
1715 void
vn_CmdEndRenderPass2(VkCommandBuffer commandBuffer,const VkSubpassEndInfo * pSubpassEndInfo)1716 vn_CmdEndRenderPass2(VkCommandBuffer commandBuffer,
1717 const VkSubpassEndInfo *pSubpassEndInfo)
1718 {
1719 struct vn_command_buffer *cmd =
1720 vn_command_buffer_from_handle(commandBuffer);
1721 size_t cmd_size;
1722
1723 cmd_size = vn_sizeof_vkCmdEndRenderPass2(commandBuffer, pSubpassEndInfo);
1724 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1725 return;
1726
1727 vn_encode_vkCmdEndRenderPass2(&cmd->cs, 0, commandBuffer, pSubpassEndInfo);
1728
1729 vn_cmd_end_render_pass(cmd);
1730 }
1731
1732 void
vn_CmdExecuteCommands(VkCommandBuffer commandBuffer,uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)1733 vn_CmdExecuteCommands(VkCommandBuffer commandBuffer,
1734 uint32_t commandBufferCount,
1735 const VkCommandBuffer *pCommandBuffers)
1736 {
1737 struct vn_command_buffer *cmd =
1738 vn_command_buffer_from_handle(commandBuffer);
1739 size_t cmd_size;
1740
1741 cmd_size = vn_sizeof_vkCmdExecuteCommands(
1742 commandBuffer, commandBufferCount, pCommandBuffers);
1743 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1744 return;
1745
1746 vn_encode_vkCmdExecuteCommands(&cmd->cs, 0, commandBuffer,
1747 commandBufferCount, pCommandBuffers);
1748 }
1749
1750 void
vn_CmdSetDeviceMask(VkCommandBuffer commandBuffer,uint32_t deviceMask)1751 vn_CmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask)
1752 {
1753 struct vn_command_buffer *cmd =
1754 vn_command_buffer_from_handle(commandBuffer);
1755 size_t cmd_size;
1756
1757 cmd_size = vn_sizeof_vkCmdSetDeviceMask(commandBuffer, deviceMask);
1758 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1759 return;
1760
1761 vn_encode_vkCmdSetDeviceMask(&cmd->cs, 0, commandBuffer, deviceMask);
1762 }
1763
1764 void
vn_CmdDispatchBase(VkCommandBuffer commandBuffer,uint32_t baseGroupX,uint32_t baseGroupY,uint32_t baseGroupZ,uint32_t groupCountX,uint32_t groupCountY,uint32_t groupCountZ)1765 vn_CmdDispatchBase(VkCommandBuffer commandBuffer,
1766 uint32_t baseGroupX,
1767 uint32_t baseGroupY,
1768 uint32_t baseGroupZ,
1769 uint32_t groupCountX,
1770 uint32_t groupCountY,
1771 uint32_t groupCountZ)
1772 {
1773 struct vn_command_buffer *cmd =
1774 vn_command_buffer_from_handle(commandBuffer);
1775 size_t cmd_size;
1776
1777 cmd_size = vn_sizeof_vkCmdDispatchBase(commandBuffer, baseGroupX,
1778 baseGroupY, baseGroupZ, groupCountX,
1779 groupCountY, groupCountZ);
1780 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1781 return;
1782
1783 vn_encode_vkCmdDispatchBase(&cmd->cs, 0, commandBuffer, baseGroupX,
1784 baseGroupY, baseGroupZ, groupCountX,
1785 groupCountY, groupCountZ);
1786 }
1787
1788 void
vn_CmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer,VkQueryPool queryPool,uint32_t query,VkQueryControlFlags flags,uint32_t index)1789 vn_CmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer,
1790 VkQueryPool queryPool,
1791 uint32_t query,
1792 VkQueryControlFlags flags,
1793 uint32_t index)
1794 {
1795 struct vn_command_buffer *cmd =
1796 vn_command_buffer_from_handle(commandBuffer);
1797 size_t cmd_size;
1798
1799 cmd_size = vn_sizeof_vkCmdBeginQueryIndexedEXT(commandBuffer, queryPool,
1800 query, flags, index);
1801 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1802 return;
1803
1804 vn_encode_vkCmdBeginQueryIndexedEXT(&cmd->cs, 0, commandBuffer, queryPool,
1805 query, flags, index);
1806 }
1807
1808 void
vn_CmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer,VkQueryPool queryPool,uint32_t query,uint32_t index)1809 vn_CmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer,
1810 VkQueryPool queryPool,
1811 uint32_t query,
1812 uint32_t index)
1813 {
1814 struct vn_command_buffer *cmd =
1815 vn_command_buffer_from_handle(commandBuffer);
1816 size_t cmd_size;
1817
1818 cmd_size = vn_sizeof_vkCmdEndQueryIndexedEXT(commandBuffer, queryPool,
1819 query, index);
1820 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1821 return;
1822
1823 vn_encode_vkCmdEndQueryIndexedEXT(&cmd->cs, 0, commandBuffer, queryPool,
1824 query, index);
1825 }
1826
1827 void
vn_CmdBindTransformFeedbackBuffersEXT(VkCommandBuffer commandBuffer,uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * pBuffers,const VkDeviceSize * pOffsets,const VkDeviceSize * pSizes)1828 vn_CmdBindTransformFeedbackBuffersEXT(VkCommandBuffer commandBuffer,
1829 uint32_t firstBinding,
1830 uint32_t bindingCount,
1831 const VkBuffer *pBuffers,
1832 const VkDeviceSize *pOffsets,
1833 const VkDeviceSize *pSizes)
1834 {
1835 struct vn_command_buffer *cmd =
1836 vn_command_buffer_from_handle(commandBuffer);
1837 size_t cmd_size;
1838
1839 cmd_size = vn_sizeof_vkCmdBindTransformFeedbackBuffersEXT(
1840 commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes);
1841 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1842 return;
1843
1844 vn_encode_vkCmdBindTransformFeedbackBuffersEXT(&cmd->cs, 0, commandBuffer,
1845 firstBinding, bindingCount,
1846 pBuffers, pOffsets, pSizes);
1847 }
1848
1849 void
vn_CmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer,uint32_t firstCounterBuffer,uint32_t counterBufferCount,const VkBuffer * pCounterBuffers,const VkDeviceSize * pCounterBufferOffsets)1850 vn_CmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer,
1851 uint32_t firstCounterBuffer,
1852 uint32_t counterBufferCount,
1853 const VkBuffer *pCounterBuffers,
1854 const VkDeviceSize *pCounterBufferOffsets)
1855 {
1856 struct vn_command_buffer *cmd =
1857 vn_command_buffer_from_handle(commandBuffer);
1858 size_t cmd_size;
1859
1860 cmd_size = vn_sizeof_vkCmdBeginTransformFeedbackEXT(
1861 commandBuffer, firstCounterBuffer, counterBufferCount, pCounterBuffers,
1862 pCounterBufferOffsets);
1863 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1864 return;
1865
1866 vn_encode_vkCmdBeginTransformFeedbackEXT(
1867 &cmd->cs, 0, commandBuffer, firstCounterBuffer, counterBufferCount,
1868 pCounterBuffers, pCounterBufferOffsets);
1869 }
1870
1871 void
vn_CmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer,uint32_t firstCounterBuffer,uint32_t counterBufferCount,const VkBuffer * pCounterBuffers,const VkDeviceSize * pCounterBufferOffsets)1872 vn_CmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer,
1873 uint32_t firstCounterBuffer,
1874 uint32_t counterBufferCount,
1875 const VkBuffer *pCounterBuffers,
1876 const VkDeviceSize *pCounterBufferOffsets)
1877 {
1878 struct vn_command_buffer *cmd =
1879 vn_command_buffer_from_handle(commandBuffer);
1880 size_t cmd_size;
1881
1882 cmd_size = vn_sizeof_vkCmdEndTransformFeedbackEXT(
1883 commandBuffer, firstCounterBuffer, counterBufferCount, pCounterBuffers,
1884 pCounterBufferOffsets);
1885 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1886 return;
1887
1888 vn_encode_vkCmdEndTransformFeedbackEXT(
1889 &cmd->cs, 0, commandBuffer, firstCounterBuffer, counterBufferCount,
1890 pCounterBuffers, pCounterBufferOffsets);
1891 }
1892
1893 void
vn_CmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer,uint32_t instanceCount,uint32_t firstInstance,VkBuffer counterBuffer,VkDeviceSize counterBufferOffset,uint32_t counterOffset,uint32_t vertexStride)1894 vn_CmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer,
1895 uint32_t instanceCount,
1896 uint32_t firstInstance,
1897 VkBuffer counterBuffer,
1898 VkDeviceSize counterBufferOffset,
1899 uint32_t counterOffset,
1900 uint32_t vertexStride)
1901 {
1902 struct vn_command_buffer *cmd =
1903 vn_command_buffer_from_handle(commandBuffer);
1904 size_t cmd_size;
1905
1906 cmd_size = vn_sizeof_vkCmdDrawIndirectByteCountEXT(
1907 commandBuffer, instanceCount, firstInstance, counterBuffer,
1908 counterBufferOffset, counterOffset, vertexStride);
1909 if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size))
1910 return;
1911
1912 vn_encode_vkCmdDrawIndirectByteCountEXT(
1913 &cmd->cs, 0, commandBuffer, instanceCount, firstInstance, counterBuffer,
1914 counterBufferOffset, counterOffset, vertexStride);
1915 }
1916