Vulkan: Renaming, we want InitInfo to source MinImageCount which is the "source" value (so viewport creation can use this). Made ImGui_ImplVulkan_DestroyFrameRenderBuffers public. (#2071)
diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt
index 0b3ed42..b4f17df 100644
--- a/docs/CHANGELOG.txt
+++ b/docs/CHANGELOG.txt
@@ -37,8 +37,8 @@
 - Examples: Vulkan: Added extra parameter to ImGui_ImplVulkan_RenderDrawData(). Engine/app is
   in charge of owning/storing 1 ImGui_ImplVulkan_FrameRenderBuffers per in-flight rendering frame.
   (The demo helper ImGui_ImplVulkanH_WindowData structure carries them.) (#2461, #2348, #2378, #2097)
-- Examples: Vulkan: Added FramesQueueSize field in ImGui_ImplVulkan_InitInfo, required during
-  initialization to specify the number of in-flight image required by the swap chain.
+- Examples: Vulkan: Added MinImageCount field in ImGui_ImplVulkan_InitInfo, required during
+  initialization to specify the number of in-flight image requested by swap chains.
   (was previously a hard #define IMGUI_VK_QUEUED_FRAMES 2). (#2071, #1677) [@nathanvoglsam]
 
 
diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp
index 037d479..ae6bb66 100644
--- a/examples/example_glfw_vulkan/main.cpp
+++ b/examples/example_glfw_vulkan/main.cpp
@@ -192,7 +192,7 @@
     }
 }
 
-static void SetupVulkanWindowData(ImGui_ImplVulkanH_WindowData* wd, VkSurfaceKHR surface, int width, int height)
+static void SetupVulkanWindow(ImGui_ImplVulkanH_WindowData* wd, VkSurfaceKHR surface, int width, int height)
 {
     wd->Surface = surface;
 
@@ -226,8 +226,6 @@
 
 static void CleanupVulkan()
 {
-    ImGui_ImplVulkanH_WindowData* wd = &g_WindowData;
-    ImGui_ImplVulkanH_DestroyWindowData(g_Instance, g_Device, wd, g_Allocator);
     vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
 
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
@@ -240,6 +238,15 @@
     vkDestroyInstance(g_Instance, g_Allocator);
 }
 
+static void CleanupVulkanWindow()
+{
+    // In a normal engine/app integration, you wouldn't use the ImGui_ImplVulkanH_WindowData helpers,
+    // however you would instead need to call ImGui_ImplVulkan_DestroyFrameRenderBuffers() on each 
+    // ImGui_ImplVulkan_FrameRenderBuffers structure that you own.
+    ImGui_ImplVulkanH_WindowData* wd = &g_WindowData;
+    ImGui_ImplVulkanH_DestroyWindowData(g_Instance, g_Device, wd, g_Allocator);
+}
+
 static void FrameRender(ImGui_ImplVulkanH_WindowData* wd)
 {
     VkResult err;
@@ -357,7 +364,7 @@
     glfwGetFramebufferSize(window, &w, &h);
     glfwSetFramebufferSizeCallback(window, glfw_resize_callback);
     ImGui_ImplVulkanH_WindowData* wd = &g_WindowData;
-    SetupVulkanWindowData(wd, surface, w, h);
+    SetupVulkanWindow(wd, surface, w, h);
 
     // Setup Dear ImGui context
     IMGUI_CHECKVERSION();
@@ -381,7 +388,7 @@
     init_info.PipelineCache = g_PipelineCache;
     init_info.DescriptorPool = g_DescriptorPool;
     init_info.Allocator = g_Allocator;
-    init_info.FramesQueueSize = wd->FramesQueueSize;
+    init_info.MinImageCount = g_MinImageCount;
     init_info.CheckVkResultFn = check_vk_result;
     ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
 
@@ -446,7 +453,7 @@
         if (g_WantSwapChainRebuild)
         {
             ImGui_ImplVulkanH_CreateWindowData(g_Instance, g_PhysicalDevice, g_Device, &g_WindowData, g_QueueFamily, g_Allocator, g_ResizeWidth, g_ResizeHeight, g_MinImageCount);
-            ImGui_ImplVulkan_SetFramesQueueSize(g_WindowData.FramesQueueSize);
+            ImGui_ImplVulkan_SetSwapChainMinImageCount(g_MinImageCount);
             g_WindowData.FrameIndex = 0;
             g_WantSwapChainRebuild = false;
         }
@@ -507,6 +514,8 @@
     ImGui_ImplVulkan_Shutdown();
     ImGui_ImplGlfw_Shutdown();
     ImGui::DestroyContext();
+
+    CleanupVulkanWindow();
     CleanupVulkan();
 
     glfwDestroyWindow(window);
diff --git a/examples/example_sdl_vulkan/main.cpp b/examples/example_sdl_vulkan/main.cpp
index e472194..58d3444 100644
--- a/examples/example_sdl_vulkan/main.cpp
+++ b/examples/example_sdl_vulkan/main.cpp
@@ -183,7 +183,7 @@
     }
 }
 
-static void SetupVulkanWindowData(ImGui_ImplVulkanH_WindowData* wd, VkSurfaceKHR surface, int width, int height)
+static void SetupVulkanWindow(ImGui_ImplVulkanH_WindowData* wd, VkSurfaceKHR surface, int width, int height)
 {
     wd->Surface = surface;
 
@@ -217,8 +217,6 @@
 
 static void CleanupVulkan()
 {
-    ImGui_ImplVulkanH_WindowData* wd = &g_WindowData;
-    ImGui_ImplVulkanH_DestroyWindowData(g_Instance, g_Device, wd, g_Allocator);
     vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
 
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
@@ -231,6 +229,15 @@
     vkDestroyInstance(g_Instance, g_Allocator);
 }
 
+static void CleanupVulkanWindow()
+{
+    // In a normal engine/app integration, you wouldn't use the ImGui_ImplVulkanH_WindowData helpers,
+    // however you would instead need to call ImGui_ImplVulkan_DestroyFrameRenderBuffers() on each 
+    // ImGui_ImplVulkan_FrameRenderBuffers structure that you own.
+    ImGui_ImplVulkanH_WindowData* wd = &g_WindowData;
+    ImGui_ImplVulkanH_DestroyWindowData(g_Instance, g_Device, wd, g_Allocator);
+}
+
 static void FrameRender(ImGui_ImplVulkanH_WindowData* wd)
 {
     VkResult err;
@@ -342,7 +349,7 @@
     int w, h;
     SDL_GetWindowSize(window, &w, &h);
     ImGui_ImplVulkanH_WindowData* wd = &g_WindowData;
-    SetupVulkanWindowData(wd, surface, w, h);
+    SetupVulkanWindow(wd, surface, w, h);
 
     // Setup Dear ImGui context
     ImGui::CreateContext();
@@ -364,7 +371,7 @@
     init_info.PipelineCache = g_PipelineCache;
     init_info.DescriptorPool = g_DescriptorPool;
     init_info.Allocator = g_Allocator;
-    init_info.FramesQueueSize = wd->FramesQueueSize;
+    init_info.MinImageCount = g_MinImageCount;
     init_info.CheckVkResultFn = check_vk_result;
     ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
 
@@ -443,7 +450,7 @@
         if (g_WantSwapChainRebuild)
         {
             ImGui_ImplVulkanH_CreateWindowData(g_Instance, g_PhysicalDevice, g_Device, &g_WindowData, g_QueueFamily, g_Allocator, g_WindowData.Width, g_WindowData.Height, g_MinImageCount);
-            ImGui_ImplVulkan_SetFramesQueueSize(g_WindowData.FramesQueueSize);
+            ImGui_ImplVulkan_SetSwapChainMinImageCount(g_MinImageCount);
             g_WindowData.FrameIndex = 0;
             g_WantSwapChainRebuild = false;
         }
@@ -504,6 +511,8 @@
     ImGui_ImplVulkan_Shutdown();
     ImGui_ImplSDL2_Shutdown();
     ImGui::DestroyContext();
+
+    CleanupVulkanWindow();
     CleanupVulkan();
 
     SDL_DestroyWindow(window);
diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp
index 25b6428..afe6dce 100644
--- a/examples/imgui_impl_vulkan.cpp
+++ b/examples/imgui_impl_vulkan.cpp
@@ -21,7 +21,7 @@
 // CHANGELOG
 // (minor and older changes stripped away, please see git history for details)
 //  2019-XX-XX: *BREAKING CHANGE*: Vulkan: Added extra parameter to ImGui_ImplVulkan_RenderDrawData(). Engine/app is in charge of owning/storing 1 ImGui_ImplVulkan_FrameRenderBuffers per in-flight rendering frame. (The demo helper ImGui_ImplVulkanH_WindowData structure carries them.)
-//  2019-XX-XX: *BREAKING CHANGE*: Vulkan: Added FramesQueueSize field in ImGui_ImplVulkan_InitInfo, required for initialization (was previously a hard #define IMGUI_VK_QUEUED_FRAMES 2). Added ImGui_ImplVulkan_SetFramesQueueSize() to override FramesQueueSize while running.
+//  2019-XX-XX: *BREAKING CHANGE*: Vulkan: Added MinImageCount field in ImGui_ImplVulkan_InitInfo, required for initialization (was previously a hard #define IMGUI_VK_QUEUED_FRAMES 2). Added ImGui_ImplVulkan_SetSwapChainMinImageCount().
 //  2019-XX-XX: Vulkan: Added VkInstance argument to ImGui_ImplVulkanH_CreateWindowData() optional helper.
 //  2019-04-04: Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like.
 //  2019-04-01: Vulkan: Support for 32-bit index buffer (#define ImDrawIdx unsigned int).
@@ -64,7 +64,6 @@
 
 // Forward Declarations
 void ImGui_ImplVulkanH_DestroyFrameData(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameData* fd, const VkAllocationCallbacks* allocator);
-void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkInstance instance, VkDevice device, ImGui_ImplVulkan_FrameRenderBuffers* frb, const VkAllocationCallbacks* allocator);
 void ImGui_ImplVulkanH_CreateWindowDataSwapChain(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
 void ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator);
 
@@ -754,7 +753,7 @@
     IM_ASSERT(info->Device != VK_NULL_HANDLE);
     IM_ASSERT(info->Queue != VK_NULL_HANDLE);
     IM_ASSERT(info->DescriptorPool != VK_NULL_HANDLE);
-    IM_ASSERT(info->FramesQueueSize >= 2);
+    IM_ASSERT(info->MinImageCount >= 2);
     IM_ASSERT(render_pass != VK_NULL_HANDLE);
 
     g_VulkanInitInfo = *info;
@@ -773,9 +772,24 @@
 {
 }
 
-void ImGui_ImplVulkan_SetFramesQueueSize(int frames_queue_size)
+// Note: this has no effect in the 'master' branch, but multi-viewports needs this to recreate swap-chains.
+void ImGui_ImplVulkan_SetSwapChainMinImageCount(int min_image_count)
 {
-    (void)frames_queue_size;
+    IM_ASSERT(min_image_count >= 2);
+    g_VulkanInitInfo.MinImageCount = min_image_count;
+}
+
+// This is a public function because we require the user to pass a ImGui_ImplVulkan_FrameRenderBuffers 
+// structure to ImGui_ImplVulkan_RenderDrawData.
+void ImGui_ImplVulkan_DestroyFrameRenderBuffers(VkInstance instance, VkDevice device, ImGui_ImplVulkan_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
+{
+    (void)instance;
+    if (buffers->VertexBuffer)       { vkDestroyBuffer(device, buffers->VertexBuffer,       allocator); buffers->VertexBuffer = VK_NULL_HANDLE; }
+    if (buffers->VertexBufferMemory) { vkFreeMemory   (device, buffers->VertexBufferMemory, allocator); buffers->VertexBufferMemory = VK_NULL_HANDLE; }
+    if (buffers->IndexBuffer)        { vkDestroyBuffer(device, buffers->IndexBuffer,        allocator); buffers->IndexBuffer = VK_NULL_HANDLE; }
+    if (buffers->IndexBufferMemory)  { vkFreeMemory   (device, buffers->IndexBufferMemory,  allocator); buffers->IndexBufferMemory = VK_NULL_HANDLE; }
+    buffers->VertexBufferSize = 0;
+    buffers->IndexBufferSize = 0;
 }
 
 
@@ -910,7 +924,6 @@
     }
 }
 
-// MinImageCount will usually turn into FramesQueueSize
 int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode)
 {
     if (present_mode == VK_PRESENT_MODE_MAILBOX_KHR)
@@ -984,6 +997,7 @@
         err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->FramesQueueSize, NULL);
         check_vk_result(err);
         VkImage backbuffers[16] = {};
+        IM_ASSERT(wd->FramesQueueSize >= min_image_count);
         IM_ASSERT(wd->FramesQueueSize < IM_ARRAYSIZE(backbuffers));
         err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->FramesQueueSize, backbuffers);
         check_vk_result(err);
@@ -1114,16 +1128,6 @@
     vkDestroyImageView(device, fd->BackbufferView, allocator);
     vkDestroyFramebuffer(device, fd->Framebuffer, allocator);
 
-    ImGui_ImplVulkanH_DestroyFrameRenderBuffers(instance, device, &fd->RenderBuffers, allocator);
+    ImGui_ImplVulkan_DestroyFrameRenderBuffers(instance, device, &fd->RenderBuffers, allocator);
 }
 
-void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkInstance instance, VkDevice device, ImGui_ImplVulkan_FrameRenderBuffers* frb, const VkAllocationCallbacks* allocator)
-{
-    (void)instance;
-    if (frb->VertexBuffer)       { vkDestroyBuffer(device, frb->VertexBuffer,       allocator); frb->VertexBuffer = VK_NULL_HANDLE; }
-    if (frb->VertexBufferMemory) { vkFreeMemory   (device, frb->VertexBufferMemory, allocator); frb->VertexBufferMemory = VK_NULL_HANDLE; }
-    if (frb->IndexBuffer)        { vkDestroyBuffer(device, frb->IndexBuffer,        allocator); frb->IndexBuffer = VK_NULL_HANDLE; }
-    if (frb->IndexBufferMemory)  { vkFreeMemory   (device, frb->IndexBufferMemory,  allocator); frb->IndexBufferMemory = VK_NULL_HANDLE; }
-    frb->VertexBufferSize = 0;
-    frb->IndexBufferSize = 0;
-}
diff --git a/examples/imgui_impl_vulkan.h b/examples/imgui_impl_vulkan.h
index 334910f..4e62ec8 100644
--- a/examples/imgui_impl_vulkan.h
+++ b/examples/imgui_impl_vulkan.h
@@ -33,7 +33,7 @@
     VkQueue                         Queue;
     VkPipelineCache                 PipelineCache;
     VkDescriptorPool                DescriptorPool;
-    int                             FramesQueueSize;        // >= 2, generally matches the image count returned by vkGetSwapchainImagesKHR
+    int                             MinImageCount;      // >= 2
     const VkAllocationCallbacks*    Allocator;
     void                            (*CheckVkResultFn)(VkResult err);
 };
@@ -56,10 +56,11 @@
 IMGUI_IMPL_API bool     ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass);
 IMGUI_IMPL_API void     ImGui_ImplVulkan_Shutdown();
 IMGUI_IMPL_API void     ImGui_ImplVulkan_NewFrame();
-IMGUI_IMPL_API void     ImGui_ImplVulkan_SetFramesQueueSize(int frames_queue_size); // To override FramesQueueSize after initialization
 IMGUI_IMPL_API void     ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, ImGui_ImplVulkan_FrameRenderBuffers* buffers);
 IMGUI_IMPL_API bool     ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer);
 IMGUI_IMPL_API void     ImGui_ImplVulkan_DestroyFontUploadObjects();
+IMGUI_IMPL_API void     ImGui_ImplVulkan_DestroyFrameRenderBuffers(VkInstance instance, VkDevice device, ImGui_ImplVulkan_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
+IMGUI_IMPL_API void     ImGui_ImplVulkan_SetSwapChainMinImageCount(int frames_queue_size); // To override MinImageCount after initialization
 
 // Called by ImGui_ImplVulkan_Init(), might be useful elsewhere.
 IMGUI_IMPL_API bool     ImGui_ImplVulkan_CreateDeviceObjects();