~mmach/netext73/mesa-ryzen

« back to all changes in this revision

Viewing changes to src/virtio/vulkan/vn_command_buffer.c

  • Committer: mmach
  • Date: 2023-11-02 21:31:35 UTC
  • Revision ID: netbit73@gmail.com-20231102213135-18d4tzh7tj0uz752
2023-11-02 22:11:57

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
#include "vn_descriptor_set.h"
17
17
#include "vn_device.h"
18
18
#include "vn_image.h"
 
19
#include "vn_query_pool.h"
19
20
#include "vn_render_pass.h"
20
21
 
21
22
static void
72
73
   /* avoid shrinking in case of non efficient reallocation implementation */
73
74
   if (size > cmd->builder.tmp.size) {
74
75
      void *data =
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);
77
78
      if (!data)
78
79
         return NULL;
504
505
                                 count, img_barriers);
505
506
}
506
507
 
 
508
/* query feedback batch for deferred recording */
 
509
struct vn_command_buffer_query_batch {
 
510
   struct vn_query_pool *query_pool;
 
511
   uint32_t query;
 
512
   uint32_t query_count;
 
513
 
 
514
   struct list_head head;
 
515
};
 
516
 
 
517
static bool
 
518
vn_cmd_query_batch_push(struct vn_command_buffer *cmd,
 
519
                        struct vn_query_pool *query_pool,
 
520
                        uint32_t query,
 
521
                        uint32_t query_count)
 
522
{
 
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);
 
527
      if (!batch)
 
528
         return false;
 
529
   } else {
 
530
      batch = list_first_entry(&cmd->pool->free_query_batches,
 
531
                               struct vn_command_buffer_query_batch, head);
 
532
      list_del(&batch->head);
 
533
   }
 
534
 
 
535
   batch->query_pool = query_pool;
 
536
   batch->query = query;
 
537
   batch->query_count = query_count;
 
538
   list_add(&batch->head, &cmd->query_batches);
 
539
 
 
540
   return true;
 
541
}
 
542
 
 
543
static inline void
 
544
vn_cmd_query_batch_pop(struct vn_command_buffer *cmd,
 
545
                       struct vn_command_buffer_query_batch *batch)
 
546
{
 
547
   list_move_to(&batch->head, &cmd->pool->free_query_batches);
 
548
}
 
549
 
 
550
static void
 
551
vn_cmd_record_batched_query_feedback(struct vn_command_buffer *cmd)
 
552
{
 
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,
 
558
         batch->query_count);
 
559
 
 
560
      vn_cmd_query_batch_pop(cmd, batch);
 
561
   }
 
562
}
 
563
 
 
564
static inline void
 
565
vn_cmd_merge_batched_query_feedback(struct vn_command_buffer *primary_cmd,
 
566
                                    struct vn_command_buffer *secondary_cmd)
 
567
{
 
568
   list_for_each_entry_safe(struct vn_command_buffer_query_batch,
 
569
                            secondary_batch, &secondary_cmd->query_batches,
 
570
                            head) {
 
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;
 
575
         return;
 
576
      }
 
577
   }
 
578
}
 
579
 
507
580
static void
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;
515
588
 
 
589
   if (begin_info) {
 
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;
 
594
   }
 
595
 
516
596
   if (!pass->present_count ||
517
597
       cmd->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY)
518
598
      return;
533
613
   }
534
614
 
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);
538
618
   if (!images) {
539
619
      cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
563
643
   cmd->builder.render_pass = NULL;
564
644
   cmd->builder.framebuffer = NULL;
565
645
 
 
646
   vn_cmd_record_batched_query_feedback(cmd);
 
647
   cmd->in_render_pass = false;
 
648
   cmd->render_pass = NULL;
 
649
   cmd->subpass_index = 0;
 
650
   cmd->view_mask = 0;
 
651
 
566
652
   if (!pass->present_count || !cmd->builder.present_src_images)
567
653
      return;
568
654
 
575
661
         pass->present_release_attachments, pass->present_release_count);
576
662
   }
577
663
 
578
 
   vk_free(&cmd->allocator, images);
 
664
   vk_free(&cmd->pool->allocator, images);
579
665
}
580
666
 
581
667
/* command pool commands */
600
686
   vn_object_base_init(&pool->base, VK_OBJECT_TYPE_COMMAND_POOL, &dev->base);
601
687
 
602
688
   pool->allocator = *alloc;
 
689
   pool->device = dev;
603
690
   pool->queue_family_index = pCreateInfo->queueFamilyIndex;
604
691
   list_inithead(&pool->command_buffers);
 
692
   list_inithead(&pool->free_query_batches);
605
693
 
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);
 
729
 
 
730
      if (cmd->builder.present_src_images)
 
731
         vk_free(alloc, cmd->builder.present_src_images);
 
732
 
 
733
      if (cmd->builder.tmp.data)
 
734
         vk_free(alloc, cmd->builder.tmp.data);
 
735
 
 
736
      list_for_each_entry_safe(struct vn_command_buffer_query_batch, batch,
 
737
                               &cmd->query_batches, head)
 
738
         vk_free(alloc, batch);
 
739
 
641
740
      vk_free(alloc, cmd);
642
741
   }
643
742
 
 
743
   list_for_each_entry_safe(struct vn_command_buffer_query_batch, batch,
 
744
                            &pool->free_query_batches, head)
 
745
      vk_free(alloc, batch);
 
746
 
644
747
   vn_object_base_fini(&pool->base);
645
748
   vk_free(alloc, pool);
646
749
}
649
752
vn_cmd_reset(struct vn_command_buffer *cmd)
650
753
{
651
754
   vn_cs_encoder_reset(&cmd->cs);
 
755
 
 
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;
 
760
   }
 
761
 
652
762
   cmd->state = VN_COMMAND_BUFFER_STATE_INITIAL;
653
763
   cmd->draw_cmd_batched = 0;
 
764
 
 
765
   cmd->in_render_pass = false;
 
766
   cmd->suspends = false;
 
767
   cmd->render_pass = NULL;
 
768
   cmd->subpass_index = 0;
 
769
   cmd->view_mask = 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);
654
773
}
655
774
 
656
775
VkResult
663
782
   struct vn_command_pool *pool = vn_command_pool_from_handle(commandPool);
664
783
 
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);
668
 
   }
669
787
 
670
788
   vn_async_vkResetCommandPool(dev->instance, device, commandPool, flags);
671
789
 
715
833
 
716
834
      vn_object_base_init(&cmd->base, VK_OBJECT_TYPE_COMMAND_BUFFER,
717
835
                          &dev->base);
718
 
      cmd->device = dev;
719
 
      cmd->allocator = pool->allocator;
 
836
      cmd->pool = pool;
720
837
      cmd->level = pAllocateInfo->level;
721
838
      cmd->queue_family_index = pool->queue_family_index;
722
839
 
726
843
      vn_cs_encoder_init(&cmd->cs, dev->instance,
727
844
                         VN_CS_ENCODER_STORAGE_SHMEM_POOL, 16 * 1024);
728
845
 
 
846
      list_inithead(&cmd->query_batches);
 
847
 
729
848
      VkCommandBuffer cmd_handle = vn_command_buffer_to_handle(cmd);
730
849
      pCommandBuffers[i] = cmd_handle;
731
850
   }
760
879
      if (cmd->builder.tmp.data)
761
880
         vk_free(alloc, cmd->builder.tmp.data);
762
881
 
 
882
      if (cmd->builder.present_src_images)
 
883
         vk_free(alloc, cmd->builder.present_src_images);
 
884
 
763
885
      vn_cs_encoder_fini(&cmd->cs);
764
886
      list_del(&cmd->head);
765
887
 
 
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);
 
891
 
766
892
      vn_object_base_fini(&cmd->base);
767
893
      vk_free(alloc, cmd);
768
894
   }
775
901
   VN_TRACE_FUNC();
776
902
   struct vn_command_buffer *cmd =
777
903
      vn_command_buffer_from_handle(commandBuffer);
 
904
   struct vn_instance *instance = cmd->pool->device->instance;
778
905
 
779
906
   vn_cmd_reset(cmd);
780
907
 
781
 
   vn_async_vkResetCommandBuffer(cmd->device->instance, commandBuffer, flags);
 
908
   vn_async_vkResetCommandBuffer(instance, commandBuffer, flags);
782
909
 
783
910
   return VK_SUCCESS;
784
911
}
789
916
   VkCommandBufferInheritanceConditionalRenderingInfoEXT conditional_rendering;
790
917
 
791
918
   bool has_inherited_pass;
 
919
   bool in_render_pass;
792
920
};
793
921
 
794
922
static const VkCommandBufferBeginInfo *
809
937
      is_cmd_secondary &&
810
938
      begin_info->pInheritanceInfo->renderPass != VK_NULL_HANDLE;
811
939
 
 
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."
 
944
    */
 
945
   local->in_render_pass = has_continue && is_cmd_secondary;
 
946
 
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.
814
949
    */
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;
883
1018
 
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 */
 
1020
   vn_cmd_reset(cmd);
886
1021
 
887
1022
   struct vn_command_buffer_begin_info local_begin_info;
888
1023
   pBeginInfo =
898
1033
 
899
1034
   cmd->state = VN_COMMAND_BUFFER_STATE_RECORDING;
900
1035
 
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;
 
1038
 
 
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);
 
1045
 
 
1046
         /* Store the viewMask from the inherited render pass subpass for
 
1047
          * query feedback.
 
1048
          */
 
1049
         const struct vn_render_pass *pass =
 
1050
            vn_render_pass_from_handle(inheritance_info->renderPass);
 
1051
         cmd->view_mask =
 
1052
            pass->subpasses[inheritance_info->subpass].view_mask;
 
1053
      } else {
 
1054
         /* Store the viewMask from the
 
1055
          * VkCommandBufferInheritanceRenderingInfo.
 
1056
          */
 
1057
         const VkCommandBufferInheritanceRenderingInfo
 
1058
            *inheritance_rendering_info = vk_find_struct_const(
 
1059
               inheritance_info->pNext,
 
1060
               COMMAND_BUFFER_INHERITANCE_RENDERING_INFO);
 
1061
 
 
1062
         if (inheritance_rendering_info)
 
1063
            cmd->view_mask = inheritance_rendering_info->viewMask;
 
1064
      }
907
1065
   }
908
1066
 
909
1067
   return VK_SUCCESS;
912
1070
static void
913
1071
vn_cmd_submit(struct vn_command_buffer *cmd)
914
1072
{
915
 
   struct vn_instance *instance = cmd->device->instance;
 
1073
   struct vn_instance *instance = cmd->pool->device->instance;
916
1074
 
917
1075
   if (cmd->state != VN_COMMAND_BUFFER_STATE_RECORDING)
918
1076
      return;
946
1104
   VN_TRACE_FUNC();
947
1105
   struct vn_command_buffer *cmd =
948
1106
      vn_command_buffer_from_handle(commandBuffer);
949
 
   struct vn_instance *instance = cmd->device->instance;
 
1107
   struct vn_instance *instance = cmd->pool->device->instance;
950
1108
   size_t cmd_size;
951
1109
 
952
1110
   if (cmd->state != VN_COMMAND_BUFFER_STATE_RECORDING)
1111
1269
vn_CmdBeginRendering(VkCommandBuffer commandBuffer,
1112
1270
                     const VkRenderingInfo *pRenderingInfo)
1113
1271
{
 
1272
   struct vn_command_buffer *cmd =
 
1273
      vn_command_buffer_from_handle(commandBuffer);
 
1274
 
 
1275
   cmd->in_render_pass = true;
 
1276
   cmd->view_mask = pRenderingInfo->viewMask;
 
1277
 
 
1278
   cmd->suspends = pRenderingInfo->flags & VK_RENDERING_SUSPENDING_BIT;
 
1279
 
1114
1280
   VN_CMD_ENQUEUE(vkCmdBeginRendering, commandBuffer, pRenderingInfo);
1115
1281
}
1116
1282
 
1117
1283
void
1118
1284
vn_CmdEndRendering(VkCommandBuffer commandBuffer)
1119
1285
{
 
1286
   struct vn_command_buffer *cmd =
 
1287
      vn_command_buffer_from_handle(commandBuffer);
 
1288
 
1120
1289
   VN_CMD_ENQUEUE(vkCmdEndRendering, commandBuffer);
 
1290
 
 
1291
   /* Feedback commands not allowed during suspended render pass either
 
1292
    * so defer until it actually ends.
 
1293
    */
 
1294
   if (!cmd->suspends) {
 
1295
      vn_cmd_record_batched_query_feedback(cmd);
 
1296
      cmd->in_render_pass = false;
 
1297
      cmd->view_mask = 0;
 
1298
   }
1121
1299
}
1122
1300
 
1123
1301
void
1609
1787
   VN_CMD_ENQUEUE(vkCmdBeginQuery, commandBuffer, queryPool, query, flags);
1610
1788
}
1611
1789
 
 
1790
static inline void
 
1791
vn_cmd_add_query_feedback(VkCommandBuffer cmd_handle,
 
1792
                          VkQueryPool pool_handle,
 
1793
                          uint32_t query)
 
1794
{
 
1795
   struct vn_command_buffer *cmd = vn_command_buffer_from_handle(cmd_handle);
 
1796
 
 
1797
   /* Outside the render pass instance, vkCmdCopyQueryPoolResults can be
 
1798
    * directly appended. Otherwise, defer the copy cmd until outside.
 
1799
    */
 
1800
   if (!cmd->in_render_pass) {
 
1801
      vn_feedback_query_copy_cmd_record(cmd_handle, pool_handle, query, 1);
 
1802
      return;
 
1803
   }
 
1804
 
 
1805
   struct vn_query_pool *pool = vn_query_pool_from_handle(pool_handle);
 
1806
   if (!pool->feedback)
 
1807
      return;
 
1808
 
 
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."
 
1813
    */
 
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;
 
1818
}
 
1819
 
1612
1820
void
1613
1821
vn_CmdEndQuery(VkCommandBuffer commandBuffer,
1614
1822
               VkQueryPool queryPool,
1615
1823
               uint32_t query)
1616
1824
{
1617
1825
   VN_CMD_ENQUEUE(vkCmdEndQuery, commandBuffer, queryPool, query);
 
1826
 
 
1827
   vn_cmd_add_query_feedback(commandBuffer, queryPool, query);
1618
1828
}
1619
1829
 
1620
1830
void
1625
1835
{
1626
1836
   VN_CMD_ENQUEUE(vkCmdResetQueryPool, commandBuffer, queryPool, firstQuery,
1627
1837
                  queryCount);
 
1838
 
 
1839
   vn_feedback_query_reset_cmd_record(commandBuffer, queryPool, firstQuery,
 
1840
                                      queryCount);
1628
1841
}
1629
1842
 
1630
1843
void
1635
1848
{
1636
1849
   VN_CMD_ENQUEUE(vkCmdWriteTimestamp, commandBuffer, pipelineStage,
1637
1850
                  queryPool, query);
 
1851
 
 
1852
   vn_cmd_add_query_feedback(commandBuffer, queryPool, query);
1638
1853
}
1639
1854
 
1640
1855
void
1645
1860
{
1646
1861
   VN_CMD_ENQUEUE(vkCmdWriteTimestamp2, commandBuffer, stage, queryPool,
1647
1862
                  query);
 
1863
 
 
1864
   vn_cmd_add_query_feedback(commandBuffer, queryPool, query);
1648
1865
}
1649
1866
 
1650
1867
void
1694
1911
void
1695
1912
vn_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
1696
1913
{
 
1914
   struct vn_command_buffer *cmd =
 
1915
      vn_command_buffer_from_handle(commandBuffer);
 
1916
   cmd->view_mask =
 
1917
      cmd->render_pass->subpasses[++cmd->subpass_index].view_mask;
 
1918
 
1697
1919
   VN_CMD_ENQUEUE(vkCmdNextSubpass, commandBuffer, contents);
1698
1920
}
1699
1921
 
1730
1952
                   const VkSubpassBeginInfo *pSubpassBeginInfo,
1731
1953
                   const VkSubpassEndInfo *pSubpassEndInfo)
1732
1954
{
 
1955
   struct vn_command_buffer *cmd =
 
1956
      vn_command_buffer_from_handle(commandBuffer);
 
1957
   cmd->view_mask =
 
1958
      cmd->render_pass->subpasses[++cmd->subpass_index].view_mask;
 
1959
 
1733
1960
   VN_CMD_ENQUEUE(vkCmdNextSubpass2, commandBuffer, pSubpassBeginInfo,
1734
1961
                  pSubpassEndInfo);
1735
1962
}
1751
1978
                      uint32_t commandBufferCount,
1752
1979
                      const VkCommandBuffer *pCommandBuffers)
1753
1980
{
 
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);
 
1985
 
 
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);
 
1992
      }
 
1993
   }
1756
1994
}
1757
1995
 
1758
1996
void
1802
2040
{
1803
2041
   VN_CMD_ENQUEUE(vkCmdEndQueryIndexedEXT, commandBuffer, queryPool, query,
1804
2042
                  index);
 
2043
 
 
2044
   vn_cmd_add_query_feedback(commandBuffer, queryPool, query);
1805
2045
}
1806
2046
 
1807
2047
void
1971
2211
}
1972
2212
 
1973
2213
void
 
2214
vn_CmdSetColorWriteEnableEXT(VkCommandBuffer commandBuffer,
 
2215
                             uint32_t attachmentCount,
 
2216
                             const VkBool32 *pColorWriteEnables)
 
2217
{
 
2218
   VN_CMD_ENQUEUE(vkCmdSetColorWriteEnableEXT, commandBuffer, attachmentCount,
 
2219
                  pColorWriteEnables);
 
2220
}
 
2221
 
 
2222
void
1974
2223
vn_CmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer,
1975
2224
                               uint32_t patchControlPoints)
1976
2225
{
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,
 
2308
            layout);
2059
2309
      if (!update) {
2060
2310
         cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
2061
 
         vn_log(cmd->device->instance,
2062
 
                "descriptor set push ignored due to OOM");
2063
2311
         return;
2064
2312
      }
2065
2313
 
2067
2315
                     pipelineBindPoint, layout, set, update->write_count,
2068
2316
                     update->writes);
2069
2317
 
2070
 
      vk_free(&cmd->allocator, update);
 
2318
      vk_free(&cmd->pool->allocator, update);
2071
2319
   } else {
2072
2320
      VN_CMD_ENQUEUE(vkCmdPushDescriptorSetKHR, commandBuffer,
2073
2321
                     pipelineBindPoint, layout, set, descriptorWriteCount,