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/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/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/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/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();