72
73
/* avoid shrinking in case of non efficient reallocation implementation */
73
74
if (size > cmd->builder.tmp.size) {
75
vk_realloc(&cmd->allocator, cmd->builder.tmp.data, size,
76
vk_realloc(&cmd->pool->allocator, cmd->builder.tmp.data, size,
76
77
VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
504
505
count, img_barriers);
508
/* query feedback batch for deferred recording */
509
struct vn_command_buffer_query_batch {
510
struct vn_query_pool *query_pool;
512
uint32_t query_count;
514
struct list_head head;
518
vn_cmd_query_batch_push(struct vn_command_buffer *cmd,
519
struct vn_query_pool *query_pool,
521
uint32_t query_count)
523
struct vn_command_buffer_query_batch *batch;
524
if (list_is_empty(&cmd->pool->free_query_batches)) {
525
batch = vk_alloc(&cmd->pool->allocator, sizeof(*batch),
526
VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
530
batch = list_first_entry(&cmd->pool->free_query_batches,
531
struct vn_command_buffer_query_batch, head);
532
list_del(&batch->head);
535
batch->query_pool = query_pool;
536
batch->query = query;
537
batch->query_count = query_count;
538
list_add(&batch->head, &cmd->query_batches);
544
vn_cmd_query_batch_pop(struct vn_command_buffer *cmd,
545
struct vn_command_buffer_query_batch *batch)
547
list_move_to(&batch->head, &cmd->pool->free_query_batches);
551
vn_cmd_record_batched_query_feedback(struct vn_command_buffer *cmd)
553
list_for_each_entry_safe(struct vn_command_buffer_query_batch, batch,
554
&cmd->query_batches, head) {
555
vn_feedback_query_copy_cmd_record(
556
vn_command_buffer_to_handle(cmd),
557
vn_query_pool_to_handle(batch->query_pool), batch->query,
560
vn_cmd_query_batch_pop(cmd, batch);
565
vn_cmd_merge_batched_query_feedback(struct vn_command_buffer *primary_cmd,
566
struct vn_command_buffer *secondary_cmd)
568
list_for_each_entry_safe(struct vn_command_buffer_query_batch,
569
secondary_batch, &secondary_cmd->query_batches,
571
if (!vn_cmd_query_batch_push(primary_cmd, secondary_batch->query_pool,
572
secondary_batch->query,
573
secondary_batch->query_count)) {
574
primary_cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
508
581
vn_cmd_begin_render_pass(struct vn_command_buffer *cmd,
509
582
const struct vn_render_pass *pass,
513
586
cmd->builder.render_pass = pass;
514
587
cmd->builder.framebuffer = fb;
590
cmd->in_render_pass = true;
591
cmd->render_pass = pass;
592
cmd->subpass_index = 0;
593
cmd->view_mask = cmd->render_pass->subpasses[0].view_mask;
516
596
if (!pass->present_count ||
517
597
cmd->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY)
535
615
const struct vn_image **images =
536
vk_alloc(&cmd->allocator, sizeof(*images) * pass->present_count,
616
vk_alloc(&cmd->pool->allocator, sizeof(*images) * pass->present_count,
537
617
VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
539
619
cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
600
686
vn_object_base_init(&pool->base, VK_OBJECT_TYPE_COMMAND_POOL, &dev->base);
602
688
pool->allocator = *alloc;
603
690
pool->queue_family_index = pCreateInfo->queueFamilyIndex;
604
691
list_inithead(&pool->command_buffers);
692
list_inithead(&pool->free_query_batches);
606
694
VkCommandPool pool_handle = vn_command_pool_to_handle(pool);
607
695
vn_async_vkCreateCommandPool(dev->instance, device, pCreateInfo, NULL,
638
726
&pool->command_buffers, head) {
639
727
vn_cs_encoder_fini(&cmd->cs);
640
728
vn_object_base_fini(&cmd->base);
730
if (cmd->builder.present_src_images)
731
vk_free(alloc, cmd->builder.present_src_images);
733
if (cmd->builder.tmp.data)
734
vk_free(alloc, cmd->builder.tmp.data);
736
list_for_each_entry_safe(struct vn_command_buffer_query_batch, batch,
737
&cmd->query_batches, head)
738
vk_free(alloc, batch);
641
740
vk_free(alloc, cmd);
743
list_for_each_entry_safe(struct vn_command_buffer_query_batch, batch,
744
&pool->free_query_batches, head)
745
vk_free(alloc, batch);
644
747
vn_object_base_fini(&pool->base);
645
748
vk_free(alloc, pool);
649
752
vn_cmd_reset(struct vn_command_buffer *cmd)
651
754
vn_cs_encoder_reset(&cmd->cs);
756
cmd->builder.render_pass = NULL;
757
if (cmd->builder.present_src_images) {
758
vk_free(&cmd->pool->allocator, cmd->builder.present_src_images);
759
cmd->builder.present_src_images = NULL;
652
762
cmd->state = VN_COMMAND_BUFFER_STATE_INITIAL;
653
763
cmd->draw_cmd_batched = 0;
765
cmd->in_render_pass = false;
766
cmd->suspends = false;
767
cmd->render_pass = NULL;
768
cmd->subpass_index = 0;
770
list_for_each_entry_safe(struct vn_command_buffer_query_batch, batch,
771
&cmd->query_batches, head)
772
vn_cmd_query_batch_pop(cmd, batch);
663
782
struct vn_command_pool *pool = vn_command_pool_from_handle(commandPool);
665
784
list_for_each_entry_safe(struct vn_command_buffer, cmd,
666
&pool->command_buffers, head) {
785
&pool->command_buffers, head)
667
786
vn_cmd_reset(cmd);
670
788
vn_async_vkResetCommandPool(dev->instance, device, commandPool, flags);
726
843
vn_cs_encoder_init(&cmd->cs, dev->instance,
727
844
VN_CS_ENCODER_STORAGE_SHMEM_POOL, 16 * 1024);
846
list_inithead(&cmd->query_batches);
729
848
VkCommandBuffer cmd_handle = vn_command_buffer_to_handle(cmd);
730
849
pCommandBuffers[i] = cmd_handle;
760
879
if (cmd->builder.tmp.data)
761
880
vk_free(alloc, cmd->builder.tmp.data);
882
if (cmd->builder.present_src_images)
883
vk_free(alloc, cmd->builder.present_src_images);
763
885
vn_cs_encoder_fini(&cmd->cs);
764
886
list_del(&cmd->head);
888
list_for_each_entry_safe(struct vn_command_buffer_query_batch, batch,
889
&cmd->query_batches, head)
890
vn_cmd_query_batch_pop(cmd, batch);
766
892
vn_object_base_fini(&cmd->base);
767
893
vk_free(alloc, cmd);
776
902
struct vn_command_buffer *cmd =
777
903
vn_command_buffer_from_handle(commandBuffer);
904
struct vn_instance *instance = cmd->pool->device->instance;
779
906
vn_cmd_reset(cmd);
781
vn_async_vkResetCommandBuffer(cmd->device->instance, commandBuffer, flags);
908
vn_async_vkResetCommandBuffer(instance, commandBuffer, flags);
783
910
return VK_SUCCESS;
809
937
is_cmd_secondary &&
810
938
begin_info->pInheritanceInfo->renderPass != VK_NULL_HANDLE;
940
/* Per spec 1.3.255: "VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
941
* specifies that a secondary command buffer is considered to be
942
* entirely inside a render pass. If this is a primary command buffer,
943
* then this bit is ignored."
945
local->in_render_pass = has_continue && is_cmd_secondary;
812
947
/* Can early-return if dynamic rendering is used and no structures need to
813
948
* be dropped from the pNext chain of VkCommandBufferInheritanceInfo.
878
1013
VN_TRACE_FUNC();
879
1014
struct vn_command_buffer *cmd =
880
1015
vn_command_buffer_from_handle(commandBuffer);
881
struct vn_instance *instance = cmd->device->instance;
1016
struct vn_instance *instance = cmd->pool->device->instance;
882
1017
size_t cmd_size;
884
vn_cs_encoder_reset(&cmd->cs);
885
cmd->draw_cmd_batched = 0;
1019
/* reset regardless of VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT */
887
1022
struct vn_command_buffer_begin_info local_begin_info;
899
1034
cmd->state = VN_COMMAND_BUFFER_STATE_RECORDING;
901
if (local_begin_info.has_inherited_pass) {
902
const VkCommandBufferInheritanceInfo *inheritance_info =
903
pBeginInfo->pInheritanceInfo;
904
vn_cmd_begin_render_pass(
905
cmd, vn_render_pass_from_handle(inheritance_info->renderPass),
906
vn_framebuffer_from_handle(inheritance_info->framebuffer), NULL);
1036
const VkCommandBufferInheritanceInfo *inheritance_info =
1037
pBeginInfo->pInheritanceInfo;
1039
if (inheritance_info) {
1040
cmd->in_render_pass = local_begin_info.in_render_pass;
1041
if (local_begin_info.has_inherited_pass) {
1042
vn_cmd_begin_render_pass(
1043
cmd, vn_render_pass_from_handle(inheritance_info->renderPass),
1044
vn_framebuffer_from_handle(inheritance_info->framebuffer), NULL);
1046
/* Store the viewMask from the inherited render pass subpass for
1049
const struct vn_render_pass *pass =
1050
vn_render_pass_from_handle(inheritance_info->renderPass);
1052
pass->subpasses[inheritance_info->subpass].view_mask;
1054
/* Store the viewMask from the
1055
* VkCommandBufferInheritanceRenderingInfo.
1057
const VkCommandBufferInheritanceRenderingInfo
1058
*inheritance_rendering_info = vk_find_struct_const(
1059
inheritance_info->pNext,
1060
COMMAND_BUFFER_INHERITANCE_RENDERING_INFO);
1062
if (inheritance_rendering_info)
1063
cmd->view_mask = inheritance_rendering_info->viewMask;
909
1067
return VK_SUCCESS;
1111
1269
vn_CmdBeginRendering(VkCommandBuffer commandBuffer,
1112
1270
const VkRenderingInfo *pRenderingInfo)
1272
struct vn_command_buffer *cmd =
1273
vn_command_buffer_from_handle(commandBuffer);
1275
cmd->in_render_pass = true;
1276
cmd->view_mask = pRenderingInfo->viewMask;
1278
cmd->suspends = pRenderingInfo->flags & VK_RENDERING_SUSPENDING_BIT;
1114
1280
VN_CMD_ENQUEUE(vkCmdBeginRendering, commandBuffer, pRenderingInfo);
1118
1284
vn_CmdEndRendering(VkCommandBuffer commandBuffer)
1286
struct vn_command_buffer *cmd =
1287
vn_command_buffer_from_handle(commandBuffer);
1120
1289
VN_CMD_ENQUEUE(vkCmdEndRendering, commandBuffer);
1291
/* Feedback commands not allowed during suspended render pass either
1292
* so defer until it actually ends.
1294
if (!cmd->suspends) {
1295
vn_cmd_record_batched_query_feedback(cmd);
1296
cmd->in_render_pass = false;
1609
1787
VN_CMD_ENQUEUE(vkCmdBeginQuery, commandBuffer, queryPool, query, flags);
1791
vn_cmd_add_query_feedback(VkCommandBuffer cmd_handle,
1792
VkQueryPool pool_handle,
1795
struct vn_command_buffer *cmd = vn_command_buffer_from_handle(cmd_handle);
1797
/* Outside the render pass instance, vkCmdCopyQueryPoolResults can be
1798
* directly appended. Otherwise, defer the copy cmd until outside.
1800
if (!cmd->in_render_pass) {
1801
vn_feedback_query_copy_cmd_record(cmd_handle, pool_handle, query, 1);
1805
struct vn_query_pool *pool = vn_query_pool_from_handle(pool_handle);
1806
if (!pool->feedback)
1809
/* Per 1.3.255 spec "If queries are used while executing a render pass
1810
* instance that has multiview enabled, the query uses N consecutive query
1811
* indices in the query pool (starting at query) where N is the number of
1812
* bits set in the view mask in the subpass the query is used in."
1814
const uint32_t query_count =
1815
cmd->view_mask ? util_bitcount(cmd->view_mask) : 1;
1816
if (!vn_cmd_query_batch_push(cmd, pool, query, query_count))
1817
cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
1613
1821
vn_CmdEndQuery(VkCommandBuffer commandBuffer,
1614
1822
VkQueryPool queryPool,
1615
1823
uint32_t query)
1617
1825
VN_CMD_ENQUEUE(vkCmdEndQuery, commandBuffer, queryPool, query);
1827
vn_cmd_add_query_feedback(commandBuffer, queryPool, query);
1695
1912
vn_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
1914
struct vn_command_buffer *cmd =
1915
vn_command_buffer_from_handle(commandBuffer);
1917
cmd->render_pass->subpasses[++cmd->subpass_index].view_mask;
1697
1919
VN_CMD_ENQUEUE(vkCmdNextSubpass, commandBuffer, contents);
1730
1952
const VkSubpassBeginInfo *pSubpassBeginInfo,
1731
1953
const VkSubpassEndInfo *pSubpassEndInfo)
1955
struct vn_command_buffer *cmd =
1956
vn_command_buffer_from_handle(commandBuffer);
1958
cmd->render_pass->subpasses[++cmd->subpass_index].view_mask;
1733
1960
VN_CMD_ENQUEUE(vkCmdNextSubpass2, commandBuffer, pSubpassBeginInfo,
1734
1961
pSubpassEndInfo);
1751
1978
uint32_t commandBufferCount,
1752
1979
const VkCommandBuffer *pCommandBuffers)
1981
struct vn_command_buffer *primary_cmd =
1982
vn_command_buffer_from_handle(commandBuffer);
1754
1983
VN_CMD_ENQUEUE(vkCmdExecuteCommands, commandBuffer, commandBufferCount,
1755
1984
pCommandBuffers);
1986
if (primary_cmd->in_render_pass) {
1987
for (uint32_t i = 0; i < commandBufferCount; i++) {
1988
struct vn_command_buffer *secondary_cmd =
1989
vn_command_buffer_from_handle(pCommandBuffers[i]);
1990
assert(secondary_cmd->in_render_pass);
1991
vn_cmd_merge_batched_query_feedback(primary_cmd, secondary_cmd);
2214
vn_CmdSetColorWriteEnableEXT(VkCommandBuffer commandBuffer,
2215
uint32_t attachmentCount,
2216
const VkBool32 *pColorWriteEnables)
2218
VN_CMD_ENQUEUE(vkCmdSetColorWriteEnableEXT, commandBuffer, attachmentCount,
2219
pColorWriteEnables);
1974
2223
vn_CmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer,
1975
2224
uint32_t patchControlPoints)
2055
2304
vn_command_buffer_from_handle(commandBuffer);
2056
2305
struct vn_update_descriptor_sets *update =
2057
2306
vn_update_descriptor_sets_parse_writes(
2058
descriptorWriteCount, pDescriptorWrites, &cmd->allocator, layout);
2307
descriptorWriteCount, pDescriptorWrites, &cmd->pool->allocator,
2060
2310
cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
2061
vn_log(cmd->device->instance,
2062
"descriptor set push ignored due to OOM");
2067
2315
pipelineBindPoint, layout, set, update->write_count,
2068
2316
update->writes);
2070
vk_free(&cmd->allocator, update);
2318
vk_free(&cmd->pool->allocator, update);
2072
2320
VN_CMD_ENQUEUE(vkCmdPushDescriptorSetKHR, commandBuffer,
2073
2321
pipelineBindPoint, layout, set, descriptorWriteCount,