diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index cec1217d..fbb2f499 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -1,6 +1,11 @@ // dear imgui: standalone example application for Glfw + Vulkan // If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. +// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own application. +// - Common ImGui_ImplVulkan_XXXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h. +// - Helper ImGui_ImplVulkanH_XXXX functions and structures are used by this example (main.cpp) and by imgui_impl_vulkan.cpp, +// but should PROBABLY NOT be used by your own app code. Read comments in imgui_impl_vulkan.h. + #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_vulkan.h" @@ -212,8 +217,7 @@ static void SetupVulkanWindowData(ImGui_ImplVulkanH_WindowData* wd, VkSurfaceKHR //printf("[vulkan] Selected PresentMode = %d\n", wd->PresentMode); // Create SwapChain, RenderPass, Framebuffer, etc. - ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, wd, g_Allocator, width, height, g_MinImageCount); - ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(g_PhysicalDevice, g_Device, g_QueueFamily, wd, g_Allocator); + ImGui_ImplVulkanH_CreateWindowData(g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); IM_ASSERT(wd->FramesQueueSize >= 2); } @@ -438,8 +442,7 @@ int main(int, char**) glfwPollEvents(); if (g_WantSwapChainRebuild) { - ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, &g_WindowData, g_Allocator, g_ResizeWidth, g_ResizeHeight, g_MinImageCount); - ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(g_PhysicalDevice, g_Device, g_QueueFamily, &g_WindowData, g_Allocator); + ImGui_ImplVulkanH_CreateWindowData(g_PhysicalDevice, g_Device, &g_WindowData, g_QueueFamily, g_Allocator, g_ResizeWidth, g_ResizeHeight, g_MinImageCount); ImGui_ImplVulkan_SetFramesQueueSize(g_WindowData.FramesQueueSize); g_WindowData.FrameIndex = 0; g_WantSwapChainRebuild = false; diff --git a/examples/example_sdl_vulkan/main.cpp b/examples/example_sdl_vulkan/main.cpp index 70ba5a2d..af331302 100644 --- a/examples/example_sdl_vulkan/main.cpp +++ b/examples/example_sdl_vulkan/main.cpp @@ -1,6 +1,11 @@ // dear imgui: standalone example application for SDL2 + Vulkan // If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. +// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own application. +// - Common ImGui_ImplVulkan_XXXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h. +// - Helper ImGui_ImplVulkanH_XXXX functions and structures are used by this example (main.cpp) and by imgui_impl_vulkan.cpp, +// but should PROBABLY NOT be used by your own app code. Read comments in imgui_impl_vulkan.h. + #include "imgui.h" #include "imgui_impl_sdl.h" #include "imgui_impl_vulkan.h" @@ -203,8 +208,7 @@ static void SetupVulkanWindowData(ImGui_ImplVulkanH_WindowData* wd, VkSurfaceKHR //printf("[vulkan] Selected PresentMode = %d\n", wd->PresentMode); // Create SwapChain, RenderPass, Framebuffer, etc. - ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, wd, g_Allocator, width, height, g_MinImageCount); - ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(g_PhysicalDevice, g_Device, g_QueueFamily, wd, g_Allocator); + ImGui_ImplVulkanH_CreateWindowData(g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); IM_ASSERT(wd->FramesQueueSize >= 2); } @@ -435,8 +439,7 @@ int main(int, char**) if (g_WantSwapChainRebuild) { - ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, &g_WindowData, g_Allocator, g_WindowData.Width, g_WindowData.Height, g_MinImageCount); - ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(g_PhysicalDevice, g_Device, g_QueueFamily, &g_WindowData, g_Allocator); + ImGui_ImplVulkanH_CreateWindowData(g_PhysicalDevice, g_Device, &g_WindowData, g_QueueFamily, g_Allocator, g_WindowData.Width, g_WindowData.Height, g_MinImageCount); ImGui_ImplVulkan_SetFramesQueueSize(g_WindowData.FramesQueueSize); g_WindowData.FrameIndex = 0; g_WantSwapChainRebuild = false; diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp index 2d6fc373..97a5b9a8 100644 --- a/examples/imgui_impl_vulkan.cpp +++ b/examples/imgui_impl_vulkan.cpp @@ -78,6 +78,15 @@ static VkImageView g_FontView = VK_NULL_HANDLE; static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE; static VkBuffer g_UploadBuffer = VK_NULL_HANDLE; +// Forward Declarations +void ImGui_ImplVulkanH_DestroyFrameData(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameData* fd, const VkAllocationCallbacks* allocator); +void ImGui_ImplVulkanH_CreateWindowDataSwapChain(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(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator); + +//----------------------------------------------------------------------------- +// SHADERS +//----------------------------------------------------------------------------- + // glsl_shader.vert, compiled with: // # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert /* @@ -183,6 +192,10 @@ static uint32_t __glsl_shader_frag_spv[] = 0x00010038 }; +//----------------------------------------------------------------------------- +// FUNCTIONS +//----------------------------------------------------------------------------- + static uint32_t ImGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits) { VkPhysicalDeviceMemoryProperties prop; @@ -727,20 +740,7 @@ void ImGui_ImplVulkan_InvalidateFontUploadObjects() } } -void ImGui_ImplVulkan_InvalidateDeviceObjects() -{ - ImGui_ImplVulkan_InvalidateFontUploadObjects(); - - if (g_FontView) { vkDestroyImageView(g_Device, g_FontView, g_Allocator); g_FontView = VK_NULL_HANDLE; } - if (g_FontImage) { vkDestroyImage(g_Device, g_FontImage, g_Allocator); g_FontImage = VK_NULL_HANDLE; } - if (g_FontMemory) { vkFreeMemory(g_Device, g_FontMemory, g_Allocator); g_FontMemory = VK_NULL_HANDLE; } - if (g_FontSampler) { vkDestroySampler(g_Device, g_FontSampler, g_Allocator); g_FontSampler = VK_NULL_HANDLE; } - if (g_DescriptorSetLayout) { vkDestroyDescriptorSetLayout(g_Device, g_DescriptorSetLayout, g_Allocator); g_DescriptorSetLayout = VK_NULL_HANDLE; } - if (g_PipelineLayout) { vkDestroyPipelineLayout(g_Device, g_PipelineLayout, g_Allocator); g_PipelineLayout = VK_NULL_HANDLE; } - if (g_Pipeline) { vkDestroyPipeline(g_Device, g_Pipeline, g_Allocator); g_Pipeline = VK_NULL_HANDLE; } -} - -void ImGui_ImplVulkan_InvalidateFrameDeviceObjects() +static void ImGui_ImplVulkan_InvalidateFrameDeviceObjects() { for (int i = 0; i < g_FramesDataBuffers.Size; i++) { @@ -753,6 +753,20 @@ void ImGui_ImplVulkan_InvalidateFrameDeviceObjects() g_FramesDataBuffers.clear(); } +void ImGui_ImplVulkan_InvalidateDeviceObjects() +{ + ImGui_ImplVulkan_InvalidateFrameDeviceObjects(); + ImGui_ImplVulkan_InvalidateFontUploadObjects(); + + if (g_FontView) { vkDestroyImageView(g_Device, g_FontView, g_Allocator); g_FontView = VK_NULL_HANDLE; } + if (g_FontImage) { vkDestroyImage(g_Device, g_FontImage, g_Allocator); g_FontImage = VK_NULL_HANDLE; } + if (g_FontMemory) { vkFreeMemory(g_Device, g_FontMemory, g_Allocator); g_FontMemory = VK_NULL_HANDLE; } + if (g_FontSampler) { vkDestroySampler(g_Device, g_FontSampler, g_Allocator); g_FontSampler = VK_NULL_HANDLE; } + if (g_DescriptorSetLayout) { vkDestroyDescriptorSetLayout(g_Device, g_DescriptorSetLayout, g_Allocator); g_DescriptorSetLayout = VK_NULL_HANDLE; } + if (g_PipelineLayout) { vkDestroyPipelineLayout(g_Device, g_PipelineLayout, g_Allocator); g_PipelineLayout = VK_NULL_HANDLE; } + if (g_Pipeline) { vkDestroyPipeline(g_Device, g_Pipeline, g_Allocator); g_Pipeline = VK_NULL_HANDLE; } +} + bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass) { ImGuiIO& io = ImGui::GetIO(); @@ -788,7 +802,6 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend void ImGui_ImplVulkan_Shutdown() { - ImGui_ImplVulkan_InvalidateFrameDeviceObjects(); ImGui_ImplVulkan_InvalidateDeviceObjects(); } @@ -811,6 +824,7 @@ void ImGui_ImplVulkan_SetFramesQueueSize(int frames_queue_size) //------------------------------------------------------------------------- // Internal / Miscellaneous Vulkan Helpers +// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own app.) //------------------------------------------------------------------------- // You probably do NOT need to use or care about those functions. // Those functions only exist because: @@ -818,9 +832,10 @@ void ImGui_ImplVulkan_SetFramesQueueSize(int frames_queue_size) // 2) the upcoming multi-viewport feature will need them internally. // Generally we avoid exposing any kind of superfluous high-level helpers in the bindings, // but it is too much code to duplicate everywhere so we exceptionally expose them. -// Your application/engine will likely already have code to setup all that stuff (swap chain, render pass, frame buffers, etc.). +// +// Your application/engine will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.). // You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work. -// (those functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions) +// (The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions) //------------------------------------------------------------------------- #include // malloc @@ -917,7 +932,7 @@ VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_d return VK_PRESENT_MODE_FIFO_KHR; // Always available } -void ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, uint32_t queue_family, ImGui_ImplVulkanH_WindowData* wd, const VkAllocationCallbacks* allocator) +void ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator) { IM_ASSERT(physical_device != VK_NULL_HANDLE && device != VK_NULL_HANDLE); (void)physical_device; @@ -975,7 +990,7 @@ int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_m return 1; } -void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count) +void ImGui_ImplVulkanH_CreateWindowDataSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count) { VkResult err; VkSwapchainKHR old_swapchain = wd->Swapchain; @@ -1126,6 +1141,12 @@ void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice } } +void ImGui_ImplVulkanH_CreateWindowData(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int width, int height, uint32_t min_image_count) +{ + ImGui_ImplVulkanH_CreateWindowDataSwapChain(physical_device, device, wd, allocator, width, height, min_image_count); + ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(physical_device, device, wd, queue_family, allocator); +} + void ImGui_ImplVulkanH_DestroyWindowData(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, const VkAllocationCallbacks* allocator) { vkDeviceWaitIdle(device); // FIXME: We could wait on the Queue if we had the queue in wd-> (otherwise VulkanH functions can't use globals) diff --git a/examples/imgui_impl_vulkan.h b/examples/imgui_impl_vulkan.h index 495f6d47..1fb2711b 100644 --- a/examples/imgui_impl_vulkan.h +++ b/examples/imgui_impl_vulkan.h @@ -15,8 +15,6 @@ #include -//#define IMGUI_VK_QUEUED_FRAMES 2 - // Please zero-clear before use. struct ImGui_ImplVulkan_InitInfo { @@ -41,15 +39,14 @@ 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_InvalidateFontUploadObjects(); -// Called by ImGui_ImplVulkan_Init() might be useful elsewhere. +// Called by ImGui_ImplVulkan_Init(), might be useful elsewhere. IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplVulkan_InvalidateDeviceObjects(); -IMGUI_IMPL_API void ImGui_ImplVulkan_InvalidateFrameDeviceObjects(); //------------------------------------------------------------------------- // Internal / Miscellaneous Vulkan Helpers -// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own app.) +// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own app.) //------------------------------------------------------------------------- // You probably do NOT need to use or care about those functions. // Those functions only exist because: @@ -57,18 +54,17 @@ IMGUI_IMPL_API void ImGui_ImplVulkan_InvalidateFrameDeviceObjects(); // 2) the upcoming multi-viewport feature will need them internally. // Generally we avoid exposing any kind of superfluous high-level helpers in the bindings, // but it is too much code to duplicate everywhere so we exceptionally expose them. -// Your application/engine will likely already have code to setup all that stuff (swap chain, render pass, frame buffers, etc.). +// +// Your application/engine will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.). // You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work. -// (those functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions) +// (The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions) //------------------------------------------------------------------------- struct ImGui_ImplVulkanH_FrameData; struct ImGui_ImplVulkanH_WindowData; -IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, uint32_t queue_family, ImGui_ImplVulkanH_WindowData* wd, const VkAllocationCallbacks* allocator); -IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count); +IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateWindowData(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count); IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindowData(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, const VkAllocationCallbacks* allocator); -IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyFrameData(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_FrameData* fd, const VkAllocationCallbacks* allocator); IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space); IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count); IMGUI_IMPL_API int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode);