From a45840746e171b3e258f29a716d7634cfd832e1c Mon Sep 17 00:00:00 2001 From: MindSpunk Date: Fri, 5 Apr 2019 15:50:21 +1100 Subject: [PATCH 1/4] Vulkan, Viewports: Fix for resizing viewport windows crashing. (#2472) --- examples/example_glfw_vulkan/main.cpp | 9 ++++---- examples/example_sdl_vulkan/main.cpp | 9 ++++---- examples/imgui_impl_vulkan.cpp | 30 +++++++++++++++++++++------ examples/imgui_impl_vulkan.h | 11 ++++++++-- 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index 7a9a4502..c8417391 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -252,7 +252,8 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd) { VkResult err; - VkSemaphore& image_acquired_semaphore = wd->Frames[wd->FrameIndex].ImageAcquiredSemaphore; + VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore; + VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); check_vk_result(err); @@ -300,7 +301,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd) info.commandBufferCount = 1; info.pCommandBuffers = &fd->CommandBuffer; info.signalSemaphoreCount = 1; - info.pSignalSemaphores = &fd->RenderCompleteSemaphore; + info.pSignalSemaphores = &render_complete_semaphore; err = vkEndCommandBuffer(fd->CommandBuffer); check_vk_result(err); @@ -311,11 +312,11 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd) static void FramePresent(ImGui_ImplVulkanH_Window* wd) { - ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex]; + VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; VkPresentInfoKHR info = {}; info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; info.waitSemaphoreCount = 1; - info.pWaitSemaphores = &fd->RenderCompleteSemaphore; + info.pWaitSemaphores = &render_complete_semaphore; info.swapchainCount = 1; info.pSwapchains = &wd->Swapchain; info.pImageIndices = &wd->FrameIndex; diff --git a/examples/example_sdl_vulkan/main.cpp b/examples/example_sdl_vulkan/main.cpp index 2e7e6c6e..2124f613 100644 --- a/examples/example_sdl_vulkan/main.cpp +++ b/examples/example_sdl_vulkan/main.cpp @@ -244,7 +244,8 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd) { VkResult err; - VkSemaphore& image_acquired_semaphore = wd->Frames[wd->FrameIndex].ImageAcquiredSemaphore; + VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore; + VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); check_vk_result(err); @@ -292,7 +293,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd) info.commandBufferCount = 1; info.pCommandBuffers = &fd->CommandBuffer; info.signalSemaphoreCount = 1; - info.pSignalSemaphores = &fd->RenderCompleteSemaphore; + info.pSignalSemaphores = &render_complete_semaphore; err = vkEndCommandBuffer(fd->CommandBuffer); check_vk_result(err); @@ -303,11 +304,11 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd) static void FramePresent(ImGui_ImplVulkanH_Window* wd) { - ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex]; + VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; VkPresentInfoKHR info = {}; info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; info.waitSemaphoreCount = 1; - info.pWaitSemaphores = &fd->RenderCompleteSemaphore; + info.pWaitSemaphores = &render_complete_semaphore; info.swapchainCount = 1; info.pSwapchains = &wd->Swapchain; info.pImageIndices = &wd->FrameIndex; diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp index edf4848b..c8bb7ab9 100644 --- a/examples/imgui_impl_vulkan.cpp +++ b/examples/imgui_impl_vulkan.cpp @@ -64,6 +64,7 @@ static VkBuffer g_UploadBuffer = VK_NULL_HANDLE; // Forward Declarations void ImGui_ImplVulkanH_DestroyFrame(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator); +void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator); void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count); void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator); @@ -889,6 +890,7 @@ void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkInstance instance, VkPhysica for (uint32_t i = 0; i < wd->FramesQueueSize; i++) { ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i]; + ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[i]; { VkCommandPoolCreateInfo info = {}; info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; @@ -916,9 +918,9 @@ void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkInstance instance, VkPhysica { VkSemaphoreCreateInfo info = {}; info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - err = vkCreateSemaphore(device, &info, allocator, &fd->ImageAcquiredSemaphore); + err = vkCreateSemaphore(device, &info, allocator, &fsd->ImageAcquiredSemaphore); check_vk_result(err); - err = vkCreateSemaphore(device, &info, allocator, &fd->RenderCompleteSemaphore); + err = vkCreateSemaphore(device, &info, allocator, &fsd->RenderCompleteSemaphore); check_vk_result(err); } } @@ -947,9 +949,14 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevi // We don't use ImGui_ImplVulkanH_DestroyWindow() because we want to preserve the old swapchain to create the new one. // Destroy old Framebuffer for (uint32_t i = 0; i < wd->FramesQueueSize; i++) + { ImGui_ImplVulkanH_DestroyFrame(instance, device, &wd->Frames[i], allocator); + ImGui_ImplVulkanH_DestroyFrameSemaphores(instance, device, &wd->FrameSemaphores[i], allocator); + } delete[] wd->Frames; + delete[] wd->FrameSemaphores; wd->Frames = NULL; + wd->FrameSemaphores = NULL; wd->FramesQueueSize = 0; if (wd->RenderPass) vkDestroyRenderPass(device, wd->RenderPass, allocator); @@ -1004,7 +1011,9 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevi IM_ASSERT(wd->Frames == NULL); wd->Frames = new ImGui_ImplVulkanH_Frame[wd->FramesQueueSize]; + wd->FrameSemaphores = new ImGui_ImplVulkanH_FrameSemaphores[wd->FramesQueueSize]; memset(wd->Frames, 0, sizeof(wd->Frames[0]) * wd->FramesQueueSize); + memset(wd->FrameSemaphores, 0, sizeof(wd->FrameSemaphores[0]) * wd->FramesQueueSize); for (uint32_t i = 0; i < wd->FramesQueueSize; i++) wd->Frames[i].Backbuffer = backbuffers[i]; } @@ -1102,9 +1111,14 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui //vkQueueWaitIdle(g_Queue); for (uint32_t i = 0; i < wd->FramesQueueSize; i++) + { ImGui_ImplVulkanH_DestroyFrame(instance, device, &wd->Frames[i], allocator); + ImGui_ImplVulkanH_DestroyFrameSemaphores(instance, device, &wd->FrameSemaphores[i], allocator); + } delete[] wd->Frames; + delete[] wd->FrameSemaphores; wd->Frames = NULL; + wd->FrameSemaphores = NULL; vkDestroyRenderPass(device, wd->RenderPass, allocator); vkDestroySwapchainKHR(device, wd->Swapchain, allocator); vkDestroySurfaceKHR(instance, wd->Surface, allocator); @@ -1112,22 +1126,26 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui *wd = ImGui_ImplVulkanH_Window(); } +void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator) +{ + (void)instance; + vkDestroySemaphore(device, fsd->ImageAcquiredSemaphore, allocator); + vkDestroySemaphore(device, fsd->RenderCompleteSemaphore, allocator); + fsd->ImageAcquiredSemaphore = fsd->RenderCompleteSemaphore = VK_NULL_HANDLE; +} + void ImGui_ImplVulkanH_DestroyFrame(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator) { (void)instance; vkDestroyFence(device, fd->Fence, allocator); vkFreeCommandBuffers(device, fd->CommandPool, 1, &fd->CommandBuffer); vkDestroyCommandPool(device, fd->CommandPool, allocator); - vkDestroySemaphore(device, fd->ImageAcquiredSemaphore, allocator); - vkDestroySemaphore(device, fd->RenderCompleteSemaphore, allocator); fd->Fence = VK_NULL_HANDLE; fd->CommandBuffer = VK_NULL_HANDLE; fd->CommandPool = VK_NULL_HANDLE; - fd->ImageAcquiredSemaphore = fd->RenderCompleteSemaphore = VK_NULL_HANDLE; vkDestroyImageView(device, fd->BackbufferView, allocator); vkDestroyFramebuffer(device, fd->Framebuffer, allocator); ImGui_ImplVulkan_DestroyFrameRenderBuffers(instance, device, &fd->RenderBuffers, allocator); } - diff --git a/examples/imgui_impl_vulkan.h b/examples/imgui_impl_vulkan.h index 0a770afa..b872ae21 100644 --- a/examples/imgui_impl_vulkan.h +++ b/examples/imgui_impl_vulkan.h @@ -101,14 +101,18 @@ struct ImGui_ImplVulkanH_Frame VkCommandPool CommandPool; VkCommandBuffer CommandBuffer; VkFence Fence; - VkSemaphore ImageAcquiredSemaphore; - VkSemaphore RenderCompleteSemaphore; VkImage Backbuffer; VkImageView BackbufferView; VkFramebuffer Framebuffer; ImGui_ImplVulkan_FrameRenderBuffers RenderBuffers; }; +struct ImGui_ImplVulkanH_FrameSemaphores +{ + VkSemaphore ImageAcquiredSemaphore; + VkSemaphore RenderCompleteSemaphore; +}; + // Helper structure to hold the data needed by one rendering context into one OS window // (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.) struct ImGui_ImplVulkanH_Window @@ -124,7 +128,10 @@ struct ImGui_ImplVulkanH_Window VkClearValue ClearValue; uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount) uint32_t FramesQueueSize; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count) + uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data) ImGui_ImplVulkanH_Frame* Frames; + ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores; + ImGui_ImplVulkanH_Window() { From ec76722d2d7945d8b6bf7f152a7acc81e0a507e6 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 5 Apr 2019 17:22:24 +0200 Subject: [PATCH 2/4] Vulkan: Added ImageCount to InitInfo structure (!= MinImageCount) will be needed for viewports. Renamed FramesQueueSize -> ImageCount. (#2472, #2071) --- docs/CHANGELOG.txt | 4 ++-- examples/example_glfw_vulkan/main.cpp | 1 + examples/example_sdl_vulkan/main.cpp | 1 + examples/imgui_impl_vulkan.cpp | 31 ++++++++++++++------------- examples/imgui_impl_vulkan.h | 14 ++++++------ 5 files changed, 27 insertions(+), 24 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 7f038134..a3283b1b 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -37,8 +37,8 @@ Breaking Changes: - 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_Window structure carries them.) (#2461, #2348, #2378, #2097) -- Examples: Vulkan: Added MinImageCount field in ImGui_ImplVulkan_InitInfo, required during - initialization to specify the number of in-flight image requested by swap chains. +- Examples: Vulkan: Added MinImageCount/ImageCount fields 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] - Examples: Vulkan: Tidying up the demo/internals helpers (most engine/app should not rely on them but it is possible you have!). diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index c8417391..81630838 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -391,6 +391,7 @@ int main(int, char**) init_info.DescriptorPool = g_DescriptorPool; init_info.Allocator = g_Allocator; init_info.MinImageCount = g_MinImageCount; + init_info.ImageCount = wd->ImageCount; init_info.CheckVkResultFn = check_vk_result; ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); diff --git a/examples/example_sdl_vulkan/main.cpp b/examples/example_sdl_vulkan/main.cpp index 2124f613..976d026e 100644 --- a/examples/example_sdl_vulkan/main.cpp +++ b/examples/example_sdl_vulkan/main.cpp @@ -375,6 +375,7 @@ int main(int, char**) init_info.DescriptorPool = g_DescriptorPool; init_info.Allocator = g_Allocator; init_info.MinImageCount = g_MinImageCount; + init_info.ImageCount = wd->ImageCount; init_info.CheckVkResultFn = check_vk_result; ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp index c8bb7ab9..df8f84fc 100644 --- a/examples/imgui_impl_vulkan.cpp +++ b/examples/imgui_impl_vulkan.cpp @@ -755,6 +755,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend IM_ASSERT(info->Queue != VK_NULL_HANDLE); IM_ASSERT(info->DescriptorPool != VK_NULL_HANDLE); IM_ASSERT(info->MinImageCount >= 2); + IM_ASSERT(info->ImageCount >= info->MinImageCount); IM_ASSERT(render_pass != VK_NULL_HANDLE); g_VulkanInitInfo = *info; @@ -887,7 +888,7 @@ void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkInstance instance, VkPhysica // Create Command Buffers VkResult err; - for (uint32_t i = 0; i < wd->FramesQueueSize; i++) + for (uint32_t i = 0; i < wd->ImageCount; i++) { ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i]; ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[i]; @@ -948,7 +949,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevi // We don't use ImGui_ImplVulkanH_DestroyWindow() because we want to preserve the old swapchain to create the new one. // Destroy old Framebuffer - for (uint32_t i = 0; i < wd->FramesQueueSize; i++) + for (uint32_t i = 0; i < wd->ImageCount; i++) { ImGui_ImplVulkanH_DestroyFrame(instance, device, &wd->Frames[i], allocator); ImGui_ImplVulkanH_DestroyFrameSemaphores(instance, device, &wd->FrameSemaphores[i], allocator); @@ -957,7 +958,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevi delete[] wd->FrameSemaphores; wd->Frames = NULL; wd->FrameSemaphores = NULL; - wd->FramesQueueSize = 0; + wd->ImageCount = 0; if (wd->RenderPass) vkDestroyRenderPass(device, wd->RenderPass, allocator); @@ -1001,20 +1002,20 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevi } err = vkCreateSwapchainKHR(device, &info, allocator, &wd->Swapchain); check_vk_result(err); - err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->FramesQueueSize, NULL); + err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->ImageCount, 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); + IM_ASSERT(wd->ImageCount >= min_image_count); + IM_ASSERT(wd->ImageCount < IM_ARRAYSIZE(backbuffers)); + err = vkGetSwapchainImagesKHR(device, wd->Swapchain, &wd->ImageCount, backbuffers); check_vk_result(err); IM_ASSERT(wd->Frames == NULL); - wd->Frames = new ImGui_ImplVulkanH_Frame[wd->FramesQueueSize]; - wd->FrameSemaphores = new ImGui_ImplVulkanH_FrameSemaphores[wd->FramesQueueSize]; - memset(wd->Frames, 0, sizeof(wd->Frames[0]) * wd->FramesQueueSize); - memset(wd->FrameSemaphores, 0, sizeof(wd->FrameSemaphores[0]) * wd->FramesQueueSize); - for (uint32_t i = 0; i < wd->FramesQueueSize; i++) + wd->Frames = new ImGui_ImplVulkanH_Frame[wd->ImageCount]; + wd->FrameSemaphores = new ImGui_ImplVulkanH_FrameSemaphores[wd->ImageCount]; + memset(wd->Frames, 0, sizeof(wd->Frames[0]) * wd->ImageCount); + memset(wd->FrameSemaphores, 0, sizeof(wd->FrameSemaphores[0]) * wd->ImageCount); + for (uint32_t i = 0; i < wd->ImageCount; i++) wd->Frames[i].Backbuffer = backbuffers[i]; } if (old_swapchain) @@ -1069,7 +1070,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevi info.components.a = VK_COMPONENT_SWIZZLE_A; VkImageSubresourceRange image_range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; info.subresourceRange = image_range; - for (uint32_t i = 0; i < wd->FramesQueueSize; i++) + for (uint32_t i = 0; i < wd->ImageCount; i++) { ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i]; info.image = fd->Backbuffer; @@ -1089,7 +1090,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevi info.width = wd->Width; info.height = wd->Height; info.layers = 1; - for (uint32_t i = 0; i < wd->FramesQueueSize; i++) + for (uint32_t i = 0; i < wd->ImageCount; i++) { ImGui_ImplVulkanH_Frame* fd = &wd->Frames[i]; attachment[0] = fd->BackbufferView; @@ -1110,7 +1111,7 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui vkDeviceWaitIdle(device); // FIXME: We could wait on the Queue if we had the queue in wd-> (otherwise VulkanH functions can't use globals) //vkQueueWaitIdle(g_Queue); - for (uint32_t i = 0; i < wd->FramesQueueSize; i++) + for (uint32_t i = 0; i < wd->ImageCount; i++) { ImGui_ImplVulkanH_DestroyFrame(instance, device, &wd->Frames[i], allocator); ImGui_ImplVulkanH_DestroyFrameSemaphores(instance, device, &wd->FrameSemaphores[i], allocator); diff --git a/examples/imgui_impl_vulkan.h b/examples/imgui_impl_vulkan.h index b872ae21..55d72dfb 100644 --- a/examples/imgui_impl_vulkan.h +++ b/examples/imgui_impl_vulkan.h @@ -33,7 +33,8 @@ struct ImGui_ImplVulkan_InitInfo VkQueue Queue; VkPipelineCache PipelineCache; VkDescriptorPool DescriptorPool; - int MinImageCount; // >= 2 + uint32_t MinImageCount; // >= 2 + uint32_t ImageCount; // >= MinImageCount const VkAllocationCallbacks* Allocator; void (*CheckVkResultFn)(VkResult err); }; @@ -60,7 +61,7 @@ IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, V 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 +IMGUI_IMPL_API void ImGui_ImplVulkan_SetSwapChainMinImageCount(int min_image_count); // To override MinImageCount after initialization // Called by ImGui_ImplVulkan_Init(), might be useful elsewhere. IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateDeviceObjects(); @@ -127,12 +128,11 @@ struct ImGui_ImplVulkanH_Window bool ClearEnable; VkClearValue ClearValue; uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount) - uint32_t FramesQueueSize; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count) + uint32_t ImageCount; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count) uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data) - ImGui_ImplVulkanH_Frame* Frames; - ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores; - - + ImGui_ImplVulkanH_Frame* Frames; + ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores; + ImGui_ImplVulkanH_Window() { memset(this, 0, sizeof(*this)); From 452047c7cadb9e4c88537a4c0c2e1b9e571ceccd Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 5 Apr 2019 17:48:47 +0200 Subject: [PATCH 3/4] Vulkan: Removed requirement for user to pass their own render buffer storage to ImGui_ImplVulkan_RenderDrawData(), this is managed internally. --- docs/CHANGELOG.txt | 6 +- examples/example_glfw_vulkan/main.cpp | 4 +- examples/example_sdl_vulkan/main.cpp | 4 +- examples/imgui_impl_vulkan.cpp | 136 ++++++++++++++++++-------- examples/imgui_impl_vulkan.h | 22 +---- 5 files changed, 103 insertions(+), 69 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index a3283b1b..1822526f 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -34,16 +34,12 @@ HOW TO UPDATE? ----------------------------------------------------------------------- Breaking Changes: -- 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_Window structure carries them.) (#2461, #2348, #2378, #2097) - Examples: Vulkan: Added MinImageCount/ImageCount fields 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] - Examples: Vulkan: Tidying up the demo/internals helpers (most engine/app should not rely on them but it is possible you have!). - Other Changes: - InputText: Fixed selection background starts rendering one frame after the cursor movement when first transitioning from no-selection to has-selection. (Bug in 1.69) (#2436) [@Nazg-Gul] @@ -56,8 +52,10 @@ Other Changes: - Examples: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early, and help users understand what they are missing. (#2421) - Examples: OpenGL3: Minor tweaks + not calling glBindBuffer more than necessary in the render loop. +- Examples: Vulkan: Fixed in-flight buffers issues when using multi-viewports. (#2461, #2348, #2378, #2097) - Examples: Vulkan: Added missing support for 32-bit indices (#define ImDrawIdx unsigned int). - Examples: Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like. +- Examples: Vulkan: Added ImGui_ImplVulkan_SetMinImageCount() to change min image count at runtime. (#2071) [@nathanvoglsam] - Examples: DirectX9: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). (#2454) - Examples: GLUT: Fixed existing FreeGLUT example to work with regular GLUT. (#2465) [@andrewwillmott] - Examples: GLUT: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h. (#2465) [@andrewwillmott] diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index 81630838..972c12b0 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -287,7 +287,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd) } // Record Imgui Draw Data and draw funcs into command buffer - ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer, &fd->RenderBuffers); + ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); // Submit command buffer vkCmdEndRenderPass(fd->CommandBuffer); @@ -457,8 +457,8 @@ int main(int, char**) if (g_SwapChainRebuild) { g_SwapChainRebuild = false; + ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); ImGui_ImplVulkanH_CreateWindow(g_Instance, g_PhysicalDevice, g_Device, &g_WindowData, g_QueueFamily, g_Allocator, g_SwapChainResizeWidth, g_SwapChainResizeHeight, g_MinImageCount); - ImGui_ImplVulkan_SetSwapChainMinImageCount(g_MinImageCount); g_WindowData.FrameIndex = 0; } diff --git a/examples/example_sdl_vulkan/main.cpp b/examples/example_sdl_vulkan/main.cpp index 976d026e..d2a829c4 100644 --- a/examples/example_sdl_vulkan/main.cpp +++ b/examples/example_sdl_vulkan/main.cpp @@ -279,7 +279,7 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd) } // Record Imgui Draw Data and draw funcs into command buffer - ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer, &fd->RenderBuffers); + ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); // Submit command buffer vkCmdEndRenderPass(fd->CommandBuffer); @@ -454,8 +454,8 @@ int main(int, char**) if (g_SwapChainRebuild) { g_SwapChainRebuild = false; + ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); ImGui_ImplVulkanH_CreateWindow(g_Instance, g_PhysicalDevice, g_Device, &g_WindowData, g_QueueFamily, g_Allocator, g_SwapChainResizeWidth, g_SwapChainResizeHeight, g_MinImageCount); - ImGui_ImplVulkan_SetSwapChainMinImageCount(g_MinImageCount); g_WindowData.FrameIndex = 0; } diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp index df8f84fc..fb54801f 100644 --- a/examples/imgui_impl_vulkan.cpp +++ b/examples/imgui_impl_vulkan.cpp @@ -20,8 +20,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_Window structure carries them.) -// 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: *BREAKING CHANGE*: Vulkan: Added ImageCount/MinImageCount fields in ImGui_ImplVulkan_InitInfo, required for initialization (was previously a hard #define IMGUI_VK_QUEUED_FRAMES 2). Added ImGui_ImplVulkan_SetMinImageCount(). // 2019-XX-XX: Vulkan: Added VkInstance argument to ImGui_ImplVulkanH_CreateWindow() 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). @@ -44,6 +43,27 @@ #include "imgui_impl_vulkan.h" #include +// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData() +// [Please zero-clear before use!] +struct ImGui_ImplVulkanH_FrameRenderBuffers +{ + VkDeviceMemory VertexBufferMemory; + VkDeviceMemory IndexBufferMemory; + VkDeviceSize VertexBufferSize; + VkDeviceSize IndexBufferSize; + VkBuffer VertexBuffer; + VkBuffer IndexBuffer; +}; + +// Each viewport will hold 1 ImGui_ImplVulkanH_WindowRenderBuffers +// [Please zero-clear before use!] +struct ImGui_ImplVulkanH_WindowRenderBuffers +{ + uint32_t Index; + uint32_t Count; + ImGui_ImplVulkanH_FrameRenderBuffers* FrameRenderBuffers; +}; + // Vulkan data static ImGui_ImplVulkan_InitInfo g_VulkanInitInfo = {}; static VkRenderPass g_RenderPass = VK_NULL_HANDLE; @@ -62,9 +82,14 @@ static VkImageView g_FontView = VK_NULL_HANDLE; static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE; static VkBuffer g_UploadBuffer = VK_NULL_HANDLE; +// Render buffers +static ImGui_ImplVulkanH_WindowRenderBuffers g_MainWindowRenderBuffers; + // Forward Declarations void ImGui_ImplVulkanH_DestroyFrame(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator); void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator); +void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator); +void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator); void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count); void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator); @@ -234,7 +259,7 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory // Render function // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) -void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, ImGui_ImplVulkan_FrameRenderBuffers* fd) +void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); @@ -243,23 +268,37 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm return; ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo; + + // Allocate array to store enough vertex/index buffers + ImGui_ImplVulkanH_WindowRenderBuffers* wrb = &g_MainWindowRenderBuffers; + if (wrb->FrameRenderBuffers == NULL) + { + wrb->Index = 0; + wrb->Count = v->ImageCount; + wrb->FrameRenderBuffers = new ImGui_ImplVulkanH_FrameRenderBuffers[wrb->Count]; + memset(wrb->FrameRenderBuffers, 0, sizeof(ImGui_ImplVulkanH_FrameRenderBuffers) * wrb->Count); + } + IM_ASSERT(wrb->Count == v->ImageCount); + wrb->Index = (wrb->Index + 1) % wrb->Count; + ImGui_ImplVulkanH_FrameRenderBuffers* rb = &wrb->FrameRenderBuffers[wrb->Index]; + VkResult err; - // Create the Vertex and Index buffers: + // Create or resize the vertex/index buffers size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert); size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx); - if (fd->VertexBuffer == VK_NULL_HANDLE || fd->VertexBufferSize < vertex_size) - CreateOrResizeBuffer(fd->VertexBuffer, fd->VertexBufferMemory, fd->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); - if (fd->IndexBuffer == VK_NULL_HANDLE || fd->IndexBufferSize < index_size) - CreateOrResizeBuffer(fd->IndexBuffer, fd->IndexBufferMemory, fd->IndexBufferSize, index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); + if (rb->VertexBuffer == VK_NULL_HANDLE || rb->VertexBufferSize < vertex_size) + CreateOrResizeBuffer(rb->VertexBuffer, rb->VertexBufferMemory, rb->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + if (rb->IndexBuffer == VK_NULL_HANDLE || rb->IndexBufferSize < index_size) + CreateOrResizeBuffer(rb->IndexBuffer, rb->IndexBufferMemory, rb->IndexBufferSize, index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); // Upload vertex/index data into a single contiguous GPU buffer { ImDrawVert* vtx_dst = NULL; ImDrawIdx* idx_dst = NULL; - err = vkMapMemory(v->Device, fd->VertexBufferMemory, 0, vertex_size, 0, (void**)(&vtx_dst)); + err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, vertex_size, 0, (void**)(&vtx_dst)); check_vk_result(err); - err = vkMapMemory(v->Device, fd->IndexBufferMemory, 0, index_size, 0, (void**)(&idx_dst)); + err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, index_size, 0, (void**)(&idx_dst)); check_vk_result(err); for (int n = 0; n < draw_data->CmdListsCount; n++) { @@ -271,15 +310,15 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm } VkMappedMemoryRange range[2] = {}; range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - range[0].memory = fd->VertexBufferMemory; + range[0].memory = rb->VertexBufferMemory; range[0].size = VK_WHOLE_SIZE; range[1].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - range[1].memory = fd->IndexBufferMemory; + range[1].memory = rb->IndexBufferMemory; range[1].size = VK_WHOLE_SIZE; err = vkFlushMappedMemoryRanges(v->Device, 2, range); check_vk_result(err); - vkUnmapMemory(v->Device, fd->VertexBufferMemory); - vkUnmapMemory(v->Device, fd->IndexBufferMemory); + vkUnmapMemory(v->Device, rb->VertexBufferMemory); + vkUnmapMemory(v->Device, rb->IndexBufferMemory); } // Bind pipeline and descriptor sets: @@ -291,10 +330,10 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm // Bind Vertex And Index Buffer: { - VkBuffer vertex_buffers[1] = { fd->VertexBuffer }; + VkBuffer vertex_buffers[1] = { rb->VertexBuffer }; VkDeviceSize vertex_offset[1] = { 0 }; vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, vertex_offset); - vkCmdBindIndexBuffer(command_buffer, fd->IndexBuffer, 0, sizeof(ImDrawIdx) == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32); + vkCmdBindIndexBuffer(command_buffer, rb->IndexBuffer, 0, sizeof(ImDrawIdx) == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32); } // Setup viewport: @@ -733,8 +772,9 @@ void ImGui_ImplVulkan_DestroyFontUploadObjects() void ImGui_ImplVulkan_DestroyDeviceObjects() { ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo; - + ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Instance, v->Device, &g_MainWindowRenderBuffers, v->Allocator); ImGui_ImplVulkan_DestroyFontUploadObjects(); + if (g_FontView) { vkDestroyImageView(v->Device, g_FontView, v->Allocator); g_FontView = VK_NULL_HANDLE; } if (g_FontImage) { vkDestroyImage(v->Device, g_FontImage, v->Allocator); g_FontImage = VK_NULL_HANDLE; } if (g_FontMemory) { vkFreeMemory(v->Device, g_FontMemory, v->Allocator); g_FontMemory = VK_NULL_HANDLE; } @@ -774,24 +814,17 @@ void ImGui_ImplVulkan_NewFrame() { } -// 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 ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count) { IM_ASSERT(min_image_count >= 2); - g_VulkanInitInfo.MinImageCount = min_image_count; -} + if (g_VulkanInitInfo.MinImageCount == min_image_count) + return; -// 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; + ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo; + VkResult err = vkDeviceWaitIdle(v->Device); + check_vk_result(err); + ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Instance, v->Device, &g_MainWindowRenderBuffers, v->Allocator); + g_VulkanInitInfo.MinImageCount = min_image_count; } @@ -1127,14 +1160,6 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui *wd = ImGui_ImplVulkanH_Window(); } -void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator) -{ - (void)instance; - vkDestroySemaphore(device, fsd->ImageAcquiredSemaphore, allocator); - vkDestroySemaphore(device, fsd->RenderCompleteSemaphore, allocator); - fsd->ImageAcquiredSemaphore = fsd->RenderCompleteSemaphore = VK_NULL_HANDLE; -} - void ImGui_ImplVulkanH_DestroyFrame(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator) { (void)instance; @@ -1147,6 +1172,33 @@ void ImGui_ImplVulkanH_DestroyFrame(VkInstance instance, VkDevice device, ImGui_ vkDestroyImageView(device, fd->BackbufferView, allocator); vkDestroyFramebuffer(device, fd->Framebuffer, allocator); - - ImGui_ImplVulkan_DestroyFrameRenderBuffers(instance, device, &fd->RenderBuffers, allocator); +} + +void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator) +{ + (void)instance; + vkDestroySemaphore(device, fsd->ImageAcquiredSemaphore, allocator); + vkDestroySemaphore(device, fsd->RenderCompleteSemaphore, allocator); + fsd->ImageAcquiredSemaphore = fsd->RenderCompleteSemaphore = VK_NULL_HANDLE; +} + +void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_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; +} + +void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator) +{ + for (uint32_t n = 0; n < buffers->Count; n++) + ImGui_ImplVulkanH_DestroyFrameRenderBuffers(instance, device, &buffers->FrameRenderBuffers[n], allocator); + delete[] buffers->FrameRenderBuffers; + buffers->FrameRenderBuffers = NULL; + buffers->Index = 0; + buffers->Count = 0; } diff --git a/examples/imgui_impl_vulkan.h b/examples/imgui_impl_vulkan.h index 55d72dfb..8b5421cc 100644 --- a/examples/imgui_impl_vulkan.h +++ b/examples/imgui_impl_vulkan.h @@ -39,29 +39,14 @@ struct ImGui_ImplVulkan_InitInfo void (*CheckVkResultFn)(VkResult err); }; -// Reusable buffers used for rendering by current in-flight frame, for ImGui_ImplVulkan_RenderDrawData() -// [Please zero-clear before use!] -// In the examples we store those in the helper ImGui_ImplVulkanH_FrameData structure, however as your own engine/app likely won't use the ImGui_Impl_VulkanH_XXXX helpers, -// you are expected to hold on as many ImGui_ImplVulkan_FrameRenderBuffers structures on your side as you have in-flight frames (== init_info.FramesQueueSize) -struct ImGui_ImplVulkan_FrameRenderBuffers -{ - VkDeviceMemory VertexBufferMemory; - VkDeviceMemory IndexBufferMemory; - VkDeviceSize VertexBufferSize; - VkDeviceSize IndexBufferSize; - VkBuffer VertexBuffer; - VkBuffer IndexBuffer; -}; - // Called by user code 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_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, ImGui_ImplVulkan_FrameRenderBuffers* buffers); +IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer); 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 min_image_count); // To override MinImageCount after initialization +IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated) // Called by ImGui_ImplVulkan_Init(), might be useful elsewhere. IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateDeviceObjects(); @@ -105,7 +90,6 @@ struct ImGui_ImplVulkanH_Frame VkImage Backbuffer; VkImageView BackbufferView; VkFramebuffer Framebuffer; - ImGui_ImplVulkan_FrameRenderBuffers RenderBuffers; }; struct ImGui_ImplVulkanH_FrameSemaphores @@ -132,7 +116,7 @@ struct ImGui_ImplVulkanH_Window uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data) ImGui_ImplVulkanH_Frame* Frames; ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores; - + ImGui_ImplVulkanH_Window() { memset(this, 0, sizeof(*this)); From 6bc47dfe48825b55c428e1ecb26910676ec7a007 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 5 Apr 2019 17:54:16 +0200 Subject: [PATCH 4/4] Vulkan: Removed superfluous vkInstance parameters being passed along. --- examples/imgui_impl_vulkan.cpp | 49 ++++++++++++++++------------------ 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp index fb54801f..48237139 100644 --- a/examples/imgui_impl_vulkan.cpp +++ b/examples/imgui_impl_vulkan.cpp @@ -86,12 +86,12 @@ static VkBuffer g_UploadBuffer = VK_NULL_HANDLE; static ImGui_ImplVulkanH_WindowRenderBuffers g_MainWindowRenderBuffers; // Forward Declarations -void ImGui_ImplVulkanH_DestroyFrame(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator); -void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator); -void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator); -void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator); -void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count); -void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator); +void ImGui_ImplVulkanH_DestroyFrame(VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator); +void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator); +void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator); +void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator); +void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count); +void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator); //----------------------------------------------------------------------------- // SHADERS @@ -772,7 +772,7 @@ void ImGui_ImplVulkan_DestroyFontUploadObjects() void ImGui_ImplVulkan_DestroyDeviceObjects() { ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo; - ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Instance, v->Device, &g_MainWindowRenderBuffers, v->Allocator); + ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &g_MainWindowRenderBuffers, v->Allocator); ImGui_ImplVulkan_DestroyFontUploadObjects(); if (g_FontView) { vkDestroyImageView(v->Device, g_FontView, v->Allocator); g_FontView = VK_NULL_HANDLE; } @@ -823,7 +823,7 @@ void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count) ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo; VkResult err = vkDeviceWaitIdle(v->Device); check_vk_result(err); - ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Instance, v->Device, &g_MainWindowRenderBuffers, v->Allocator); + ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &g_MainWindowRenderBuffers, v->Allocator); g_VulkanInitInfo.MinImageCount = min_image_count; } @@ -912,10 +912,9 @@ VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_d return VK_PRESENT_MODE_FIFO_KHR; // Always available } -void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator) +void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator) { - IM_ASSERT(instance != VK_NULL_HANDLE && physical_device != VK_NULL_HANDLE && device != VK_NULL_HANDLE); - (void)instance; + IM_ASSERT(physical_device != VK_NULL_HANDLE && device != VK_NULL_HANDLE); (void)physical_device; (void)allocator; @@ -973,7 +972,7 @@ int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_m } // Also destroy old swap chain and in-flight frames data, if any. -void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count) +void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count) { VkResult err; VkSwapchainKHR old_swapchain = wd->Swapchain; @@ -984,8 +983,8 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevi // Destroy old Framebuffer for (uint32_t i = 0; i < wd->ImageCount; i++) { - ImGui_ImplVulkanH_DestroyFrame(instance, device, &wd->Frames[i], allocator); - ImGui_ImplVulkanH_DestroyFrameSemaphores(instance, device, &wd->FrameSemaphores[i], allocator); + ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator); + ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator); } delete[] wd->Frames; delete[] wd->FrameSemaphores; @@ -1135,8 +1134,9 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkInstance instance, VkPhysicalDevi void ImGui_ImplVulkanH_CreateWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int width, int height, uint32_t min_image_count) { - ImGui_ImplVulkanH_CreateWindowSwapChain(instance, physical_device, device, wd, allocator, width, height, min_image_count); - ImGui_ImplVulkanH_CreateWindowCommandBuffers(instance, physical_device, device, wd, queue_family, allocator); + (void)instance; + ImGui_ImplVulkanH_CreateWindowSwapChain(physical_device, device, wd, allocator, width, height, min_image_count); + ImGui_ImplVulkanH_CreateWindowCommandBuffers(physical_device, device, wd, queue_family, allocator); } void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator) @@ -1146,8 +1146,8 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui for (uint32_t i = 0; i < wd->ImageCount; i++) { - ImGui_ImplVulkanH_DestroyFrame(instance, device, &wd->Frames[i], allocator); - ImGui_ImplVulkanH_DestroyFrameSemaphores(instance, device, &wd->FrameSemaphores[i], allocator); + ImGui_ImplVulkanH_DestroyFrame(device, &wd->Frames[i], allocator); + ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator); } delete[] wd->Frames; delete[] wd->FrameSemaphores; @@ -1160,9 +1160,8 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui *wd = ImGui_ImplVulkanH_Window(); } -void ImGui_ImplVulkanH_DestroyFrame(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator) +void ImGui_ImplVulkanH_DestroyFrame(VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator) { - (void)instance; vkDestroyFence(device, fd->Fence, allocator); vkFreeCommandBuffers(device, fd->CommandPool, 1, &fd->CommandBuffer); vkDestroyCommandPool(device, fd->CommandPool, allocator); @@ -1174,17 +1173,15 @@ void ImGui_ImplVulkanH_DestroyFrame(VkInstance instance, VkDevice device, ImGui_ vkDestroyFramebuffer(device, fd->Framebuffer, allocator); } -void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator) +void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator) { - (void)instance; vkDestroySemaphore(device, fsd->ImageAcquiredSemaphore, allocator); vkDestroySemaphore(device, fsd->RenderCompleteSemaphore, allocator); fsd->ImageAcquiredSemaphore = fsd->RenderCompleteSemaphore = VK_NULL_HANDLE; } -void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator) +void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkanH_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; } @@ -1193,10 +1190,10 @@ void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkInstance instance, VkDevice d buffers->IndexBufferSize = 0; } -void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator) +void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator) { for (uint32_t n = 0; n < buffers->Count; n++) - ImGui_ImplVulkanH_DestroyFrameRenderBuffers(instance, device, &buffers->FrameRenderBuffers[n], allocator); + ImGui_ImplVulkanH_DestroyFrameRenderBuffers(device, &buffers->FrameRenderBuffers[n], allocator); delete[] buffers->FrameRenderBuffers; buffers->FrameRenderBuffers = NULL; buffers->Index = 0;