@@ -76,8 +76,14 @@ static VkDeviceSize g_BufferMemoryAlignment = 256;
76
76
static VkPipelineCreateFlags g_PipelineCreateFlags = 0x00 ;
77
77
static VkDescriptorSetLayout g_DescriptorSetLayout = VK_NULL_HANDLE;
78
78
static VkPipelineLayout g_PipelineLayout = VK_NULL_HANDLE;
79
- static VkDescriptorSet g_DescriptorSet = VK_NULL_HANDLE;
80
79
static VkPipeline g_Pipeline = VK_NULL_HANDLE;
80
+ static ImTextureID g_hLastTextureSet = NULL ;
81
+
82
+ // Default Descriptor management
83
+ static uint32_t g_DescriptorPoolSize = 32 ; // will create and double on first frame
84
+ static uint32_t g_DescriptorsAllocated = 32 ;
85
+ static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
86
+ ImVector<VkDescriptorPool> g_DescriptorPoolToDelete;
81
87
82
88
// Font data
83
89
static VkSampler g_FontSampler = VK_NULL_HANDLE;
@@ -269,8 +275,6 @@ static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkCommandBu
269
275
// Bind pipeline and descriptor sets:
270
276
{
271
277
vkCmdBindPipeline (command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_Pipeline);
272
- VkDescriptorSet desc_set[1 ] = { g_DescriptorSet };
273
- vkCmdBindDescriptorSets (command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_PipelineLayout, 0 , 1 , desc_set, 0 , NULL );
274
278
}
275
279
276
280
// Bind Vertex And Index Buffer:
@@ -305,6 +309,8 @@ static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkCommandBu
305
309
vkCmdPushConstants (command_buffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof (float ) * 0 , sizeof (float ) * 2 , scale);
306
310
vkCmdPushConstants (command_buffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof (float ) * 2 , sizeof (float ) * 2 , translate);
307
311
}
312
+
313
+ g_hLastTextureSet = NULL ;
308
314
}
309
315
310
316
// Render function
@@ -317,6 +323,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
317
323
if (fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount == 0 )
318
324
return ;
319
325
326
+ ImGuiIO& io = ImGui::GetIO ();
320
327
ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo;
321
328
322
329
// Allocate array to store enough vertex/index buffers
@@ -371,6 +378,25 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
371
378
vkUnmapMemory (v->Device , rb->IndexBufferMemory );
372
379
}
373
380
381
+ // Reset descriptor pool once per draw
382
+ if (g_DescriptorPool)
383
+ {
384
+ err = vkResetDescriptorPool (v->Device , g_DescriptorPool, 0 );
385
+ check_vk_result (err);
386
+
387
+ g_DescriptorsAllocated = 0 ;
388
+
389
+ // destroy old pools
390
+ if (!g_DescriptorPoolToDelete.empty ())
391
+ {
392
+ for (int i = 0 ; i < g_DescriptorPoolToDelete.size (); i++)
393
+ {
394
+ vkDestroyDescriptorPool (v->Device , g_DescriptorPoolToDelete[i], v->Allocator );
395
+ }
396
+ g_DescriptorPoolToDelete.resize (0 );
397
+ }
398
+ }
399
+
374
400
// Setup desired Vulkan state
375
401
ImGui_ImplVulkan_SetupRenderState (draw_data, command_buffer, rb, fb_width, fb_height);
376
402
@@ -399,6 +425,16 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
399
425
}
400
426
else
401
427
{
428
+ if (g_hLastTextureSet != pcmd->TextureId )
429
+ {
430
+ g_hLastTextureSet = pcmd->TextureId ;
431
+ if (io.SetTextureFn )
432
+ io.SetTextureFn (pcmd->TextureId );
433
+ else
434
+ {
435
+ ImGui_ImplVulkan_SetTexture ((VkImageView)pcmd->TextureId , command_buffer);
436
+ }
437
+ }
402
438
// Project scissor/clipping rectangles into framebuffer space
403
439
ImVec4 clip_rect;
404
440
clip_rect.x = (pcmd->ClipRect .x - clip_off.x ) * clip_scale.x ;
@@ -432,6 +468,66 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
432
468
}
433
469
}
434
470
471
+ void ImGui_ImplVulkan_SetTexture (VkImageView image_view, VkCommandBuffer command_buffer)
472
+ {
473
+ ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo;
474
+
475
+ // Out of descriptors, add a new bigger pool and mark the old one to be freed next frame
476
+ if (g_DescriptorsAllocated == g_DescriptorPoolSize)
477
+ {
478
+ if (g_DescriptorsAllocated < 1024 )
479
+ g_DescriptorPoolSize *= 2 ;
480
+ else
481
+ g_DescriptorPoolSize += 1024 ;
482
+
483
+ if (g_DescriptorPool)
484
+ g_DescriptorPoolToDelete.push_back (g_DescriptorPool);
485
+
486
+ g_DescriptorsAllocated = 0 ;
487
+
488
+ VkDescriptorPoolSize poolSizes[1 ] =
489
+ {
490
+ { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, g_DescriptorPoolSize },
491
+ };
492
+
493
+ VkDescriptorPoolCreateInfo descriptor_pool_info = {};
494
+ descriptor_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
495
+ descriptor_pool_info.poolSizeCount = 1 ;
496
+ descriptor_pool_info.pPoolSizes = poolSizes;
497
+ descriptor_pool_info.maxSets = g_DescriptorPoolSize;
498
+
499
+ VkResult err = vkCreateDescriptorPool (v->Device , &descriptor_pool_info, v->Allocator , &g_DescriptorPool);
500
+ check_vk_result (err);
501
+ }
502
+
503
+ VkDescriptorSet desc_set;
504
+
505
+ // Create and update new set
506
+ VkDescriptorSetAllocateInfo allocate_info = {};
507
+ allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
508
+ allocate_info.descriptorPool = g_DescriptorPool;
509
+ allocate_info.descriptorSetCount = 1 ;
510
+ allocate_info.pSetLayouts = &g_DescriptorSetLayout;
511
+ VkResult err = vkAllocateDescriptorSets (v->Device , &allocate_info, &desc_set);
512
+ check_vk_result (err);
513
+
514
+ VkDescriptorImageInfo desc_image = {};
515
+ desc_image.imageView = image_view;
516
+ desc_image.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
517
+
518
+ VkWriteDescriptorSet write_desc[1 ] = {};
519
+ write_desc[0 ].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
520
+ write_desc[0 ].dstSet = desc_set;
521
+ write_desc[0 ].descriptorCount = 1 ;
522
+ write_desc[0 ].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
523
+ write_desc[0 ].pImageInfo = &desc_image;
524
+ vkUpdateDescriptorSets (v->Device , 1 , write_desc, 0 , NULL );
525
+
526
+ vkCmdBindDescriptorSets (command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_PipelineLayout, 0 , 1 , &desc_set, 0 , NULL );
527
+
528
+ ++g_DescriptorsAllocated;
529
+ }
530
+
435
531
bool ImGui_ImplVulkan_CreateFontsTexture (VkCommandBuffer command_buffer)
436
532
{
437
533
ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo;
@@ -488,20 +584,6 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
488
584
check_vk_result (err);
489
585
}
490
586
491
- // Update the Descriptor Set:
492
- {
493
- VkDescriptorImageInfo desc_image[1 ] = {};
494
- desc_image[0 ].sampler = g_FontSampler;
495
- desc_image[0 ].imageView = g_FontView;
496
- desc_image[0 ].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
497
- VkWriteDescriptorSet write_desc[1 ] = {};
498
- write_desc[0 ].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
499
- write_desc[0 ].dstSet = g_DescriptorSet;
500
- write_desc[0 ].descriptorCount = 1 ;
501
- write_desc[0 ].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
502
- write_desc[0 ].pImageInfo = desc_image;
503
- vkUpdateDescriptorSets (v->Device , 1 , write_desc, 0 , NULL );
504
- }
505
587
506
588
// Create the Upload Buffer:
507
589
{
@@ -578,8 +660,10 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
578
660
vkCmdPipelineBarrier (command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0 , 0 , NULL , 0 , NULL , 1 , use_barrier);
579
661
}
580
662
663
+ // Update the descriptor set
664
+
581
665
// Store our identifier
582
- io.Fonts ->TexID = (ImTextureID)(intptr_t )g_FontImage ;
666
+ io.Fonts ->TexID = (ImTextureID)(intptr_t )g_FontView ;
583
667
584
668
return true ;
585
669
}
@@ -640,17 +724,6 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
640
724
check_vk_result (err);
641
725
}
642
726
643
- // Create Descriptor Set:
644
- {
645
- VkDescriptorSetAllocateInfo alloc_info = {};
646
- alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
647
- alloc_info.descriptorPool = v->DescriptorPool ;
648
- alloc_info.descriptorSetCount = 1 ;
649
- alloc_info.pSetLayouts = &g_DescriptorSetLayout;
650
- err = vkAllocateDescriptorSets (v->Device , &alloc_info, &g_DescriptorSet);
651
- check_vk_result (err);
652
- }
653
-
654
727
if (!g_PipelineLayout)
655
728
{
656
729
// Constants: we are using 'vec2 offset' and 'vec2 scale' instead of a full 3d projection matrix
@@ -796,10 +869,18 @@ void ImGui_ImplVulkan_DestroyDeviceObjects()
796
869
ImGui_ImplVulkanH_DestroyWindowRenderBuffers (v->Device , &g_MainWindowRenderBuffers, v->Allocator );
797
870
ImGui_ImplVulkan_DestroyFontUploadObjects ();
798
871
872
+ for (int i = 0 ; i < g_DescriptorPoolToDelete.size (); i++)
873
+ {
874
+ vkDestroyDescriptorPool (v->Device , g_DescriptorPoolToDelete[i], v->Allocator );
875
+ }
876
+ g_DescriptorPoolToDelete.clear ();
877
+ g_DescriptorPoolSize = g_DescriptorsAllocated = 32 ;
878
+
799
879
if (g_FontView) { vkDestroyImageView (v->Device , g_FontView, v->Allocator ); g_FontView = VK_NULL_HANDLE; }
800
880
if (g_FontImage) { vkDestroyImage (v->Device , g_FontImage, v->Allocator ); g_FontImage = VK_NULL_HANDLE; }
801
881
if (g_FontMemory) { vkFreeMemory (v->Device , g_FontMemory, v->Allocator ); g_FontMemory = VK_NULL_HANDLE; }
802
882
if (g_FontSampler) { vkDestroySampler (v->Device , g_FontSampler, v->Allocator ); g_FontSampler = VK_NULL_HANDLE; }
883
+ if (g_DescriptorPool) { vkDestroyDescriptorPool (v->Device , g_DescriptorPool, v->Allocator ); g_DescriptorPool = VK_NULL_HANDLE; }
803
884
if (g_DescriptorSetLayout) { vkDestroyDescriptorSetLayout (v->Device , g_DescriptorSetLayout, v->Allocator ); g_DescriptorSetLayout = VK_NULL_HANDLE; }
804
885
if (g_PipelineLayout) { vkDestroyPipelineLayout (v->Device , g_PipelineLayout, v->Allocator ); g_PipelineLayout = VK_NULL_HANDLE; }
805
886
if (g_Pipeline) { vkDestroyPipeline (v->Device , g_Pipeline, v->Allocator ); g_Pipeline = VK_NULL_HANDLE; }
@@ -816,7 +897,6 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
816
897
IM_ASSERT (info->PhysicalDevice != VK_NULL_HANDLE);
817
898
IM_ASSERT (info->Device != VK_NULL_HANDLE);
818
899
IM_ASSERT (info->Queue != VK_NULL_HANDLE);
819
- IM_ASSERT (info->DescriptorPool != VK_NULL_HANDLE);
820
900
IM_ASSERT (info->MinImageCount >= 2 );
821
901
IM_ASSERT (info->ImageCount >= info->MinImageCount );
822
902
IM_ASSERT (render_pass != VK_NULL_HANDLE);
0 commit comments